Make changes to code to download attachments - vba

In Excel I use the following coding to download attachments from a sub folder in my inbox, it works fine but is it possible to ONLY download attachemnts from emails that are unread?
I would appreciate any advise or help that you can give me.
I think it might be If objItem.unread Then... but i'm not entirely sure how to implement it in my coding?
' public objects moved from Userform code module
Public OutlookApp As New Outlook.Application
Public oNameSpace As Namespace
Public oFldrList As Outlook.MAPIFolder
Public objItem As Outlook.MAPIFolder
Public oSubFldrList As Outlook.MAPIFolder
Public oSubFldritem As Outlook.MAPIFolder
Sub GetAttachments(Name As String)
On Error GoTo GetAttachments_err
Dim MyMail As MailItem
Dim ns As Namespace
Dim Inbox As MAPIFolder
Dim SubFolder As MAPIFolder
Dim Item As Object
Dim Atmt As Attachment
Dim FileName As String
Dim i As Integer
Dim olItem As MailItem
Dim olAtt As Outlook.Attachment
i = 0
If oFldrList.Folders.Count = 0 Then
MsgBox oFldrList.Name & " has no sub folders"
MsgBox "There are " & oFldrList.Items.Count & " items in folder"
Else
Set SubFolder = oFldrList.Folders(Name)
' MsgBox SubFolder.Name & " has " & SubFolder.Items.Count & " items folders"
End If
For Each olItem In SubFolder.Items
' MsgBox olItem.Subject & vbLf & "has " & olItem.Attachments.Count & " attachements"
For Each olAtt In olItem.Attachments
Select Case Right(olAtt.FileName, 4)
Case ".xls"
FileName = frmdownloadattchmts.TextBox1.Value & olAtt.FileName
olAtt.SaveAsFile FileName
i = i + 1
Case ".csv"
FileName = frmdownloadattchmts.TextBox1.Value & olAtt.FileName
olAtt.SaveAsFile FileName
i = i + 1
Case ".txt"
FileName = frmdownloadattchmts.TextBox1.Value & olAtt.FileName
olAtt.SaveAsFile FileName
i = i + 1
Case ".mp3"
FileName = frmdownloadattchmts.TextBox1.Value & olAtt.FileName
olAtt.SaveAsFile FileName
i = i + 1
Case ".jpg"
FileName = frmdownloadattchmts.TextBox1.Value & olAtt.FileName
olAtt.SaveAsFile FileName
i = i + 1
Case Else
Select Case Right(olAtt.FileName, 5)
Case ".xlsx"
FileName = frmdownloadattchmts.TextBox1.Value & olAtt.FileName
olAtt.SaveAsFile FileName
i = i + 1
Case ".alnk"
FileName = frmdownloadattchmts.TextBox1.Value & olAtt.FileName
olAtt.SaveAsFile FileName
i = i + 1
End Select
End Select
Next
Next
If i > 0 Then
MsgBox "I found " & i & " attached files." _
& vbCrLf & "I have saved them on the" & frmdownloadattchmts.TextBox1.Value & " Path." _
& vbCrLf & vbCrLf & " ", vbInformation, "Download Finished!"
Unload Me
Else
MsgBox "I didn't find any attached files in your mail.", vbInformation, _
"Finished!"
End If
GetAttachments_exit:
Set Atmt = Nothing
Set Item = Nothing
Set ns = Nothing
Exit Sub
GetAttachments_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information." _
& vbCrLf & "Macro Name: GetAttachments" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume GetAttachments_exit
End Sub

Something like this should work, though I'm not sure if Unread is a property only of MailItems, so you may also need to check what type of object it is before trying to read the Unread value
Dim fn
For Each olItem In SubFolder.Items
' MsgBox olItem.Subject & vbLf & "has " & olItem.Attachments.Count & " attachements"
If olItem.Unread Then
For Each olAtt In olItem.Attachments
fn = olAtt.Filename
If fn Like "*.xls" Or fn Like "*.csv" Or fn Like "*.txt" Or _
fn Like "*.mp3" Or fn Like "*.jpg" Or fn Like "*.xlsx" Or _
fn Like "*.alnk" Then
Filename = frmdownloadattchmts.TextBox1.Value & olAtt.Filename
olAtt.SaveAsFile Filename
i = i + 1
End If
Next 'attachment
End If 'unread
Next

Related

Create array of PDF files in directory that start with the letters "AB"

I'm trying to create a list of files in a specific directory folder where I am renaming the files, but because there is a chance some files should not be renamed, I only need to rename the PDF files that begin with the letters "AB".
The renaming works fine, I just need to make sure it only renames specific files.
Private Sub CMD_RENAME_FILES_Click()
On Error GoTo CMD_RENAME_FILES_ERR
Dim varDir As String
varDir = Me.TXT_BILLING_STATEMENT_PATH
If MsgBox("Are you sure you want to rename all of the files in the directory " & "'" & varDir & "'", vbYesNo, "Confirm") = vbNo Then
Exit Sub
Else
Dim strFileName, varDateString As String
Dim strFolder As String: strFolder = Nz(Me.TXT_BILLING_STATEMENT_PATH, "Z:\")
Dim strFileSpec As String: strFileSpec = strFolder & "*.pdf"
Dim FileList() As String
Dim intFoundFiles As Integer
DoCmd.RunSQL ("UPDATE tblDirFileList SET tblDirFileList.RenameSelection = -1 WHERE FileName LIKE 'AB*'")
strFileName = Dir(strFileSpec, "AB*.PDF") 'THIS AB* DOESN'T WORK"
varDateString = Format(Date, "mmddyy")
Do While Len(strFileName) > 0
ReDim Preserve FileList(intFoundFiles)
FileList(intFoundFiles) = strFileName
intFoundFiles = intFoundFiles + 1
varLoanNumString = Mid(strFileName, 4, 9)
varNewStrFile = varLoanNumString & " - BILL STMT - " & varDateString & ".pdf"
On Error Resume Next
Name strFolder & strFileName As strFolder & varNewStrFile
strFileName = Dir
Loop
Call CMD_GET_FILE_NAMES_Click
End If
CMD_RENAME_FILES_ERR_EXIT:
Exit Sub
CMD_RENAME_FILES_ERR:
Call LogError(Err.Number, Err.Description, "CMD_RENAME_FILES_Click()")
MsgBox "Error: (" & Err.Number & ") " & Err.Description, vbCritical
Resume CMD_RENAME_FILES_ERR_EXIT
End Sub

How to filter out gif files when removing attachments?

When I incorporate a filter into my VBA sub, it does not filter out all the gif files from being excluded.
The sub is to remove attachments from emails and replace them with a link.
I expect to skip all instances of the gif attachments. The reasoning is for email threads where users have gif pictures in their signature, and removing the gif files will ruin the cleanness of the thread, and make it difficult for users to see who wrote which part of the email.
Here is the entire sub.
Private Sub BrowseFolder()
Dim oShell As Object
Set oShell = CreateObject("Shell.Application")
Dim fsSaveFolder As Object
Set fsSaveFolder = oShell.BrowseForFolder(0, "Please Select a Save Folder:", 1)
'Set fsSaveFolder = oShell.BrowseForFolder(0, "Please Select a Save Folder:", NO_OPTIONS, "C:\users\" & Environ("Username") & "Documents\Outlook Files")
If fsSaveFolder Is Nothing Then Exit Sub
' Note: BrowseForFolder doesn't add a trailing slash
' Ask the user to select an Outlook folder to process
Dim olPurgeFolder As Outlook.MAPIFolder
Set olPurgeFolder = Outlook.GetNamespace("MAPI").PickFolder
If olPurgeFolder Is Nothing Then Exit Sub
Dim msg As Variant
Dim att As Outlook.Attachments
Dim sSavePathFS As String
Dim sDelAtts
For Each msg In olPurgeFolder.Items
On Error GoTo GetAttachments_err
sDelAtts = ""
If TypeName(msg) = "MailItem" Then
If msg.MessageClass <> "IPM.Note.SMIME.MultipartSigned" Then
If msg.MessageClass <> "IPM.Note.Secure.Sign" Then
'If msg.Attachments.Count > 0 Then '& olByValue <> 5 & olByValue <> 6 Then
Set att = msg.Attachments
lngCount = att.Count
DelAtts = ""
If lngCount > 0 Then
' We need to use a count down loop for removing items
' from a collection. Otherwise, the loop counter gets
' confused and only every other item is removed.
For i = lngCount To 1 Step -1
' Save attachment before deleting from item.
' Get the file name.
strFile = att.Item(i).FileName
' This code looks at the last 4 characters in a filename
sFileType = LCase$(Right$(strFile, 4))
If att.Item(i).Size < 5234111 Then
Select Case sFileType
' Add additional file types below
Case ".gif", "gif"
Case Else
'While msg.Attachments.Count > 0
On Error GoTo GetAttachments_err
' Save the attachment to the file system
sSavePathFS = fsSaveFolder.Self.Path & "\"
attachName = msg.Attachments(1).FileName
msg.Attachments(1).SaveAsFile sSavePathFS & Format(msg.ReceivedTime, "mm-dd-yyyy-ss") & attachName
' Build up a string to denote the file system save path(s)
' Format the string according to the msg.BodyFormat.
If msg.BodyFormat <> olFormatHTML Then
sDelAtts = sDelAtts & vbCrLf & "<file://" & sSavePathFS & Format(msg.ReceivedTime, "mm-dd-yyyy-ss") & attachName & ">"
Else
sDelAtts = sDelAtts & "<br>" & "<a href='file://" & sSavePathFS & Format(msg.ReceivedTime, "mm-dd-yyyy-ss") & attachName & "'>" & sSavePathFS & Format(msg.ReceivedTime, "mm-dd-yyyy-ss") & attachName & "</a>"
End If
' Delete the current attachment. We use a "1" here instead of an "i"
' because the .Delete method will shrink the size of the msg.Attachments
' collection for us. Use some well placed Debug.Print statements to see
' the behavior. ~~
msg.Attachments(1).Delete
' Wend
End Select
End If
Next
' Modify the body of the msg to show the file system location of
' the deleted attachments.
If msg.BodyFormat <> olFormatHTML Then
msg.Body = vbCrLf & vbCrLf & "Attachments Deleted: " & Date & " " & Time & vbCrLf & vbCrLf & "Saved To: " & vbCrLf & sDelAtts & msg.Body
Else
msg.HTMLBody = "<p></p><p>" & "Attachments Deleted: " & Date & " " & Time & vbCrLf & vbCrLf & "Saved To: " & vbCrLf & sDelAtts & "</p>" & msg.HTMLBody
End If
' Save the edits to the msg. If you forget this line, the attachments will not be deleted. ~~
msg.Save
End If
End If
End If
End If
Next
GetAttachments_exit:
Set att = Nothing
Set fso = Nothing
Set olPurgeFolder = Nothing
Exit Sub
' Handle errors
GetAttachments_err:
If Err.Description = "Outlook cannot perform this action on this type of attachment." Then
Err.Clear
Resume Next
End If
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information." _
& vbCrLf & "Macro Name: GetAttachments" _
& vbCrLf & "Error Number: " & Err.Number _
, vbCritical, "Error!"
Resume GetAttachments_exit
End Sub
Your code had some syntax errors. Those have been corrected in the code below.
If lngCount > 0 Then
For i = lngCount To 1 Step -1
' Save attachment before deleting from item.
' Get the file name.
strFile = att.Item(i).Filename
' This code looks at the last 4 characters in a filename
sFileType = LCase$(Right$(strFile, 4))
If att.Item(i).Size < 5234111 Then
Select Case sFileType
Case ".gif", "gif"
End Select
End If
Next
End If
If your intention is to delete the gif attachments then you might want to try att.Item(i).Delete on the line after Case ".gif", "gif"

VB script + delete files that contain word and older then X month

the following VB script , will remove the files under Temp dir and contain the word access.log
how to change this VB script in order to remove only files that contain the word "access.log" and are old then 1 or 2 or 3 ... month
I want to add in the VB some parameter that will contain the month Number
and the files will be deleted according to this parameter
for example if Month_do_del=12
Then only files that contain access.log that old then 12 month will be deleted
If LCase(Right(Wscript.FullName, 11)) = "wscript.exe" Then
strPath = Wscript.ScriptFullName
strCommand = "%comspec% /k cscript """ & strPath & """"
Set objShell = CreateObject("Wscript.Shell")
objShell.Run(strCommand), 1, True
Wscript.Quit
End If
Set objNetwork = CreateObject("WScript.Network")
strLog = "Files deleted on " & objNetwork.ComputerName & " at " & Now & VbCrLf & "===================================================="
Set objFSO = CreateObject("Scripting.FileSystemObject")
strFilesToDelete = ""
ShowSubFolders objFSO.GetFolder("G:\Temp")
If InStr(strFilesToDelete, "|") > 0 Then
arrFiles = Split(strFilesToDelete, "|")
For Each strFilePath In arrFiles
DeleteFile strFilePath
Next
ElseIf strFilesToDelete <> "" Then
DeleteFile strFilesToDelete
Else
WScript.Echo "No files were found."
strLog = strLog & VbCrLf & "No files were found."
End If
Set objLogFile = objFSO.CreateTextFile("C:\FileDeletionLog.log", True)
objLogFile.Write strLog
objLogFile.Close
Set objLogFile = Nothing
Sub ShowSubFolders(Folder)
On Error Resume Next
For Each objFile In Folder.Files
If Err.Number <> 0 Then
WScript.Echo "Error reading " & Folder.Path
strLog = strLog & VbCrLf & "Error reading " & Folder.Path
Err.Clear
On Error Resume Next
Exit For
Else
On Error GoTo 0
If Instr(UCase(objFile.Name), UCase ("access.log")) Then
If strFilesToDelete = "" Then
strFilesToDelete = objFile.Path
Else
strFilesToDelete = strFilesToDelete & "|" & objFile.Path
End If
End If
End If
Next
For Each Subfolder in Folder.SubFolders
ShowSubFolders Subfolder
Next
End Sub
Sub DeleteFile(strFilePath)
On Error Resume Next
WScript.Echo "Deleting " & strFilePath
objFSO.DeleteFile strFilePath, True
If Err.Number <> 0 Then
WScript.Echo "Could not delete " & strFilePath
strLog = strLog & VbCrLf & "Could not delete " & strFilePath
Err.Clear
On Error GoTo 0
Else
On Error GoTo 0
strLog = strLog & VbCrLf & "Successfully deleted " & strFilePath
End If
End Sub
I don't know if FileDateTime, Date and DateDiff are supported in VBS. If not you can easily port your VBS code to VBA. DateDiff will find the difference between two dates in months.
Function CheckMonths(nMonths As Integer, fPath As String) As Boolean
CheckMonths = False
If DateDiff("m", FileDateTime(fPath), Date) = nMonths Then
CheckMonths = True
End If
End Function
Change this line
If Instr(UCase(objFile.Name), UCase ("access.log")) Then
to this
If Instr(1, UCase(objFile.Name), UCase("access.log")) And DateDiff("m", objFile.DateLastModified, Date) >= 12 Then

VBA Outlook rule to Run Script is not completing

I'm have trouble with this macro/script that doesn't completely run via email rule
I have an outlook rule that looks for an email with a subject then move the email to a subfolder then runs a script that move the email attachment to a folder on the C drive and then deletes the original email from the subfolder
Everything seem to be setup correctly, security is ok, and the macro runs as a macro outside the rule It's just the rule doesn't run the script, here is the script I'm using
Sub Get_SOH_All(MyMail As MailItem)
On Error GoTo SaveAttachmentsToFolder_err
Dim ns As NameSpace
Dim Inbox As MAPIFolder
Dim SubFolder As MAPIFolder
Dim item As Object
Dim Atmt As Attachment
Dim FileName As String
Dim i As Integer
Dim varResponse As VbMsgBoxResult
Set ns = GetNamespace("MAPI")
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
Set SubFolder = Inbox.Folders("DATA DUMP") ' Enter correct subfolder name.
i = 0
If Len(Dir("c:\DATA DUMP\Stock On Hand", vbDirectory)) = 0 Then
MkDir "c:\DATA DUMP\Stock On Hand"
End If
For Each item In SubFolder.Items
For Each Atmt In item.Attachments
If Right(Atmt.FileName, 3) = "csv" Then
FileName = "C:\DATA DUMP\Stock On Hand\"
Atmt.SaveAsFile FileName & "Stock_On_Hand_All.csv"
item.Delete
i = i + 1
End If
Next Atmt
Next item
SaveAttachmentsToFolder_exit:
Set Atmt = Nothing
Set item = Nothing
Set ns = Nothing
Exit Sub
SaveAttachmentsToFolder_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information to Jarrod Hall." _
& vbCrLf & "Macro Name: GetAttachmentsSOH" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume SaveAttachmentsToFolder_exit
End Sub
The code in a script is normally used on one item not multiple.
The mail is to be deleted so you can drop the part of the rule that moves the mail and try this.
Sub Get_SOH_All(MyMail As MailItem)
On Error GoTo SaveAttachmentsToFolder_err
Dim Atmt As Attachment
Dim FileName As String
If Len(Dir("c:\DATA DUMP\Stock On Hand", vbDirectory)) = 0 Then
MkDir "c:\DATA DUMP\Stock On Hand"
End If
For Each Atmt In MyMail.Attachments
If Right(Atmt.FileName, 3) = "csv" Then
FileName = "C:\DATA DUMP\Stock On Hand\"
Atmt.SaveAsFile FileName & "Stock_On_Hand_All.csv"
MyMail.Delete
End If
Next Atmt
SaveAttachmentsToFolder_exit:
Set MyMail = Nothing
Exit Sub
SaveAttachmentsToFolder_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information to Jarrod Hall." _
& vbCrLf & "Macro Name: GetAttachmentsSOH" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume SaveAttachmentsToFolder_exit
End Sub

Outlook Macro to save attachments from public mailbox

I have the following macro, it all works fine but I would like it to read a public mailbox instead of the inbox, I would also like it to move the emails that have been processed to a different folder:
Option Explicit
Sub SaveSubFolderAttachments()
On Error GoTo SaveAttachmentsToFolder_err
' Declare variables
Dim ns As NameSpace
Dim Inbox As MAPIFolder
Dim SubFolder As MAPIFolder
Dim Item As Object
Dim Atmt As Attachment
Dim FileName As String
Dim i As Integer
Dim varResponse As VbMsgBoxResult
Set ns = GetNamespace("MAPI")
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
Set SubFolder = Inbox.Folders("Test") ' Enter correct subfolder name.
i = 0
' Check subfolder for messages and exit of none found
If SubFolder.Items.Count = 0 Then
MsgBox "There are no messages in folder.", vbInformation, _
"Nothing Found"
Exit Sub
End If
' Check each message for attachments
For Each Item In SubFolder.Items
For Each Atmt In Item.Attachments
FileName = "S:\SME folder\Registrations\NKC Test Email Extract\" & _
Format(Item.CreationTime, "yyyymmdd_hhnnss_") & Atmt.FileName
Atmt.SaveAsFile FileName
i = i + 1
Next Atmt
Next Item
' Show summary message
If i > 0 Then
varResponse = MsgBox("I found " & i & " attached files." _
& vbCrLf & "I have saved them into the S:\SME folder\Registrations\NKC Test Email Extract\ folder." _
& vbCrLf & vbCrLf & "Would you like to view the files now?" _
, vbQuestion + vbYesNo, "Finished!")
' Open Windows Explorer to display saved files if user chooses
If varResponse = vbYes Then
Shell "Explorer.exe /e,S:\SME folder\Registrations\NKC Test Email Extract\", vbNormalFocus
End If
Else
MsgBox "I didn't find any attached files in your mail.", vbInformation, "Finished!"
End If
' Clear memory
SaveAttachmentsToFolder_exit:
Set Atmt = Nothing
Set Item = Nothing
Set ns = Nothing
Exit Sub
' Handle Errors
SaveAttachmentsToFolder_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information." _
& vbCrLf & "Macro Name: GetAttachments" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume SaveAttachmentsToFolder_exit
End Sub
By "public mailbox", do you mean another user's mailbox? Use GetSharedDefaultFolder instead of GetDefaultFolder.