I want to convert a list of text files in a particular folder into PDF.
I have written logic to open a single text file from Word document to be saved in a PDF format but it is not saved as a PDF file.
This is Excel VBA.
Dim file As Variant
inp_dir = "C:\Users\HP\OneDrive\Desktop\vbatest\pdfconv\"
inp_file_name = Dir(inp_dir & "*.txt") 'txt path
inp_file = inp_dir & inp_file_name
Dim wdApp As New Word.Application, wdDoc As Word.Document
MsgBox (inp_file)
' Set wdDoc = Documents.Open(inp_file)
Set wdDoc = Documents.Open(Filename:=inp_file, ReadOnly:=True, _
AddToRecentFiles:=False, Format:=wdOpenFormatAuto, Visible:=False)
wdDoc.SaveAs2 Filename:="inp_file" & Replace(inp_file, ".txt", ".pdf"), _
FileFormat:=wdFormatPDF, AddToRecentFiles:=False
wdDoc.Close False
I guess you are close - you just have a small mistake in your destination file name: You write Filename:="inp_file" & Replace(inp_file, ".txt", ".pdf"), but the fixed string "inp_file" makes no sense and invalidates the filename.
I always advice to use intermediate variables, with that it gets much easier to debug and to find errors.
Some more small things:
You should use Option Explicit and declare all variables.
You have a variable file declared that is never used.
declare your path as Constant
Your code could look like:
Const inp_dir = "C:\Users\HP\OneDrive\Desktop\vbatest\pdfconv\"
Dim inp_file_name As String, inp_full_name As String
inp_file_name = Dir(inp_dir & "*.txt") 'txt path
inp_full_name = inp_dir & inp_file_name
Dim wdApp As New Word.Application, wdDoc As Word.Document
Set wdDoc = wdApp.Documents.Open(Filename:=inp_full_name, ReadOnly:=True, _
AddToRecentFiles:=False, Format:=wdOpenFormatAuto, Visible:=False)
Dim pdf_Filename As String
pdf_Filename = Replace(inp_full_name, ".txt", ".pdf")
Debug.Print pdf_Filename
wdDoc.SaveAs2 Filename:=pdf_Filename, FileFormat:=wdFormatPDF, AddToRecentFiles:=False
wdDoc.Close False
wdApp.Quit
Your code is very close to running. Basically you need to open Word using your wdApp object. This example shows how...
Option Explicit
Sub TxtToPDF()
Dim inp_dir As String
Dim inp_file_name As String
Dim inp_file As String
inp_dir = "C:\Temp\"
inp_file_name = Dir(inp_dir & "*.txt") 'txt path
Dim wordWasRunning As Boolean
wordWasRunning = IsMSWordRunning
Dim wdApp As Word.Application
Set wdApp = AttachToMSWordApplication
Do While Len(inp_file_name) > 0
inp_file = inp_dir & inp_file_name
Debug.Print "currently opening " & inp_file
Dim wdDoc As Word.Document
Set wdDoc = wdApp.Documents.Open(Filename:=inp_file, _
ReadOnly:=True, _
AddToRecentFiles:=False, _
Format:=wdOpenFormatAuto, _
Visible:=False)
Dim out_file As String
out_file = Replace(inp_file, ".txt", ".pdf")
Debug.Print "saving as " & out_file
wdDoc.SaveAs2 Filename:=out_file, _
FileFormat:=wdFormatPDF, AddToRecentFiles:=False
wdDoc.Close False
'--- get the next txt file
inp_file_name = Dir
Loop
If Not wordWasRunning Then
wdApp.Quit
End If
End Sub
Put this code in another module to use (from my personal library).
Option Explicit
Public Function IsMSWordRunning() As Boolean
'--- quick check to see if an instance of MS Word is running
Dim msApp As Object
On Error Resume Next
Set msApp = GetObject(, "Word.Application")
If Err > 0 Then
'--- not running
IsMSWordRunning = False
Else
'--- running
IsMSWordRunning = True
End If
End Function
Public Function AttachToMSWordApplication() As Word.Application
'--- finds an existing and running instance of MS Word, or starts
' the application if one is not already running
Dim msApp As Word.Application
On Error Resume Next
Set msApp = GetObject(, "Word.Application")
If Err > 0 Then
'--- we have to start one
' an exception will be raised if the application is not installed
Set msApp = CreateObject("Word.Application")
End If
Set AttachToMSWordApplication = msApp
End Function
Related
I have a script that exports specific range of cell from Excel to Word. Below you can see the script
Sub Export_to_Word_Mac()
Dim filename As String
Dim FolderName As String
Dim Folderstring As String
Dim FilePathName As String
Dim sh As Worksheet
Dim print_area As Range
Dim appWD As Object
Dim wddoc As Object
Dim rng As Range
Dim paragraphCount As Long
Set sh = ThisWorkbook.Sheets("Sheet1")
sh.Unprotect
sh.Rows("15:16").EntireRow.Hidden = True
For Each rng In sh.Range("B17:B26")
If rng.Value Like "wpisz zakres usług tutaj..." Then
rng.EntireRow.Hidden = True
Else
rng.EntireRow.Hidden = False
End If
Next rng
sh.Protect
FolderName = "Export"
filename = sh.Range("G4") & "_test_" & Format(Now, "dd-mm-yyyy_hhmm") & ".docx"
Folderstring = CreateFolderinMacOffice2016(NameFolder:=FolderName)
FilePathName = Folderstring & Application.PathSeparator & filename
On Error Resume Next
Set appWD = GetObject(, "Word.application")
If Err = 429 Then
Set appWD = CreateObject("Word.application")
Err.Clear
End If
Set wddoc = appWD.Documents.Add
appWD.Visible = True
With appWD.ActiveDocument.PageSetup
.TopMargin = appWD.InchesToPoints(0.5)
.BottomMargin = appWD.InchesToPoints(0.5)
.LeftMargin = appWD.InchesToPoints(0.5)
.RightMargin = appWD.InchesToPoints(0.5)
End With
'copy range to word
Set print_area = sh.Range("B1:C27")
print_area.Copy
'paste range to Word table
paragraphCount = wddoc.Content.Paragraphs.Count
wddoc.Paragraphs(paragraphCount).Range.Paste
Application.CutCopyMode = False
appWD.ActiveDocument.Tables(1).Rows.Alignment = wdAlignRowCenter
appWD.ActiveDocument.Cells.VerticalAlignment = wdCellAlignVerticalTop
'appWD.Activate
appWD.ActiveDocument.SaveAs (FilePathName)
MsgBox "Plik zostal zapisany jako: " & vbNewLine & filename & vbNewLine & _
" w nowo stworzonym " & FolderName & " w folderze: " & vbNewLine & "Library/Group Containers/UBF8T346G9.Office/"
appWD.Quit
Set wddoc = Nothing
Set appWD = Nothing
End Sub
Function CreateFolderinMacOffice2016(NameFolder As String) As String
Dim OfficeFolder As String
Dim PathToFolder As String
Dim TestStr As String
OfficeFolder = MacScript("return POSIX path of (path to desktop folder) as string")
OfficeFolder = Replace(OfficeFolder, "/Desktop", "") & _
"Library/Group Containers/UBF8T346G9.Office/"
PathToFolder = OfficeFolder & NameFolder
On Error Resume Next
TestStr = Dir(PathToFolder & "*", vbDirectory)
On Error GoTo 0
If TestStr = vbNullString Then
MkDir PathToFolder
'MsgBox "You find the new folder in this location :" & PathToFolder
End If
CreateFolderinMacOffice2016 = PathToFolder
End Function
Unfortunetely, there are a couple of issues:
It takes 1,5-2 minutes to export and save the Word file. Could you please help me to optimize the code?
I need to open Word application on my Mac to run the script. Otherwise I get Run-time error '9' (Script out of Range). The issue is with this line: Set appWD = GetObject(, "Word.application") .
The only solution I came up with is to use .CopyPicture xlScreen and paste it to Word document. I takes arpund 5 second create Word file, however the content is not editable and it is saved as image.
Option 1: Keep using Copy but optimize VBA execution
There are many options to improve speed execution in Excel VBA (see this articles for more details), but the most useful when copy-pasting is certainly to set :
Application.ScreenUpdating = False
However, since you are pasting in Word, you'd have to do the same this for the Word Application to get the maximum speed improvement:
appWD.ScreenUpdating = False
Note: Make sure to reset Application.ScreenUpdating = True at the end of your code.
Option 2 : Use an array to transfer the data
If the formatting of the cell in Excel is not necessary, then you could load the content of the cells into an array and write this array to the word document like this:
'copy range to word
Dim DataArray() As Variant
DataArray = sh.Range("B1:C27").Value
Dim i As Integer, j As Integer
Dim MyWordRange As Object
Set MyRange = appWD.ActiveDocument.Range(0, 0)
appWD.ActiveDocument.Tables.Add Range:=MyRange, NumRows:=UBound(DataArray, 1), NumColumns:=UBound(DataArray, 2)
'paste range to Word table
For i = 1 To UBound(DataArray, 1)
For j = 1 To UBound(DataArray, 2)
appWD.ActiveDocument.Tables(1).Cell(i, j).Range.Text = DataArray(i, j)
Next j
Next i
Note that option 1 and 2 are not necessarily mutually exclusives.
So I got the project working with opening the .dotx and inserting the values from the excel file and saving as .docx.
But I can't for the life of me get it to save as .pdf instead. Well I can, but the pdf can't be opened.
Sub Cost_Statement()
Dim wrdApp As Word.Application
Dim wrdDoc As Word.Document
Dim i As Integer
Set wrdApp = CreateObject("Word.Application")
wrdApp.Visible = False
Application.ScreenUpdating = True
TemplateLocation = "C:\Custom documents\Cost_statement.dotx"
Set wrdDoc = wrdApp.Documents.Add(TemplateLocation, False, , False)
On Error GoTo NextNumber
cellno = "Main!C19"
FindText2 = "<<EXCELCOST>>"
ReplacementText2 = Range(cellno).Value
wrdDoc.Content.Find.Execute FindText2, ReplaceWith:=ReplacementText2, Replace:=wdReplaceAll
cellno = "Main!C20"
FindText3 = "<<EXCELDEST>>"
ReplacementText3 = Range(cellno).Value
wrdDoc.Content.Find.Execute FindText3, ReplaceWith:=ReplacementText3, Replace:=wdReplaceAll
NextNumber:
FileAddress = Range("Main!C21").Text
FileAddress = "C:\Cost Statement pdfs\" & FileAddress & ".docx"
With wrdDoc
.SaveAs (FileAddress)
.Close
End With
wrdApp.Quit
Set wrdDoc = Nothing
Set wrdApp = Nothing
End Sub
Any help would be appreciated.
Did you try this way?
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:="C:\PathPDF.pdf"
also note that
FileAddress = Range("Main!C21").Text
FileAddress = "C:\Cost Statement pdfs\" & FileAddress & ".docx"
is the same as
FileAddress = "C:\Cost Statement pdfs\" & FileAddress & ".docx"
I am looking for a completely lossless way of converting Excel and PowerPoint documents to PDF. I am using this script for Word and it works flawlessly https://gallery.technet.microsoft.com/office/Script-to-convert-Word-08c5154b. I am looking for a similar script for Excel and PowerPoint and cant find one on the internet. I dont have much experience with VB at all so I am confused where it specifies which office application to use. Is there anyone that can provide one for Excel and PowerPoint or someone proficient in VB that would be able to change the script to work with the other packages? I assume its just changing the intent as the programs integrated save as PDF option is the same?
The script for Word is below as well:
Option Explicit
'################################################
'This script is to convert Word documents to PDF files
'################################################
Sub main()
Dim ArgCount
ArgCount = WScript.Arguments.Count
Select Case ArgCount
Case 1
MsgBox "Please ensure Word documents are saved,if that press 'OK' to continue",,"Warning"
Dim DocPaths,objshell
DocPaths = WScript.Arguments(0)
StopWordApp
Set objshell = CreateObject("scripting.filesystemobject")
If objshell.FolderExists(DocPaths) Then 'Check if the object is a folder
Dim flag,FileNumber
flag = 0
FileNumber = 0
Dim Folder,DocFiles,DocFile
Set Folder = objshell.GetFolder(DocPaths)
Set DocFiles = Folder.Files
For Each DocFile In DocFiles 'loop the files in the folder
FileNumber=FileNumber+1
DocPath = DocFile.Path
If GetWordFile(DocPath) Then 'if the file is Word document, then convert it
ConvertWordToPDF DocPath
flag=flag+1
End If
Next
WScript.Echo "Totally " & FileNumber & " files in the folder and convert " & flag & " Word Documents to PDF fles."
Else
If GetWordFile(DocPaths) Then 'if the object is a file,then check if the file is a Word document.if that, convert it
Dim DocPath
DocPath = DocPaths
ConvertWordToPDF DocPath
Else
WScript.Echo "Please drag a word document or a folder with word documents."
End If
End If
Case Else
WScript.Echo "Please drag a word document or a folder with word documents."
End Select
End Sub
Function ConvertWordToPDF(DocPath) 'This function is to convert a word document to pdf file
Dim objshell,ParentFolder,BaseName,wordapp,doc,PDFPath
Set objshell= CreateObject("scripting.filesystemobject")
ParentFolder = objshell.GetParentFolderName(DocPath) 'Get the current folder path
BaseName = objshell.GetBaseName(DocPath) 'Get the document name
PDFPath = parentFolder & "\" & BaseName & ".pdf"
Set wordapp = CreateObject("Word.application")
Set doc = wordapp.documents.open(DocPath)
doc.saveas PDFPath,17
doc.close
wordapp.quit
Set objshell = Nothing
End Function
Function GetWordFile(DocPath) 'This function is to check if the file is a Word document
Dim objshell
Set objshell= CreateObject("scripting.filesystemobject")
Dim Arrs ,Arr
Arrs = Array("doc","docx")
Dim blnIsDocFile,FileExtension
blnIsDocFile= False
FileExtension = objshell.GetExtensionName(DocPath) 'Get the file extension
For Each Arr In Arrs
If InStr(UCase(FileExtension),UCase(Arr)) <> 0 Then
blnIsDocFile= True
Exit For
End If
Next
GetWordFile = blnIsDocFile
Set objshell = Nothing
End Function
Function StopWordApp 'This function is to stop the Word application
Dim strComputer,objWMIService,colProcessList,objProcess
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
'Get the WinWord.exe
Set colProcessList = objWMIService.ExecQuery _
("SELECT * FROM Win32_Process WHERE Name = 'Winword.exe'")
For Each objProcess in colProcessList
'Stop it
objProcess.Terminate()
Next
End Function
Call main
This will convert all Excel files into PDF files.
Sub Convert_Excel_To_PDF()
Dim MyPath As String, FilesInPath As String
Dim MyFiles() As String, Fnum As Long
Dim mybook As Workbook
Dim CalcMode As Long
Dim sh As Worksheet
Dim ErrorYes As Boolean
Dim LPosition As Integer
'Fill in the path\folder where the Excel files are
MyPath = "c:\Documents and Settings\shuerya\Desktop\ExcelFiles\"
FilesInPath = Dir(MyPath & "*.xl*")
If FilesInPath = "" Then
MsgBox "No files found"
Exit Sub
End If
Fnum = 0
Do While FilesInPath <> ""
Fnum = Fnum + 1
ReDim Preserve MyFiles(1 To Fnum)
MyFiles(Fnum) = FilesInPath
FilesInPath = Dir()
Loop
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
If Fnum > 0 Then
For Fnum = LBound(MyFiles) To UBound(MyFiles)
Set mybook = Nothing
On Error Resume Next
Set mybook = Workbooks.Open(MyPath & MyFiles(Fnum))
On Error GoTo 0
If Not mybook Is Nothing Then
LPosition = InStr(1, mybook.Name, ".") - 1
mybookname = Left(mybook.Name, LPosition)
mybook.Activate
'All PDF Files get saved in the directory below:
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\Documents and Settings\shuerya\Desktop\PDFFiles\" & mybookname & ".pdf", _
Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas _
:=False, OpenAfterPublish:=False
End If
mybook.Close SaveChanges:=False
Next Fnum
End If
If ErrorYes = True Then
MsgBox "There are problems in one or more files, possible problem:" _
& vbNewLine & "protected workbook/sheet or a sheet/range that not exist"
End If
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
Can you work with that??
This function creates a word doc, saves and closes it, but is failing when I attempt to reopen. It says this at the remote call doesn't work. What is the proper practice for reopening a word doc? Or is it unnecessary to close and open again? It appears there is difficulty with communication between word and excel.
Sub tester()
Dim wordApp As Object
Dim wordDoc As Object
Dim appendDate As String
Set wordApp = CreateObject("Word.Application")
wordApp.Visible = True
appendDate = "Y"
fName = "robot"
If appendDate = "Y" Or appendDate = "y" Then
fName = ThisWorkbook.Path & "\" & fName & "-" & Format(Now(), "yyyymmdd-hhmm") & ".docx"
Else
fName = ThisWorkbook.Path & "\" & fName & ".docx"
End If
wordApp.Documents.Add.SaveAs2 fileName:=fName
wordApp.Documents.Close
wordApp.Application.Quit
Set wordDoc = wordApp.Documents.Open(fileName:=fPath, readOnly:=False)
ThisWorkbook.Sheets("Sheet1").ChartObjects(1).Activate
ActiveChart.ChartArea.Copy
wordDoc.Application.Selection.PasteSpecial Link:=False, DataType:=wdPasteOLEObject, Placement:=wdInLine
End Sub
Since you quit the Word.Application then there's no more wordApp, so Documents.Open has no environment in which to execute.
If you want to open a file at any point, directly, without first starting the application you can use GetObject:
Set wordDoc = GetObject(FName)
If you need to address the Word.Application at a later point, after using GetObject to open the file:
Set wordApp = wordDoc.Application
This is how I would do it
Option Explicit
Const wdFormatXMLDocument As Integer = 12
Sub tester()
Dim wordApp As Object, wordDoc As Object
Dim appendDate As String, FName As String
Set wordApp = CreateObject("Word.Application")
wordApp.Visible = True
appendDate = "Y"
FName = "robot"
If UCase(appendDate) = "Y" Then '<~~ Unsure of this as you are already setting the value of Y
FName = ThisWorkbook.Path & "\" & FName & "-" & Format(Now(), "yyyymmdd-hhmm") & ".docx"
Else
FName = ThisWorkbook.Path & "\" & FName & ".docx"
End If
Set wordDoc = wordApp.Documents.Add
ThisWorkbook.Sheets("Sheet1").ChartObjects(1).Activate
ActiveChart.ChartArea.Copy
wordApp.Selection.PasteSpecial Link:=False, DataType:=0, Placement:=0
wordDoc.SaveAs2 Filename:=FName, FileFormat:=wdFormatXMLDocument
wordDoc.Close (False)
wordApp.Quit
Set wordDoc = Nothing
Set wordApp = Nothing
End Sub
Screenshot
I have an Excel VBA script that creates a pdf of the active worksheet and then sends an email with Outlook with the pdf attached.
Then I have a rule in Outlook that runs a script on Emails that arrive in the Sent folder based on keywords in the subject that saves a pdf copy of that email and/or it's attachments.
I would rather just have the Excel VBA script save that pdf copy of the email that was just sent by the excel vba script. Otherwise, I would need to implement the Outlook "run as script" rule on every computer in our system.
How can I marry the Outlook script with the Excel script??
Excel Code to send email (works fine):
Sub AttachActiveSheetPDF_01()
Dim IsCreated As Boolean
Dim PdfFile As String, Title As String
Dim OutlApp As Object
' Define PDF filename
Title = Range("C218").Value
PdfFile = CreateObject("WScript.Shell").SpecialFolders("Desktop") & "\" & Title & ".pdf"
' Exportactivesheet as PDF
With ActiveSheet
.ExportAsFixedFormat Type:=xlTypePDF, FileName:=PdfFile, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
End With
' Use already open Outlook if possible
On Error Resume Next
Set OutlApp = GetObject(, "Outlook.Application")
If Err Then
Set OutlApp = CreateObject("Outlook.Application")
IsCreated = True
End If
OutlApp.Visible = True
On Error GoTo 0
' Prepare e-mail with PDF attachment
With OutlApp.CreateItem(0)
' Prepare e-mail
.Subject = Title
.To = "" ' <-- Put email of the recipient here
.CC = "" ' <-- Put email of 'copy to' recipient here
.Body = "Hello," & vbLf & vbLf _
& "Please find attached a completed case review." & vbLf & vbLf _
& "Thank you," & vbLf _
& Application.UserName & vbLf & vbLf
.Attachments.Add PdfFile
' Try to send
Application.Visible = True
.Display
End With
' Quit Outlook if it was not already open
If IsCreated Then OutlApp.Quit
' Release the memory of object variable
Set OutlApp = Nothing
End Sub
Outlook script to save pdf copy of email (works fine):
Function CleanFileName(strText As String) As String
Dim strStripChars As String
Dim intLen As Integer
Dim i As Integer
strStripChars = "/\[]:=," & Chr(34)
intLen = Len(strStripChars)
strText = Trim(strText)
For i = 1 To intLen
strText = Replace(strText, Mid(strStripChars, i, 1), "")
Next
CleanFileName = strText
End Function
Sub SaveAsPDF(MyMail As MailItem)
' ### Requires reference to Microsoft Scripting Runtime ###
' ### Requires reference to Microsoft Word Object Library ###
' --- In VBE click TOOLS > REFERENCES and check the boxes for both of the above ---
Dim fso As FileSystemObject
Dim strSubject As String
Dim strSaveName As String
Dim blnOverwrite As Boolean
Dim strFolderPath As String
Dim sendEmailAddr As String
Dim senderName As String
Dim looper As Integer
Dim plooper As Integer
Dim strID As String
Dim olNS As Outlook.NameSpace
Dim oMail As Outlook.MailItem
strID = MyMail.EntryID
Set olNS = Application.GetNamespace("MAPI")
Set oMail = olNS.GetItemFromID(strID)
' ### Get username portion of sender email address ###
sendEmailAddr = oMail.SenderEmailAddress
senderName = Left(sendEmailAddr, InStr(sendEmailAddr, "#") - 1)
' ### USER OPTIONS ###
blnOverwrite = False ' False = don't overwrite, True = do overwrite
' ### Path to save directory ###
bPath = "Z:\email\"
' ### Create Directory if it doesnt exist ###
If Dir(bPath, vbDirectory) = vbNullString Then
MkDir bPath
End If
' ### Get Email subject & set name to be saved as ###
emailSubject = CleanFileName(oMail.Subject)
saveName = Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & emailSubject & ".mht"
Set fso = CreateObject("Scripting.FileSystemObject")
' ### Increment filename if it already exists ###
If blnOverwrite = False Then
looper = 0
Do While fso.FileExists(bPath & saveName)
looper = looper + 1
saveName = Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & senderName & "_" & emailSubject & "_" & looper & ".mht"
Loop
Else
End If
' ### Save .mht file to create pdf from Word ###
oMail.SaveAs bPath & saveName, olMHTML
pdfSave = bPath & Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & senderName & "_" & emailSubject & ".pdf"
If fso.FileExists(pdfSave) Then
plooper = 0
Do While fso.FileExists(pdfSave)
plooper = plooper + 1
pdfSave = bPath & Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & senderName & "_" & emailSubject & "_" & plooper &
".pdf"
Loop
Else
End If
' ### Open Word to convert .mht file to PDF ###
Dim wrdApp As Word.Application
Dim wrdDoc As Word.Document
Set wrdApp = CreateObject("Word.Application")
' ### Open .mht file we just saved and export as PDF ###
Set wrdDoc = wrdApp.Documents.Open(FileName:=bPath & saveName, Visible:=True)
wrdApp.ActiveDocument.ExportAsFixedFormat OutputFileName:= _
pdfSave, ExportFormat:= _
wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
wdExportOptimizeForPrint, Range:=wdExportAllDocument, From:=0, To:=0, _
Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
BitmapMissingFonts:=True, UseISO19005_1:=False
wrdDoc.Close
wrdApp.Quit
' ### Delete .mht file ###
Kill bPath & saveName
' ### Uncomment this section to save attachments ###
'If oMail.Attachments.Count > 0 Then
' For Each atmt In oMail.Attachments
' atmtName = CleanFileName(atmt.FileName)
' atmtSave = bPath & Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & atmtName
' atmt.SaveAsFile atmtSave
' Next
'End If
Set oMail = Nothing
Set olNS = Nothing
Set fso = Nothing
End Sub
It shouldn't be hard to change your outlook-vba to excel-vba, just move your outlook script to Excel Module and modify the following line.
Set App = CreateObject("Outlook.Application") '<- add
Set olNS = App.GetNamespace("MAPI") '<- change
Now create new Module and add the following code
Option Explicit
Sub Outlook()
Dim olNameSpace As Outlook.Namespace
Dim olApp As Outlook.Application
Dim olFolder As Outlook.MAPIFolder
Dim olItem As Object
Set olApp = CreateObject("Outlook.Application")
Set olNameSpace = olApp.GetNamespace("MAPI")
Set olFolder = olNameSpace.GetDefaultFolder(olFolderSentMail)
Set olItem = olApp.CreateItem(olMailItem)
For Each olItem In olFolder.Items
If olItem.Class = olMail Then
If olItem.Subject = [A1] Then '< - update cell range
Debug.Print olItem
SaveAsPDF olItem '< - Call SaveAsPDF code
End If
End If
Next
End Sub
the code will search outlook sent folder by [Subject] so update to mach your Excel code [Subject Title range]
If olItem.Subject = [A1] Then ' Update cell [C218]
If subject found then call outlook script
SaveAsPDF olItem
Remember to add - in VBE click TOOLS > REFERENCES and check the boxes for
Microsoft Outlook Object Library & Microsoft Scripting Runtime
Here is my final combined working code if anyone is interested (all in 1 module)
All props for combining code goes to Om3r who's got a frosty Colorado microbrew waiting for him!
This code will:
Create a PDF of Active Worksheet, Attach it to Email
After user sends email, searches Sent Mail folder for that email
Saves a PDF copy of the sent email (and attachments if desired)
Sorry about the 'pre' format but ctrl+K wasn't cutting it! Scratch that, got it
Sub AttachActiveSheetPDF()
Dim IsCreated As Boolean
Dim PdfFile As String, Esub As String
Dim OutlApp As Object
Dim sendTime As String
sendTime = Now()
sendTime = Format(sendTime, "yyyy-mm-dd-hhmmss")
' ### Define email subject and PDF path & filename ###
Esub = sendTime & "_Completed Case Review"
PdfFile = CreateObject("WScript.Shell").SpecialFolders("Desktop") & "\" & Esub & ".pdf"
' ### Export ActiveSheet to PDF ###
With ActiveSheet
.ExportAsFixedFormat Type:=xlTypePDF, Filename:=PdfFile, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
End With
' ### Open Outlook ###
On Error Resume Next
Set OutlApp = GetObject(, "Outlook.Application") '<-- If open, use it
If Err Then
Set OutlApp = CreateObject("Outlook.Application") '<-- If not, open it
IsCreated = True
End If
OutlApp.Visible = True
On Error GoTo 0
' ### Prepare email and attach pdf created above ###
With OutlApp.CreateItem(0)
.Subject = Esub
.To = "" ' <-- Put email of the recipient here
.CC = ""
.Body = "Hello," & vbLf & vbLf _
& "Please find attached a completed case review." & vbLf & vbLf _
& "Thank you," & vbLf _
& Application.UserName & vbLf & vbLf
.Attachments.Add PdfFile
' Try to send
Application.Visible = True
.Display True '<-- True forces code to wait for user to send email. Or just automate what the user is doing and change this to .Send
End With
Application.Wait (Now + TimeValue("0:00:05")) '<-- 5 second delay allows email to finish sending
' ### Search Sent Mail folder for emails with same timestamp in subject ###
Dim olNameSpace As Outlook.Namespace
Dim olFolder As Outlook.MAPIFolder
Dim olItem As Object
Set olNameSpace = OutlApp.GetNamespace("MAPI")
Set olFolder = olNameSpace.GetDefaultFolder(olFolderSentMail)
Set olItem = OutlApp.CreateItem(olMailItem)
For Each olItem In olFolder.Items
If olItem.Class = olMail Then
If olItem.Subject = Esub Then '<-- check for match
SaveAsPDF olItem '< - Call SaveAsPDF code
End If
End If
Next
If IsCreated Then OutlApp.Quit '<-- Quit Outlook if it was not already open
Set OutlApp = Nothing '<-- Release the memory of object variable
' ### Delete our temp pdf file if not needed anymore ###
Kill PdfFile
End Sub
Sub SaveAsPDF(MyMail As MailItem)
' ### Requires reference to Microsoft Scripting Runtime ###
' ### Requires reference to Microsoft Outlook Object Library ###
' ### Requires reference to Microsoft Word Object Library ###
' --- In VBE click TOOLS > REFERENCES and check the boxes for all of the above ---
Dim fso As FileSystemObject
Dim emailSubject As String
Dim saveName As String
Dim blnOverwrite As Boolean
Dim bPath As String
Dim strFolderPath As String
Dim sendEmailAddr As String
Dim senderName As String
Dim looper As Integer
Dim plooper As Integer
Dim strID As String
Dim olNS As Outlook.Namespace
Dim oMail As Outlook.MailItem
strID = MyMail.EntryID
Set App = CreateObject("Outlook.Application")
Set olNS = App.GetNamespace("MAPI")
Set oMail = olNS.GetItemFromID(strID)
' ### Get username portion of sender's email address ###
sendEmailAddr = oMail.SenderEmailAddress
senderName = Left(sendEmailAddr, InStr(sendEmailAddr, "#") - 1)
' ### USER OPTIONS ###
blnOverwrite = False ' False = don't overwrite, True = do overwrite
' ### Path to directory for saving pdf copy of sent email ###
bPath = "Z:\MyEmailFolder\"
' ### Create Directory if it doesnt exist ###
If Dir(bPath, vbDirectory) = vbNullString Then
MkDir bPath
End If
' ### Get Email subject & set name to be saved as ###
emailSubject = CleanFileName(oMail.Subject)
saveName = emailSubject & ".mht"
Set fso = CreateObject("Scripting.FileSystemObject")
' ### Save .mht file to create pdf from within Word ###
oMail.SaveAs bPath & saveName, olMHTML
pdfSave = bPath & emailSubject & "_" & senderName & "_" & ".pdf"
' ### Open Word to convert .mht file to PDF ###
Dim wrdApp As Word.Application
Dim wrdDoc As Word.Document
Set wrdApp = CreateObject("Word.Application")
' ### Open .mht file we just saved and export as PDF ###
Set wrdDoc = wrdApp.Documents.Open(Filename:=bPath & saveName, Visible:=True)
wrdApp.ActiveDocument.ExportAsFixedFormat OutputFileName:= _
pdfSave, ExportFormat:= _
wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
wdExportOptimizeForPrint, Range:=wdExportAllDocument, From:=0, To:=0, _
Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
BitmapMissingFonts:=True, UseISO19005_1:=False
wrdDoc.Close
wrdApp.Quit
' ### Delete our temp .mht file ###
Kill bPath & saveName
' ### Uncomment this section to save attachments also ###
'If oMail.Attachments.Count > 0 Then
' For Each atmt In oMail.Attachments
' atmtName = CleanFileName(atmt.FileName)
' atmtSave = bPath & Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & atmtName
' atmt.SaveAsFile atmtSave
' Next
'End If
Set oMail = Nothing
Set olNS = Nothing
Set fso = Nothing
End Sub
Function CleanFileName(strText As String) As String
Dim strStripChars As String
Dim intLen As Integer
Dim i As Integer
strStripChars = "/\[]:=," & Chr(34)
intLen = Len(strStripChars)
strText = Trim(strText)
For i = 1 To intLen
strText = Replace(strText, Mid(strStripChars, i, 1), "")
Next
CleanFileName = strText
End Function