Access data filling out a Word Documents through bookmarks - vba

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.

Related

Generating completed PDF forms using word docs and ms access

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

Convert Access database to late binding to work with Access runtime

I wrote code in Access database 2016 contains functions and macros, then I move this file to share with some users that don't have Access Application so, I install Access runtime it works well but I face many problems with reference libraries.
I decided to use late binding (by writing EarlyBinding = 0 in a database property of VBA editor)
and uncheck all references except two (I can't uncheck) and covert
Set appWord = New Word.Application
to
Set appWord = CreateObject(Word.Application)
note 1: I have a function to open Word document from Access form.
note 2: I convert the database extension from .accdb to .accdr
after I made changes in late binding and convert the previous statement no message error (for reference) appears but the function of open Word doesn't work.
is there a tool like Access runtime for Word? so I can't open for this reason?
below the code of this function:
Function fillWordForm()
Dim appWord As Object
Dim doc As Object
Dim path As String
Dim myID As String
On Error Resume Next
Error.Clear
'Set appWord = CreateObject("word.application")
Set appWord = CreateObject(Word.Application)
If Err.Number <> 0 Then
'Set appWord = New Word.Application
'Set appWord = CreateObject(Word.Application)
appWord.Visible = True
End If
'path = Application.CurrentProject.path & "\H_F.docx"
'path = "\\ubcdatacenter\Public\UBCIEDatabase\DOC\H_F.docx"
path = "C:\Users\LENOVO\Desktop\UBC Database\H_F.docx"
If FileExists(path) = False Then
MsgBox "Template File Not Found", vbExclamation, "File Not Found"
Else
Set doc = appWord.Documents.Add(path, , True)
myID = DLookup("ID", "Exports_imports_Table", "[ID] = " & Me.ID)
With doc
.FormFields("BookID").Result = [ID]
.FormFields("Book_BC_date").Result = Me.date_BC
.FormFields("Book_AH_date").Result = Me.date_AH
.FormFields("Book_AH_date").Result = Me.date_AH
.FormFields("BookTopic").Result = Me.topic
.FormFields("BookProjectName").Result = Me.projectName
.FormFields("BookCompanyName").Result = Me.companyName
.FormFields("BookContent").Range.Text = Me.content
'Result = Me.content
appWord.Visible = True
appWord.Active
End With
Set doc = Nothing
Set appWord = Nothing
End If
End Function
this code to ensure that file is excite
Function FileExists(ByVal strFile As String, Optional bFindFolders As Boolean) As Boolean
'Purpose: Return True if the file exists, even if it is hidden.
'Arguments: strFile: File name to look for. Current directory searched if no path included.
' bFindFolders. If strFile is a folder, FileExists() returns False unless this argument is True.
'Note: Does not look inside subdirectories for the file.
'Author: Allen Browne. http://allenbrowne.com June, 2006.
Dim lngAttributes As Long
'Include read-only files, hidden files, system files.
lngAttributes = (vbReadOnly Or vbHidden Or vbSystem)
If bFindFolders Then
lngAttributes = (lngAttributes Or vbDirectory) 'Include folders as well.
Else
'Strip any trailing slash, so Dir does not look inside the folder.
Do While Right$(strFile, 1) = "\"
strFile = Left$(strFile, Len(strFile) - 1)
Loop
End If
'If Dir() returns something, the file exists.
On Error Resume Next
FileExists = (Len(Dir(strFile, lngAttributes)) > 0)
End Function
what should also convert to make all code late binding?
Editing
after Mathieu's changes
Function fillWordForm()
Dim appWord As Object
Dim doc As Object
Dim path As String
Dim myID As String
On Error Resume Next
Error.Clear
Set appWord = GetWordApp
If appWord Is Nothing Then
'can't get ahold of Word.Application... now what?
MsgBox "No thing :(((((((((((((("
'Exit Sub
End If
appWord.Visible = True '<~ unconditional
'Set appWord = CreateObject("word.application")
'Set appWord = CreateObject(Word.Application)
'If Err.Number <> 0 Then
'Set appWord = New Word.Application
'Set appWord = CreateObject(Word.Application)
'appWord.Visible = True
'End If
'path = Application.CurrentProject.path & "\H_F.docx"
path = "\\ubcdatacenter\Public\UBCIEDatabase\DOC\H_F.docx"
'path = "C:\Users\LENOVO\Desktop\UBC Database\H_F.docx"
If FileExists(path) = False Then
MsgBox "Template File Not Found", vbExclamation, "File Not Found"
Else
Set doc = appWord.Documents.Add(path, , True)
myID = DLookup("ID", "Exports_imports_Table", "[ID] = " & Me.ID)
With doc
.FormFields("BookID").Result = [ID]
.FormFields("Book_BC_date").Result = Me.date_BC
.FormFields("Book_AH_date").Result = Me.date_AH
.FormFields("Book_AH_date").Result = Me.date_AH
.FormFields("BookTopic").Result = Me.topic
.FormFields("BookProjectName").Result = Me.projectName
.FormFields("BookCompanyName").Result = Me.companyName
.FormFields("BookContent").Range.Text = Me.content
'Result = Me.content
appWord.Visible = True
appWord.Active
End With
Set doc = Nothing
Set appWord = Nothing
End If
End Function
Private Function GetWordApp() As Object
On Error Resume Next
Set GetWordApp = CreateObject("Word.Application")
End Function
'Set appWord = CreateObject("word.application")
Set appWord = CreateObject(Word.Application)
If Err.Number <> 0 Then
'Set appWord = New Word.Application
'Set appWord = CreateObject(Word.Application)
appWord.Visible = True
End If
Several things are wrong with this code. CreateObject wants a ProgID string, and you're giving it Word.Application, which shouldn't even compile (expecting "Object Required" error on the .Application member call, and "Variable not declared"1 on Word). If it compiles, you've referenced the Word object library and need to remove it. The commented-out statement is well-formed.
Now If Err.Number <> 0, then appWord wasn't Set, and its reference is Nothing. That means if CreateObject fails, the code enters an error state and remains in an error state for the remainder of the procedure, because the error is never cleared, and error handling is never restored.
Take the error stuff into its own limited scope:
Private Function GetWordApp() As Object
On Error Resume Next
Set GetWordApp = CreateObject("Word.Application")
End Function
Now your procedure only needs to check if the function returned a valid object reference:
Set appWord = GetWordApp
If appWord Is Nothing Then
'can't get ahold of Word.Application... now what?
Exit Sub
End if
appWord.Visible = True '<~ unconditional
1 assuming Option Explicit is at the top of the module, as it should be.

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

Microsoft Access VBA - Importing data from an unnamed Word Form Field

I have been tasked with importing the contents of a Microsoft Word Form into my Access database. It's working fine using the following VBA code which is triggered from a form:
Private Sub cmdFileDialog_Click()
On Error GoTo ErrorHandler
Dim objDialog As Object
Dim varFile As Variant
Dim rec, rec2 As Recordset
Dim db As Database
'New Word Document Variables
Dim appWord As Word.Application
Dim doc As Word.Document
Const DEST_TABLE = "ap_behaviour_referrals" 'change to suit
Const PATH_DELIM = "\"
Set objDialog = Application.FileDialog(3)
' Clear listbox contents.
Me.fileList.RowSource = ""
With objDialog
.AllowMultiSelect = False
' Set the title of the dialog box.
.Title = "Please select a behaviour referral to import"
' Clear out the current filters, and add our own.
.Filters.Clear
.Filters.Add "Microsoft Word Forms", "*.docx"
.Filters.Add "All Files", "*.*"
.Show
If .SelectedItems.Count = 0 Then
MsgBox "No file selected."
Else
For Each varFile In .SelectedItems
'New docx Variable Actions
Set appWord = GetObject(, "Word.Application")
Set doc = appWord.Documents.Open(varFile)
Next
Set db = CurrentDb
Set rec = db.OpenRecordset(DEST_TABLE)
With rec
.AddNew
' my data
'preformat the date fields from the form
Dim unformattedpupildob As String
Dim formattedpupildob As Date
unformattedpupildob = doc.FormFields("Text2").Result
unformattedpupildob = Replace(unformattedpupildob, ".", "/")
formattedpupildob = Format(unformattedpupildob, "dd/mm/yy")
'And now insert the record into the table
!pupil_name = doc.FormFields("Text1").Result
!pupil_dob = formattedpupildob
!pupil_yr_grp = doc.FormFields("Text3").Result
!pupil_submitted_eth = doc.FormFields("Text4").Result
!pupil_upn = doc.FormFields("Text5").Result
!pupil_looked_after = doc.FormFields("Text6").Result
!sen_pre_statement = doc.FormFields("Text7").Result
!sen_ehcp = doc.FormFields("Text8").Result
!cat_date_final_ehcp = doc.FormFields("Text9").Result
!num_exclusion = doc.FormFields("Text10").Result
!days_exclusion = doc.FormFields("Text11").Result
!sch_name = doc.FormFields("Text12").Result
!sch_no = doc.FormFields("Text14").Result
!contact_name = doc.FormFields("Text13").Result
!contact_role = doc.FormFields("Text40").Result
!contact_email = doc.FormFields("Text31").Result
.Update
.Close
MsgBox "File Processing Complete"
End With
End If
End With
Set objDialog = Nothing
Me.fileList.RowSource = ""
ExitSub:
Set rec = Nothing
Set db = Nothing
'...and set it to nothing
Exit Sub
ErrorHandler:
If Err.Number <> 0 Then
Msg = "Error # " & Str(Err.Number) & " was generated by " & Err.Source & Chr(13) & "Error Line: " & Erl() & Chr(13) & Err.Description
MsgBox Msg, , "Error", Err.HelpFile, Err.HelpContext
End If
Resume ExitSub
End Sub
All but one of the fields are (badly) bookmarked so I can use this to grab the contents of the field HOWEVER, I've come across an unnamed form field:
Which I need to import and I have no idea how to get the contents of it without a named bookmark.
I have no ability to modify the form since it's controlled by somebody else and is widely distributed, but was wondering if there was any way to pull the contents of this field without it being named?
Thanks!
Like other collections of objects, you can address them either by name (as you do for the other fields) or by numeric index.
For i = 1 To doc.FormFields.Count
Debug.Print i, doc.FormFields(i).Result
Next i
This should give you the index of the field, if you know its content.
Then use !the_answer = doc.FormFields(42).Result in your code. (42 is an example!)
Edit: minimal working example (running in Access):
Public Sub TestWord()
Dim oWord As Word.Application
Dim oDoc As Word.Document
Dim i As Long
Set oWord = CreateObject("Word.Application")
Set oDoc = oWord.Documents.Open("C:\Users\foobar\Documents\Dok1.docx")
oWord.Visible = True
For i = 1 To oDoc.FormFields.Count
Debug.Print i, oDoc.FormFields(i).Name, oDoc.FormFields(i).Result
Next i
oDoc.Close
oWord.Quit
End Sub
The direct window (Ctrl+g) lists all form fields with their index, name = bookmark, and default text.

EXCEL VBA word to pdf multiple times SaveAs2

I whould like to fill a word with values and export to pdf multiple times.
If is use a SaveAs2 the firt time it make a pdf but second or third it doesen't work.
'ActiveDocument.SaveAs2 FileName:="C:\alap\" & fajlneve & ".pdf", FileFormat:=wdFormatPDF
If I use the CutePDf printer, the result is the same, first time i=1 it works, but second it doesen't.
Public compname As String
Public filename As String
Function FillwordForm()
Dim appword As Word.Application
Dim doc As Word.Document
Dim Path As String
On Error Resume Next
Error.Clear
Set appword = GetObject(, "word.application")
If Err.Number <> 0 Then
Set appword = New Word.Application
appword.Visible = True
End If
Path = "C:\pelda\MINTA.docx"
Set doc = appword.Documents.Open(Path, , True)
With doc
.formfields("szerzCegnev").result = compname
End With
appword.Visible = True
appword.Activate
Set doc = Nothing
Set appword = Nothing
appword.ActivePrinter = "CutePDF Writer"
ActiveDocument.PrintOut OutPutFileName:="C:\pelda\" & filename & ".pdf"
ActiveDocument.Close SaveChanges:=wdDoNotSaveChanges
Word.Application.Quit
End Function
'---------------------------------------------------------------
Sub cucc()
For i = 1 To 2
compname = Cells(i, 1)
filename = Cells(i, 2)
Call FillwordForm
Next i
End Sub
can you use:
ActiveDocument.SaveAs2(docname,17);
?
(17 is PDF-format -link to fileformats)
Greetz