Consulting

Results 1 to 14 of 14

Thread: Table Code Oddity

  1. #1
    Microsoft Word MVP 2003-2009 VBAX Guru gmaxey's Avatar
    Joined
    Sep 2005
    Posts
    3,335
    Location

    Table Code Oddity

    Maybe it is known and documented but this is the first time I've encountered this oddity:

    Sub ScratchMacroOddity()
    'A basic Word macro coded by Greg Maxey
    Dim lngIndex As Long
    Dim oTbl As Word.Table
      'Add a 3x3 table
      Set oTbl = ActiveDocument.Tables.Add(Selection.Range, 3, 3)
      On Error GoTo Err_NoRow
      For lngIndex = 1 To 5
        'I would expect a RTE 5941 - The requested memeber of the collection does not exist, but it doesn't occur.
        oTbl.Cell(lngIndex, 1).Range.Text = lngIndex & "-1"
        oTbl.Cell(lngIndex, 2).Range.Text = lngIndex & "-2"
        oTbl.Cell(lngIndex, 3).Range.Text = lngIndex & "-3"
        'Even though rows 4 and 5 don't exists the data is written to the "last" row.
      Next lngIndex
    lbl_Exit:
      Exit Sub
    Err_NoRow:
      oTbl.Rows.Add
      Resume
    End Sub
    
    Sub ScratchMacroWorking()
    'A basic Word macro coded by Greg Maxey
    Dim lngIndex As Long
    Dim oTbl As Word.Table
      Set oTbl = ActiveDocument.Tables.Add(Selection.Range, 3, 3)
      On Error GoTo Err_NoRow
      For lngIndex = 1 To 5
        oTbl.Rows(lngIndex).Cells(1).Range.Text = lngIndex & "-1"
        oTbl.Rows(lngIndex).Cells(2).Range.Text = lngIndex & "-2"
        oTbl.Rows(lngIndex).Cells(3).Range.Text = lngIndex & "-3"
      Next lngIndex
    lbl_Exit:
      Exit Sub
    Err_NoRow:
      MsgBox Err.Number & " " & Err.Description
      oTbl.Rows.Add
      Resume
    End Sub
    Greg

    Visit my website: http://gregmaxey.com

  2. #2
    Knowledge Base Approver VBAX Guru macropod's Avatar
    Joined
    Jul 2008
    Posts
    4,435
    Location
    Odd!
    Cheers
    Paul Edstein
    [Fmr MS MVP - Word]

  3. #3
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    Hmmmm. Odd indeed.

  4. #4
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    What is interesting is if you put an arbitrary number:

    lngIndex = 23
    oTbl.Cell(lngIndex, 3).Range.Text = lngIndex & "-3"

    into the first procedure, it puts 23-3 into the last cell. No error. Even though Cell should be Cell(Row as Long, Column as Long), apparently VBA does not give a crap about whether the number makes sense. Weird.

    lngIndex = 23
    oTbl.Cell(lngIndex, 2).Range.Text = lngIndex & "-2"
    oTbl.Cell(44, 2).Range.Text = "whatever"

    the 44,2 replaces (at least the weirdness is consistent) 23-2 with "whatever". Note that this weirdness works on the Rows, but not Columns.

    44,2 put the text in cell(2), but 44,7 gives an error. Rows do not really get validated, but columns do? Or more accurately, the Row parameter value of CELL does not seem to get validated - clearly as shown in the second procedure the INDEX value of Row does get validated.

    Nice one Greg.
    Last edited by fumei; 02-23-2014 at 11:42 PM.

  5. #5
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    This seems like an extremely glaring bug.

  6. #6
    Knowledge Base Approver VBAX Guru macropod's Avatar
    Joined
    Jul 2008
    Posts
    4,435
    Location
    Quote Originally Posted by fumei View Post
    This seems like an extremely glaring bug.
    Not likely to be fixed in a hurry, though - it goes back at least as far as Word 2003 and this is the first time I've seen it mentioned.
    Cheers
    Paul Edstein
    [Fmr MS MVP - Word]

  7. #7
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    Me too. I have heard of this before. But then whenever I work through rows I would do something more explicit - that is getting a real value - like:
    For lngIndex = 1 to oTbl.Rows.Count
    rather than an arbitrary number. Greg, how did you come across this? Why did you use 5 when you put in 3 as the row count?

    And no, there is no chance that this is going to be fixed any time soon...or ever. It does seem a very odd and incredibly sloppy hole. I mean they catch the error if it is the column value.

  8. #8
    Microsoft Word MVP 2003-2009 VBAX Guru gmaxey's Avatar
    Joined
    Sep 2005
    Posts
    3,335
    Location
    Gerry,

    5 was just a arbitrary number for to illustrate the issue. I came across the issue while attempting to insert a pre-defined buildingblock table with three rows and then fill it with the contents of a listbox. In several cases the listbox had more list entries than the table had rows and I need to add rows. So .listEntries.ListCount - 1 isn't really an arbitrary number and I thought I could detect the need for an additional row by error handling:

    Private Sub AddAndFillTable_Click()
    Dim oRng As Word.Range
     Dim oTmp As Template
    Dim lngIndex As Long
      Selection.Paragraphs(1).Style = "Normal"
      Set oRng = Selection.Range
      Set oRng = ThisDocument.AttachedTemplate.BuildingBlockTypes(wdTypeCustomTextBox).Categories("Tables") _
                .BuildingBlocks("Selection Condition Box").Insert(Where:=Selection.Range, RichText:=True)
      Set oTbl = oRng.Tables(1)
      On Error GoTo Err_NoRow
      For lngIndex = 0 To 5 'listEntries.ListCount - 1
        oTbl.Cell(lngIndex + 2, 1).Range.Text = lngIndex & "-1" 'listEntries.List(lngIndex, 0)
        oTbl.Cell(lngIndex + 2, 2).Range.Text = lngIndex & "-2" 'listEntries.List(lngIndex, 1)
        oTbl.Cell(lngIndex + 2, 2).Range.Text = lngIndex & "-3" 'listEntries.List(lngIndex, 2)
      Next lngIndex
      oRng.Collapse wdCollapseEnd
      Unload Me
    lbl_Exit:
      Exit Sub
    Err_NoRow:
      oTbl.Rows.Add
      Resume
    End Sub
    Greg

    Visit my website: http://gregmaxey.com

  9. #9
    VBAX Master
    Joined
    Feb 2011
    Posts
    1,480
    Location
    Ah, tables. What a disaster... and has been since Word 97 (at least).
    You could try to write your own function so that your error handling would work...
    [VBA]
    Public Function fGetCell(lRow As Long, lColumn As Long, oTable As Word.Table) As Word.Cell
    Dim oRet As Word.Cell
    On Error GoTo l_err
    If lRow > oTable.Rows.Count Then
    'what microsoft *should* do
    GoTo l_exit
    'what microsoft *does*
    'lRow = oTable.Rows.Count
    End If
    Set oRet = oTable.Cell(lRow, lColumn)

    l_exit:
    Set fGetCell = oRet
    Exit Function
    l_err:
    Set oRet = Nothing
    Resume l_exit
    End Function
    [/VBA]

  10. #10
    Microsoft Word MVP 2003-2009 VBAX Guru gmaxey's Avatar
    Joined
    Sep 2005
    Posts
    3,335
    Location
    Jason,

    Thanks. Using the row method instead of cell above worked fine, so I'm not going to bother going back and changing it.
    Greg

    Visit my website: http://gregmaxey.com

  11. #11
    VBAX Master
    Joined
    Feb 2011
    Posts
    1,480
    Location
    I suspect the behavior is because what microsoft is really doing is iterating through the .Cells collection off the table's .Range... and then exiting the loop once it runs out of cells in the table, rather than validating that the number is correct. The help file clearly states it can be an integer (despite being a long parameter) between 1 and the .Count of the rows/columns.

    But you could also just validate your table before trying to go through your loop (if your error trapping is just going to add a row... then add rows until your .Rows.Count is the same as your highest desired row value to insert text in.

    Pretty weird, but after running into bugs in the Table object when I selected the entire table from the bottom right of the table to the top left (instead of the top left down to the bottom right), I cease to be surprised at any bugs in the table object anymore. You just work around them. There are so many ways to break how you reference elements of a table, that there is no "right" approach to avoid bugs, just the one that works for that particular code.

  12. #12
    VBAX Master
    Joined
    Feb 2011
    Posts
    1,480
    Location
    Yeah, if you don't have to worry about merged cells anywhere, it's pretty easy to work around. But if you do, then working off the .Rows object will cause problems, where the .Cell Method is more "robust" (albeit, "robust" can also mean "doesn't cause an error when you want it to").

  13. #13
    Microsoft Word MVP 2003-2009 VBAX Guru gmaxey's Avatar
    Joined
    Sep 2005
    Posts
    3,335
    Location
    It all makes sense. Or sort of. Or maybe not
    Greg

    Visit my website: http://gregmaxey.com

  14. #14
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    Ah, yes Word tables. As I have posted elsewhere, it sometimes seems like Word programmers are castoff (read rejected and sloppy) failed Excel programmers...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •