Question : Access 2007 merge form + subform to Word

I have created a form in Access which displays info required by a govt dept. It contains 1 form + 2 subforms (subforms are datasheets). Is there any way I can import it into a word template? I am having trouble getting the subforms with multiple lines in.

Answer : Access 2007 merge form + subform to Word

Here is a code sample that exports linked data to a Word document (an invoice with main invoice info in the top, and a table listing invoice details below.  The code is listed below; it uses a Word template
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
Private Sub cmdCreateInvoice_Click()
'Written by Helen Feddema 19-Aug-1999
'Last modified 22-Feb-2009
'Needs references to the DAO, Office, Word and Scripting Runtime libraries
 
   Dim appWord As Object
   Dim blnSaveNameFail As Boolean
   Dim curFreight As Currency
   Dim curSubtotal As Currency
   Dim curTotal As Currency
   Dim dblQuantity As Double
   Dim dbs As DAO.Database
   Dim doc As Word.Document
   Dim docs As Object
   Dim dteOrderDate As Date
   Dim dteRequiredDate As Date
   Dim dteShippedDate As Date
   Dim dteTodayDate As Date
   Dim fil As Scripting.File
   Dim fso As New Scripting.FileSystemObject
   Dim intCount As Integer
   Dim intReturn As Integer
   Dim lngOrderID As Long
   Dim lngProductID As Long
   Dim prps As Object
   Dim rst As DAO.Recordset
   Dim strBillToAddress As String
   Dim strBillToCityStateZip As String
   Dim strBillToCountry As String
   Dim strCompanyName As String
   Dim strCustomerID As String
   Dim strDefaultDocsPath As String
   Dim strDefaultTemplatesPath As String
   Dim strDiscount As String
   Dim strDoc As String
   Dim strDocsPath As String
   Dim strExtendedPrice As String
   Dim strMessage As String
   Dim strMessageTitle As String
   Dim strProductName As String
   Dim strPrompt As String
   Dim strSalesperson As String
   Dim strSaveName As String
   Dim strSaveNamePath As String
   Dim strShipAddress As String
   Dim strShipCityStateZip As String
   Dim strShipCountry As String
   Dim strShipName As String
   Dim strShipper As String
   Dim strShortDate As String
   Dim strTemplateName As String
   Dim strTemplateNameAndPath As String
   Dim strTemplatesPath As String
   Dim strTest As String
   Dim strTestFile As String
   Dim strTitle As String
   Dim strUnitPrice As String
   
On Error GoTo ErrorHandler
   
   'Create a Word instance to use for the invoice; uses the existing Word
   'instance if there is one, otherwise creates a new instance
    Set appWord = GetObject(, "Word.Application")
   
   'Keep Word invisible until the document is finished
   appWord.Visible = False
   
   'Run make-table queries to create tables to use for export;
   'I use make-table queries instead of select queries, because the
   'queries have a criterion limiting the Order ID to the one selected
   'on the form, and such parameter queries can't be used in a recordset.
   'Instead, the make-table queries are run to create tables which will
   'be used in the recordsets later in the code.
   DoCmd.SetWarnings False
   DoCmd.OpenQuery "qmakInvoice"
   DoCmd.OpenQuery "qmakInvoiceDetails"
   
   'Check that there is at least one detail item before creating invoice
   intCount = DCount("*", "tmakInvoiceDetails")
   Debug.Print "Number of Detail items: " & intCount
   
   If intCount < 1 Then
      strTitle = "Nothing to invoice"
      strPrompt = "No detail items for invoice; canceling"
      MsgBox prompt:=strPrompt, _
         buttons:=vbExclamation + vbOKOnly, _
         Title:=strTitle
      GoTo ErrorHandlerExit
   End If
   
   'Create recordset and get needed doc properties for this invoice
   Set dbs = CurrentDb
   Set rst = dbs.OpenRecordset("tmakInvoice", dbOpenDynaset)
   With rst
      'The Nz function is used to convert any Nulls to zeros or
      'zero-length strings, to prevent problems with exporting
      'to Word
      lngOrderID = Nz(![OrderID])
      Debug.Print "Order ID: " & lngOrderID
      strShipName = Nz(![ShipName])
      strShipAddress = Nz(![ShipAddress])
      strShipCityStateZip = Nz(![ShipCityStateZip])
      strShipCountry = Nz(![ShipCountry])
      strCompanyName = Nz(![CompanyName])
      strCustomerID = Nz(![CustomerID])
      strCompanyName = Nz(![CompanyName])
      strBillToAddress = Nz(![BillToAddress])
      strBillToCityStateZip = Nz(![BillToCityStateZip])
      strBillToCountry = Nz(![BillToCountry])
      strSalesperson = Nz(![Salesperson])
      dteOrderDate = Nz(![OrderDate])
      dteRequiredDate = Nz(![RequiredDate])
      dteShippedDate = Nz(![ShippedDate])
      strShipper = Nz(![Shipper])
      curSubtotal = Nz(![Subtotal])
      curFreight = Nz(![Freight])
      curTotal = Nz(![Total])
   End With
   rst.Close
   
   'Get selected Docs and Templates paths from database properties
   '(saved from controls on main menu)
   strDefaultDocsPath = appWord.Options.DefaultFilePath(wdDocumentsPath) & "\"
   strDocsPath = GetProperty("DocsPath", strDefaultDocsPath)
   Debug.Print "Docs path: " & strDocsPath
   strDefaultTemplatesPath = appWord.Options.DefaultFilePath(wdUserTemplatesPath) & "\"
   strTemplatesPath = GetProperty("TemplatesPath", strDefaultTemplatesPath)
   strTemplateName = "Northwind Invoice.dot"
   strTemplateNameAndPath = strTemplatesPath & strTemplateName
   
   'This date string is used in creating the invoice's save name
   strShortDate = Format(Date, "m-d-yyyy")
   'This date variable is used to print today's date on the invoice
   '(unlike a Word date code, it remains stable when the invoice is
   'reopened later)
   dteTodayDate = Date
   
   'Check for existence of template in templates folder,
   'and exit if not found
On Error Resume Next
 
   Set fil = fso.GetFile(strTemplateNameAndPath)
   If fil Is Nothing Then
      strTitle = "Template not found"
      strPrompt = "Can't find " & strTemplateName & " in " _
         & strTemplatesPath & "; canceling"
      MsgBox prompt:=strPrompt, _
         buttons:=vbInformation + vbOKOnly, _
         Title:=strTitle
      GoTo ErrorHandlerExit
   End If
   
On Error GoTo ErrorHandler
   
   Set docs = appWord.Documents
   Set doc = docs.Add(strTemplateNameAndPath)
   
   'Write information to Word custom document properties from
   'previously created variables
   Set prps = doc.CustomDocumentProperties
   prps.Item("TodayDate").Value = dteTodayDate
   prps.Item("OrderID").Value = lngOrderID
   prps.Item("ShipName").Value = strShipName
   prps.Item("ShipAddress").Value = strShipAddress
   prps.Item("ShipCityStateZip").Value = strShipCityStateZip
   prps.Item("ShipCountry").Value = strShipCountry
   prps.Item("CompanyName").Value = strCompanyName
   prps.Item("CustomerID").Value = strCustomerID
   prps.Item("CompanyName").Value = strCompanyName
   prps.Item("BillToAddress").Value = strBillToAddress
   prps.Item("BillToCityStateZip").Value = strBillToCityStateZip
   prps.Item("BillToCountry").Value = strBillToCountry
   prps.Item("Salesperson").Value = strSalesperson
   prps.Item("OrderDate").Value = dteOrderDate
   prps.Item("RequiredDate").Value = dteRequiredDate
   prps.Item("ShippedDate").Value = dteShippedDate
   prps.Item("Shipper").Value = strShipper
   prps.Item("Subtotal").Value = curSubtotal
   prps.Item("Freight").Value = curFreight
   prps.Item("Total").Value = curTotal
   
   'Highlight the entire Word document and update fields, so the data
   'written to the custom doc props is displayed in the DocProperty fields
   With appWord
      .Selection.WholeStory
      .Selection.Fields.Update
      .Selection.HomeKey Unit:=6
   End With
   
   'Go to table to fill with Details data
   With appWord.Selection
      .GoTo What:=wdGoToTable, Which:=wdGoToFirst, Count:=3, Name:=""
      .MoveDown Unit:=wdLine, Count:=1
   End With
   
   'Set up recordset of linked Details data to put in table on
   'Word invoice
   Set rst = dbs.OpenRecordset("tmakInvoiceDetails", dbOpenDynaset)
   
   'Save Details information to variables
   'Use Format function to apply appropriate formatting to
   'Currency and Percent fields
   With rst
      .MoveFirst
      Do While Not .EOF
         lngProductID = Nz(![ProductID])
         Debug.Print "Product ID: " & lngProductID
         strProductName = Nz(![ProductName])
         Debug.Print "Product Name: " & strProductName
         dblQuantity = Nz(![Quantity])
         Debug.Print "Quantity: " & dblQuantity
         strUnitPrice = Format(Nz(![UnitPrice]), "$##.00")
         Debug.Print "Unit price: " & strUnitPrice
         strDiscount = Format(Nz(![Discount]), "0%")
         Debug.Print "Discount: " & strDiscount
         strExtendedPrice = Format(Nz(![ExtendedPrice]), "$#,###.00")
         Debug.Print "Extended price: " & strExtendedPrice
         
         'Move through the table, writing values from the variables
         'to cells in the Word table
         With appWord.Selection
            .TypeText Text:=CStr(lngProductID)
            .MoveRight Unit:=wdCell
            .TypeText Text:=strProductName
            .MoveRight Unit:=wdCell
            .TypeText Text:=CStr(dblQuantity)
            .MoveRight Unit:=wdCell
            .TypeText Text:=strUnitPrice
            .MoveRight Unit:=wdCell
            .TypeText Text:=strDiscount
            .MoveRight Unit:=wdCell
            .TypeText Text:=strExtendedPrice
            .MoveRight Unit:=wdCell
         End With
         .MoveNext
      Loop
      .Close
   End With
   dbs.Close
   
   'Delete last, empty row
   Selection.SelectRow
   Selection.Rows.Delete
   
   'Check for existence of previously saved letter in documents folder,
   'and append an incremented number to save name if found
   strSaveName = "Invoice to " & strCompanyName & " for Order " _
      & lngOrderID & " on " & strShortDate & ".doc"
    
   intCount = 2
   blnSaveNameFail = True
   Do While blnSaveNameFail
      strSaveNamePath = strDocsPath & strSaveName
      Debug.Print "Proposed save name and path: " _
         & vbCrLf & strSaveNamePath
      strTestFile = Nz(Dir(strSaveNamePath))
      If strTestFile = strSaveName Then
         
         'Create new save name with incremented number
         blnSaveNameFail = True
       strSaveName = "Invoice " & CStr(intCount) & " to " & strCompanyName _
       & " for Order " & lngOrderID & " on " & strShortDate & ".doc"
 
         strSaveNamePath = strDocsPath & strSaveName
         intCount = intCount + 1
      Else
         blnSaveNameFail = False
      End If
   Loop
   
   'Ask whether user wants to save the document
   'If you prefer, you could eliminate the prompt and just
   'save the document with the save name automatically.
   strMessageTitle = "Save document?"
   strMessage = "Save invoice as '" & strSaveName & "'?"
   intReturn = MsgBox(strMessage, vbYesNoCancel + _
      vbQuestion + vbDefaultButton1, strMessageTitle)
   
   If intReturn = vbNo Then
      doc.Close savechanges:=wdDoNotSaveChanges
      GoTo ErrorHandlerExit
   ElseIf intReturn = vbYes Then
      doc.SaveAs strSaveNamePath
      appWord.Visible = True
   ElseIf intReturn = vbCancel Then
      GoTo ErrorHandlerExit
   End If
   
ErrorHandlerExit:
   Set appWord = Nothing
   'Close any open recordset or database, in case code stops because
   'of an error
   On Error Resume Next
   rst.Close
   On Error Resume Next
   dbs.Close
   Exit Sub
 
ErrorHandler:
   If Err = 429 Then
      'Word is not running; open Word with CreateObject
      Set appWord = CreateObject("Word.Application")
      Resume Next
   Else
      MsgBox "Error No: " & Err.Number & "; Description: " _
         & Err.Description
      Resume ErrorHandlerExit
   End If
 
End Sub
Random Solutions  
 
programming4us programming4us