If you are using Word to build a report that relies on Excel tables, you have a couple of ways to achieve it. One is to create links to the Excel file, which is OK if the file is not very large or calculation-intensive, and you don’t have too many bookmarks. However, you may find that you have one or more of the following problems:
There are articles showing how to push data from Excel to Word using VBA, [see the following], but I hadn’t come across any that used Word as the driver when I had a recent need to do this. The code needed to meet some specific criteria:
The approach that I came up with uses bookmarks in the Word document, matched to range names in the Excel file. This requires the following:
Bookmark | Sheet | Range Name |
---|---|---|
Bookmark1001 | Main Data | PL_01 |
Bookmark1002 | Summary Data | CF_02 |
Note: The sheet name is required because Word cannot reference an Excel range without knowing which sheet the range is on. Also, watch out for the range names in Excel. If you like to use 3-letter acronyms for your ranges, you will have problems updating this code to Office 2007 because the native format in 2007 goes out to column XFD, and Excel won't let you use column or cell references as range names.
The code for the procedure is shown below. First, the declarations…
Sub RefreshAllTables() ''============================================================================== ''Purpose: To refresh the current table in a Word document with new data from '' the corresponding range in an Excel document. ''The code uses bookmarks in the Word document and corresponding named ranges in '' Excel. The Excel data is brought in as pictures. This has the advantage that any '' formatting in the Excel document is retained, and the dimensions don't change '' significantly. '' Also, bookmarks are simpler to create and maintain because a picture is only a '' single character in a Word document. ''Requires: A table in the Excel file to line up the bookmarks and named ranges ''Created: 23 Oct 2008 by Denis Wright ''============================================================================== Dim objExcel As Object, _ objWbk As Object, _ objDoc As Document Dim sBookmark As String, _ sWbkName As String Dim sRange As String, _ sSheet As String Dim BMRange As Range Dim bmk As Bookmark Dim i As Integer, _ j As Integer, _ k As Integer, _ bmkCount As Integer Dim vNames() Dim vBookmarks() Dim dlgOpen As FileDialog Dim bnExcel As Boolean On Error GoTo Err_Handle
The FileDialog object lets you pick a file for processing. It is placed within a Do … Loop to ensure that the user picks an Excel file. It could also be modified to ensure that they pick an Excel file with a table called Bookmarks, located on the List sheet.
Set dlgOpen = Application.FileDialog( _ FileDialogType:=msoFileDialogOpen) bnExcel = False Do Until bnExcel = True With dlgOpen .AllowMultiSelect = True .Show If .SelectedItems.Count > 0 Then sWbkName = .SelectedItems(1) Else MsgBox "Please select a workbook to use for processing" End If End With If InStr(1, sWbkName, ".xls") > 0 Then 'proceed bnExcel = True Else MsgBox "The file must be a valid Excel file. Try again please..." End If Loop
The next step is to open or activate the workbook. This section checks to see whether the selected file is already open; if not, it is opened. The error handling routine at the end of the code launches Excel if it is not already running.
Set objDoc = ActiveDocument 'check to see that the Excel file is open. If not, open the file 'also grab the wbk name to enable switching Set objExcel = GetObject(, "Excel.Application") For i = 1 To objExcel.Workbooks.Count If objExcel.Workbooks(i).Name = sWbkName Then Set objWbk = objExcel.Workbooks(i) Exit For End If Next
Now we minimize the Excel window and hide the application. There are two arrays to be populated as well. The first uses the Bookmarks table in the Excel file; the second contains the names of all bookmarks in the active Word document. We also set an object reference to the Excel workbook, to simplify the code later on.
If objWbk Is Nothing Then Set objWbk = objExcel.Workbooks.Open(sWbkName) End If 'minimize the Excel window objExcel.WindowState = -4140 'minimized 'switch to Excel, find range name that corresponds to the bookmark objExcel.Visible = False objWbk.Activate vNames = objWbk.Worksheets("Lists").Range("Bookmarks").Value 'loop through the bookmarks bmkCount = ActiveDocument.Bookmarks.Count ReDim vBookmarks(bmkCount - 1) j = LBound(vBookmarks) For Each bmk In ActiveDocument.Bookmarks vBookmarks(j) = bmk.Name j = j + 1 Next bmk
This section loops through all the bookmarks in the array,
retrieving the Excel tables and pasting them into the word document.
A few points are worth commenting on:
There are some quirks to using pictures with bookmarks.
Another major frustration is that recording the Paste Special code to insert the Excel table as an enhanced metafile, was ignored by Word, which defaulted to inserting the table as a formatted Word table. This is what we were trying to avoid because it changed the layout of the Word document. The workaround was to use the CopyPicture method in Excel, to guarantee that the data was inserted as a picture.
For j = LBound(vBookmarks) To UBound(vBookmarks) 'go to the bookmark Selection.GoTo What:=wdGoToBookmark, Name:=vBookmarks(j) Set BMRange = ActiveDocument.Bookmarks(vBookmarks(j)).Range For k = 1 To UBound(vNames) If vNames(k, 1) = vBookmarks(j) Then sSheet = vNames(k, 2) sRange = vNames(k, 3) Exit For End If Next k 'copy data from the range as a picture objWbk.Worksheets(sSheet).Range(sRange).CopyPicture 1, -4147 'return to Word and paste objDoc.Activate BMRange.Select Selection.Delete 'Note: only required if the bookmark encloses a picture. 'If the bmk held text, deleting the selection removes the bmk too. 'Under those circumstances the code throws an error. 'Clunky workaround: tell Word to ignore the error On Error Resume Next ActiveDocument.Bookmarks(sBookmark).Delete On Error GoTo 0 'paste the picture, then move back one character so the new bookmark 'encloses the pasted picture Selection.PasteAndFormat (wdPasteDefault) Selection.Move Unit:=wdCharacter, Count:=-1 'now reinstate the bookmark objDoc.Bookmarks.Add Name:=vBookmarks(j), Range:=Selection.Range Next j
The final part is some error handling and a cleanup section to remove the object references, and redisplay the Excel window.
Err_Exit: 'clean up Set BMRange = Nothing Set objWbk = Nothing objExcel.Visible = True Set objExcel = Nothing Set objDoc = Nothing MsgBox "The document has been updated" Err_Handle: If Err.Number = 429 Then 'excel not running; launch Excel Set objExcel = CreateObject("Excel.Application") Resume Next ElseIf Err.Number <> 0 Then MsgBox "Error " & Err.Number & ": " & Err.Description Resume Err_Exit End If End Sub
This code has been broken up into sections to help with describing its function. If you want to copy it as a single block, it is provided on this page.
To run the code copy it into a new module in your Word document: