excelvba

copy table from one workbook to another using vba


I have a table in wb1, I want to be able to copy this table then paste it to another sheet in wb2 but I want to make it more dynamic so that instead of just selecting the table, my code goes through the column names then copies each column using the name then paste it in the other worksheet. Here is my code

'get column names from table "Table1"
Dim TblHeadings() As String
Dim z As Variant
Dim i As Integer
i = -1
For Each z In Rows(2).Cells
    If z.Value = "" Then Exit For
    i = i + 1
    ReDim Preserve TblHeadings(i) As String
    TblHeadings(i) = z.Value
Next z

'copy columns with headers from previous loop
Dim a As Range, w
With wb1.Sheets("Sheet1").ListObjects("Table1")
    For Each a In z
        If w Is Nothing Then
            Set w = .ListColumns(a).Range
        Else
            Set w = Union(w, .ListColumns(a).Range)
        End If
    Next
End With

w.Select
Selection.Copy

Table1 starts on B2. How do I modify Rows(2).Cells to start on B2? Currently it starts on B1 which is empty so my loop exits? Does the rest of this code look okay?

Edit: to answer why I am doing it this way is because in another part of the code I am clearing content from wb2 table2. If I do it this way; copy and paste it as values over table2, the table goes away and it just paste as values. I want the table2 format to remain as a table. There may be a better way to do this?

wb2Sheet1.Activate
Range("Table2").Select
Selection.ClearContents

With wb1.Sheets("Sheet1").ListObjects("Table1")
   .Range.Copy
End with

wb2.Activate
wb2.Worksheets("Sheet1").Activate
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False

Solution

  • I would probably do something like this. The column heading array is just overhead unless you have a large number of columns to copy.

    Sub Tester()
    
        Dim wbSrc As Workbook, wbDest As Workbook, loSource As ListObject, wsDest As Worksheet
        Dim lc As ListColumn, destHeaders As Range, c As Range, loDest As ListObject
        
        'set up the source and destination listobjects
        '  (on the same sheet for my testing...)
        With ThisWorkbook.Worksheets("Sheet1")
            Set loSource = .ListObjects("Table1")
            Set loDest = .ListObjects("Table2")
        End With
        
        'clear the destination table
        loDest.DataBodyRange.Rows.Delete shift:=xlShiftUp
        
        Application.ScreenUpdating = False
        Application.Calculation = xlCalculationManual
        
        For Each c In loDest.HeaderRowRange.Cells
            Set lc = Nothing 'clear this first
            On Error Resume Next 'ignore if no matching column
            Set lc = loSource.ListColumns(c.Value)
            On Error GoTo 0      'stop ignoring error
            If Not lc Is Nothing Then  'got a match
                lc.DataBodyRange.Copy c.Offset(1)
            Else
                'flag no match
                Debug.Print "No source list column for '" & c.Value & "'"
            End If
        Next c
        
        Application.ScreenUpdating = True
        Application.Calculation = xlCalculationAutomatic
        
    End Sub
    

    EDIT: If you just want to replace a table with a copy of another table you can do something like this.

        Dim loA As ListObject, loB As ListObject, rngB As Range
        
        Set loA = ActiveSheet.ListObjects("TableA")
        Set loB = ActiveSheet.ListObjects("TableB")
        
        Set rngB = loB.Range 'remember where the table was
        loB.Delete 'delete the destination table
        
        Set rngB = rngB.Cells(1).Resize(loA.Range.Rows.Count, loA.Range.Columns.Count)
        loA.Range.Copy rngB.Cells(1)    'copy the table
        rngB.ListObject.Name = "TableB" 'rename the copy