Nested Table question

K

KWarner

I have a table (table1) with 10 rows, 1 column.
Inside each row I have a nested table (table2 - table11).
So, if a user is somewhere in table4, they would be in row3 of table1.
Using VBA, how can I determine which row of table1 they are actually in,
preferrably without changing the selection.

Thanks for any help,
KevinWarner
 
T

TimvG

One way is to move the selection (or a range) until it pops out of the
nested table, then get the rowindex of the cell you're in.

However I suspect there must be a more elegant/direct way. Anyone
know of one?

- Tim
 
J

Jay Freedman

I have a table (table1) with 10 rows, 1 column.
Inside each row I have a nested table (table2 - table11).
So, if a user is somewhere in table4, they would be in row3 of table1.
Using VBA, how can I determine which row of table1 they are actually in,
preferrably without changing the selection.

Thanks for any help,
KevinWarner

There might be something more elegant than this, but it works:

Sub WhatRow()
Dim T1 As Table
Dim T1row As Long

If Not Selection.Information(wdWithInTable) Then Exit Sub

Set T1 = ActiveDocument.Tables(1)

For T1row = 1 To T1.Rows.Count
If Selection.InRange(T1.Rows(T1row).Range) Then
MsgBox "Selection is in row " & T1row & " of outer table"
Exit For
End If
Next
End Sub
 
F

Fumei2 via OfficeKB.com

First of all let me confirm...

You have one table - Table(1) - which has 10 tables nested inside it.

Yes?

Let me ask if you know the answer to this question. How many tables does the
document have?

Hopefully, you answer...one. the document has ONE table.

Try this:

MsgBox ActiveDocument.Tables.Count

It returns 1. The document has ONE table. The table has...10 tables.
However, even doing a count of the tables IN a table does not give a good
answer.

MsgBox ActiveDocument.Tables(1).Range.Tables.Count

will still give 1.

You can get the RowIndex of the Selection with:

If Selection.Information(wdWithInTable) = True Then
MsgBox Selection.Cells(1).RowIndex
End If

BUT, if the selection is in Row 1 of the table in - say Row 3 of table 1 - it
will return...1. If it is Row 2 of the table in Row 5 of Table 1, it will
return...2. It returns the RowIndex of the table it is IN.

"So, if a user is somewhere in table4, they would be in row3 of table1."

Maybe so, but to VBA they are NOT. They are in whatever row of table 4.

Let me repeat that: from a table perspective, they are NOT in table 1, they
are in table 4.

Why do you need to know what row of table 1 they seem to be in? What are you
trying to do?
 
F

Fumei2 via OfficeKB.com

And yes, as it was noted, IF you could move the Selection outside of the
table in the row - but still in the row - you can use RowIndex.
First of all let me confirm...

You have one table - Table(1) - which has 10 tables nested inside it.

Yes?

Let me ask if you know the answer to this question. How many tables does the
document have?

Hopefully, you answer...one. the document has ONE table.

Try this:

MsgBox ActiveDocument.Tables.Count

It returns 1. The document has ONE table. The table has...10 tables.
However, even doing a count of the tables IN a table does not give a good
answer.

MsgBox ActiveDocument.Tables(1).Range.Tables.Count

will still give 1.

You can get the RowIndex of the Selection with:

If Selection.Information(wdWithInTable) = True Then
MsgBox Selection.Cells(1).RowIndex
End If

BUT, if the selection is in Row 1 of the table in - say Row 3 of table 1 - it
will return...1. If it is Row 2 of the table in Row 5 of Table 1, it will
return...2. It returns the RowIndex of the table it is IN.

"So, if a user is somewhere in table4, they would be in row3 of table1."

Maybe so, but to VBA they are NOT. They are in whatever row of table 4.

Let me repeat that: from a table perspective, they are NOT in table 1, they
are in table 4.

Why do you need to know what row of table 1 they seem to be in? What are you
trying to do?
I have a table (table1) with 10 rows, 1 column.
Inside each row I have a nested table (table2 - table11).
[quoted text clipped - 4 lines]
Thanks for any help,
KevinWarner
 
T

TimvG

Interesting... Jay's approach works from the "outside in" as opposed
to mine which works "inside out".

You'd need a recursive version of Jay's algorithm if you wanted to
answer Kevin's question in the more general case in which you want to
find the nesting row for a nested table which may be arbitrarily
deeply nested.

- Tim
 
K

KWarner

Perfect, this is exactly what I needed. thank you.
On a related question, why does the following not execute any code after the
for? When I stop execution at End Sub, t1Row is nothing.

Private Function GetRowNumber() As Integer
Dim t1 As Table
Set t1 = ActiveDocument.Tables(1)
Dim t1Row As row
For Each t1Row In t1.Rows
If Selection.InRange(t1Row.Range) Then
GetRowNumber = t1Row.index
Exit For
End If
Next
End Function
 
J

Jay Freedman

I don't see any code after the For loop (that is, between the Next and
the End Function). What do you expect to execute?

I would expect t1Row = Nothing at the End Function statement only if
the For Each loop executes all the way to the end for all of the rows
of the table. If the selection is in any row of the table, though, the
Exit For statement should terminate the loop before t1Row gets set to
Nothing.

Under the hood, the For Each loop is equivalent to this:

Set t1Row = t1.Rows.First
Do
' do some action
Set t1Row = t1Row.Next
Loop Until t1Row Is Nothing

This loop terminates after acting unsuccessfully on the last row
because the .Next property of the last row is Nothing. The same thing
happens in the For Each loop. But the Exit For prevents that -- if the
selection is inside the table. That's why my code includes a check of
Selection.Information(wdWithInTable) at the very beginning.
 
K

KWarner

What I meant was that the code gets to the "For Each t1Row In t1.Rows"
statement, t1Row is nothing so no code inside the loop is executed. When I do
it with "For T1row = 1 To T1.Rows.Count", the code inside the "For" loop is
executed. The "For Each" way acts like T1.Rows.Count=0.
After playing around with it a little more, this behavior is only observed
if T1 has nested tables. If none of the rows has a nested table, then the
code executes as expected.
 
J

Jay Freedman

Very odd -- I do see what you described, and it looks like a bug to
me. This version does work properly with nested tables:

Private Function GetRowNumber() As Integer
Dim t1 As Table
Set t1 = ActiveDocument.Tables(1)
Dim t1Row As Row
Set t1Row = t1.Rows.First
Do
If Selection.InRange(t1Row.Range) Then
GetRowNumber = t1Row.Index
Exit Do
End If
Set t1Row = t1Row.Next
Loop Until t1Row Is Nothing
End Function
 
K

KWarner

Thanks for your help and thanks for verifying that I'm not crazy.
How do we get this reported to MS so they can fix it?
Kevin
 
J

Jay Freedman

I'll report it as a bug in Word 2010 beta, where it's remotely
possible that it might be fixed before final release.

I'd be very surprised if it gets fixed in Word 2007 or earlier (the
same bug is in Word 2003, and probably versions before that). The
reason is that it fails two of Microsoft's criteria for making the top
of the list to be fixed:

- It doesn't affect a lot of people (otherwise we would have seen
posts about it over a long period).

- It has an easy workaround, as in my previous post.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top