PDA

View Full Version : [SOLVED:] Suppress Microsoft Word Security Notice with VBA



amount
01-27-2022, 05:17 PM
I'm using a VBA script to generate separate PDF files with a MS Word mail merge. The script is from here:


https://imnoss.com/word-mail-merge-to-separate-pdfs/


It works fine for most of the mail merge fields in my template. The only ones that pose a problem are dynamic image fields which don't update automatically.


Here is a sample field code for one of the images:



{ INCLUDEPICTURE "{FILENAME \p}/../signatures/{MERGEFIELD "LastName"}.png" \* MERGEFORMAT }


If I go to "Edit Individual Documents in Word," I need to update all of the fields manually to get the right images (CTRL+A > F9). I tried adding a line to the script to update the fields programmatically:



ActiveDocument.Fields.Update


But this results in a security popup:



Microsoft Office has identified a potential security concern.
This document contains fields that can share data with external files and websites. It is important that this file is from a trustworthy source.
Choosing Yes will enable updating all fields in this file, until you close it.


I don't want to have to press Yes hundreds of times whenever I run the script. Is there anyway to disable these security notices with VBA? If not, can they be disabled in the Word settings? I've tried adding this, but it didn't make a difference:



Application.DisplayAlerts = False


For reference, here is the script in its entirety:



Sub MailMergeToPdfBasic()


' Macro created by Imnoss Ltd
' Please share freely while retaining attribution
' Last Updated 2021-05-03


' Create variables ("Post-it Notes") for later use
Dim masterDoc As Document, singleDoc As Document, lastRecordNum As Long


' Identify the ActiveDocument (foremost doc when Macro run) as "masterDoc"
Set masterDoc = ActiveDocument

' jump to the last active record (active = ticked in edit recipients)
masterDoc.MailMerge.DataSource.ActiveRecord = wdLastRecord

' retrieve the record number of the last active record so we know when to stop
lastRecordNum = masterDoc.MailMerge.DataSource.ActiveRecord


' jump to the first active record (active = ticked in edit recipients)
masterDoc.MailMerge.DataSource.ActiveRecord = wdFirstRecord


' create a loop, lastRecordNum is used to end the loop by setting to zero (see below)
Do While lastRecordNum > 0


' Identify that we are creating a word docx (and no e.g. an email)
masterDoc.MailMerge.Destination = wdSendToNewDocument
' Limit the selection to just one document by setting the start ...
masterDoc.MailMerge.DataSource.FirstRecord = masterDoc.MailMerge.DataSource.ActiveRecord
' ... and end points to the active record
masterDoc.MailMerge.DataSource.LastRecord = masterDoc.MailMerge.DataSource.ActiveRecord
' run the MailMerge based on the above settings (i.e. for one record)
masterDoc.MailMerge.Execute False


' Identify the ActiveDocument (foremost doc after running the MailMerge) as "singleDoc"
Set singleDoc = ActiveDocument


' update all fields in active document
singleDoc.Fields.Update


' Save "singleDoc" as a word docx with the details provided in the DocFolderPath and DocFileName fields in the MailMerge data
singleDoc.SaveAs2 _
FileName:=masterDoc.Path & Application.PathSeparator & "output" & Application.PathSeparator & masterDoc.MailMerge.DataSource.DataFields("LastName").Value & "_" & masterDoc.MailMerge.DataSource.DataFields("FirstName").Value & ".docx", _
FileFormat:=wdFormatXMLDocument


' Export "singleDoc" as a PDF with the details provided in the PdfFolderPath and PdfFileName fields in the MailMerge data
singleDoc.ExportAsFixedFormat _
OutputFileName:=masterDoc.Path & Application.PathSeparator & "output" & Application.PathSeparator & masterDoc.MailMerge.DataSource.DataFields("LastName").Value & "_" & masterDoc.MailMerge.DataSource.DataFields("FirstName").Value & ".pdf", _
ExportFormat:=wdExportFormatPDF


' Close "singleDoc", the variable "singleDoc" can now be used for the next record when created
singleDoc.Close False


' test if we have just created a document for the last record
If masterDoc.MailMerge.DataSource.ActiveRecord >= lastRecordNum Then
' if so we set lastRecordNum to zero to indicate that the loop should end
lastRecordNum = 0
Else
' otherwise go to the next active record
masterDoc.MailMerge.DataSource.ActiveRecord = wdNextRecord
End If


' loop back to the Do start
Loop


' Mark the end of the Subroutine
End Sub

gmayor
01-27-2022, 11:08 PM
See https://www.gmayor.com/mail_merge_graphics.htm and https://www.gmayor.com/mail_merge_graphics_addin.htm with regard to the correct syntax for merging images.
You may find https://www.gmayor.com/email_merge_addin.html or https://www.gmayor.com/MergeAndSplit.htm useful. Both of these, when used with the correct syntax for graphics, will update the fields on the fly.
Ensure the document and its data and the images you are merging are stored on the local hard drive.

amount
01-28-2022, 03:30 AM
That worked!

I changed my picture field from:


{INCLUDEPICTURE "{FILENAME \p}/../signatures/{MERGEFIELD "LastName"}.png" \* MERGEFORMAT}

to:



{INCLUDEPICTURE "{IF TRUE "{FILENAME \p}/../signatures/{MERGEFIELD "LastName"}.png"}" \* MERGEFORMAT}


and the pictures updated without the need to refresh the fields.

Thanks!