PDF file seach and sending it through outlook - vba

the below code search for the file in the mentioned folder and send the searched file through outlook. But I need to add few more conditions to it.
It should also mention the count of files found in the folder with the same name > duplicate files< and put the count in excel sheet next to the file name.
The below code only search in a respective folder and not in sub-folders. It should search in sub-folders as well inside the folder for the files.
Sub CheckandSend()
Dim obMail As Outlook.MailItem
Dim irow As Integer
Dim dpath As String
Dim pfile As String
`dpath = "xxxx"
`'' loop through all files and send mail
irow = 1
Do While Cells(irow, 1) <> Empty
'' get file name in column A
pfile = Dir(dpath & "\*" & Cells(irow, 1) & "*")
'' check file exist and pdf file
If pfile <> "" And Right(pfile, 3) = "pdf"
Then
Set obMail = Outlook.CreateItem(olMailItem)
With obMail
.To = "xxx#domain.com"
.Subject = "123"
.BodyFormat = olFormatPlain
.Body = "123"
.Attachments.Add (dpath & "\" & pfile)
.Send
End With
End If
irow = irow + 1
Loop
End sub

You could simplify your code to this, which will search the directory (and sub-directories) for all PDF files using Windows scripting and then send each file found.
This handles your second issue, but I don't understand your first issue as:
a) How can you have identically named files in the same folder?
b) You haven't showed what you have tried yourself so far.
Sub SO()
Const masterFolder As String = "C:\Users\Macro Man\Files"
Dim files, file
files = Filter(Split(CreateObject("WScript.Shell").Exec("CMD /C DIR """ & masterFolder & "\*.pdf"" /S /B /A:-D").StdOut.ReadAll, vbCrLf), ".")
For Each file In files
With Outlook.CreateItem(0)
.To = "xxx#domain.com"
.Subject = "123"
.BodyFormat = olFormatPlain
.Body = "123"
.Attachments.Add CStr(file)
.Send
End With
Next
End Sub

Related

Delete files in a folder that are not found in Excel Spreadsheet

I developed a code that loops through files and folders' names found in an Excel Spreadsheet, finds them in a folder and deletes them.
The problem is that there are some files and folders that don't appear on the spreadsheet, but still need to be deleted.
My goal is to have more free space.
Someone suggested i copied the folder list into another column, match the file names and then delete the ones that don't match.
I'd prefer automation, though.
Any suggestions?
Thanks in advance!
Code:
Sub DeleteSpecificFilesAndFolders()
'This module deletes Extracted Files folders, Flat Files folders and Final Flat Files (.txt format)
Const path = "C:\Users\N\Desktop\Kill_function_test\Test folder for deleting\"
Dim r As Range
Dim r2 As Range
Dim folderpath As String
Dim folderpath_1 As String
Dim fso As FileSystemObject
Set fso = New Scripting.FileSystemObject
Set r2 = Cells(2, 1)
Do Until r2 = ""
folderpath = path & r2 & "\" & "Extracted Files"
'Checks if the folder exists and then deletes it.
If fso.FolderExists(folderpath) Then
fso.DeleteFolder (folderpath)
End If
'Checks if the folder exists and then deletes it
folderpath_1 = path & r2 & "\" & "Flat Files"
If fso.FolderExists(folderpath_1) Then
fso.DeleteFolder (folderpath_1)
End If
Set r2 = r2.Offset(1, 0)
DoEvents
Loop
'Loops through and deletes the "INACTIVE" Final Flat Files (.txt)
Set r = Cells(1, 5)
Do Until r = ""
If UCase(r.Value) = "INACTIVE" Then
'Checks if the extracted flat file exists.
If Dir(path & r.Offset(0, -4) & "\" & "Final Flat Files" & "\" & r.Offset(0, 1) & ".txt") <> "" Then
Kill path & r.Offset(0, -4) & "\" & "Final Flat Files" & "\" & r.Offset(0, 1) & ".txt"
End If
End If
Set r = r.Offset(1, 0)
Loop
End Sub
Try the code below. I used the Dir() command/function. This allows you to obtain all the folder/files that exists in a path.
Sub DeleteSpecificFilesAndFolders()
'This module deletes Extracted Files folders, Flat Files folders and Final Flat Files (.txt format)
Const path = "C:\Users\N\Desktop\Kill_function_test\Test folder for deleting\"
Dim r As Range
Dim folderpath As String
Dim folderpath_1 As String
Dim FolderName As String
Dim fso As FileSystemObject
Set fso = New Scripting.FileSystemObject
FolderName=Dir(Path & "*", vbDirectory)
While FolderName <> ""
if Not FolderName like "*.*" then 'This is because when using Dir(,vbdirectory) you can get . and .. or if files exist
folderpath = path & FolderName & "\" & "Extracted Files"
'Checks if the folder exists and then deletes it.
If fso.FolderExists(folderpath) Then
fso.DeleteFolder (folderpath)
End If
'Checks if the folder exists and then deletes it
folderpath_1 = path & FolderName & "\" & "Flat Files"
If fso.FolderExists(folderpath_1) Then
fso.DeleteFolder (folderpath_1)
End If
end if
FolderName=Dir() 'This will set FolderName to the next folder
DoEvents
wend
'Loops through and deletes the "INACTIVE" Final Flat Files (.txt)
Set r = Cells(1, 5)
Do Until r = ""
If UCase(r.Value) = "INACTIVE" Then
'Checks if the extracted flat file exists.
If Dir(path & r.Offset(0, -4) & "\" & "Final Flat Files" & "\" & r.Offset(0, 1) & ".txt") <> "" Then
Kill path & r.Offset(0, -4) & "\" & "Final Flat Files" & "\" & r.Offset(0, 1) & ".txt"
End If
End If
Set r = r.Offset(1, 0)
Loop
End Sub
Hope this helps

Unable to search/loop through subfolders

Can any one help why I can't pickup file from sub-folders?
My code will locate locate and attach the file to an email if the file is in the main folder, but not if the file is located in sub-folders.
Code Sample:
Set obMail = Outlook.CreateItem(olMailItem)
With obMail
.to = "email#comapny.com"
.Subject = "O/S Blanace"
.BodyFormat = olFormatPlain
.Body = "Please see attached files"
iRow = 24 'initialize row index from 24
Do While Cells(iRow, 1) <> Empty
'picking up file name from column A
pFile = Dir(dPath & "\*" & Cells(iRow, 1) & "*")
'checking for file exist in a folder and if its a pdf file
If pFile <> "" And Right(pFile, 3) = "pdf" Then
.Attachments.Add (dPath & "\" & pFile)
End If
'go to next file listed on the A column
iRow = iRow + 1
Loop
.Send
End With
The Dir function doesn't traverse subfolders. It traverses the path you give it, not the tree structure. It also resets when called so calling recursively is not an option.
So if you pass it "C:\Test\" you can use it to traverse Test; if cell contains "C:\Test\NextTest\", you can use it to iterate over NextTest.
What you can do is use a Collection to hold each directory and explore recursively in that way.
For an example of how to do this see the following from How To Traverse Subdirectories with Dir
Sub TraversePath(path As String)
Dim currentPath As String, directory As Variant
Dim dirCollection As Collection
Set dirCollection = New Collection
currentPath = Dir(path, vbDirectory)
'Explore current directory
Do Until currentPath = vbNullString
Debug.Print currentPath
If Left(currentPath, 1) <> "." And _
(GetAttr(path & currentPath) And vbDirectory) = vbDirectory Then
dirCollection.Add currentPath
End If
currentPath = Dir()
Loop
'Explore subsequent directories
For Each directory In dirCollection
Debug.Print "---SubDirectory: " & directory & "---"
TraversePath path & directory & "\"
Next directory
End Sub
Sub Test()
TraversePath "C:\Root\"
End Sub
You can easily adapt this to suit your purposes.

Attach Multiple files via VBA

Can someone please help me edit below script to add multiple files listed on 3rd column (Column C) of the spreadsheet?
My current macro looks for one file at a time and sends out individual emails. I need it to look for multiple files name (in listed folder path) listed in column C (3rd Column) and it does this until it reaches the empty cell.
My current scrip is below where you will see it looks for one file at a time.
Sub AttachandSendEmail()
Dim obMail As Outlook.MailItem
Dim irow As Integer
Dim dpath As String
Dim pfile As String
'file path
dpath = "C:\Users\filelocation"
'looping through all the files and sending an mail
irow = 1
Do While Cells(irow, 3) <> Empty
'pikcing up file name from column C
pfile = Dir(dpath & "\*" & Cells(irow, 3) & "*")
'checking for file exist in a folder and if its a pdf file
If pfile <> "" And Right(pfile, 3) = "pdf" Then
Set obMail = Outlook.CreateItem(olMailItem)
With obMail
.To = "email#comapny.com"
.Subject = "O/S Blanace"
.BodyFormat = olFormatPlain
.Body = "Please see attached files"
.Attachments.Add (dpath & "\" & pfile)
.Send
End With
End If
'go to next file listed on the C column
irow = irow + 1
Loop
End Sub
Try this, it sends one message with all files attached.
Set obMail = Outlook.CreateItem(olMailItem)
With obMail
.To = "email#comapny.com"
.Subject = "O/S Blanace"
.BodyFormat = olFormatPlain
.Body = "Please see attached files"
Do While Cells(irow, 3) <> Empty
'pikcing up file name from column C
pfile = Dir(dpath & "\*" & Cells(irow, 3) & "*")
'checking for file exist in a folder and if its a pdf file
If pfile <> "" And Right(pfile, 3) = "pdf" Then
.Attachments.Add (dpath & "\" & pfile)
End If
'go to next file listed on the C column
irow = irow + 1
Loop
.Send
End With

Save attachments to a folder in outlook and rename them

I am trying to save outlook attachments to a folder and where the filename already exists save the newer file under a different name so as not to save over the existing file....perhaps just give an extension "v2" or even "v3" if "v2" exists.
I came across this answer but am finding that the newer file is saved over the existing file
Save attachments to a folder and rename them
I have used the below code;
Dim objAttachments As Outlook.Attachments
Dim objSelection As Outlook.Selection
Dim i As Long
Dim lngCount As Long
Dim strFile As String
Dim strFolderpath As String
Dim strDeletedFiles As String
' Get the path to your My Documents folder
strFolderpath = "C:\Users\Owner\my folder is here"
On Error Resume Next
' Instantiate an Outlook Application object.
Set objOL = CreateObject("Outlook.Application")
' Get the collection of selected objects.
Set objSelection = objOL.ActiveExplorer.Selection
' Set the Attachment folder.
strFolderpath = strFolderpath & "\my subfolder is here\"
' Check each selected item for attachments. If attachments exist,
' save them to the strFolderPath folder and strip them from the item.
For Each objMsg In objSelection
' This code only strips attachments from mail items.
' If objMsg.class=olMail Then
' Get the Attachments collection of the item.
Set objAttachments = objMsg.Attachments
lngCount = objAttachments.Count
strDeletedFiles = ""
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 = objAttachments.Item(i).FileName
' Combine with the path to the Temp folder.
strFile = strFolderpath & strFile
' Save the attachment as a file.
objAttachments.Item(i).SaveAsFile strFile
' Delete the attachment.
objAttachments.Item(i).Delete
'write the save as path to a string to add to the message
'check for html and use html tags in link
If objMsg.BodyFormat <> olFormatHTML Then
strDeletedFiles = strDeletedFiles & vbCrLf & "<file://" & strFile & ">"
Else
strDeletedFiles = strDeletedFiles & "<br>" & "<a href='file://" & _
strFile & "'>" & strFile & "</a>"
End If
'Use the MsgBox command to troubleshoot. Remove it from the final code.
'MsgBox strDeletedFiles
Next i
' Adds the filename string to the message body and save it
' Check for HTML body
If objMsg.BodyFormat <> olFormatHTML Then
objMsg.Body = vbCrLf & "The file(s) were saved to " & strDeletedFiles & vbCrLf & objMsg.Body
Else
objMsg.HTMLBody = "<p>" & "The file(s) were saved to " & strDeletedFiles & "</p>" & objMsg.HTMLBody
End If
objMsg.Save
End If
Next
ExitSub:
Set objAttachments = Nothing
Set objMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
End Sub
I am relatively new to vba so perhaps the solution is there but am not seeing it!
Take a look at my code below. It goes through all of the items in a specific Outlook folder (that you designate), goes through each attachment in each item, and saves the attachment in a specified file path.
'Establish path of folder you want to save to
Dim FilePath As Variant
FilePath = "C:\Users\Owner\my folder is here\my subfolder is here\"
Set FSOobj = CreateObject("Scripting.FilesystemObject")
'If path doesn't exist, create it. If it does, either do nothing or delete its contents
If FSOobj.FolderExists(FilePath) = False Then
FSOobj.CreateFolder FilePath
Else
' This code is if you want to delete the items in the existing folder first.
' It's not necessary for your case.
On Error Resume Next
Kill FilePath & "*.*"
On Error GoTo 0
End If
'Establish Outlook folders, attachments, and other items
Dim msOutlook As Outlook.NameSpace 'Establish Outlook NameSpace
Dim Folder As Outlook.MAPIFolder 'Establish Folder as a MAPIFolder
Dim messageAttachments As Outlook.Attachments
Set msOutlook = Application.GetNamespace("MAPI")
'Set the folder that contains the email with the attachment
Set Folder = msOutlook.GetDefaultFolder(olFolderInbox).Folders("FOLDER NAME HERE")
Set folderItems = Folder.Items
Dim folderItemsCount As Long
folderItemsCount = folderItems.Count
Dim number as Integer
number = 1
For i = 1 To folderItemsCount
'If you want to pull the attachments on some criteria, like the Subject of the email or
'the date received, you need to write an IF statement like:
'If InStr(Folder.Items(i).Subject, "SPECIFIC SUBJECT TEXT") Then
Set messageAttachments = folderItems.item(i).Attachments
lngCount = messageAttachments.Count 'This lets you pull more than one attachment per message
For thisAttachment = 1 To lngCount
messageAttachments.item(thisAttachment).SaveAsFile FilePath & "YOUR_CHOSEN_FILENAME" & number & ".xlsx"
number = number + 1
Next thisAttachment
Next i
EDIT
In order to delete the items after scraping the attachments, you would use the same code as above except you would also include folderItems.item(i).Delete. Also, since you are moving items, I switched to looping backwards in your for loop as to not mess up your iteration. I've written it below:
For i = folderItemsCount To 1 Step -1
'If you want to pull the attachments on some criteria, like the Subject of the email or
'the date received, you need to write an IF statement like:
'If InStr(Folder.Items(i).Subject, "SPECIFIC SUBJECT TEXT") Then
Set messageAttachments = folderItems.item(i).Attachments
lngCount = messageAttachments.Count 'This lets you pull more than one attachment per message
For thisAttachment = 1 To lngCount
messageAttachments.item(thisAttachment).SaveAsFile FilePath & "YOUR_CHOSEN_FILENAME" & number & ".xlsx"
number = number + 1
Next thisAttachment
folderItems.item(i).Delete
Next i
I hope this helps!

Word macro that removes highlight in batch from .doc documents (and saves it as .docx)

I was searching for macro that batch opens .doc documents and save them as .docx. I have already found one. Now I want to remove any highlight (keep the text; as well as to do more cleaning operations) in all the documents. When I add a line into it (to the best place I could guess), then it runs continuously without stopping after the last document. Any idea where and how to do amend it ?
Sub batch_cleaner()
Dim strFilename As String
Dim strDocName As String
Dim strPath As String
Dim oDoc As Document
Dim fDialog As FileDialog
Dim intPos As Integer
Set fDialog = Application.FileDialog(msoFileDialogFolderPicker)
With fDialog
.Title = "Select folder and click OK"
.AllowMultiSelect = False
.InitialView = msoFileDialogViewList
If .Show <> -1 Then
MsgBox "Cancelled By User", , "List Folder Contents"
Exit Sub
End If
strPath = fDialog.SelectedItems.Item(1)
If Right(strPath, 1) <> "\" Then strPath = strPath + "\"
End With
If Documents.Count > 0 Then
Documents.Close SaveChanges:=wdPromptToSaveChanges
End If
If Left(strPath, 1) = Chr(34) Then
strPath = Mid(strPath, 2, Len(strPath) - 2)
End If
strFilename = Dir$(strPath & "*.doc")
While Len(strFilename) <> 0
Set oDoc = Documents.Open(strPath & strFilename)
' here I was trying to add stuff
strDocName = ActiveDocument.FullName
intPos = InStrRev(strDocName, ".")
strDocName = Left(strDocName, intPos - 1)
strDocName = strDocName & ".docx"
oDoc.SaveAs FileName:=strDocName, _
FileFormat:=wdFormatDocumentDefault
oDoc.Close SaveChanges:=wdDoNotSaveChanges
strFilename = Dir$()
Wend
End Sub
And this code always ruins it:
Selection.WholeStory
Selection.Range.HighlightColorIndex = wdNoHighlight
The problem lies in the "short name" (8.3 name) for your .docx files. It'll still have a name ending in .doc so it also finds your new file in the dir$() call.
This can be demonstrated at a command prompt fairly easily (fake .doc file just to show the name issue):
C:\> echo x> 1.docx
C:\> if exist *.doc echo y
y
C:\> dir *.doc
09/03/2014 06:27 PM 3 1.docx
C:\> dir /x *.doc
09/03/2014 06:27 PM 3 100FD~1.DOC 1.docx
So you see the short name, although hidden from normal view, is actually a .DOC file so it matches. Likewise in your script it'll match.
A couple of options come to mind offhand:
name the files to something else that won't match like .xyz and then do a bulk rename later
use subdirectories to store the resulting files so it won't, again, match in the dir$() call