Moving/transferring data between tables with matching column names, not by column order - vba

wbstadeli

Board Regular
Joined
Mar 11, 2016
Messages
153
Office Version
  1. 365
Platform
  1. Windows
Hi,

I'm making a workbook that I'm using as a job list for the company. As jobs are completed, I want the job (for each job, all the data is in contained in a single table row) to move to a separate table, in a separate worksheet within the same workbook. What I want to make sure of is this: that for each column of data in the table row getting moved/transferred from table #1 to the table #2, goes into the same (matching) column name as table #1. If no match is found, popup a msgbox, and don't do any transferring (exit sub). This would allow the two tables to have different column orders and still ensure the data transferred corresponds to the correct column name. Once the data is moved/transferred to the second table, the row in table 1 gets deleted/cleared. The data transfer is triggered by a worksheet event, if a cell in a column in table 1 called "Row Action" is "Move to completed" then... See below info. Thank you for any time looking at this for me! :)

Workbook= Priority List
Worksheet1=Job list
Table1=Job_List_Table
Worksheet2=Completed Job List
Table2=Completed_Job_List_Table

Here is code that is almost working, but I can't figure out how to get this line working, it says it is out of range.
.Columns(T2.ListColumns(strCurrentColName).Index).Value = c.Value
It is not recognizing the strCurrentColName as a valid variable? When i hover over it i see what is wrong, it needs to read the strCurrentColName with quotations, but it is not.
It is reading it as .Columns(T2.ListColumns(strCurrentColName).Index).Value and it needs to be .Columns(T2.ListColumns("strCurrentColName").Index).Value correct?

I'm open to better ways of doing this also, this is just what i came up with so far. Another note, with my current code the code to exit sub if no matching column is found prior to any data transfer isn't coded properly, but that is a sample of how i would want the code to function.

Rich (BB code):
Private Sub Worksheet_Change(ByVal Target As Range)

If Not Intersect(Target, ActiveSheet.ListObjects("Job_List_Table").ListColumns("Row Action").Range) Is Nothing Then
    Dim ws1 As Worksheet
    Dim ws2 As Worksheet
    Dim T1 As ListObject
    Dim T2 As ListObject
    Dim tblRow1 As Range
    Dim tblRow2 As Range
    Dim strCurrentColName As String
    
    Set ws1 = ThisWorkbook.Sheets("Job List")
    Set ws2 = ThisWorkbook.Sheets("Completed Job List")
    Set T1 = ws1.ListObjects("Job_List_Table")
    Set T2 = ws2.ListObjects("Completed_Job_List_Table")
    
        If Target.Value = "Move to completed" Then
            'If (no matching column found in Table 2,msgbox and exit the macro prior to any data transfer) Then
            '    MsgBox "There is not a matching column for " & strCurrentColName & ", this row will not be moved."
            '    Exit Sub
            'End If
            Set tblRow1 = Intersect(Target.EntireRow, ws1.ListObjects("Job_List_Table").Range)
            Set tblRow2 = T2.ListRows.Add.Range
                With tblRow2
                    For Each c In tblRow1
                        strCurrentColName = Cells(c.ListObject.Range.Row, c.Column).Value
                        .Columns(T2.ListColumns(strCurrentColName).Index).Value = c.Value 'NOT WORKING
                    Next c
                End With
        End If
End If
 

Excel Facts

Shade all formula cells
To shade all formula cells: Home, Find & Select, Formulas to select all formulas. Then apply a light fill color.
hello, this was kind of tough... but you say you're open to other ideas, so maybe you want to give this a try... trying to have an event driven macro was pulling hair for me, because you're asking to do two things. 1, to find the word. 2, to find the header after finding the word. so, i was not able to make the event driven macro work. however, with this macro below, you will need to Manually run the macro every time. The macro to run is "macro1_____find_copy_paste". when you run it, it looks a bit clunky, but i think it works. Hopes this helps. Cheers!


VBA Code:
''assume you have two sheets, Sheet1 and Sheet2.
''Sheet1 contain your raw data, Sheet2 is where you're pasting your data into.
'''assume columns A and B are blank in both sheets and can be used to hold temporary data.
'''assume your data starts in column C or anywhere to the right of C in both sheets
'''assume your headers are always in row1 in both sheets
'' assumes the word "Move to completed" is in the column you want to move.
''for example, the word is in cell G24, therefore, move the entire column G


Sub macro1_____find_copy_paste()
    Application.DisplayAlerts = False
    Application.Run "Macro12a____find_word"
    Application.Run "Macro13a___paste_over"
'clear A and B again
    Sheets("Sheet1").Select
    Application.Goto Reference:="R1C1"
    ActiveCell.Columns("A:B").EntireColumn.Select
    Selection.Clear
    Sheets("Sheet2").Select
    Application.Goto Reference:="R1C1"
    ActiveCell.Columns("A:B").EntireColumn.Select
    Selection.Clear
    Sheets("Sheet1").Select
    Application.Goto Reference:="R1C1"
    
    MsgBox "done"

End Sub

Sub Macro12a____find_word()
    On Error GoTo Err_Handler
For i = 1 To 1

'clear A and B first
    Sheets("Sheet1").Select
    Application.Goto Reference:="R1C1"
    ActiveCell.Columns("A:B").EntireColumn.Select
    Selection.Clear
    Sheets("Sheet2").Select
    Application.Goto Reference:="R1C1"
    ActiveCell.Columns("A:B").EntireColumn.Select
    Selection.Clear
    Sheets("Sheet1").Select
    Application.Goto Reference:="R1C1"

'''find in sheet1
    Sheets("Sheet1").Select
    Application.Goto Reference:="R1C1"
    
    
    Cells.Find(What:="Move to completed", After:=ActiveCell, LookIn:=xlFormulas2, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Activate
    Sheets("Sheet1").Select
    Selection.Copy
    Selection.End(xlUp).Select
    Selection.End(xlUp).Select
''copy entire column to column A in sheet 2
    ActiveCell.Columns("A:A").EntireColumn.Select
    Selection.Copy
    Selection.Copy
    
    
    Sheets("Sheet1").Select
    Selection.Copy
    Selection.End(xlUp).Select
    Selection.End(xlUp).Select
''copy entire column to column A in sheet 2
    ActiveCell.Columns("A:A").EntireColumn.Select
    Selection.Copy
    
Next
'''If no error, exit sub
Exit Sub
'''if error, use err_handler
Err_Handler:
    Application.Calculation = xlAutomatic
    MsgBox " the word  Move to completed  is not found in this sheet.  Err_Handler"
End Sub



Sub Macro13a___paste_over()
    On Error GoTo Err_Handler
For i = 1 To 1
    Sheets("Sheet1").Select
    Selection.Copy
''paste into A1 in sheet2
    Sheets("Sheet2").Select
    Application.Goto Reference:="R1C1"
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
''''add in value in B1, so it does not find blank
    Sheets("Sheet2").Select
    Application.Goto Reference:="R1C2"
    Selection.Clear
    Selection.FormulaR1C1 = "=IF(RC[-1]="""",""Error_nothing_to_find"",RC[-1])"
'copy b1 back to a1 and clear b1
    Application.Goto Reference:="R1C2"
    Application.CutCopyMode = False
    Selection.Copy
    Application.Goto Reference:="R1C1"
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    Application.Goto Reference:="R1C2"
    Application.CutCopyMode = False
    Selection.Clear
    Application.Goto Reference:="R1C1"

'find based on value in cell A1.  Assumes all your headers are in row1, in both sheets
    Sheets("Sheet2").Select
    Application.Goto Reference:="R1C1"
    ActiveCell.Columns("A:A").EntireColumn.Select
    Selection.Copy
    ActiveCell.Offset(0, 1).Range("A1:AV1").Select
    ActiveCell.Range("A1:XFB1").Select
'' Record Macro written like this
'   Selection.Find(What:="june 4 1989 - 8", After:=ActiveCell, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True, SearchFormat:=False).Activate
'''Change it to reference cell A1
   Selection.Find(What:=Range("a1"), After:=ActiveCell, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True, SearchFormat:=False).Activate
   Sheets("Sheet2").Select
    ActiveCell.Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    Selection.Copy
    Application.Goto Reference:="R1C1"
    ActiveSheet.Paste
    
'''clear column A in Sheet2
    Selection.Clear
    Selection.Copy
    
'''clear the column where you copied it in Sheet1
    Sheets("Sheet1").Select
    ActiveSheet.Paste
    Application.Goto Reference:="R1C2"
Next
'''If no error, exit sub
Exit Sub
'''if error, use err_handler
Err_Handler:
    MsgBox " the header   " & Range("a1") & "  is not found in this sheet.  Err_Handler"
End Sub
 
Upvote 0
Your code worked fine for me. I assume you have the code in the code module of the sheet "Job List"
I took a slightly different approach to checking for a column that didn't exist, letting it error out and then rolling back the newly added row by deleting it.
I also added some checking in case multiple cells were copied in.
PS: Test on a copy of your workbook, I added the line to delete the row that is being moved.

VBA Code:
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim cellTargetAction As Range
    ' If target consists of multiple rows exit
    If Target.Rows.Count > 1 Then Exit Sub
    ' In case target consists of multiple cells in the same row identify the Action column
    Set cellTargetAction = Intersect(Target, ActiveSheet.ListObjects("Job_List_Table").ListColumns("Row Action").Range)

    If Not cellTargetAction Is Nothing Then
        Dim ws1 As Worksheet
        Dim ws2 As Worksheet
        Dim T1 As ListObject
        Dim T2 As ListObject
        Dim tblRow1 As Range
        Dim tblRow2 As Range
        Dim strCurrentColName As String
       
        Dim c As Range
       
        Set ws1 = ThisWorkbook.Sheets("Job List")
        Set ws2 = ThisWorkbook.Sheets("Completed Job List")
        Set T1 = ws1.ListObjects("Job_List_Table")
        Set T2 = ws2.ListObjects("Completed_Job_List_Table")
       
        If cellTargetAction.Value = "Move to completed" Then
            'If (no matching column found in Table 2,msgbox and exit the macro prior to any data transfer) Then
            '    MsgBox "There is not a matching column for " & strCurrentColName & ", this row will not be moved."
            '    Exit Sub
            'End If
            Set tblRow1 = Intersect(Target.EntireRow, ws1.ListObjects("Job_List_Table").Range)
            Set tblRow2 = T2.ListRows.Add.Range
                With tblRow2
                    For Each c In tblRow1
                        strCurrentColName = Cells(c.ListObject.Range.Row, c.Column).Value
                        On Error Resume Next
                        .Columns(T2.ListColumns(strCurrentColName).Index).Value = c.Value
                        If Err <> 0 Then
                            MsgBox "There is not a matching column for " & strCurrentColName & ", this row will not be moved."
                            tblRow2.Delete              ' Reverse adding the row and what has already been copied
                            Exit Sub
                        End If
                        On Error GoTo 0
                    Next c
                End With
                Application.EnableEvents = False
                tblRow1.Delete                          ' Deletes row that has been moved
                Application.EnableEvents = True
        End If
    End If

End Sub
 
Upvote 0
Solution
hello, this was kind of tough... but you say you're open to other ideas, so maybe you want to give this a try... trying to have an event driven macro was pulling hair for me, because you're asking to do two things. 1, to find the word. 2, to find the header after finding the word. so, i was not able to make the event driven macro work. however, with this macro below, you will need to Manually run the macro every time. The macro to run is "macro1_____find_copy_paste". when you run it, it looks a bit clunky, but i think it works. Hopes this helps. Cheers!


VBA Code:
''assume you have two sheets, Sheet1 and Sheet2.
''Sheet1 contain your raw data, Sheet2 is where you're pasting your data into.
'''assume columns A and B are blank in both sheets and can be used to hold temporary data.
'''assume your data starts in column C or anywhere to the right of C in both sheets
'''assume your headers are always in row1 in both sheets
'' assumes the word "Move to completed" is in the column you want to move.
''for example, the word is in cell G24, therefore, move the entire column G


Sub macro1_____find_copy_paste()
    Application.DisplayAlerts = False
    Application.Run "Macro12a____find_word"
    Application.Run "Macro13a___paste_over"
'clear A and B again
    Sheets("Sheet1").Select
    Application.Goto Reference:="R1C1"
    ActiveCell.Columns("A:B").EntireColumn.Select
    Selection.Clear
    Sheets("Sheet2").Select
    Application.Goto Reference:="R1C1"
    ActiveCell.Columns("A:B").EntireColumn.Select
    Selection.Clear
    Sheets("Sheet1").Select
    Application.Goto Reference:="R1C1"
   
    MsgBox "done"

End Sub

Sub Macro12a____find_word()
    On Error GoTo Err_Handler
For i = 1 To 1

'clear A and B first
    Sheets("Sheet1").Select
    Application.Goto Reference:="R1C1"
    ActiveCell.Columns("A:B").EntireColumn.Select
    Selection.Clear
    Sheets("Sheet2").Select
    Application.Goto Reference:="R1C1"
    ActiveCell.Columns("A:B").EntireColumn.Select
    Selection.Clear
    Sheets("Sheet1").Select
    Application.Goto Reference:="R1C1"

'''find in sheet1
    Sheets("Sheet1").Select
    Application.Goto Reference:="R1C1"
   
   
    Cells.Find(What:="Move to completed", After:=ActiveCell, LookIn:=xlFormulas2, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Activate
    Sheets("Sheet1").Select
    Selection.Copy
    Selection.End(xlUp).Select
    Selection.End(xlUp).Select
''copy entire column to column A in sheet 2
    ActiveCell.Columns("A:A").EntireColumn.Select
    Selection.Copy
    Selection.Copy
   
   
    Sheets("Sheet1").Select
    Selection.Copy
    Selection.End(xlUp).Select
    Selection.End(xlUp).Select
''copy entire column to column A in sheet 2
    ActiveCell.Columns("A:A").EntireColumn.Select
    Selection.Copy
   
Next
'''If no error, exit sub
Exit Sub
'''if error, use err_handler
Err_Handler:
    Application.Calculation = xlAutomatic
    MsgBox " the word  Move to completed  is not found in this sheet.  Err_Handler"
End Sub



Sub Macro13a___paste_over()
    On Error GoTo Err_Handler
For i = 1 To 1
    Sheets("Sheet1").Select
    Selection.Copy
''paste into A1 in sheet2
    Sheets("Sheet2").Select
    Application.Goto Reference:="R1C1"
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
''''add in value in B1, so it does not find blank
    Sheets("Sheet2").Select
    Application.Goto Reference:="R1C2"
    Selection.Clear
    Selection.FormulaR1C1 = "=IF(RC[-1]="""",""Error_nothing_to_find"",RC[-1])"
'copy b1 back to a1 and clear b1
    Application.Goto Reference:="R1C2"
    Application.CutCopyMode = False
    Selection.Copy
    Application.Goto Reference:="R1C1"
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    Application.Goto Reference:="R1C2"
    Application.CutCopyMode = False
    Selection.Clear
    Application.Goto Reference:="R1C1"

'find based on value in cell A1.  Assumes all your headers are in row1, in both sheets
    Sheets("Sheet2").Select
    Application.Goto Reference:="R1C1"
    ActiveCell.Columns("A:A").EntireColumn.Select
    Selection.Copy
    ActiveCell.Offset(0, 1).Range("A1:AV1").Select
    ActiveCell.Range("A1:XFB1").Select
'' Record Macro written like this
'   Selection.Find(What:="june 4 1989 - 8", After:=ActiveCell, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True, SearchFormat:=False).Activate
'''Change it to reference cell A1
   Selection.Find(What:=Range("a1"), After:=ActiveCell, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True, SearchFormat:=False).Activate
   Sheets("Sheet2").Select
    ActiveCell.Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    Selection.Copy
    Application.Goto Reference:="R1C1"
    ActiveSheet.Paste
   
'''clear column A in Sheet2
    Selection.Clear
    Selection.Copy
   
'''clear the column where you copied it in Sheet1
    Sheets("Sheet1").Select
    ActiveSheet.Paste
    Application.Goto Reference:="R1C2"
Next
'''If no error, exit sub
Exit Sub
'''if error, use err_handler
Err_Handler:
    MsgBox " the header   " & Range("a1") & "  is not found in this sheet.  Err_Handler"
End Sub
Interesting! Unfortunately I would not want to run manual macros for my application. Thank you for looking at this!
 
Upvote 0
Your code worked fine for me. I assume you have the code in the code module of the sheet "Job List"
I took a slightly different approach to checking for a column that didn't exist, letting it error out and then rolling back the newly added row by deleting it.
I also added some checking in case multiple cells were copied in.
PS: Test on a copy of your workbook, I added the line to delete the row that is being moved.

VBA Code:
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim cellTargetAction As Range
    ' If target consists of multiple rows exit
    If Target.Rows.Count > 1 Then Exit Sub
    ' In case target consists of multiple cells in the same row identify the Action column
    Set cellTargetAction = Intersect(Target, ActiveSheet.ListObjects("Job_List_Table").ListColumns("Row Action").Range)

    If Not cellTargetAction Is Nothing Then
        Dim ws1 As Worksheet
        Dim ws2 As Worksheet
        Dim T1 As ListObject
        Dim T2 As ListObject
        Dim tblRow1 As Range
        Dim tblRow2 As Range
        Dim strCurrentColName As String
      
        Dim c As Range
      
        Set ws1 = ThisWorkbook.Sheets("Job List")
        Set ws2 = ThisWorkbook.Sheets("Completed Job List")
        Set T1 = ws1.ListObjects("Job_List_Table")
        Set T2 = ws2.ListObjects("Completed_Job_List_Table")
      
        If cellTargetAction.Value = "Move to completed" Then
            'If (no matching column found in Table 2,msgbox and exit the macro prior to any data transfer) Then
            '    MsgBox "There is not a matching column for " & strCurrentColName & ", this row will not be moved."
            '    Exit Sub
            'End If
            Set tblRow1 = Intersect(Target.EntireRow, ws1.ListObjects("Job_List_Table").Range)
            Set tblRow2 = T2.ListRows.Add.Range
                With tblRow2
                    For Each c In tblRow1
                        strCurrentColName = Cells(c.ListObject.Range.Row, c.Column).Value
                        On Error Resume Next
                        .Columns(T2.ListColumns(strCurrentColName).Index).Value = c.Value
                        If Err <> 0 Then
                            MsgBox "There is not a matching column for " & strCurrentColName & ", this row will not be moved."
                            tblRow2.Delete              ' Reverse adding the row and what has already been copied
                            Exit Sub
                        End If
                        On Error GoTo 0
                    Next c
                End With
                Application.EnableEvents = False
                tblRow1.Delete                          ' Deletes row that has been moved
                Application.EnableEvents = True
        End If
    End If

End Sub
Nice! Thank you :)
 
Upvote 0

Forum statistics

Threads
1,215,069
Messages
6,122,952
Members
449,095
Latest member
nmaske

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top