MS Word 2013 VBA Macro Function - vba

The following VBA Code will not save an open document to a sub-folder under the active 'My Documents' Folder. The code is called from App_DocumentBeforeClose and it executes without throwing a fault flag or process failed notification. All the code and save location string building works just the way its supposed to - the open document just doesn't get saved to the 'My Documents' sub-folder. The file itself is a working copy stored on a SDHC chip - could this be the problem? I have checked the folder rights and the sub-folder 'Read Only' attribute is turned off.
Public Sub SaveToTwoLocations()
Dim Res
Dim oDoc As Document, SourceFile As String, DestinationFile As String
Dim strBackUpPath As String, fDialog As FileDialog, Reps, DocName As String
If Right(ActiveWindow.Caption, 4) = "ode]" Then
DocName = Left(ActiveWindow.Caption, Len(ActiveWindow.Caption) - 21)
ElseIf Right(ActiveWindow.Caption, 5) = ".docx" Then
DocName = Left(ActiveWindow.Caption, Len(ActiveWindow.Caption) - 5)
End If
On Error GoTo CanceledByUser
Res = MsgBox("Save Source File?", vbQuestion + vbYesNo, "Save Original Prior to Back-Up Interrogative")
If Res = vbYes Then
Application.ActiveDocument.Save
End If
If GetSetting("My_Books", DocName, "Save_2") = "" Then
Set fDialog = Application.FileDialog(msoFileDialogFolderPicker)
With fDialog
.Title = "Select Folder to Save The Copy To & Click Ok"
.AllowMultiSelect = False
.InitialView = msoFileDialogViewList
If .Show <> -1 Then
MsgBox "Canceled By user", , "Save To Two Locatiions"
Exit Sub
End If
strBackUpPath = fDialog.SelectedItems.Item(1) & "\"
Res = MsgBox("Save File To Selected 'SaveTo' Location?", vbQuestion + vbYesNo, "'SaveTo' Interrogative")
If Res = vbYes Then
SaveSetting "My_Books", DocName, "Save_2", strBackUpPath
strBackUpPath = strBackUpPath & DocName & ".docx"
Application.ActiveDocument.SaveAs2 (strBackUpPath)
Else
Exit Sub
End If
End With
Else
strBackUpPath = GetSetting("My_Books", DocName, "Save_2")
Res = MsgBox("Save This Document To: " & strBackUpPath & "?", vbQuestion + vbYesNo, "Two Location Save Interrogative")
If Res = vbYes Then
If Right(ActiveDocument.Name, 1) = "x" Then
Application.ActiveDocument.SaveAs2 (strBackUpPath = strBackUpPath & DocName & ".docx")
Else
MsgBox "Non-docx Doument File Save Error", vbCritical, "2nd Location File Save Error"
GoTo CanceledByUser
End If
Else
Set fDialog = Application.FileDialog(msoFileDialogSaveAs)
With fDialog
.Title = "Select Folder to Save The Copy To & Click Ok"
.AllowMultiSelect = False
.InitialView = msoFileDialogViewList
If .Show <> -1 Then
MsgBox "File Save Canceled By User", , "Save To Two Locatiions Canceled"
Exit Sub
End If
End With
End If
End If
CanceledByUser:
End Sub

Application.ActiveDocument.SaveAs2 (strBackUpPath = strBackUpPath & DocName & ".docx")
should be
Application.ActiveDocument.SaveAs2 strBackUpPath

The code should have been: Application.ActiveDocument.SaveAs2 (strBackUpPath & DocName & ".docx") In my defense, I will say that Microsoft is often its own worst enemy for reasons amply documented elsewhere - as for the code as originally written, it would have worked in standard VB6, BUT VBA is not VB6. To Tim Williams I offer my thanks - while technically incorrect, you put me on to the right answer, AND it's possible the concatenation, as written was being misinterpreted by the compiler. But the concatenation as rewritten was still required for reasons of efficiency and compactness. Oh, and it's working perfectly now that i have corrected my mistake! Thanks to all!

Related

Print to PDF not working

My code is suppose to check cell j2 for an email address and if found, convert that specific tab to pdf and save it in a file path that the user chooses. It works fine on the original workbook I made the macro in. When I copy the code and try running it, it prints to pdf different sheets that don't even have anything in j2 with the incorrect tab name. I keep getting an Run time error 5 Invalid procedure call or argument when i run the code on the print pdf line.
Sub SaveSheetsAsPDF()
Dim DestFolder As String
Dim PDFFile As String
Dim wb As Worksheet
Dim AlwaysOverwritePDF As Boolean
'Speed up macro
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Prompt for file destination
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show = True Then
DestFolder = .SelectedItems(1)
Else
MsgBox "You must specify a folder to save the PDF into." & vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Must Specify Destination Folder"
Exit Sub
End If
End With
'Create new PDF file name including path and file extension
For Each wb In ThisWorkbook.Worksheets
'Test j2 for a mail address
If wb.Range("J2").Value Like "?*#?*.?*" Then
PDFFile = DestFolder & Application.PathSeparator & wb.Name & "-" & Format(Date, "mmyy") & ".pdf"
'If the PDF already exists
If Len(Dir(PDFFile)) > 0 Then
If AlwaysOverwritePDF = False Then
OverwritePDF = MsgBox(PDFFile & " already exists." & vbCrLf & vbCrLf & "Do you want to overwrite it?", vbYesNo + vbQuestion, "File Exists")
On Error Resume Next
'If you want to overwrite the file then delete the current one
If OverwritePDF = vbYes Then
Kill PDFFile
Else
MsgBox "OK then, if you don't overwrite the existing PDF, I can't continue." _
& vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Exiting Macro"
Exit Sub
End If
Else
On Error Resume Next
Kill PDFFile
End If
If Err.Number <> 0 Then
MsgBox "Unable to delete existing file. Please make sure the file is not open or write protected." _
& vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Unable to Delete File"
Exit Sub
End If
End If
End If
'Prints PDF
wb.ExportAsFixedFormat Type:=xlTypePDF, FileName:=PDFFile, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
Next wb
MsgBox "All Files Have Been Converted!"
ResetSettings:
'Resets optimization settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Edit: Also not all worksheets on the workbook will need to converted. So only the sheets that need to be converted will have the email address in J2.

Convert excel tabs to PDF and send in separate emails

I am trying to convert excel tabs to PDF and send each tab as a single attachment on different emails in outlook with different email recipients.
For example, Tab A would correspond to a "Vendor Emails" Tab with a To, Cc, and Bcc for each tab. Same would go for Tab B but a different set of recipients.
My Code:
Option Explicit
Sub create_and_email_pdf()
Dim EmailSubject As String, EmailSignature As String
Dim CurrentMonth As String, DestFolder As String, PDFFile As String
Dim Email_To As String, Email_CC As String, Email_BCC As String
Dim OpenPDFAfterCreating As Boolean, AlwaysOverwritePDF As Boolean, DisplayEmail As Boolean
Dim OverwritePDF As VbMsgBoxResult
Dim OutlookApp As Object, OutlookMail As Object
CurrentMonth = ""
EmailSubject = "Invoice Attached for "
OpenPDFAfterCreating = True
AlwaysOverwritePDF = False
DisplayEmail = True
Email_To = ThisWorkbook.Sheets("Vendor Emails").Range("B2").Value
Email_CC = ""
Email_BCC = ""
'Prompt for file destination
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show = True Then
DestFolder = .SelectedItems(1)
Else
MsgBox "You must specify a folder to save the PDF into." & vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Must Specify Destination Folder"
Exit Sub
End If
End With
'Current month/year
CurrentMonth = Mid(ThisWorkbook.Sheets("Vendor Emails").Range("E1").Value, InStr(1, ThisWorkbook.Sheets("Vendor Emails").Range("E1").Value, " ") + 1)
'Create new PDF file name including path and file extension
PDFFile = DestFolder & Application.PathSeparator & ActiveSheet.Name _
& "-" & CurrentMonth & ".pdf"
'If the PDF already exists
If Len(Dir(PDFFile)) > 0 Then
If AlwaysOverwritePDF = False Then
OverwritePDF = MsgBox(PDFFile & " already exists." & vbCrLf & vbCrLf & "Do you want to overwrite it?", vbYesNo + vbQuestion, "File Exists")
On Error Resume Next
'If you want to overwrite the file then delete the current one
If OverwritePDF = vbYes Then
Kill PDFFile
Else
MsgBox "OK then, if you don't overwrite the existing PDF, I can't continue." _
& vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Exiting Macro"
Exit Sub
End If
Else
On Error Resume Next
Kill PDFFile
End If
If Err.Number <> 0 Then
MsgBox "Unable to delete existing file. Please make sure the file is not open or write protected." _
& vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Unable to Delete File"
Exit Sub
End If
End If
'Create the PDF
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=PDFFile, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas _
:=False, OpenAfterPublish:=OpenPDFAfterCreating
'Create an Outlook object and new mail message
Set OutlookApp = CreateObject("Outlook.Application")
Set OutlookMail = OutlookApp.CreateItem(0)
'Display email and specify To, Subject, etc
With OutlookMail
.Display
.To = Email_To
.CC = Email_CC
.BCC = Email_BCC
.Subject = EmailSubject & CurrentMonth
.Attachments.Add PDFFile
If DisplayEmail = False Then
.Send
End If
End With
End Sub
I keep having an issue with this line, I keep getting a run-time 1004 and that the file may be open/error while saving:
'Create the PDF
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=PDFFile, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas _
:=False, OpenAfterPublish:=OpenPDFAfterCreating
If I don't use the reference ThisWookbook.Sheets(), I dont get an issue, but it only sends out the tab that I'm currently active on, not sure how to specify which tabs to convert.
For more context these tabs I'm converting would be part of a bigger worksheet with additional backup tabs that would not get sent as they are for internal purposes.
Thanks.

Saving a File in Desired Folder Through Browsing With VBA

Writing a code to save a file with a defined filename to a specific folder entered by the user. However the file is being saved in a location previous to the specified location. For example I provide file save path as "C:\Users\arorapr\Documents\PAT" but the file is saving it in the path "C:\Users\arorapr\Documents". I have written the below code.
File_Name = Format(Now(), "DDMMYYYY") & "_" & LName & EmpIN & "_" & Range("C6").Value & "_" & Range("J3").Value & "_" & "PAT"
Application.DisplayAlerts = False
MsgBox "Please select the folder to save PAT"
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
.Show
End With
ActiveWorkbook.saveas Filename:=File_Name & ".xlsm", FileFormat:=52
Application.DisplayAlerts = True
ActiveWorkbook.Close
Your challenge is that you're opening a file dialog, but not using the user's choice from that in the saveas. Try something along these lines:
Sub SaveFile()
Dim FolderName As String
File_Name = Format(Now(), "DDMMYYYY") & "_" & LName & EmpIN & "_" & Range("C6").Value & "_" & Range("J3").Value & "_" & "PAT"
Application.DisplayAlerts = False
MsgBox "Please select the folder to save PAT"
' Pop up the folder-selection box to get the folder form the user:
FolderName = GetFolder()
' If the user didn't select anything, you can't save, so tell them so:
If FolderName = "" Then
MsgBox "No folder was selected. Program will terminate."
Exit Sub
End If
' Create a path by combining the file and folder names:
File_Name = FolderName & "\" & File_Name & ".xlsm"
ActiveWorkbook.SaveAs Filename:=File_Name, FileFormat:=52
Application.DisplayAlerts = True
ActiveWorkbook.Close
End Sub
' A separate function to get the folder name and return it as a string
Function GetFolder() As String
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = Application.DefaultFilePath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
GetFolder = sItem
Set fldr = Nothing
End Function
Hope that helps.
In your code, you are not saving the path of the selected folder to a variable. In the code below, the path is saved to the variable selectedFolder, which gets its value from fldr.SelectedItems(1). Then the path + "\" + YourFileName & .xlsm is saved:
Option Explicit
Sub TestMe()
Dim fldr As FileDialog
Dim selectedFolder As String
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.Show
selectedFolder = .SelectedItems(1)
End With
ActiveWorkbook.SaveAs Filename:=selectedFolder & "\" & "YourFileName" & ".xlsm"
End Sub
Or alternatively, you may use a function, returning the folder's path from here:
VBA - Folder Picker - set where to start
A robust funciton, that I am using to GetFolder is this one:
Option Explicit
Sub myPathForFolder()
Debug.Print GetFolder(Environ("USERPROFILE"))
End Sub
Function GetFolder(Optional InitialLocation As String) As String
On Error GoTo GetFolder_Error
Dim FolderDialog As FileDialog
Dim SelectedFolder As String
If Len(InitialLocation) = 0 Then InitialLocation = ThisWorkbook.Path
Set FolderDialog = Excel.Application.FileDialog(msoFileDialogFolderPicker)
With FolderDialog
.Title = "My Title For Dialog"
.AllowMultiSelect = False
.InitialFileName = InitialLocation
If .Show <> -1 Then GoTo GetFolder_Error
SelectedFolder = .SelectedItems(1)
End With
GetFolder = SelectedFolder
On Error GoTo 0
Exit Function
GetFolder_Error:
Debug.Print "Error " & Err.Number & " (" & Err.Description & ")
End Function

Why doesn't my VB mail merge from Access actually send the email(s)?

I wish to mail merge and email from an Access query and pre setup word doc. It appears to work fine, as a the merged data document appears along with a new merged document that I have (for now) save. BUT what I really want it to do is send the actual email, rather than having to manually go to 'Finish & Merge" from MsWord. Simply it just doesn't actually send the email(s).
Function runMerge()
Dim StrFullDocPath As String
Dim oApp As Object
'Path to the word document
StrFullDocPath = "merge.docx" 'have removed the full path
'to save file name
outFileName = "Renewals_" & Format(Now(), "dd-mm-yyyy")
If Dir(StrFullDocPath) = "" Then
MsgBox "Document not found"
Else
'Create an instance of MS Word
Set oApp = CreateObject("Word.Application")
oApp.Visible = True
'Open the Document
oApp.Documents.Open FileName:=StrFullDocPath
End If
With oApp
With .ActiveDocument.MailMerge
.MainDocumentType = wdEMail
.OpenDataSource _
Name:="myDB.accdb", _
LinkToSource:=True, _
AddToRecentFiles:=False, _
Connection:="QUERY qryCheckRenews", _
SQLStatement:="SELECT * FROM [qryCheckRenews]"
.Destination = wdSendToEmail
.MailAddressFieldName = "EmailAddress"
.MailFormat = wdMailFormatHTML
.MailAsAttachment = False
.MailSubject = "testing testing 1, 2, 3"
.SuppressBlankLines = True
.Execute Pause:=False
MsgBox "Mail Merge Complete ", vbOKOnly, "myDB"
End With
oApp.ActiveDocument.SaveAs2 FileName:="Renewal" & outFileName & ".docx"
'oApp.Documents.Close savechanges:=False
Set oApp = Nothing
End With
'Exit Sub
'ErrTrap:
' MsgBox Err.Description, vbCritical
End Function
Any help gratefully received

Select filename using FileDialog

I am trying to get a fullpath and filename using the file dialog from MS Access VBA.
What I am trying to do is to open the file Dialog on button click by calling this function. This function should return the fullpath and filename that was selected from the filedialog.
I commented the loop part because I only want to select single file.
This function is returning an error Error: 0 after I select a file
So far this is my code.
Anyone can figure out what's wrong?
Thanks
Public Function SelectTheFile() As String
On Error GoTo SelectTheFile_ErrorHandler
Dim fDialog As Office.FileDialog
Dim varFile As Variant
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
.AllowMultiSelect = False
.Title = "Please select one file"
If .Show = True Then
'For Each varFile In .SelectedItems
'SelectTheFile = varFile
'Debug.Print SelectTheFile
'Next
SelectTheFile = .SelectedItems(1)
Debug.Print SelectTheFile
Else
Debug.Print "Cancel"
End If
End With
SelectTheFile_ErrorHandler:
Set fd = Nothing
MsgBox "Error " & Err & ": " & Error(Err)
End Function
your code always reach the SelectTheFile_ErrorHandler: section whatever the file dialog result
you must exit the function before that section
Public Function SelectTheFile() As String
On Error GoTo SelectTheFile_ErrorHandler
Dim fDialog As Office.FileDialog
Dim varFile As Variant
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
.AllowMultiSelect = False
.Title = "Please select one file"
If .Show = True Then
'For Each varFile In .SelectedItems
'SelectTheFile = varFile
'Debug.Print SelectTheFile
'Next
SelectTheFile = .SelectedItems(1)
Debug.Print SelectTheFile
Else
Debug.Print "Cancel"
End If
End With
Exit Function '<==== exit here, otherwise code goes on to following section
SelectTheFile_ErrorHandler:
Set fDialog = Nothing
MsgBox "Error " & Err & ": " & Error(Err)
End Function
Try just using this:
Application.GetOpenFilename
That works for me and saves the full file path without actually opening the file. Much simpler unless I am missing what you're trying to do. Read more here in the docs: https://msdn.microsoft.com/en-us/library/office/ff834966.aspx