none
How do you add multiple tables in a Word document using Visual Studio 2010? RRS feed

  • Question

  • I'm trying to add a second table to my Word document using Visual Basic, but I can't get it to work.  The second table does not show up in my Word document.  I had no problem creating the first table.  

    This is my code for Table 1 and Table 2:

    Dim wordApp As New Word.Application
    wordApp.Visible = True
    Dim doc As Word.Document = wordApp.Documents.Add()
    Dim range As Word.Range
    range = doc.Range()
    doc.Sections(1).PageSetup.Orientation = Word.WdOrientation.wdOrientLandscape
    
    range.SetRange(range.End, range.End)
    
    ' Add the table.
    doc.Tables.Add( _
    Range:=range, _
    NumRows:=1, NumColumns:=1)
    
    Dim tbl As Word.Table = doc.Tables(1)
    tbl.Range.Font.Size = 8
    tbl.Range.Font.Name = "Times New Roman"
    tbl.Style = "Table Grid 8"
    tbl.ApplyStyleFirstColumn = False
    tbl.ApplyStyleLastColumn = False
    tbl.ApplyStyleLastRow = False
    
    Dim rngCell As Word.Range
    rngCell = tbl.Cell(1, 1).Range
    tbl.Cell(1, 1).Range.Text = "1.  Account Creation"
    tbl.Cell(1, 1).Range.Font.Size = 18
    tbl.Cell(1, 1).Range.Font.Bold = vbYes
    tbl.Cell(1, 1).Range.Font.ColorIndex = Word.WdColorIndex.wdBlack
    rngCell.ParagraphFormat.Alignment = _
    Word.WdParagraphAlignment.wdAlignParagraphCenter
    
    tbl.Rows.Add()
    rngCell = tbl.Cell(2, 1).Range
    tbl.Cell(2, 1).Range.Text = "Overall Result:    Pass:_____   Fail:_____     Test Date:_____________      SCA Rep:____________________________"
    tbl.Cell(2, 1).Range.Font.Size = 12
    tbl.Cell(2, 1).Range.Font.Bold = vbYes
    tbl.Range.Shading.BackgroundPatternColor = Word.WdColor.wdColorGray05
    rngCell.ParagraphFormat.Alignment = _
    Word.WdParagraphAlignment.wdAlignParagraphLeft
    
    ' Add the table.
    doc.Tables.Add( _
    Range:=range, _
    NumRows:=1, NumColumns:=1)
    
    Dim tbl2 As Word.Table = doc.Tables(2)
    tbl2.Range.Font.Size = 8
    tbl2.Range.Font.Name = "Times New Roman"
    tbl2.Style = "Table Grid 8"
    tbl2.ApplyStyleFirstColumn = False
    tbl2.ApplyStyleLastColumn = False
    tbl2.ApplyStyleLastRow = False
    
    ' Insert header text and format the columns.
    'tbl.Cell(1, 1).Range.Text = "Name"
    
    Dim rngCell2 As Word.Range
    rngCell2 = tbl2.Cell(1, 1).Range
    tbl2.Cell(1, 1).Range.Text = "Step #"
    tbl2.Cell(1, 1).Range.Font.Size = 14
    tbl2.Cell(1, 1).Range.Font.Bold = vbYes
    tbl2.Cell(1, 1).Range.Font.ColorIndex = Word.WdColorIndex.wdBlack
    rngCell2.ParagraphFormat.Alignment = _
    Word.WdParagraphAlignment.wdAlignParagraphCenter
    
    

    For the "Dim tbl2 As Word.Table = doc.Tables(2)" line of code, I receive the following error:

    "The requested member of the collection does not exist."

    Does anyone know what I need to change to get this code to work?

    Thanks in advance,

    Jim


    James Hutchinson

    Wednesday, January 6, 2016 5:48 AM

Answers

  • The problem is that you're defining the entire document range (once) as the range to add both tables to. Consequently, the second table replaces the first one. Furthermore, having defined the entire document range (as the range to add the first table to), you'd need to insert at least an empty paragraph after that table so that you could then add the second table to the last paragraph in the document (i.e. reset the range to point to the last paragraph); otherwise both tables would be joined immediately the second one is created.

    Cheers
    Paul Edstein
    [MS MVP - Word]

    Wednesday, January 6, 2016 12:31 PM
  • Instead of:

    Dim range2 As Word.Range = doc.Content
    range2
    = doc.Range()


    'Add the table.
    doc.Tables.Add( _
                Range:=range2, _
                NumRows:=4, NumColumns:=4)

    use:

    'Add the second table.
    doc.Tables.Add( _
                Range:=rngTbl, _
                NumRows:=4, NumColumns:=4)

    Frankly, I don't see why you even bother defining the variables for ranges; the code I posted shows that's quite unnecessary.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    • Marked as answer by jhutch03 Wednesday, January 20, 2016 3:15 PM
    Tuesday, January 19, 2016 9:04 PM
  • This worked for me.  Thank you very much, Paul!

    James Hutchinson

    • Marked as answer by jhutch03 Wednesday, January 20, 2016 3:15 PM
    Wednesday, January 20, 2016 3:15 PM

All replies

  • The problem is that you're defining the entire document range (once) as the range to add both tables to. Consequently, the second table replaces the first one. Furthermore, having defined the entire document range (as the range to add the first table to), you'd need to insert at least an empty paragraph after that table so that you could then add the second table to the last paragraph in the document (i.e. reset the range to point to the last paragraph); otherwise both tables would be joined immediately the second one is created.

    Cheers
    Paul Edstein
    [MS MVP - Word]

    Wednesday, January 6, 2016 12:31 PM
  • Paul,

    Could you please provide me a simple example of how to use the range function for two tables? 

    Thanks,

    Jim


    James Hutchinson

    Wednesday, January 6, 2016 3:18 PM
  • I don't really know VSTO but in VBA you might approach the task along the lines of:

    Sub Demo()
    Dim wordApp As New Word.Application
    wordApp.Visible = True
    Dim wdDoc As Word.Document
    Set wdDoc = wordApp.Documents.Add()
    With wdDoc
      .PageSetup.Orientation = Word.WdOrientation.wdOrientLandscape
      .Tables.Add Range:=.Range, NumRows:=3, NumColumns:=1
      With .Tables(1)
        'Apply common formatting for both tables here
        .Range.Font.Name = "Times New Roman"
        .Style = "Table Grid 8"
        .ApplyStyleFirstColumn = False
        .ApplyStyleLastColumn = False
        .ApplyStyleLastRow = False
        'Split the table here
        .Split BeforeRow:=3
        'Apply unique formatting Table 1 here
        With .Range.Cells(1).Range
          .Text = "1.  Account Creation"
          .Font.Size = 18
          .Font.Bold = True
          .Font.ColorIndex = Word.WdColorIndex.wdBlack
          .ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter
        End With
        With .Range.Cells(2).Range
          .Text = "Overall Result:    Pass:_____   Fail:_____     Test Date:_____________      SCA Rep:____________________________"
          .Font.Size = 12
          .Font.Bold = True
          .Font.ColorIndex = Word.WdColorIndex.wdGray25
          .ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft
        End With
      End With
      With .Tables(2)
        'Apply unique formatting Table 2 here
        With .Range.Cells(1).Range
          .Text = "Step #"
          .Font.Size = 14
          .Font.Bold = True
          .Font.ColorIndex = Word.WdColorIndex.wdBlack
          .ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter
        End With
      End With
    End With
    End Sub

    Note how I start off by creating a single table with all the rows required for both tables. I'd then apply whatever formatting is common to both before splitting the table then applying whatever formatting is unique to each.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Wednesday, January 6, 2016 9:58 PM
  • Paul,

    I greatly appreciate your help, but I don't know if this is going to be a viable solution for me.  I'm going to have numerous tables in my document, with different formatting applied to many of the tables.  For example, in some of the tables, I need a "header" row that automatically appears at the top of each new page in the Word document.  If I'm using one giant table and then splitting it up, then I don't know if I will be able to apply different formatting to each "subtable".

    I think I might just need to know how to properly use the range function.   I think I just need to know how to properly start and stop the document range so that I can add multiple tables to the document.  It shouldn't be that difficult to add two or more tables to a Word doc.

    Thanks,

    Jim


    James Hutchinson

    Thursday, January 7, 2016 4:03 PM
  • In that case, try something along the lines of:

    Sub Demo()
    Dim wordApp As New Word.Application
    wordApp.Visible = True
    Dim wdDoc As Word.Document
    Set wdDoc = wordApp.Documents.Add()
    With wdDoc
      .PageSetup.Orientation = Word.WdOrientation.wdOrientLandscape
      .Tables.Add Range:=.Range.Characters.Last, NumRows:=2, NumColumns:=1
      With .Tables(1)
        .Range.Font.Name = "Times New Roman"
        .Style = "Table Grid 8"
        .ApplyStyleFirstColumn = False
        .ApplyStyleLastColumn = False
        .ApplyStyleLastRow = False
        With .Range.Cells(1).Range
          .Text = "1.  Account Creation"
          .Font.Size = 18
          .Font.Bold = True
          .Font.ColorIndex = Word.WdColorIndex.wdBlack
          .ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter
        End With
        With .Range.Cells(2).Range
          .Text = "Overall Result:    Pass:_____   Fail:_____     Test Date:_____________      SCA Rep:____________________________"
          .Font.Size = 12
          .Font.Bold = True
          .Font.ColorIndex = Word.WdColorIndex.wdGray25
          .ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft
        End With
      End With
      .Range.Characters.Last.InsertParagraphAfter
      .Tables.Add Range:=.Range.Characters.Last, NumRows:=1, NumColumns:=1
      With .Tables(2)
        .Range.Font.Name = "Times New Roman"
        .Style = "Table Grid 8"
        .ApplyStyleFirstColumn = False
        .ApplyStyleLastColumn = False
        .ApplyStyleLastRow = False
        With .Range.Cells(1).Range
          .Text = "Step #"
          .Font.Size = 14
          .Font.Bold = True
          .Font.ColorIndex = Word.WdColorIndex.wdBlack
          .ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter
        End With
      End With
    End With
    End Sub

    Do note that you could save a lot of programming effort and future maintenance overheads by using a template that contains the required document structure.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Thursday, January 7, 2016 11:08 PM
  • Hi James

    The trick is to always "collapse" the range to its end-point. Think of it like pressing the right-arrow key if you have a selection to get a blinking insertion point.

    Dim doc as Word.Document =  wordApp.Documents.Add()
    Dim rngDoc as Word.Range = doc.Content
    Dim tbl as Word.Table = doc.Tables.Add(rngDoc, 'stuff here)
    'Do things to the table
    Dim rngTbl as Word.Range = tbl.Range
    'Put focus after the table
    rngTbl.Collapse(Word.WdCollapseDirection.wdCollapseEnd)
    rngTbl.Text = "Text between the tables..."
    rngTbl.Collapse(Word.WdCollapseDirection.wdCollapseEnd)
    tbl = doc.Table.Add(rngTbl, 'stuff here)
    'and repeat
    


    Cindy Meister, Office Developer/Word MVP, <a href="http://blogs.msmvps.com/wordmeister"> my blog</a>

    Friday, January 8, 2016 5:00 PM
    Moderator
  • The trick is to always "collapse" the range to its end-point.

    With multiple table creation, though, it often requires more than collapsing the range to its end, since merely doing so in an otherwise empty document merely results in the second table being appended to the first. Even your example adds some text between them to overcome that.

    Cheers
    Paul Edstein
    [MS MVP - Word]

    Saturday, January 9, 2016 5:20 AM
  • Cindy,

    I'm trying to implement your suggestion, but I keep running into problems.  Here is the part of my code where I attempt to transition from the first table to the second table:

    'This is the end of the first table, no problems here
    
    'tbl.Rows.Add()
    tbl.Cell(7, 1)
    tbl.Rows(7).Cells(1).SetHeight(10.0, Microsoft.Office.Interop.Word.WdRowHeightRule.wdRowHeightAtLeast)
            
    
    'This is my code to transition to the next table.
    
    range.SetRange(tbl.Range.Start, tbl.Range.End)
    
    Dim rngTbl As Word.Range = tbl.Range
    rngTbl.Collapse(Word.WdCollapseDirection.wdCollapseEnd)
    rngTbl.Text = "Text between the tables..."
    rngTbl.Collapse(Word.WdCollapseDirection.wdCollapseEnd)
    
    
    'Here is where I try to create the second table
    
    Dim range2 As Word.Range = doc.Content
    range2 = doc.Range()
    
    
    'Add the table.
     doc.Tables.Add( _
                Range:=range2, _
                NumRows:=4, NumColumns:=4)
    
    Dim tbl2 As Word.Table = doc.Tables(2)
    tbl2.Range.Font.Size = 8
    tbl2.Range.Font.Name = "Times New Roman"
    tbl2.Style = "Table Grid 8"
    tbl2.ApplyStyleFirstColumn = False
    tbl2.ApplyStyleLastColumn = False
    tbl2.ApplyStyleLastRow = False
    
    tbl2.Rows.Add()
    Dim rngCell2 As Word.Range
    rngCell2 = tbl2.Cell(1, 1).Range
    tbl2.Cell(1, 1).Range.Text = "Step #"
    tbl2.Cell(1, 1).Range.Font.Size = 14
    tbl2.Cell(1, 1).Range.Font.Bold = vbYes
    tbl2.Cell(1, 1).Range.Font.ColorIndex = Word.WdColorIndex.wdBlack
    rngCell2.ParagraphFormat.Alignment = _
    Word.WdParagraphAlignment.wdAlignParagraphCenter
    
    
    
    

    I keep getting an error regarding this line of code:

    Dib tbl2 As Word.Table = doc.Tables(2)

    The error message is "COMException was unhandled.   The requested member of the collection does not exist"

    So this is where I'm currently at.  Please advise me on where I'm going wrong.

    Thanks in advance,

    Jim


    James Hutchinson

    Monday, January 18, 2016 10:11 PM
  • Hi Jim,

    Based on your code, you still use the whole range of document (doc.Tables.Add(Range:=range2….), the range2 is the range of document, please use rngTbl instead (doc.Tables.Add(Range:=rngTbl….).

    Regards

    Starain


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, January 19, 2016 1:34 AM
    Moderator
  • Starain,

    Could you please provide me the whole line of code for your rngTbl example?  I don't know what to put after "rngTbl...". 

    Thanks,

    Jim 


    James Hutchinson

    Tuesday, January 19, 2016 3:17 PM
  • Instead of:

    Dim range2 As Word.Range = doc.Content
    range2
    = doc.Range()


    'Add the table.
    doc.Tables.Add( _
                Range:=range2, _
                NumRows:=4, NumColumns:=4)

    use:

    'Add the second table.
    doc.Tables.Add( _
                Range:=rngTbl, _
                NumRows:=4, NumColumns:=4)

    Frankly, I don't see why you even bother defining the variables for ranges; the code I posted shows that's quite unnecessary.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    • Marked as answer by jhutch03 Wednesday, January 20, 2016 3:15 PM
    Tuesday, January 19, 2016 9:04 PM
  • This worked for me.  Thank you very much, Paul!

    James Hutchinson

    • Marked as answer by jhutch03 Wednesday, January 20, 2016 3:15 PM
    Wednesday, January 20, 2016 3:15 PM