I know this has been asked before and I tried to update the other thread but was not allowed.
I have a spreadsheet that has data that is used in a MS mail merge. I have a Word mail merge document that is all set up to run. The fields are already set up. When I open the word doc I get a prompt that says "Opening this document will run the following SQL command", etc, etc. What I want to do is have the Excel spreadsheet run the mail merge without any user intervention when I click a button. I put together the following code from examples on this forum but is not working. When run Word opens and I get the same prompt. How do I get this to work?
Public Sub RunMailMerge(MMFileName As String)
Dim wdDoc As Object
' open the mail merge layout file
Set wdDoc = GetObject(MMFileName, "Word.document")
wdDoc.Application.Visible = True
With wdDoc.MailMerge
.MainDocumentType = wdFormLetters
.Destination = wdSendToPrinter
.SuppressBlankLines = True
.Execute Pause:=False
End With
' cleanup
wdDoc.Close SaveChanges:=False
Set wdDoc = Nothing
End Sub
Also all of the examples I have seen use late binding. Wouldn't it better to use early bind of the word object?
Thanks Don
How about this concept?
Sub PushToWord()
Dim objWord As New Word.Application
Dim doc As Word.Document
Dim bkmk As Word.Bookmark
sWdFileName = Application.GetOpenFilename(, , , , False)
Set doc = objWord.Documents.Open(sWdFileName)
objWord.activedocument.variables("FirstName").Value = Range("FirstName").Value
objWord.activedocument.variables("LastName").Value = Range("LastName").Value
ActiveDocument.Fields.Update
objWord.Visible = True
End Sub
Add DocVariables to your word document, and name them appropriately. Run the code from Excel.
The prompt that is described in the "Symptoms" section is by design.
This prompt exists in all later versions of Microsoft Office and was introduced in Office XP Service Pack 3. This prompt was added in the products listed in the "Applies to" section to make mail merge more secure. If you click Yes when you receive the prompt, you let code run on your computer. A malicious user may be able to craft a SQL query that is designed to steal or to destroy data that you have access to. If you click No when you receive the prompt, you do not let code to run.
Note Setting DisplayAlerts=none through VBA suppresses the prompt when the file is opened by using VBA, but uses the NO option to open the document and no data is attached to the mail merge main document .
There are two basic approaches that can be used to run a mail merge without triggering the prompt. Note that the prompt is a security measure since the SQL a mail merge runs could cause harm to a system. The prompt ensures that the user is aware of this and (supposedly) only runs the mail merge if the document is from a "trusted source".
The advantage to this approach is that it upholds Word's security setting. If the user allows the VBA to run, then supposedly the entire project is trusted, so attaching the data source using code is allowed.
The data source can be removed from the document by choosing the option to open the document without allowing the mail merge (the button labelled "No" in the version of Word I'm looking at). Save the document in that state. Add a line to your code that links in the data source before executing the mail merge.
In order to figure out the necessary syntax, you can either record a macro while connecting to the data source (this is most certain and fastest), or you can query the data source from the document before disconnecting it. In Word, in the Immediate Window ( Ctrl + G ) of the VBA Editor enter the ?
lines and press Enter, one-by-one:
?ActiveDocument.MailMerge.DataSource.Name
C:\Users\Cindy Meister\Documents\Personal\klpFeb00.mdb
?Document.MailMerge.DataSource.QueryString
SELECT * FROM `Q_MailMergeInvite`
Then
?ActiveDocument.MailMerge.DataSource.ConnectString
After pressing Enter for this one you should see something along the lines of
Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=C:\Users\[username]\Documents\Personal\Text.mdb;Mode=Read;Extended Properties="";Jet OLEDB:System database="";Jet OLEDB:Registry Path="";Jet OLEDB:Engine Type=5;Jet OLEDB:Database Locking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="";Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False;Jet OLEDB:Support Complex Data=False;Jet OLEDB:Bypass UserInfo Validation=False
These, in double-quotes, are assigned to the Name
, SQLStatement
and Connection
parameters of Document.MailMerge.OpenDataSource
.
This is described in the Knowledge Base article about the prompt .
The exact Registry key varies, depending on the version of Word, but follows the pattern
HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Word\Options
The above is for Word 2013, version 15. Change it to 14 for Word 2010; 16 for Word 2016, etc.
A new Registry entry of the type DWord
needs to be created in this location, named SQLSecurityCheck
. Assign it the value 00000000
.
For example:
Sub MergetoPrint()
Dim wrdObj As Object, wrdDoc As Object, strFile As String
strFile = ThisWorkbook.FullName
Const wdFormLetters As Long = 0
Const wdSendToNewDocument As Long = 0
Const wdSendToPrinter = 1
Const wdSendToEmail As Long = 2
Const wdMergeSubTypeAccess As Long = 1
Const wdMailFormatHTML As Long = 1
Set wrdObj = CreateObject("Word.Application")
With wrdObj
.Visible = False
.DisplayAlerts = False
Set wrdDoc = .Documents.Open(ThisWorkbook.Path & "\MailMergeMainDocument.docx", False, True, False, , , , , , , , False)
With wrdDoc
With .MailMerge
.MainDocumentType = wdFormLetters
.Destination = wdSendToPrinter
.SuppressBlankLines = True
.OpenDataSource Name:=strFile, ReadOnly:=True, AddToRecentFiles:=False, LinkToSource:=False, _
Connection:="Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=strFile;Mode=Read;" & _
"Extended Properties=""HDR=YES;IMEX=1"";", SQLStatement:="SELECT * FROM [Sheet1$]", _
SQLStatement1:="", SubType:=wdMergeSubTypeAccess
.Execute
End With
.Close 0
End With
End With
Set wrdDoc = Nothing: Set wrdObj = Nothing
End Sub
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.