Find multiple non-matching cells and copy to new worksheet - excel

I would like to compare cells in Worksheet 2 against Worksheet 1.
First check for matching cells in range A for both Worksheets 1 and 2.
Next, if there are no matches, check for matching cells in range B for both Worksheets 1 and 2, otherwise if there are matches, check the next cell in range A.
If there are no matches as well, copy these non-matching cells in ranges A and B in Worksheet 2 to a new worksheet, Worksheet 3.
Here are my worksheets' layout:
Worksheet 1 -
Worksheet 2 -
Worksheet 3 -
Here is my code (which is not working as intended):
Dim Cl As Range, Rng As Range, Dic As Object
Set Dic = CreateObject("scripting.dictionary")
With Dic
For Each Cl In MyWorkSheet1Name.Range("A2:B" & MyWorkSheet1Name.Range("B" & Rows.Count).End(xlUp))
.Item(Cl.Value) = Empty
Next Cl
For Each Cl In MyWorkSheet2Name.Range("A2:B" & MyWorkSheet2Name.Range("B" & Rows.Count).End(xlUp))
If Not .Exists(Cl.Value) Then
If Rng Is Nothing Then Set Rng = Cl Else Set Rng = Union(Rng, Cl)
End If
Next Cl
End With
If Not Rng Is Nothing Then
Rng.EntireRow.Copy MyWorkSheet3Name.Range("A" & Rows.Count).End(xlUp)
End If
How do I get the code to run as intended?
Many thanks!

You could try this:
Dim lRow1 As Long, lRow2 As Long
lRow1 = Sheets(1).Range("A" & Sheets(1).Rows.Count).End(xlUp).Row
lRow2 = Sheets(2).Range("A" & Sheets(2).Rows.Count).End(xlUp).Row
Application.ScreenUpdating = False
With Sheets(3)
Sheets(1).Range("A1:B" & lRow1).Copy Destination:=.Range("A1")
Sheets(2).Range("A2:B" & lRow2).Copy Destination:=.Range("A" & lRow1 + 1)
.Range("C2").Formula = "=COUNTIFS($A$2:$A$" & lRow1 + lRow2 - 1 & ",A2,$B$2:$B$" & lRow1 + lRow2 - 1 & ",B2)"
.Range("C2").AutoFill Destination:=.Range("C2:C" & lRow1 + lRow2 - 1)
.Range("A1").AutoFilter Field:=3, Criteria1:=">1"
.Rows("2:" & lRow1 + lRow2 - 1).SpecialCells(xlCellTypeVisible).Delete
.Range("A1").AutoFilter
.Columns(3).EntireColumn.Delete
End With
Application.ScreenUpdating = True

Related

Remove rows containing keyword and indented records below it

Attached is a small sample of my data, row 7, 8, 12 and 13 are parent headings and rows 9-11 are child headings of row 8 because it is indented under it. When I run Range().IndentLevel, it returns 2 for rows 7, 8, 12, 13 and 3 for rows 9-11. These are the only two IndentLevels in the column
I am trying to remove all the rows with the keyword "Pursuit Adjustment" which I was able to do with the following:
Dim ws As Worksheet
Dim strSearch As String
Dim lRow As Long
strSearch = "Pursuit Adjustment"
Set ws = Sheets("PFSR All (formatted)")
With ws
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Remove any filters
.AutoFilterMode = False
'~~> Filter, offset(to exclude headers) and delete visible rows
With .Range("A1:A" & lRow)
.AutoFilter Field:=1, Criteria1:="=*" & strSearch & "*"
.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
'~~> Remove any filters
.AutoFilterMode = False
End With
However I am having difficulties figuring out two things:
How do I also remove all child headings of the associated parent heading in my strSearch (rows 9-11)?
In my strSearch, I have only specified "Pursuit Adjustment", how can I add multiple search conditions to it?
You could try this code:
Dim ws As Worksheet
Dim i As Long, j As Long, lRow As Long
Dim strSearch As Variant
strSearch = Array("Pursuit Adjustment", "str2", "str3") 'Put here all the strings you want to search and delete
Set ws = Sheets("PFSR All (formatted)")
With ws
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
.AutoFilterMode = False
For i = LBound(strSearch) To UBound(strSearch)
For j = 1 To lRow
If InStr(.Range("A" & j), strSearch(i)) Then
.Rows(j).EntireRow.Delete
Do While .Range("A" & j).IndentLevel > 2
.Rows(j).EntireRow.Delete
Loop
j = j - 1
End If
Next j
Next i
End With
Please, try the next code, too. It will be faster, placing the necessary ranges in a Union range and delete them at once, at the end. The actual code only selects the rows to be deleted. If it returns what you need, you can replace Select with Delete on the last code line:
Sub teleteSpecificRowsAndIndentedBelow()
Dim ws As Worksheet, strSearch As String, lRow As Long, arrA, arrSearch, El
Dim i As Long, j As Long, rngDel As Range, boolFound As Boolean
arrSearch = Split("Pursuit Adjustment,second string,third string,etc", ",") 'no space after comma!!!
Set ws = ActiveSheet ' Sheets("PFSR All (formatted)")
lRow = ws.Range("A" & ws.rows.count).End(xlUp).row
arrA = ws.Range("A1:A" & lRow).Value 'put it in an array to make iteration faster
For i = 1 To UBound(arrA)
For Each El In arrSearch
If InStr(arrA(i, 1), El) > 0 Then boolFound = True: Exit For
Next
If boolFound Then
If rngDel Is Nothing Then
Set rngDel = ws.Range("A" & i)
Else
Set rngDel = Union(rngDel, ws.Range("A" & i))
End If
'start searching for indented following rows:
For j = 1 To lRow
If ws.Range("A" & i + j).IndentLevel < 2 Then Exit For
Set rngDel = Union(rngDel, ws.Range("A" & i + j))
Next j
i = i + j - 1: boolFound = False
End If
Next i
If Not rngDel Is Nothing Then rngDel.EntireRow.Select 'if the output is correct, please replace Select with Delete
End Sub

Insert Row when 2 conditions are met

I have created below code which works like IF Col"B" any cell <> "" And Col"L" any cell = "Leop" then add row below to the active cell.
I mean I'm trying to achieve is to insert single row after certain row which contain in column B any value, and if column L in same row contains value = "Leop". Then add the row after that certain row.
But an error is appear. Compile Error: Invalid use of property on xlDown
Your help will be appreciated to fix it.
From this:
to this:
Sub firstcondition()
Dim ws As Worksheet
Dim LRow As Long
Dim rng As Range
Dim rng2 As Range
Dim i As Long
Dim p As Long
Dim dat As Variant
Dim datt As Variant
Dim IRow As Long
Set ws = Thisworkbooks.Sheets("Sheet2")
With ws
LRow = .Range("A" & .Rows.Count).End(xlUp).Row
Set rng = .Range("B2:B" & LRow)
Set rng2 = .Range("L2:L" & LRow)
dat = rng
datt = rng2
IRow = Selection.Row
For i = LBound(dat, 1) To UBound(dat, 1)
For p = LBound(datt, 1) To UBound(datt, 1)
If dat(i, 1) <> "" And datt(p, 1) = "Leop" Then
Rows(IRow + 1).Select
Selection.Insert Shift: xlDown
End If
End Sub
It will be like in formula:
IF(AND(B2<>"",L2="Leop"),"InsertRowBelow to Row 2 If condition is met","")
and will drag it down to the lastRow.
Thisworkbooks.Sheets("Sheet2") should be Thisworkbook.Sheets("Sheet2") and missing = in Selection.Insert Shift:= xlDown
Inserting or deleting rows will change the last row number so start at the bottom and work upwards.
Option Explicit
Sub firstcondition()
Dim ws As Worksheet, LRow As Long, r As Long
Dim n As Long
Set ws = ThisWorkbook.Sheets("Sheet2")
With ws
LRow = .Range("B" & .Rows.Count).End(xlUp).Row
For r = LRow To 2 Step -1
If .Cells(r, "B") <> "" And .Cells(r, "L") = "Leop" Then
.Rows(r + 1).Insert shift:=xlDown
n = n + 1
End If
Next
End With
MsgBox n & " rows inserted", vbInformation
End Sub
Try this with autofilter, you dont have to loop through each row. So it will work faster for larger data.
Option Explicit
Sub firstcondition()
Dim ws As Worksheet
Dim LRow As Long, cl As Range
Set ws = ThisWorkbook.Sheets("Sheet2")
LRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
ws.Range("L1:L" & LRow).AutoFilter 1, "Leop"
For Each cl In ws.Range("_FilterDatabase").SpecialCells(12).Cells
If ws.Range("B" & cl.Row) <> "" Then
cl.Offset(1).EntireRow.Insert Shift:=xlDown
End If
Next
ws.AutoFilterMode = False
End Sub

Need Macro to find a cell value and then copy the entire line to a new sheet

Trying to create a macro that will do a search for a cell value, then when found cut the entire row and past it to another sheet!
Help is appreciated, I've never programmed before in excel....
Sub test2()
Dim cel As Range, lRow As Long
findWhat = InputBox("Enter what you want to find?", "Find what...")
For Each cel In ThisWorkbook.Sheets("Sheet1").Range("W2:W250000" &Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row)
If cel.Value = findWhat Then
lRow = ThisWorkbook.Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
ThisWorkbook.Sheets("Sheet2").Cells(lRow + 1, 1).Value = ThisWorkbook.Sheets("Sheet2").Cells(cel.Row, 1).Resize(, 48)
End If
Next
End Sub
I am just modifying some of your existing code to do what is required, assuming that you want to search only in column W and then copy the entire row if a match is found.
Sub test2()
Dim cel As Range, lRow As Long
findWhat = InputBox("Enter what you want to find?", "Find what...")
'Following loop will only search for the values in column W and between rows 2 to 250000, change the values as required.
For Each cel In ThisWorkbook.Sheets("Sheet1").Range("W2:W250000")
If cel.Value = findWhat Then
currentRow = cel.Row
lRow = ThisWorkbook.Sheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row
Thisworkbook.Sheets("Sheet1").Rows(currentRow).EntireRow.copy
ThisWorkbook.Sheets("Sheet2").Range("A" & lRow + 1 ).Select
ThisWorkbook.Sheets("Sheet2").Paste
Thisworkbook.Sheets("Sheet1").Rows(currentRow).EntireRow.Delete
End If
Next
End Sub
UPDATE: This code will copy all the rows that matches the given value.
If you're just needing to find the input value once within the range you could use this to copy. If you're wanting to cut the line that you copy from as well then take away the ' from the delete line in the code.
This is for if you just want the first found cell:
Sub test2()
Dim lRow1 As Long, lRow2 As Long, found As Range, findwhat As String
findwhat = InputBox("Enter what you want to find?", "Find what...")
lRow1 = ThisWorkbook.Sheets("Sheet1").Range("W" & Rows.Count).End(xlUp).Row
lRow2 = ThisWorkbook.Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Row
Set found = Sheets("Sheet1").Range("W2:W" & lRow1).Find(What:=findwhat, LookIn:=xlValues, lookat:=xlWhole, searchdirection:=xlNext)
If Not found Is Nothing Then
Sheets("Sheet1").Range("W" & found.Row).EntireRow.Copy
Sheets("Sheet2").Range("A" & lRow2 + 1).PasteSpecial
'Sheets("Sheet1").Range("W" & found.Row).EntireRow.Delete
End If
Application.CutCopyMode = False
End Sub
EDIT:
If you're needing every row that is found with that value then use this one. It's just modified from yours which is pretty much the easiest way to do it:
EDIT2: Changed it so now it loops from the bottom up which resolves the issue of skipping some of them after deleting the row.
Sub test2()
Dim lRow1 As Long, lRow2 As Long, findwhat As String, cel As Range, Sh1 As Worksheet, Sh2 As Worksheet, i As Long
findwhat = InputBox("Enter what you want to find?", "Find what...")
lRow1 = ThisWorkbook.Sheets("Sheet1").Range("W" & Rows.Count).End(xlUp).Row
Set Sh1 = ThisWorkbook.Sheets("Sheet1")
Set Sh2 = ThisWorkbook.Sheets("Sheet2")
For i = lRow1 To 2 Step -1
If Sh1.Range("W" & i).Value = findwhat Then
lRow2 = Sh2.Range("A" & Rows.Count).End(xlUp).Row
Sh1.Range("W" & i).EntireRow.Copy
Sh2.Range("A" & lRow2 + 1).PasteSpecial
Sh1.Range("W" & i).EntireRow.Delete
End If
Next i
Application.CutCopyMode = False
End Sub

I want to copy specific rows if it contains certain text to another sheet using VBA

I am trying to write a macro that copies a row if a cell in that row contains text (For ex: Mumbai, Delhi etc) from Column C.
For example if there are 30 rows but only 15 contains text(Mumbai & Delhi) in column C. I want to copy those 15 rows and paste them into "Sheet2" I was using the below code. however it is copying all the filled rows. however my requirement is the code should only need to copy columns of a, b, c, d, f, g, h, i, l & m to Sheet2.
Sub testPasteinSh2()
Dim sh1 As Worksheet, sh2 As Worksheet, rng As Range, cel As Range
Dim rngCopy As Range, lastR1 As Long, lastR2 As Long
Dim strSearch1 As String, strSearch2 As String
strSearch1 = "Mumbai" 'or combo value...
strSearch2 = "Delhi" 'or something else...
Set sh1 = ActiveSheet 'use here your worksheet
Set sh2 = Worksheets("Sheet2") 'use here your sheet
lastR1 = sh1.Range("C" & Rows.count).End(xlUp).Row
lastR2 = sh2.Range("A" & Rows.count).End(xlUp).Row + 1
Set rng = sh1.Range("C2:C" & lastR1)
For Each cel In rng.cells
If cel.Value = strSearch1 Or cel.Value = strSearch2 Then
If rngCopy Is Nothing Then
Set rngCopy = sh1.Rows(cel.Row)
Else
Set rngCopy = Union(rngCopy, sh1.Rows(cel.Row))
End If
End If
Next
If Not rngCopy Is Nothing Then
rngCopy.Copy Destination:=sh2.cells(lastR2, 1)
End If
End Sub
Can you please help me. Thank you in Advance.
It looks difficult to ask a clear question...
It happens I know what you need from a previous question. Supposing that you did not change your mind, please test the next code:
Sub testPasteinSh2Bis()
Dim sh1 As Worksheet, sh2 As Worksheet, rng As Range, cel As Range
Dim rngCopy As Range, lastR1 As Long, lastR2 As Long
Dim strSearch1 As String, strSearch2 As String
'a, b, c, d, f, g, h, i, l 'columns to be copied
strSearch1 = "Mumbai" 'or combo value...
strSearch2 = "Delhi" 'or something else...
Set sh1 = ActiveSheet 'use here your worksheet
Set sh2 = sh1.Next 'use here your sheet
lastR1 = sh1.Range("C" & Rows.count).End(xlUp).Row
lastR2 = sh2.Range("A" & Rows.count).End(xlUp).Row + 1
Set rng = sh1.Range("C2:C" & lastR1)
For Each cel In rng.cells
If cel.Value = strSearch1 Or cel.Value = strSearch2 Then
If rngCopy Is Nothing Then
Set rngCopy = sh1.Range(sh1.Range("A" & cel.Row & ":D" & cel.Row).Address & "," & _
sh1.Range("F" & cel.Row & ":I" & cel.Row).Address & "," & sh1.Range("L" & cel.Row).Address)
Else
Set rngCopy = Union(rngCopy, sh1.Range(sh1.Range("A" & cel.Row & ":D" & cel.Row).Address & "," & _
sh1.Range("F" & cel.Row & ":I" & cel.Row).Address & "," & sh1.Range("L" & cel.Row).Address))
End If
End If
Next
If Not rngCopy Is Nothing Then
rngCopy.Copy Destination:=sh2.cells(lastR2, 1)
End If
End Sub
It should copy the columns a, b, c, d, f, g, h, i, l for the matching cases...
You could try this:
Sub Macro1()
Dim lastrow As Long, erow As Long
Dim rng1 As Range
Dim rng2 As Range
'choose an empty column, in my example is O.
With Worksheets("Sheet1")
lastrow = .Cells(.Rows.Count, 1).End(xlUp).Row
.Range("O2:O" & lastrow).FormulaR1C1 = "=IF(OR(RC[-12]=""Mumbai"",RC[-12]=""Delhi""),1,"""")" 'here is -12 because difference between column C and O is 3. Change it according your needs
Set rng1 = .Range("O2:O" & lastrow).SpecialCells(xlCellTypeFormulas, 1)
For Each rng2 In rng1.Cells
erow = Worksheets("Sheet2").Cells(Worksheets("Sheet2").Rows.Count, 1).End(xlUp).Row
Worksheets("Sheet2").Range("A" & erow + 1 & ":M" & erow + 1) = .Range("A" & rng2.Row & ":M" & rng2.Row).Value 'this will copy the full row of data from A to M
Next rng2
Set rng1 = Nothing
.Range("O2:O" & lastrow).Clear
End With
'delete the columns copied but you don't want like E, J,K
With Worksheets("Sheet2")
.Columns("E:E").Delete
.Columns("J:K").Delete
End With
End Sub
This code will copy the row of data and delete the columns you don't want.
In case that's not posible, then you can copy single ranges. You could replace line
Worksheets("Sheet2").Range("A" & erow + 1 & ":M" & erow + 1) = .Range("A" & rng2.Row & ":M" & rng2.Row).Value 'this will copy the full row of data from A to M
with
Worksheets("Sheet2").Range("A" & erow + 1).Value = .Range("A" & rng2.Row).Value 'a single cell
Probably you can adapt this to your needs.

How to copy a formula over to other columns

I have a Table that I created through a previous Macro.
With the help from another question, I was able to find “All Other” in Column B, and insert a formula in the adjacent column.
PrintScreen:
Now I would like to copy the formula from the Unknown Active Cell, and paste it into the adjacent Columns: D, E, G, H, I, J, and L Offset – 0 Rows.
I currently have:
Sub AllOther()
Dim ws As Worksheet
Dim aOther As Range
Dim DataLastRow As Long
Set ws = ActiveSheet
DataLastRow = ws.Cells(ws.Rows.Count, 3).End(xlUp).Row
Set aOther = ws.Range("B:B").Find("All Other", LookIn:=xlValues, lookat:=xlWhole)
If Not aOther is Nothing Then
aOther.Offset(0, 1).Formula = "=SUM(" & aOther.Offset(3, 1).Address & ":" & ws.Cells(DataLastRow,3).Address & ")"
Else
MsgBox """All Other"" not found in column."
End If
'Copy/Paste into other Columns
End Sub
Q1/ What is the "Unknown Active Cell" you are referring to?
Q2/ What do you you want to sum in the formula
=SUM(" & aOther.Offset(3, 1).Address & ":" & ws.Cells(DataLastRow,3).Address & ")" ?
The beginning of the range aOther.Offset(3, 1).Address is 3 rows below aOther and the end of the range is anywhere.
Anyway it will be easier if in the formula you do not mix an offset of aOther with an offset of ws.
3/ doing so would enable you to loop as in the following code
Sub AllOther()
Dim ws As Worksheet
Dim aOther As Long
Dim aOtherRow As Integer ' row
Dim arr As Variant
arr = Array(3, 4, 5, 7, 8, 9, 11) ' columns to sum
Set ws = ActiveSheet
Set aOther = ws.Range("B:B").Find("All Other", LookIn:=xlValues, lookat:=xlWhole).Row
If Not aOther Is Nothing Then
aOtherRow = aOther.Row
For Each i In arr
ws.Cells(aOtherRow, i).Formula = "=SUM(" & ws.Cells(FirstRow, i).Address & ":" & ws.Cells(LastRow, i) & ")"
Next i
Else
MsgBox """All Other"" not found in column."
End If
End Sub
In which FirstRow and LastRow depend of the answer to Q2
------------------- Edit after Cari Day answers ------------------------
Sub AllOther()
Dim ws As Worksheet
Dim aOther As Range
Dim aOtherRow As Long
Dim DataFirstRow As Long
Dim DataLastRow As Long
Dim col as integer
Dim ColumnsArray As Variant
ColumnsArray = Array(3, 4, 5, 7, 8, 9, 11) ' columns to sum
Set ws = ActiveSheet
Set aOther = ws.Range("B:B").Find("All Other", LookIn:=xlValues, lookat:=xlWhole)
If Not aOther Is Nothing Then
aOtherRow = aOther.Row
DataFirstRow = aOtherRow + 1
DataLastRow = ws.Cells(ws.Rows.Count, 3).End(xlUp).Row
For Each col In ColumnsArray
ws.Cells(aOtherRow, col).Formula = "=SUM(" & ws.Cells(DataFirstRow, col).Address & ":" & ws.Cells(DataLastRow, col).Address & ")"
Next col
Else
MsgBox """All Other"" not found in column."
End If
End sub

Resources