How to use VBA to traverse the cells in the Word table so that there will be no runtime errors

Let's look at two tables in a Word document, the first table is as follows:

RowIndex=1

ColumnIndex=1

RowIndex=1

ColumnIndex=2

RowIndex=1

ColumnIndex=3

RowIndex=1

ColumnIndex=4

RowIndex=2

ColumnIndex=1

RowIndex=2

ColumnIndex=2

RowIndex=2

ColumnIndex=3

RowIndex=2

ColumnIndex=4

RowIndex=3

ColumnIndex=1

RowIndex=3

ColumnIndex=2

RowIndex=3

ColumnIndex=3

RowIndex=3

ColumnIndex=4

The second form is as follows:

RowIndex=1

ColumnIndex=1

RowIndex=1

ColumnIndex=2

RowIndex=1

ColumnIndex=3

RowIndex=2

ColumnIndex=1

RowIndex=2

ColumnIndex=2

RowIndex=2

ColumnIndex=3

RowIndex=2

ColumnIndex=4

RowIndex=3

ColumnIndex=1

RowIndex=3

ColumnIndex=2

RowIndex=3

ColumnIndex=3

RowIndex=3

ColumnIndex=4

RowIndex=4

ColumnIndex=2

RowIndex=4

ColumnIndex=3

RowIndex=4

ColumnIndex=4

We know that the following code can get the total number of rows and total columns of the table object "aTable":

' obtain aTable The total number of columns
iCols = aTable.Columns.Count
' obtain aTable The total number of rows
iRows = aTable.Rows.Count

Usually, by using index variables, you can complete the traversal of all cells in the table, the sample code is as follows:

' use index variable i and j Traverse the cells in the table in row order first
For i = 1 To iRows
     For j = 1 To iCols
        ' Replace the last character that cannot be displayed in the table content with a blank and display it in the prompt box
         MsgBox Replace(aTable.Cell(i, j).Range.Text, Chr(13) & Chr(7), "")
     Next
Next

However, when the above traversal code traverses the second table (a table with merged cells), a runtime error "Cannot access individual rows or columns in this collection because the table has vertically or horizontally merged cells." .

Whether there is a merged cell in the table can be detected by the "Uniform" attribute of the table. If the "Uniform" attribute of the table is "True", there is no merged cell, otherwise there is a merged cell. For a table with merged cells, you cannot use the above method of using the index to traverse the cells, but can only traverse the cells through the For each method (of course, tables without merged cells can also be traversed in this way). The following code demonstrates different ways to iterate over all cells for a table with merged cells and a table without merged cells:

Sub traverse word Example of a table cell in()
    Dim aCell As Cell
    Dim aTable As Table
    Dim i, j, iCols, iRows As Integer
    For Each aTable In ActiveDocument.Tables
        With aTable
            ' There are no merged cells in the table, and the row and column indexes are used to traverse.
            ' Traversing tables with merged cells in this way will cause a runtime error.
            If .Uniform Then
                iCols = aTable.Columns.Count
                iRows = aTable.Rows.Count
                For i = 1 To iRows
                    For j = 1 To iCols
                      MsgBox "uniform:" & vbCrLf & Replace(.Cell(i, j).Range.Text, Chr(13) & Chr(7), "")
                    Next
                Next
            Else ' There are merged cells in the table, using For Each way to traverse. Tables without merged cells can also be traversed in this way.
                For Each aCell In .Range.Cells
                   MsgBox Replace(aCell.Range.Text, Chr(13) & Chr(7), "")
                Next
            End If
        End With
    Next
End Sub

Here's an application example: traverse each cell in the table, if the content in the cell is a number, keep two decimal places, otherwise keep the original state:

Sub Will word Numeric cells in tables retain two decimal places()
    Dim aCell As Cell
    Dim aTable As Table
    Dim sText As String
    For Each aTable In ActiveDocument.Tables
        With aTable
            For Each aCell In .Range.Cells
                With aCell
                    ' To record the cell text, the final carriage return and bell should be removed, otherwise the correct result cannot be obtained
                    sText = Replace(.Range.Text, Chr(13) & Chr(7), "")
                    If IsNumeric(sText) Then
                        ' If the content in the cell is a number, it is set to retain two decimal places
                        sText = VBA.Format(sText, "##0.00")
                        ' rewrite cell content
                        .Range.Text = sText
                    End If
                End With
            Next
        End With
    Next
End Sub

In a Word VBA problem involving a table, one of the puzzles is to tell if a cell of a table is a merged cell or not. Tables in Word do not have a MergCells attribute to directly determine whether a cell is a merged cell like a table in Excel, and Word tables have the following VBA features:

1. For each row, the maximum column number is the max(ColumnIndex) of the row, for each column, the maximum row number is the max(RowIndex) of the column, and the columns.Count of the table is the max(ColumnIndex) of the entire table, rows .Count is the max(RowIndex) of the entire table.
2. The object pointed to by Cell.Tables(1) is the entire table.
3. After selecting a column through Cell.Select/Selection.SelectColumn, Selection.Information(wdMaximumNumberOfColumns) still returns the number of columns in the entire table.
4. After selecting the columns or rows of the table, Selection.Rows.Count and Selection.Columns.Count can respectively return the number of rows of the selected column (the max(RowIndex) of the column) and the number of columns (the max(ColumnIndex of the row) )).

Due to the above characteristics, it is really difficult to judge whether a cell is a merged cell or not. After selecting the entire row through "Selection.SelectRow", get the max(ColumnIndex) of the row, and then compare it with the max(ColumnIndex) of the table. If they are not equal, it can be determined that there is a merged cell in the row, but if they are equal, it cannot be concluded that the row is equal. There is no merged cell, and it depends on whether there is a merged cell in the vertical direction. Further judgment can hardly find an effective algorithm (because as long as there are horizontally merged cells in the column, accessing aTable.Columns(aCell.ColumnIndex) will trigger an error), I can't solve this problem for the time being, and I can only wait for the master.

Tags: Javascript Vue.js JSON VBA Office software

Posted by thehippy on Sun, 19 Feb 2023 11:51:19 +1030