You have a Word document with many tables and need to apply a consistent format, fix alignment, or extract data from each one. Manually editing each table is slow and error-prone when you have dozens or hundreds of them. A VBA macro can automate this task by looping through every table in the document and performing the same action on each. This article explains how to write that macro, covering the essential objects, the loop structure, and common pitfalls to avoid.
Key Takeaways: VBA Macro to Loop Through All Tables in Word
- Tables collection and For Each loop: Use
ActiveDocument.TablesandFor Each tbl In ActiveDocument.Tablesto iterate over every table in the document. - Cell and Range objects: Access individual cells via
tbl.Cell(Row, Column).Rangeand modify text or formatting using the Range object. - Error handling with On Error Resume Next: Prevents the macro from stopping if a table is empty or has merged cells that cause a runtime error.
Understanding Word’s Table Object Model in VBA
Word exposes all tables in a document through the Tables collection. Each table is a Table object that contains a Rows collection and a Columns collection. The Cell object represents one cell, and you access it by row and column index. The Range object inside a cell holds the text and formatting you can read or modify.
The For Each loop is the most reliable way to visit every table because it automatically handles the collection count. You do not need to know how many tables exist beforehand. The loop runs once per table object in the Tables collection, regardless of whether the tables are nested or placed in headers and footers.
Prerequisites for Running VBA Macros
Before writing the macro, ensure macros are enabled in Word. Go to File > Options > Trust Center > Trust Center Settings > Macro Settings and select Enable all macros or Enable VBA macros. You also need the Developer tab visible. Right-click the ribbon, select Customize the Ribbon, and check the Developer box in the right pane.
Writing the Core Macro to Loop Through Each Table
The following macro loops through every table in the active document and applies a simple action: it bolds the first row of each table. You can replace the body of the loop with any operation you need.
- Open the VBA editor
Press Alt + F11 in Word to open the Visual Basic for Applications editor. - Insert a new module
In the Project Explorer pane, right-click Normal or your document name. Choose Insert > Module. A blank code window appears. - Paste the macro code
Copy and paste the following code into the module window:Sub BoldFirstRowOfAllTables() Dim tbl As Table Dim r As Integer Dim c As Integer On Error Resume Next For Each tbl In ActiveDocument.Tables ' Bold all cells in the first row For c = 1 To tbl.Columns.Count tbl.Cell(1, c).Range.Bold = True Next c Next tbl On Error GoTo 0 MsgBox "Done. Processed " & ActiveDocument.Tables.Count & " tables." End Sub - Run the macro
Press F5 while the cursor is inside the macro, or go to the Developer tab and click Macros. Select BoldFirstRowOfAllTables and click Run.
The macro uses On Error Resume Next to skip tables that cause errors, such as those with merged cells that make Cell(1, c) invalid. After the loop, On Error GoTo 0 restores normal error handling. The message box shows how many tables were found.
Modifying the Loop to Perform Other Actions
You can replace the inner For c loop with any table operation. Common examples include:
- Change cell background color:
tbl.Cell(r, c).Shading.BackgroundPatternColor = wdColorLightYellow - Set column width:
tbl.Columns(1).Width = InchesToPoints(2) - Remove borders:
tbl.Borders.Enable = False - Align text in all cells:
tbl.Range.ParagraphFormat.Alignment = wdAlignParagraphCenter
To loop through every cell in every table, use a nested For r and For c loop over tbl.Rows.Count and tbl.Columns.Count.
Common Issues When Looping Through Tables
Macro Stops With a Runtime Error on a Specific Table
The most frequent cause is merged cells. When a cell spans multiple rows or columns, the Cell object may not exist at the expected coordinates. The On Error Resume Next statement bypasses this error. If you need to process merged cells, use the tbl.Range.Cells collection instead of row-column indexing, but note that this collection counts all cells including those that are part of a merge.
Macro Does Not Process Tables in Headers or Footers
ActiveDocument.Tables only includes tables in the main body of the document. To include tables in headers, footers, text boxes, or footnotes, you must access each story range. A more advanced macro would loop through ActiveDocument.StoryRanges and check each range’s Tables collection.
Macro Runs Slowly on Documents With Many Tables
Word updates the screen after each operation by default. Add Application.ScreenUpdating = False at the start of the macro and Application.ScreenUpdating = True at the end to speed it up significantly. Also disable automatic calculation with Application.Calculation = wdCalculationManual if your macro modifies fields.
ActiveDocument.Tables vs Selection.Tables: Scope Differences
| Item | ActiveDocument.Tables | Selection.Tables |
|---|---|---|
| Scope | All tables in the main body of the active document | Only tables that intersect the current selection |
| Use case | Global formatting or data extraction across the whole document | Targeted action on one or a few tables the user has highlighted |
| Error risk | May fail on tables in headers or text boxes unless story ranges are included | Requires the user to select tables manually before running the macro |
| Performance | Slower on documents with hundreds of tables | Faster because it processes only the selected subset |
Choose ActiveDocument.Tables when you need to apply a change to every table without manual intervention. Use Selection.Tables when you want the user to control which tables are affected.
You now have a working VBA macro that loops through all tables in a Word document. Start by testing the example macro on a copy of your document. Once you confirm it works, replace the inner loop with your specific formatting or data extraction logic. For documents with tables in headers or footers, extend the macro to iterate through ActiveDocument.StoryRanges. Add Application.ScreenUpdating = False to speed up processing when you have more than 50 tables.