|
This Microsoft Word Help and Tips Page provides my version of a Table & Cell Data macro that I
find more reliable than the TableCellHelper macro provided by Microsoft in
earlier Word versions and distributed with the Macros8.Dot template. In
fact I couldn't get Microsoft's version to work reliably at all. If you
are interested in experimenting with Microsoft's TableCellHelper macro you can
download it from
Macros8.Dot
(Note: This opens a Word MVP FAQ page with a link to the Macros8.Dot file.)
I call my macro TableCellData. Unlike
WordPerfect, Word has a shortcoming when it comes to determining the location of
the IP or
selection in a table. This can be frustrating when you are
working in a table with many rows or columns. TableCellData can provide
this and other information about your tables as either a message box or status
bar display. You can initiate the display by firing the macro from a
keyboard shortcut, toolbar icon or menu command. The
illustration below shows the standard status bar report for a single uniform
table (i.e., a table with no split or merged cells) |
|

|
|
Table cells can be merged or split. For this reason,
TableCellData reports the maximum "Max" column and row count. For example,
in the following table, cell C5 has been split into three cells. Therefore
there are now 12 Max columns. While the hard column headings indicate the
cursor is in column "J," notice the cursor is location is accurately
reported as L5. This would be important if you needed to reference this
cells value in a calculation field. |
|

|
|
TableCellData can also report the range of selected cells.
This feature is only 100% accurate in uniform tables (i.e., tables without split or
merged cells). |
|

|
|
Word can determine if a table has
split or merged cells, but it can't determine if there are split or merged
cells in the current selection. Therefore, all selection span
reports on tables that contain split or merged cells are susceptible
to error. (Note: TableCellHelper has the same problems but it
doesn't tell you about it). Reports for
selections containing split or merged cells may or may not be accurate
depending on the relationship of the selected cells to other split or merged
cells. This is shown in the following illustrations: |
|

|
|
In this first illustration, the selection consist of the 6 cells A2, B2, C2, A3,
B3 and C3. The light orange cells are the result of a split.
The light green cells result from a merge. The column IDs compare to the header row column IDs
and the range is unaffected by split and merged cells in the table.
The reported span span is accurate. Using the span in a calculation
produces the correct answer.
|
|

Here the selection appears blue and consist of the 3 cells split from the
former cell F6 resulting in new cells F6, G6 and H6. The reported span
is accurate. Using the span in a calculation produces the correct
answer.
|
 |
|
Here is were it starts getting ugly. Cells I6 and J6 of the original
table are merged in what appears to be a single cell spanning the header row
column IDs I an J. The selection appears to consist of cells H5, I5,
J5,H6, and the merged cell, which left unaffected by other split or merged
cells would be reported individually as I6. Look at the reported
range!! Where did "K" come from??! If you noticed the results of
the calculation you might be getting the picture. The split cells in
the "F" column are actually F6, G6, and H6. Therefore the selected
cells are in fact H5, I5, J5, J6 and K6. H6 is not in the selected
range and K5 doesn't even exist! The value in cell H6 is "5" which
explains the apparent error in the calculation. |
|
There is no readily avaliable VBA solution to this
range reporting problem. It is pretty much hit and miss and therefore
I have provided an option in the TableCellHelper code to completely suppress
span reports if the table contains split or merged cells. An example
of the suppressed report is shown below. |
|

|
| TableCellData will identify nested
tables down two levels. The following illustration will help you
understand how nested tables are reported. The cursor is located in
cell A2 of the second table in cell B3 of the first table in cell B1 of the
second table of the document. While the table IDs are reported, only
the cell ID of the lowest level nested cell is reported. To determine
the cell ID in the higher level tables, you must put the cursor directly in
the cell proper (i.e, in the cell, but outside of any nested table in the cell). |
|

|
| Here is the macro and function
required to determine the table and cell data illustrated above: |
Sub TableCellData()
Dim i&, oColMax&, oRowMax&, oCellCnt
Dim oColS$, oRowS$, oColE$, oRowE$
Dim Msg1$, Msg2$, Msg3$, Msg4$, Msg5$
If Application.Documents.Count Then
With Selection
If .Information(wdWithInTable) Then
i =
ActiveDocument.Range(0, .Tables(1).Range.End).Tables.Count
Msg1$ =
TableConfigID(i)
oColMax =
.Tables(1).Columns.Count
oRowMax =
.Tables(1).Rows.Count
oCellCnt =
.Tables(1).Range.Cells.Count
Msg2$ =
"/Max. columns: " & oColMax & "/" _
& "Max. rows: " & oRowMax
Msg3$ =
"Total cells: " & oCellCnt & ". "
oColS =
alphaChar(.Information(wdStartOfRangeColumnNumber))
oRowS = .Information(wdStartOfRangeRowNumber)
oColE =
alphaChar(.Information(wdEndOfRangeColumnNumber))
oRowE = .Information(wdEndOfRangeRowNumber)
Select Case .Cells.Count
Case Is < 2
Msg4$ = "At cell: " & oColS & oRowS & ". "
If Not .Tables(1).Uniform Then
Msg5$ = "This table contains split or merged cells."
End If
Case Else
If .Tables(1).Uniform Then
Msg4$ = "Selection spans: " _
& oColS & oRowS & ":" & oColE & oRowE & "."
Else
'Suppress or report spans in tables with split or
merged cells
'Msg4$ = "Table contains split/merged cells." _
& " The span can not be positively determined."
Msg4$ = "Selection spans: " & oColS & oRowS & ":" _
& oColE & oRowE & ". Span susceptible to" _
& " error due to split/merged cells."
Msg5$ = ""
End If
End Select
'Can use
message box, status bar, or both
'MsgBox Msg1$
& Msg2$ & vbCr & vbCr & Msg3$ _
& vbCr & vbCr & Msg4$ & vbCr & vbCr & Msg5$, _
vbInformation + vbOKOnly, "Table Data"
Application.StatusBar = Msg1$ & Msg2$ & "/" & Msg3$ & Msg4$ & Msg5$
End If
End With
End If
End Sub
Function TableConfigID(ByVal i As Long) As String
Dim TopTbl As Table, Nest1Tbl As Table, Nest2Tbl As Table
Dim x&, y&
Dim ttCell As Word.Cell, ntCell As Word.Cell
Dim tmpMsg1$, tmpMsg2$, tmpMsg3$
Set TopTbl = ActiveDocument.Tables(i)
tmpMsg1$ = "Table " & i
x = 0
For Each ttCell In TopTbl.Range.Cells
If ttCell.Tables.Count > 0 Then
For Each Nest1Tbl In ttCell.Tables
x = x + 1
If
Selection.InRange(Nest1Tbl.Range) Then
tmpMsg1$ = "Table " & i & "{Table " & x & "}"
End If
y = 0
For Each
ntCell In Nest1Tbl.Range.Cells
If ntCell.Tables.Count > 0 Then
For Each Nest2Tbl In ntCell.Tables
y = y + 1
If Selection.InRange(Nest2Tbl.Range) Then
tmpMsg1$ = "Table " & i & "{Table " & x & "{Table " & y & "}}"
End If
Next Nest2Tbl
End If
Next ntCell
Next Nest1Tbl
End If
Next ttCell
TableConfigID = tmpMsg1$
End FunctionFunction alphaChar(pAribicNum As
Integer) As String
Select Case pAribicNum
Case Is < 27
alphaChar = String(1, (pAribicNum +
64))
Case Is < 53
alphaChar = "A" & String(1, (pAribicNum
- (26) + 64))
Case Is >= 53
alphaChar = "B" & String(1, (pAribicNum
- (52) + 64))
End Select
End Function |
|
To use TableCellData, simply copy the
macro and two functions to a module in your VBA project. For help with this,
see fellow MVP Graham Mayor's
Guide for
Installing Macros. To
assign TableCellData to a keyboard shortcut see
How to assign a Word command or macro to a hot-key. To assign to a menu (including mouse right
button shortcut menu) or toolbar button, see
How to assign a Word command or macro to a toolbar or menu. |
|
I have my shortcut on the built-in
Table menu: |
|

|
| With a bit of razzmatazz coding (and
help from regular Word VBA newsgroup contributors "Jezebel" and Tony Jollans)
I set it up so that the menu command is dimmed to mimic the Table
Properties command whenever the selection is not in a table. |
|

|
| This is accomplished using a Class
module and a WindowsChangeEvent. It is hardly worth the extra coding,
but I wanted to present the process for any users that might be interested. |
1. Create a Class module in the same Project as the
macro (mine is in Normal.Dot)
2. Name the Class myClass1
3. Insert the following code in the Class:
Option Explicit
Private WithEvents mWordApp As Word.Application
Private Sub
Class_Initialize()
Set mWordApp = Word.Application
End Sub
Private Sub
mWordApp_WindowSelectionChange(ByVal oSel As Selection)
Dim bSavedState As Boolean
bSavedState = NormalTemplate.Saved
CommandBars("Table").Controls("Table Data").Enabled =
oSel.Information(wdWithInTable)
NormalTemplate.Saved = bSavedState
End Sub
4. Insert the following code in the same module as the
TableCellData macro:
Option Explicit
Private myDynamicMenu As myClass1
Sub SetMyClass1()
Set myDynamicMenu = New myClass1
End Sub
5. Call the macro from an AUTOEXEC macro in the project:
Sub AutoExec()
SetMyClass1
End Sub |
| Enjoy!! |