Programming Samples

Click here to go to:



Excel VBA

Word VBA

MS Access

T-SQL

SSIS

SSRS

Power BI

Crystal Reports

SSAS

SQL Replication

C# Code

ASP .NET Code

Oracle PL/SQL

Database Diagramming


Back to Home Page


MS Word Data Merge Rows from Excel Data Source

Merging an Excel Data Set into a Table in Word

This article describes how to use VBA to code a connection to an Excel 2013 Data Source of rows and pull them into a formatted Word Table. Also included in this article - code to Add Page Numbers in the footer and Formatting the Header Row to appear at the top of the table on each Page. In addition, the Recordset string will create the Field names from the Excel columns in SQL, some of which will be concatenated together.

Excel Data Source File

The Excel 2013 Data File used is a list of Product Vendors from the AdventureWorks 2014 database. There are Names with split address lines 1 & 2 as well as separated City, State, and Postal Code fields.

Excel Data Source File

Code the Word document Recordset and Connection

The sub created in the Module in VBA is named sPrintExcelTable. The beginning section has the declarations of all of our fields for ADODB connection and Recordsets - one to count the rows and the other to populate the data. Be sure to add a Reference to Microsoft ActiveX Data Objects 2.8 Library to the Project in Tools \ References to use the ADODB objects.

Sub sPrintExcelTable()
 Dim labelrows, labelcolumns, i As Integer
 Dim j As Integer, k As Integer, t As Integer
 Dim rsRows As Integer
 Dim rs As ADODB.Recordset, rsCount As ADODB.Recordset
 Dim cn As ADODB.Connection
 Dim sqlGetTbl As String
 Dim sDataSource As String, sDataTable As String
 Dim sProvider As String

Set up the connections in code. Note the Connection String for an Excel 2013 Object is different than an MS Access object (previously used in other articles I wrote here).

 Set cn = New ADODB.Connection
 Set rs = New ADODB.Recordset
 Set rsCount = New ADODB.Recordset

 sDataSource = "C:\MS Access\ProductVendors.xlsx"
 sDataTable = "Sheet1"

 sDataSource = sDataSource & ";Extended Properties='Excel 12.0 Xml;HDR=Yes'"
 sDataTable = "[" & sDataTable & "$]"

 sProvider = "Microsoft.ACE.OLEDB.12.0;" 'Excel Data Source version 2007 or greater

 cn.Provider = sProvider
 cn.ConnectionString = "Data Source=" & sDataSource
 cn.Open

Selecting the Fields in the SQL string from Excel into Word

Set the recordsets. Note that AddressLine1 is concatenated with AddressLine2 and the City, StateProvinceName, and Postal Code are concatenated with some formatting.

 sqlGetTbl = "SELECT COUNT(*) FROM " & sDataTable
 rsCount.Open sqlGetTbl, cn, adOpenDynamic, adLockOptimistic

 sqlGetTbl = "SELECT BusinessEntityID, VendorName, AddressLine1 + ' ' + AddressLine2 as Addr1," & _
 " City + ', ' + StateProvinceName + ' ' + PostalCode as Addr2 FROM " & sDataTable
 rs.Open sqlGetTbl, cn, adOpenDynamic, adLockOptimistic

If you are write SQL code, you might wonder why there is no additional code to check AddressLine2 and make sure it is Not Null. It is not necessary to check for the Null Value in this instance of SQL used on Excel as you normally would in SSMS when querying a SQL database - the query rows for AddressLine1 + AddressLine2 would result in blank values for the rows with Null AddressLine2 as displayed in this sample below. There is no problem like this when querying the Excel Data Source.

SQL Server Query with Nulls

Set up the beginning of the document in VBA. At the bottom of this code section, there is a comment indicating where the Page Number is added in VBA.

If Len(labelcolumns) > 0 And Len(labelrows) > 0 Then
 ActiveDocument.PageSetup.HeaderDistance = InchesToPoints(0.5)
 ActiveDocument.PageSetup.FooterDistance = InchesToPoints(0.5)
 ActiveDocument.PageSetup.LeftMargin = InchesToPoints(0.75)
 ActiveDocument.PageSetup.RightMargin = InchesToPoints(0.75)
 Selection.WholeStory
 Selection.Delete

 Selection.Font.Bold = True
 Selection.Font.Name = "Times New Roman"
 Selection.TypeText Text:="Product Vendors"

 Selection.TypeText Text:=Chr(11) & "Adventure Works"
 Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter
 Selection.ParagraphFormat.LineUnitAfter = 1

 Selection.TypeParagraph
 Selection.Font.Name = "Times New Roman"
 Selection.Font.Size = "9"
 Selection.ParagraphFormat.Alignment = wdAlignParagraphLeft
 Selection.Font.Bold = False
'Adding the Page Number to the footer here
 Selection.Sections(1).Footers(wdHeaderFooterPrimary).PageNumbers.Add _
   PageNumberAlignment:=wdAlignPageNumberCenter, FirstPage:=True

Set up the Table with Borders and format the column widths.

 t = 1

If Not rs.EOF Then
 ActiveDocument.Tables.Add Range:=Selection.Range, NumRows:=labelrows + 1, NumColumns:= _
  labelcolumns, DefaultTableBehavior:=wdWord9TableBehavior, AutoFitBehavior:= _
  wdAutoFitFixed
 ActiveDocument.Tables(t).Columns.PreferredWidth = InchesToPoints(2)
 ActiveDocument.Tables(t).Columns(2).PreferredWidth = InchesToPoints(8)
 ActiveDocument.Tables(t).Columns(3).PreferredWidth = InchesToPoints(10)
 ActiveDocument.Tables(t).Columns(4).PreferredWidth = InchesToPoints(10)
 ActiveDocument.Tables(t).Rows.Height = InchesToPoints(0.3)
 ActiveDocument.Tables(t).Borders(wdBorderLeft).Visible = True
 ActiveDocument.Tables(t).Borders(wdBorderRight).Visible = True
 ActiveDocument.Tables(t).Borders(wdBorderTop).Visible = True
 ActiveDocument.Tables(t).Borders(wdBorderBottom).Visible = True
 ActiveDocument.Tables(t).Borders(wdBorderHorizontal).Visible = True
 ActiveDocument.Tables(t).Borders(wdBorderVertical).Visible = True
End If

Write code to iterate through the 104 rows or data in the Excel file and build the table.

i = 1
j = 1

If Not rs.EOF And Not IsNull(rs.Fields(1)) Then
 For j = 1 To labelrows

  For k = 1 To labelcolumns

   If j = 1 Then

    ActiveDocument.Tables(t).Cell(j, k).Range.InsertBefore rs.Fields(k - 1).Name
    ActiveDocument.Tables(t).Cell(j, k).Range.Shading.BackgroundPatternColor = wdColorGray15
    ActiveDocument.Tables(t).Cell(j, k).Range.ParagraphFormat.Alignment = wdAlignParagraphCenter

    ActiveDocument.Tables(t).Cell(j + 1, k).Range.InsertBefore rs.Fields(k - 1)

    Selection.EndOf Unit:=wdParagraph, Extend:=wdExtend
    Selection.Range.Font.Bold = True
    Selection.Range.Font.Underline = wdUnderlineSingle

   Else
    If Len(Trim(rs.Fields(k - 1))) > 0 Then
     ActiveDocument.Tables(t).Cell(j + 1, k).Range.InsertBefore rs.Fields(k - 1)
    End If
  End If

  Select Case k
   Case 3:
    ActiveDocument.Tables(t).Cell(j + 1, k).Range.ParagraphFormat.Alignment = wdAlignParagraphLeft
   Case 1, 2:
    ActiveDocument.Tables(t).Cell(j + 1, k).Range.ParagraphFormat.Alignment = wdAlignParagraphCenter
  End Select
 Next k
 rs.MoveNext
Next j
End If

Finally, add the code for the Header to appear on each page, instead of only the first page.

 ActiveDocument.Tables(t).Rows(1).Select
 Selection.Rows.HeadingFormat = True
 ActiveDocument.Save

If Not rs.EOF Then
 rsRows = ActiveDocument.Paragraphs.Count
 Selection.Move Unit:=wdParagraph, Count:=rsRows
 Selection.InsertBreak Type:=wdPageBreak
End If

 rs.Close
 cn.Close

End If
End Sub

Word Document Merged Excel Data Rows