Search code examples
excelvbams-wordcopy-pasteword-table

Copy Word file table to Excel file (merged cells and multiple-line cells)


In another post I finally got to choose a table from a Word file and get it to an Excel file. I have the following code in Word VBA:

    Dim wrdTbl As Table
    Dim RowCount As Long, ColCount As Long, i As Long, j As Long

    'Excel Objects
    Dim oXLApp As Object, oXLwb As Object, oXLws As Object

    'Set your table
    Set wrdTbl = ActiveDocument.Tables(InputBox("Table # to copy? There are " & ActiveDocument.Tables.Count & " tables to choose from."))

    'If ActiveDocument.Tables.Count = 0 Then MsgBox "There are no tables in word document"
        'Exit Sub

    'Get the word table Row and Column counts
    ColCount = wrdTbl.Columns.Count
    RowCount = wrdTbl.Rows.Count

    'Create a new Excel Application
    Set oXLApp = CreateObject("Excel.Application")

    'Hide Excel
    oXLApp.Visible = False

    'Open the relevant Excel file
    Set oXLwb = oXLApp.Workbooks.Open("C:\Users\" & Environ("Username") & "\Desktop\ExcelEx.xlsx")
    'Work with Sheet1. Change as applicable
    Set oXLws = oXLwb.Sheets(1)

    'Loop through each row of the table
    For i = 1 To RowCount
        'Loop through each cell of the row
        For j = 1 To ColCount
        'This gives you the cell contents
            wrdTbl.Cell(i, j).Range.Copy

            With oXLws
                .Range("A1").Activate
                .Cells(i, j).Select
                .PasteSpecial (wdPasteText)
                .Range("A1").CurrentRegion.Style = "Normal"
            End With

        Next
    Next

    'Close and save Excel file
    oXLwb.Close savechanges:=True

    'Cleanup (VERY IMPORTANT)
    Set oXLws = Nothing
    Set oXLwb = Nothing
    oXLApp.Quit
    Set oXLApp = Nothing

    MsgBox "Done"

End Sub

My problem is that if I have a table with merged cells it throws the error: "5941" requested member of the collection does not exist on the line:

wrdTbl.Cell(i, j).Range.Copy

How can I get the code to copy merged cells too?

Another problem it is when I have a cell with multiple lines because in the Excel file it copies these cell lines in different cells in Excel. How can I solve this too? Thank you so much for your answers!


Solution

  • You need to loop through the cells individually, rather than by rows and columns. For example:

    Dim wrdTbl As Table, c As Long
    'Excel Objects
    Dim oXLApp As Object, oXLwb As Object, oXLws As Object
    
    'Set your table
    With ActiveDocument
        If ActiveDocument.Tables.Count = 0 Then MsgBox "There are no tables in word document"
            Exit Sub
        Else
            Set wrdTbl = .Tables(InputBox("Table # to copy? There are " & .Tables.Count & " tables to choose from."))
        End If
    End With
    
    'Create a new Excel Application
    Set oXLApp = CreateObject("Excel.Application")
    With oXLApp
    'Hide Excel
        .Visible = False
    
        'Open the relevant Excel file
        Set oXLwb = oXLApp.Workbooks.Open("C:\Users\" & Environ("Username") & "\Desktop\ExcelEx.xlsx")
    End With
    
    'Loop through each row of the table
    With wrdTbl.Range
        For c = 1 To .Cells.Count
            With .Cells(c)            
              'Work with Sheet1. Change as applicable
              oXLwb.Sheets(1).Cells(.RowIndex, .ColumnIndex).Value = Split(.Range.Text, vbCr)(0)
            End With
        Next
    End With
    
    'Close and save Excel file
    oXLwb.Close True
    
    'Cleanup (VERY IMPORTANT)
    oXLApp.Quit
    Set oXLwb = Nothing: Set oXLApp = Nothing
    
    MsgBox "Done"
    

    If you want to replicate the Word table in Excel, replace:

    'Loop through each row of the table
    With wrdTbl.Range
        For c = 1 To .Cells.Count
            With .Cells(c)
              'Work with Sheet1. Change as applicable
              oXLwb.Sheets(1).Cells(.RowIndex, .ColumnIndex).Value = Split(.Range.Text, vbCr)(0)
            End With
        Next
    End With
    

    with:

    wrdTbl.Range.Copy
    With oXLwb.Sheets(1)
    .Paste .Range("A1")
    End With