Generating completed PDF forms using word docs and ms access - vba

I'm trying to use Microsoft Access to fill out word documents with bookmarked text form fields, and then export them as PDFs. I'm struggling to produce Visual Basic code in Access that works consistently. I continue to get errors about the word documents being locked from editing. Not sure how to proceed
Code I have so far
Public Sub ExportToMGR()
Dim wApp As Word.Application
Dim wDoc As Word.Document
Dim rs As DAO.Recordset
Set wApp = New Word.Application
Set wDoc = wApp.Documents.Open("C:\filepath\doc.docx")
Set rs = CurrentDb.OpenRecordset("Detail Report - Individuals")
If Not rs.EOF Then rs.MoveFirst
Do Until rs.EOF
wDoc.Bookmarks("FullName1").Range.Text = Nz(rs!ClientName, "")
wDoc.Bookmarks("FullName2").Range.Text = Nz(rs!ClientName, "")
wDoc.SaveAs2 "C:\filepath\" & "firstTest.docx"
rs.MoveNext
Loop
End Sub

Welcome to SO.
You shouldnt be opening the Word document, instead you should create a Word Template (.dotx) and add it to the documents collection by calling the .Add() method.
Once the document is filled with data, you need to call the .ExportAsFixedFormat() method to save as PDF.
See an example below.
Option Explicit
Private Sub RunMailMerge_Click()
On Error GoTo Trap
Const TEMPLATE_PATH As String = "YourTemplateFolder\WordTemplate.dotx"
Dim wApp As Word.Application
Dim wDoc As Word.Document
Dim rs As DAO.Recordset
Dim idx As Long
Set wApp = New Word.Application
wApp.Visible = False
Set rs = CurrentDb.OpenRecordset("Detail Report - Individuals")
If rs.EOF Then GoTo Leave
With rs
.MoveLast
.MoveFirst
End With
For idx = 1 To rs.RecordCount
Set wDoc = wApp.Documents.Add(TEMPLATE_PATH)
With wDoc
.Bookmarks("FullName1").Range.Text = Nz(rs!ClientName, vbNullString)
.Bookmarks("FullName2").Range.Text = Nz(rs!ClientName, vbNullString)
.ExportAsFixedFormat "DocumentPathWithExtension.pdf", wdExportFormatPDF, False, wdExportOptimizeForOnScreen
.Close wdDoNotSaveChanges
End With
Set wDoc = Nothing
rs.MoveNext
Next
Leave:
On Error Resume Next
If Not rs Is Nothing Then rs.Close
If Not wDoc Is Nothing Then wDoc.Close wdDoNotSaveChanges
If Not wApp Is Nothing Then wApp.Quit wdDoNotSaveChanges
On Error GoTo 0
Exit Sub
Trap:
MsgBox Err.Description, vbCritical
Resume Leave
End Sub

Related

VBA Word error: Requested Member of the Collection Does Not Exist

I'm currently trying to write a script using VBA to generate a word document that has sections taken from a defined recordset in access.
However, I don't quite know how to input a field into the word vba and later reference it to data in access. Currently, I have the code below,
I managed to insert the field into the word automation, however, I get the error that the member does not exist at the rslet function.
Private Sub Command1_Click()
Dim objWord As Word.Application
Dim doc As Word.Document
Set objWord = CreateObject("Word.Application")
Dim db As Database
Set db = CurrentDb
Dim strsql As String
strsql = "SELECT Function from Function"
Dim rslet As DAO.RecordSet
Set rslet = db.OpenRecordset(strsql)
With objWord .Visible = True
Set doc = .Documents.Add
doc.SaveAs CurrentProject.Path & "\TestDoc1.docx"
End With
With objWord
.Selection.TypeText Text:="1.0 Introduction"
.Selection.TypeParagraph
.Selection.TypeText Text:="1.3 Functions"
.Selection.Fields.Add Range:=Selection.Range,
Type:=wdFieldEmpty,
Text:="F", PreserveFormatting = FALSE
.Selection.TypeParagraph
With doc.FormFields("F").Result = rslet!Function
End With
End With
doc.Save
doc.Activate
End Sub

Access data filling out a Word Documents through bookmarks

I am modifying someone's access database. The person has a button to create a report that fills out a preprinted form on a dot matrix printer. Now he would like to print it out on a laser printer. I suggested creating a Word document and have Access fill it out and then he can print however many copies he needs.
The previous programmer created a really nice way to print preview and print the reports. I want to add a button to print it to Word.
I have created a document with bookmarks.
I have added the button and have added the code as follows:
Private Sub Print_Test_Click()
On Error GoTo Err_Print_Test_Click
'Print customer slip for current customer.
Dim wApp As Word.Application
Dim wDoc As Word.Document
Dim dbs As DAO.Database
Dim rs As DAO.Recordset
Dim SelectNum As Long
'Avoid error 429, when Word isn't open.
On Error Resume Next
Err.Clear
'Set wApp object variable to running instance of Word.
Set wApp = GetObject(, "Word.Application")
If Err.Number <> 0 Then
'If Word isn't open, create a new instance of Word.
Set wApp = New Word.Application
End If
Set dbs = CurrentDb
If Me.OpenArgs = "FromViewContracts" Then
Set wDoc = wApp.Documents.Open("C:\Shafer\Contract.dotx", , True)
SelectNum = Forms![PrintDialog]![ContractNum]
Set rs = dbs.OpenRecordset("SELECT * FROM PRINTContract WHERE ContNum = SelectNum")
Else
Set wDoc = wApp.Documents.Open("C:\Shafer\Invoice.dotx", , True)
SelectNum = Forms![PrintDialog]![InvoiceNum]
Set rs = dbs.OpenRecordset("SELECT * FROM PRINTInvoice WHERE InvNum = SelectNum")
End If
If rs.NoMatch Then
MsgBox "Record not found."
GoTo Exit_Print_Test_Click
Else
MsgBox "Customer name: " & rs!Customers.Name
End If
wApp.Visible = True
wDoc.Bookmarks("CustName").Range.Text = Nz(rs!Customers.Name, "")
wDoc.Bookmarks("CustAddress").Range.Text = Nz(rs!Customers.Address, "")
wDoc.Bookmarks("CustCity").Range.Text = Nz(rs!Customers.City, "")
wDoc.Bookmarks("CustState").Range.Text = Nz(rs!Customers.State, "")
wDoc.Bookmarks("CustZip").Range.Text = Nz(rs!Customers.Zip, "")
wDoc.Bookmarks("Date").Range.Text = Nz(rs!Date, "")
wDoc.Bookmarks("ContNum").Range.Text = Nz(rs!ContNum, "")
If Me.OpenArgs = "FromViewContracts" Then
' Contract bookmarks here
Else
wDoc.Bookmarks("InvNum").Range.Text = Nz(rs!InvNum, "")
wDoc.Bookmarks("SalesPerson").Range.Text = Nz(rs!Salesperson, "")
wDoc.Bookmarks("Terms").Range.Text = Nz(rs!Terms.Name, "")
End If
wApp.Visible = True
rs.Close
rsTable.Close
Set wDoc = Nothing
Set wApp = Nothing
Set rs = Nothing
Set rsTable = Nothing
Exit Sub
Exit_Print_Test_Click:
Exit Sub
Err_Print_Test_Click:
MsgBox Err.Description
Resume Exit_Print_Test_Click
End Sub
Here is the problem: When this runs, all I get is "Record Not Found"
If I display the value of InvNum or ContNum I have a value, lets say 18500. If I display the value of SelectNum, I have a value of 18500. But I cannot get it to work.
If I change SelectNum to 18500 in the Select statement, it works.
Please help.

Setting Range based on Selection

I want to take a reference number in an email to highlight and replace with a direct link to web page.
The current code will place the new hyperlink at the start of the email instead of the selected areas (currently wddoc.Range(0 , 0)).
If I use Selection it says the variable is undefined by user.
Sub AddHyperlink()
Dim olEmail As Outlook.MailItem
Dim olInsp As Outlook.Inspector
Dim wdDoc As Object
Dim oLink As Object
Dim oRng As Object
Dim strLink As String
Dim strLinkText As String
Dim OutApp As Object
Dim OutMail As Object
Dim strText As String
On Error Resume Next
'Get Outlook if it's running
Set OutApp = GetObject(, "Outlook.Application")
'Outlook wasn't running, so cancel
If Err <> 0 Then
MsgBox "Outlook is not running so nothing can be selected!"
GoTo lbl_Exit
End If
On Error GoTo 0
Set OutMail = OutApp.ActiveExplorer.Selection.Item(1)
With OutMail
Set olInsp = .GetInspector
Set wdDoc = olInsp.WordEditor
strText = wdDoc.Application.Selection.Range.Text
End With
strLink = "http://website.com/#" & strText & "" ' the link address
strLinkText = "" & strText & "" ' the link display text
On Error Resume Next
Set olEmail = ActiveInspector.CurrentItem
With olEmail
.BodyFormat = olFormatHTML
Set olInsp = .GetInspector
Set wdDoc = olInsp.WordEditor
Set oRng = wdDoc.Range(0, 0) '!!!Cannot find something that replaces range with current selection!!!!
oRng.Collapse 0
Set oLink = wdDoc.Hyperlinks.Add(Anchor:=oRng, _
Address:=strLink, _
SubAddress:="", _
ScreenTip:="", _
TextToDisplay:=strLinkText)
Set oRng = oLink.Range
oRng.Collapse 0
.Display
End With
lbl_Exit:
Exit Sub
End Sub
When I have a new email open in MS Outlook, I'll have a keyboard shortcut setup to run the code in VBA within Outlook.
Outlook vba while working with ActiveInspector, try the following.
Option Explicit
Public Sub Example()
Dim wdDoc As Word.Document
Dim rngSel As Word.selection
If Application.ActiveInspector.EditorType = olEditorWord Then
Set wdDoc = Application.ActiveInspector.WordEditor ' use WordEditor
Set rngSel = wdDoc.Windows(1).selection ' Current selection
wdDoc.Hyperlinks.Add rngSel.Range, _
Address:="U:\plot.log", TextToDisplay:="Here is the link"
End If
Set wdDoc = Nothing
End Sub

OLE and/or runtime 438 errors when pulling Word Form data into Excel workbook

This script worked perfectly... until it didn't. I have an Excel workbook in the same folder as multiple copies of a Word form. The macro should pull the data from each form and copy it to a row in the workbook. I now get either "OLE Excel is waiting on another application" errors or Runtime 438 errors. The macro I use is as follows:
Sub GetFormData()
Application.ScreenUpdating = False
Dim wdApp As New Word.Application
Dim wdDoc As Word.Document
Dim CCtrl As Word.ContentControl
Dim strFolder As String, strFile As String
Dim WkSht As Worksheet, i As Long, j As Long
strFolder = GetFolder
If strFolder = "" Then Exit Sub
Set WkSht = ActiveSheet
i = WkSht.Cells(WkSht.Rows.Count, 1).End(xlUp).Row
strFile = Dir(strFolder & "\*.docm", vbNormal)
While strFile <> ""
i = i + 1
Set wdDoc = wdApp.Documents.Open(Filename:=strFolder & "\" & strFile, AddToRecentFiles:=False, Visible:=False)
With wdDoc
j = 0
For Each CCtrl In .ContentControls
j = j + 1
WkSht.Cells(i, j).FormulaLocal = CCtrl.Range.Text
Next
End With
wdDoc.Close SaveChanges:=False
strFile = Dir()
Wend
wdApp.Quit
Set wdDoc = Nothing: Set wdApp = Nothing: Set WkSht = Nothing
Application.ScreenUpdating = True
End Sub
Function GetFolder() As String
Dim oFolder As Object
GetFolder = ""
Set oFolder = CreateObject("Shell.Application").BrowseForFolder(0, "Choose a folder", 0)
If (Not oFolder Is Nothing) Then GetFolder = oFolder.Items.Item.Path
Set oFolder = Nothing
End Function
The issue appears to start at "Set wdDoc = wdApp..."
I am a bit of a noob at this. As such, I appreciate your help.
Matt.
I see two possible issues, the first one is almost certainly causing the error; the second could cause this error (but probably not with VBA):
You declare and instantiate the Word application in the same line:
Dim wdApp As New Word.Application
You shouldn't do this. Instead:
Dim wdApp As Word.Application
Set wdApp = New Word.Application
I don't remember the exact details about the "why", but it's something to do with the Word.Application object being created immediately, and at a level where you can no longer control it using Set wdApp = Nothing.
Correctly, all objects of the "outside" application should be released, in reverse order of their creation. You've declared an object of the type Word.ContentControl, but don't release it:
Set Set CCtrl = Nothing : Set wdDoc = Nothing: Set wdApp = Nothing: Set WkSht = Nothing

how to insert picture into word doc from access database using vba

I'm trying to read picture from access attachment field and then insert it into word document. As the below code show, I could read an attachment into a file and then insert it to word doc but it's inefficient and I want a way to directly do this. any idea?
Option Compare Database
Sub picloader()
Dim appword As Word.Application
Dim doc As Word.Document
On Error Resume Next
Err.Clear
Set appword = GetObject(, "Word.Application")
If Err.Number <> 0 Then
Set appword = New Word.Application
End If
appword.Visible = True
appword.Activate
'word doc to save picture
Set doc1 = appword.Documents.Open("D:\file1.docx")
Dim db As Database
Set db = CurrentDb
Dim picpath As String
Dim people As String
Dim rspictures As Variant
'Dim tmp As Variant
picpath = "D:\file1.jpg"
Dim rs As DAO.Recordset
people = "select * from persons"
Set rs = CurrentDb.OpenRecordset(people)
If Not (rs.EOF And rs.BOF) Then
rs.MoveFirst
Set rspictures = rs.Fields("Picture").Value
While Not rspictures.EOF
rspictures.Fields("FileData").SaveToFile (picpath)
rspictures.MoveNext
Wend
End If
Dim wrdPic As Word.InlineShape
Set wrdPic = doc1.Bookmarks("picture").Range.InlineShapes.AddPicture(picpath, LinkToFile:=False, SaveWithDocument:=True)
wrdPic.ScaleHeight = 10
wrdPic.ScaleWidth = 10
Exit Sub
errHandler:
MsgBox Err.Number & ": " & Err.Description
End Sub