简体   繁体   中英

VBA Code - Copying cells from one sheet to another sheet in excel depending on matching condition

I have two sheets Sheet1 and Sheet2 in excel .Sheet 1 has Columns C1,C2,C3,C4,C5.Sheet 2 has Columns C1,C2,C3.Now I have to perform 3 operations.

1.) Delete all rows in Sheet1 where values of Column 1 is not found in Column 1 of Sheet2.

2.) Replace values of C2,C3 of Sheet 2 into C2,C3 of Sheet 1 (C4,C5 remains the same) where value of C1 of Sheet 1 matches C1 of Sheet2.

3.) Append C1,C2,C3 data of Sheet 2 into Sheet 1 where values of C1 in Sheet 2 is not found in C1 of Sheet1(C4,C5 will be blank).

I am able to write the VB code for operation 1.Please help me with operation 2 and operation 3.

Sub delete_selected_rows()

Dim rng1 As Range, rng2 As Range, rngToDel As Range, c As Range
Dim lastRow As Long

With Worksheets("Sheet1")
    lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
    Set rng1 = .Range("A2:A" & lastRow)
End With

Set rng2 = Worksheets("Sheet2").Range("A:A")

For Each c In rng1
    If IsError(Application.Match(c.Value, rng2, 0)) Then
        'delete incidents which are not in process
        If rngToDel Is Nothing Then
            Set rngToDel = c
        Else
            Set rngToDel = Union(rngToDel, c)
        End If
    End If
Next c

If Not rngToDel Is Nothing Then rngToDel.EntireRow.Delete

End Sub

First, let my make two comments regarding your solution for step 1.

  1. You could delete the rows on the spot if you stepped through the rows from the bottom to the top. (The row indexes only change for rows below the deleted one.)
  2. IMO, it would be better to use rng2.Find instead of Applications.Match . This method of the range object returns the cell where a match is found and Nothing in case there is no match.

Now to step 2:

Using the notation as in your solution to step 1, you can get the row of the match in sheet2 using rng2.Find(c.Value).EntireRow . Then you can use its Cells property to get the second and third column.

Step 3:

You already know from step 1 how to find out that a row does not have a match in the other sheet. You just have to copy the values from the first three columns into the row after the last row of sheet1 for each row without a match in sheet1. (Best save the last row and then increment with each copied row.)

Above, I gave a simple solution to each step. However, if you have very large tables, this might be a bit slow. Basically, with this solution you are cycling through the rows three times, at each row, querying the worksheet for a value and searching all rows in the other table for a match.

An approach with better performance would be to load the entire ranges into two dimensional arrays using the Value property of the ranges, or better Value2 . Then you can do something like a merge join to solve your three problems, ie you could sort both arrays by the first column using your favorite n*log(n) sorting algorithm and then step through both list in ascending order. While stepping through, you can save which rows to delete, update the appropriate rows, and append the additional rows. To enable this, you should keep track of the original rows while sorting the arrays. Finally, you would go through the rows marked for deletion from bottom to top and delete them. (You cannot delete right away since this messes up the row indexes for the rows below the deleted one.)

Yet another approach to implement your three steps, which combines ease of use and performance, is to write SQL queries against your sheets via ADODB.

Your first step would look something like this.

DELETE [sheet1$] WHERE [sheet1$].'header of first column' NOT IN (SELECT [sheet2$].'header of first column') 

Step 2 would be an update statement and step 3 an insert into statement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM