Compare sheets to copy differences - excel

I have this working VBA code that compares 2 sheets and copies duplicates to the 'Changes' sheet. I need to do the opposite. I need to copy differences to the changes sheet.
Sub CompareSheets()
Dim Sht1Rng As Range
Dim Sht2Rng As Range
Set Sht1Rng = Worksheets("RXCP Order").Range("A1", Worksheets("RXCP Order").Range("A1000").End(xlUp))
Set Sht2Rng = Worksheets("QS1 Order").Range("A1", Worksheets("QS1 Order").Range("A1000").End(xlUp))
For Each c In Sht1Rng
Set d = Sht2Rng.Find(c.Value, LookIn:=xlValues)
If Not d Is Nothing Then
Worksheets("Changes").Range("A1000").End(xlUp).Offset(1, 0).Value = c.Value
Worksheets("Changes").Range("A1000").End(xlUp).Offset(0, 1).Value = c.Offset(0, 1).Value
Set d = Nothing
End If
Next c
End Sub

One way to find changes from one worksheet to another is to add sheet3 with the following formula in each cell of the used range of sheet1:
=if(Sheet1!A1<>Sheet2!A1,1,0)
Then add a column to sheet3 adding across the row.
Any rows with a count greater than zero should be copied.
You can filter then copy paste manually or run your for loop down the count column in sheet three and copy the row from sheet two based on the row it is on in sheet 3
dim aCell as range
with thisworkbook
for each acell in .sheets("Sheet3").Range("Z1:Z1000")
if acell.value > 0 then
.sheets("Sheet1").range("A" & acell.row).entirerow.copy _
.sheets("Sheet4").range("A" & .sheets("Sheet4").usedrange.rows.count + 1)
end if
next acell
end with
You can write a macro to copy the formula above to all the cells in the sheet3's used range, and copy the formula down the next available column also.

Related

Move rows to another sheet based on a cell criteria not working

I am trying to write a vba code to move the entire row to another existing sheet in the next available sheet for one and multiple criteria’s. The file that I am working on is exported from an application and hence has unprintable data. I first trim and clean the range and then run the code. I have 3 problems as of now:
The below code that I used to move entire to another sheet based on the value of in column BY which should be blank, then all the lines which has AG has blank was moving from ACCF main sheet to Accounts Missing Info sheet. I had lot of pre and post action macros within the same workbook. I had to change the order of the macros and pos that the below code stopped working. I tried to debug, and there is no error as well.
2.I also have another code to move entire row from ACCF main sheet to next available column row in Accounts Missing Info sheet with 2 criteria’s. Column F to be “JNTN” and column M to be blank. This was also working fine until I reordered the macros. I have tried many other codes but nothing works.
Third problem is, I am using the same code used in point 2 to include a date. I want all rows with criteria 1 = col F to be “TRST” and criteria 2 to be col Z( which is a date) to be opened before jan 5th 2012. I don’t know how to incorporate the date.
I know the best method to use is Autofilter method to filter data and move to another sheet in the next available column. I googled and checked videos but none of them work.
Please help me. One code to use for all the above will be good. Where I can change one to two criteria as per the requirement.
Code 1
Sub missingphone()
a = worksheets(“ACCF Main”).cells(rows.count,1).End(xlup).row
For i = 2 to a
If worksheets(“ACCF Main”).cells(i,77).Value= “” then
Worksheets(“ACCF Main”).rows.copy
Worksheets(“Accounts missing info”).Activate
b = worksheets(“Accounts missing info”).cells(rows.count,1).end(xlup).row
Worksheets(“accounts missing info”).cells(b+1,1).select
ActiveSheet.paste
Worksheets(“accf main”).Activate
End if
Next
Thisworkbook.worksheets(“accf main”).cells(1,1).select
End sub
Code 2
Sub marriedjoint()
a = worksheets(“ACCF Main”).cells(rows.count,1).end(xlup).row
For i=2 to a
If worksheets(“ACCF Main”).cells(i,5).Value= “JNTN” And cells(i,13).value=“” then
Worksheets(“ACCF Main”).rows.copy
Worksheets(“Accounts missing info”).Activate
b = worksheets(“Accounts missing info”).cells(rows.count,1).end(xlup).row
Worksheets(“accounts missing info”).cells(b+1,1).select
Activesheet.paste
Worksheets(“accf main”).Activate
End if
Next
Thisworkbook.worksheets(“accf main”).cells(1,1).select
End sub
If i understand you correctly about your code-1 and code-2 :
Sub test()
Dim sh1 As Worksheet: Dim sh2 As Worksheet
Dim rg As Range: Dim cell As Range: Dim rgJNTN As Range
'set the needed sheet as variable sh1 and sh2
Set sh1 = Sheets("ACCF Main")
Set sh2 = Sheets("Accounts missing info")
'set the range of data in column A of sh1
Set rg = sh1.Range("A2", sh1.Range("A" & Rows.Count).End(xlUp))
'looped to each blank cell in column BY (column 77)
For Each cell In rg.Offset(0, 76).SpecialCells(xlCellTypeBlanks)
'copy the entire row of the looped cell into sh2 blank row
cell.EntireRow.Copy Destination:=sh2.Range("A" & Rows.Count).End(xlUp).Offset(1, 0)
Next
'get the range cells which value is "JNTN" in column E sh1 as rgJNTN variable
With rg.Offset(0, 4)
.Replace "JNTN", True, xlWhole, , False, , False, False
Set rgJNTN = .SpecialCells(xlConstants, xlLogical)
.Replace True, "JNTN", xlWhole, , False, , False, False
End With
'loop to each cell (which value is "JNTN") in rgJNTN
For Each cell In rgJNTN
'if the looped cell.Offset(0,8) value = "" (column M or column 13, looped cell row)
'and if the looped cell.offset(0,72) value <> "" (column BY or column 77, looped cell row)
'then copy the entire row of the looped cell to sh2 blank row
If cell.Offset(0, 8) = "" And cell.Offset(0, 72).Value <> "" Then cell.EntireRow.Copy Destination:=sh2.Range("A" & Rows.Count).End(xlUp).Offset(1, 0)
Next
End Sub
Not tested in my side.

Copy paste a fixed row based on some condition else skip to next column in that row

Have data set in I11:X11 and I want to copy formulas seating I12:I12 into I13:X20 based on data contained in I11:X11.
Starting with I11, if that contains certain value lets say TEST, then want to increment row for that range to next column that is J11 and if J11 <> TEST, then copy J12:X12 to J13:X20.
Further want to skip pasting this entire logic based on flag seating in column H13:H20, for example if H13 = Y, then skip to next row.
Adding a screenshot to further explaining the issue.
Condition should start with first member in range I11:X11, if it encounters first member <> TEST till T11 , then it should start copying from that range. In this case it encountered first <> TEST member at L11, then it should copy from L12:T12 to L13:T24 and V12:X12 to V13:X13. Further this logic should work on the flag contained in column H. If this column H Contains Y,then above logic should not paste in that row, this pasting activity should go on until last value in column H starting from H13.
The condition value from I11:T11 can change between TEST and any other values, not further.
Want to achieve this on a button click using a VBA code.
Adding Code, but it limits to the fixed column H values and Fixed row values.
Sub CopyOnCondition1()
Dim sh1 As Worksheet, c As Range
Set sh1 = Worksheets("SheetNameHere") 'change the sheetname
For Each cel In sh1.Range("I11:T11")
If Not cel.Value = "TEST" Then
sh1.Range(Cells(12, cel.Column), Cells(12, 20)).Copy
sh1.Range(Cells(13, cel.Column), Cells(24, 20)).PasteSpecial xlPasteFormulas
End If
Next
For Each cel In sh1.Range("H13:H24")
If cel.Value = "Y" Then sh1.Range("I" & cel.row & ":T" & cel.row).ClearContents
Next
End Sub
enter image description here
As I could understand from the Question I think you are looking for something like this:
Sub CopyOnCondition1()
Dim sh1 As Worksheet, c As Range
Set sh1 = Worksheets("SheetNameHere") 'change the sheetname
For Each cel In sh1.Range("I11:T11")
If Not cel.Value = "TEST" Then
sh1.Range(Cells(12, cel.Column), Cells(12, 20)).Copy
sh1.Range(Cells(13, cel.Column), Cells(24, 20)).PasteSpecial xlPasteFormulas
End If
Next
For Each cel In sh1.Range("H13:H24")
If cel.Value = "Y" Then sh1.Range("I" & cel.row & ":T" & cel.row).ClearContents
Next
End Sub
First It will paste in the complete Range. Then it wo go and check if H have Y, if yes, then it will delete the formula from that row.

How can I copy range from sheet to sheet based on column value?

I am trying to copy a specified range of cells from one sheet (Sheet2) to a specified range of cells in another sheet (Sheet1) based on a condition. There are hundreds of rows of data, and I would like VBA code that looks at each row, and if the condition is met for that row, copies the specified cell range from sheet2 to sheet1. It is not the entire row being copied, just four cells out of a row with many more cells that contain data.
In more specific terms, I would like to copy columns B through E for each row (starting at row 2) IF the value in column AK for each row is greater than 0. I would like for this data to be pasted into columns B through E in sheet1, starting at row 8. So, for example, if row 2 in Sheet 2 meets the criteria, I would like for B2 through E2 in sheet 2 to be copied to B8 through E8 in sheet 1.
I have tried to adapt code found in other questions on StackOverFlow and other sources but I am very new to VBA and have not been successful. Any help would be greatly appreciated.
Private Sub CopySomeCells()
Dim SourceSheet As Worksheet
Dim DestinationSheet As Worksheet
Dim SourceRow As Long
Dim DestinationRow As Long
Set SourceSheet = ActiveWorkbook.Sheets(2)
Set DestinationSheet = ActiveWorkbook.Sheets(1)
DestinationRow = 8
For SourceRow = 2 To SourceSheet.UsedRange.Rows.Count
If SourceSheet.Range("AK" & SourceRow).Value > 0 Then
SourceSheet.Range(SourceSheet.Cells(SourceRow, 2), SourceSheet.Cells(SourceRow, 5)).Copy _
DestinationSheet.Cells(DestinationRow, 2)
DestinationRow = DestinationRow + 1
End If
Next SourceRow
Application.CutCopyMode = False
Set SourceSheet = Nothing
Set DestinationSheet = Nothing
End Sub
If you just want to paste the values (and not the format) then change two rows by this:
SourceSheet.Range(SourceSheet.Cells(SourceRow, 2), SourceSheet.Cells(SourceRow, 5)).Copy
DestinationSheet.Cells(DestinationRow, 2).PasteSpecial Paste:=xlPasteValues
Or better by this (faster and without clipboard):
DestinationSheet.Cells(DestinationRow, 2).Resize(1, 4).Value = _
SourceSheet.Cells(SourceRow, 2).Resize(1, 4).Value

Using SpecialCells for multi-column same-row copy/pasting

Is there a way to, when grabbing all numbers in column "B" by using the .SpecialCells(xlCellTypeConstants, 1), to also copy a cell in the same row?
Example:
Let's say the script found cells B2, B4, B5 with numbers. How would I also copy D2, D4, and D5? Can I do that and still use specialcells? Ultimately, I'd like to copy/paste those values into columns A & B on another sheet.
Thanks!
Dim strOutputFile As Variant
Dim wbkOut As Workbook
Dim tenln As Range
Dim tenlnPaste As Range
Dim wbkVer As Workbook
If strOutputFile(u) Like "*Lines.csv" Then
With wbkOut.Worksheets(1)
Set tenln = wbkOut.Worksheets(1).Cells(Rows.Count, 2).End(xlUp)
Set tenlnPaste = wbkVer.Worksheets("TLines").Range("A" & .Rows.Count).End(xlUp).Offset(1).Resize(tenln.Rows.Count, 1)
wbkOut.Worksheets(1).Range("B:B").SpecialCells(xlCellTypeConstants, 1).Copy
With wbkVer.Worksheets("TenLines")
tenlnPaste.PasteSpecial xlPasteValues
End With
End With
End If
Yes. It's actually very easy. Do like below:
Dim rngConst as Range
On Error Resume Next
Set rngConst = wbkOut.Worksheets(1).Range("B:B").SpecialCells(xlCellTypeConstants, 1)
If Not rngConst is Nothing Then
rngConst.Copy
'do your pasting
Set rngConts = rngConst.Offset(,2) 'for moving from B to D
rngConst.Copy
'do your pasting
End If
On Error Go To 0
You could also do this, to get it all into 1 copy area:
Dim rngConst as Range
On Error Resume Next
If Not rngConst is Nothing
Set rngConst = wbkOut.Worksheets(1).Range("B:B").SpecialCells(xlCellTypeConstants, 1)
Set rngConst = Range(rngConst, rngConst.Offset(,2))
rngConst.Copy
'do your pasting
End If
On Error Go To 0
But this will copy the data onto the new sheet into two contiguous columns. It will not copy from B to B and D to D, for instance.

Macro to copy and paste column by column from one sheet into master sheet by header to maintain growing data

I am fairly new to Excel VBA and have been trying to look for (as well as come up with my own) solutions to a dilemma I am facing. Routinely, I receive raw data files from a colleague and these raw data files may have varying number of columns but consistent header names. I have in my workbook, a master spreadsheet that I want to keep up to date by appending the new data (so keep appending data of new spreadsheet to next empty row). I would like to create a macro that can take the imported spreadsheet (say, spreadsheet A) and look at the header value of a column, copy the column range (starting from row 2 to end of populated within column), go to spreadsheet Master, look for header value, and paste the column range in the next empty cell down in the column. And this procedure would be for all columns present in spreadsheet A.
Any help/guidance/advice would be very much appreciated.
Ex) I have "master" sheet and "imported" sheet. I want to take the "imported" sheet, look at headers in row 1, starting from column 1. If that header is present in "master" sheet, copy the column (minus the header) from "imported sheet" and paste into "master" under the appropriate column header starting from the next empty cell in that column. What I ultimately want to do is keep the "master" sheet with historical data but the "imported" sheet contains columns which moves around so I just couldn't copy and paste the range starting from next empty cell in master.
Untested but compiles OK:
Sub CopyByHeader()
Dim shtA As Worksheet, shtB As Worksheet
Dim c As Range, f As Range
Dim rngCopy As Range, rngCopyTo
Set shtA = ActiveSheet ' "incoming data" - could be different workbook
Set shtB = ThisWorkbook.Sheets("Master")
For Each c In Application.Intersect(shtA.UsedRange, shtA.Rows(1))
'only copy if >1 value in this column (ie. not just the header)
If Len(c.Value) > 0 And Application.CountA(c.EntireColumn) > 1 Then
Set f = shtB.Rows(1).Find(what:=c.Value, LookIn:=xlValues, _
LookAt:=xlWhole)
If Not f Is Nothing Then
Set rngCopy = shtA.Range(c.Offset(1, 0), _
shtA.Cells(Rows.Count, c.Column).End(xlUp))
Set rngCopyTo = shtB.Cells(Rows.Count, _
f.Column).End(xlUp).Offset(1, 0)
'copy values
rngCopyTo.Resize(rngCopy.Rows.Count, 1).Value = rngCopy.Value
End If
End If
Next c
End Sub
EDIT: updated to only copy columns which have any content, and to only copy values
I cannot get the above to work, and need the same result as the original question. Any thoughts on what is missing? I thought I changed everything that needed to be changed to fit my sheets:
Sub CopyByHeader()
Dim shtMain As Worksheet, shtImport As Worksheet
Dim c As Range, f As Range
Dim rngCopy As Range, rngCopyTo
Set shtImport = ActiveSheet
' "Import"
Set shtMain = ThisWorkbook.Sheets("Main")
For Each c In Application.Intersect(shtImport.UsedRange, shtImport.Rows(1))
'only copy if >1 value in this column (ie. not just the header)
If Len(c.Value) > 0 And Application.CountA(c.EntireColumn) > 1 Then
Set f = shtMain.Rows(1).Find(what:=c.Value, LookIn:=xlValues, _
LookAt:=xlWhole)
If Not f Is Nothing Then
Set rngCopy = shtImport.Range(c.Offset(1, 0), _
shtImport.Cells(Rows.Count, c.Column).End(xlUp))
Set rngCopyTo = shtMain.Cells(Rows.Count, _
f.Column).End(xlUp).Offset(1, 0)
'copy values
rngCopyTo.Resize(rngCopy.Rows.Count, 1).Value = rngCopy.Value
End If
End If
Next c
End Sub
Thanks,
Ryan

Resources