Macro to find duplicates rows - excel

I am looking for a macro to find duplicate rows in a spreadsheet. So far I have come up with this set of code:
Application.ScreenUpdating = False
For Each cell In ActiveSheet.UsedRange.Columns("A").Cells
For Each cell2 In ActiveSheet.UsedRange.Columns("A").Cells 'Loop through entire column A for each iteration in nested for loop
If Cells(y, 1).Value = Cells(z, 1).Value Then 'Duplicate value found
For icol = 1 To 19
If Cells(y, icol).Value = Cells(z, icol).Value Then 'If cell value in current row matches, highlight red
Cells(z, icol).Interior.ColorIndex = 3
End If
Next icol
End If
z = z + 1
Next cell2
y = y + 1 'Next cell
z = y + 1 'Next cell (y+1)
Next cell
Application.ScreenUpdating = True
I have approached this with nested foor loops. The macro is supposed to look for a duplicate value in column A. If found the macro then loops through that row to check if the entire row matches. Every matching cell in this row is then highlighted red. This seems to work fine in small scale when the number of rows isn't too big. However when applying this macro to a spreadsheet with 7000+ rows Excel freeze up and crashes. I suspect this has to do with the nested foor loops. Is there a faster and more practical approach to this?

Try conditional formatting instead of hard-coding the red cell fills.
Option Explicit
Sub dupeRed()
Dim lr As Long, lc As Long
With Worksheets("sheet1")
lr = .Cells(.Rows.Count, "A").End(xlUp).Row
lc = .Cells(1, .Columns.Count).End(xlToLeft).Column
With .Range(.Cells(2, "A"), .Cells(lr, lc))
.FormatConditions.Delete
.FormatConditions.Add Type:=xlExpression, _
Formula1:="=AND(COUNTIF($A$1:$A1, $A2), A2=INDEX(A:A, MATCH($A2, $A:$A, 0)))"
.FormatConditions(.FormatConditions.Count).Interior.Color = vbRed
End With
End With
End Sub

Related

Check if consecutive rows have identical value, if not insert new row between them

i am looking for a solution to my problem. The task is to compare two consecutive rows with each other,in the range from column D1 to the last written cell in Column D. If the value of a consecutive cell is equal to the value of the previous cell , i.e. D2=D1, the macro can go next, else it shall insert a new row between the two values. Since i am fairly new to vba and mostly use information based on online research, i could not find a fitting solution til now. Below you can see a part of what tried.
Sub Macro()
'check rows
Dim a As Long
Dim b As Long, c As Long
a = Cells(Rows.Count, "D").End(xlUp).Row
For b = a To 2 Step -1
c = b - 1
If Cells(b, 4).Value = Cells(c, 4).Value Then
If Cells(b, 4).Value <> Cells(c, 4).Value Then
Rows("c").Select
Selection.Insert Shift:=xlDown
End If
End If
Next b
End Sub
Sub InsertRows()
Dim cl As Range
With ActiveSheet
Set cl = .Cells(.Rows.Count, "D").End(xlUp)
Do Until cl.Row < 2
Set cl = cl.Offset(-1)
If cl.Value <> cl.Offset(1).Value Then cl.Offset(1).EntireRow.Insert
Loop
End With
End Sub
Side note. You can benefit from reading How to avoid using Select in Excel VBA

For Loop not iterating VBA

I am trying to delete an entire row if the values in row i column 2 and row i column 3 are empty. My for loop only iterates once. Any idea why?
Sub DeleteEm()
RowCount = Cells(Rows.Count, "A").End(xlUp).Row
For i = 2 To RowCount
If IsEmpty(Cells(i, 2).Value) = True And IsEmpty(Cells(i, 3).Value) = True Then
Rows(i).EntireRow.Delete
End If
Next i
End Sub
Thank you!
You have made an error which is very common for newbies in VBA. To correct the error you need to change
For i = 2 To RowCount
to
For i = RowCount to 2 Step -1
Your original code is deleting rows within the range over which you are iterating.
Consider what happens when i=4 and you delete the row corresponding to that i. Row 4 is deleted. What was row 5 now becomes row 4 BUT at the Next, i becomes 5 so i is now pointing at what was row 6 in your starting range having skipped over what was previously row 5, because that became row 4.
If you use F8 to step through your code whilst watching your sheet you will see it all happen before your eyes.
Delete Rows With Empty Cells in Two Columns
You could also consider using Application.Union to 'collect' the row ranges in a range and then delete the range in one go.
The Code
Option Explicit
Sub DeleteEm()
RowCount = Cells(Rows.Count, "A").End(xlUp).Row
Dim rng As Range
For i = 2 To RowCount
' Considering 'blank cells = empty cells + ""-cells'.
' Either (For empty cells)...
If IsEmpty(Cells(i, 2)) And IsEmpty(Cells(i, 3)) Then
' ...or (for blank cells)
'If Len(Cells(i, 2)) = 0 And Len(Cells(i, 3)) = 0 Then
If rng Is Nothing Then
Set rng = Rows(i)
Else
Set rng = Union(rng, Rows(i))
End If
End If
Next i
If Not rng Is Nothing Then
rng.Delete
End If
End Sub

Run-Time Error '1004': Application Defined or Object-Defined Error

I am trying to copy and paste data from one sheet to the next from a selected range entered by the user. TxtDateStart takes the start date, and TxtDateEnd takes the end date. Then it would copy and paste the data from the range of dates to a new sheet.
When I run the code in a form, it works but I rather have the form call the module. This is where I get the run-time error. I'm no expert in VBA, help would be appreciated.
The sheet where the data is is called Unit2Data, and the sheet i want to paste the data is Graphing Sheet.
The error occurs in this line
Sheets("Unit2Data").Range(Cells(i, 1), Cells(i, 73)).Select
Sub Unit2Data()
Dim lrow As Long, i As Long, x As Date, y As Date, erow As Long
x = TxtDateStart
y = TxtDateEnd
'Find the Last Row of Sheet1
lrow = Sheets("Unit2Data").Range("A" & Rows.Count).End(xlUp).Row
'start counting from row 3 to last row
For i = 4 To lrow
' Date value converted as numeric value by multiplying with number 1
If Cells(i, 1) * 1 >= x * 1 Then
If Cells(i, 1) * 1 <= y * 1 Then
'If above conditions matched then select the matched range/ entire column
Sheets("Unit2Data").Range(Cells(i, 1), Cells(i, 73)).Select
'copy the selected row
Selection.Copy
'to make sheet2 active where we want to paste the selected row
Sheets("Graphing Sheet").Activate
'to find the empty row from where the copied row of sheet1 to be pasted in sheet2
erow = Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
'to activate or select the empty row of sheet2
ActiveSheet.Cells(erow, 1).Select
'paste the copied data
ActiveSheet.Paste
'to deselect the copy and selected mode
Application.CutCopyMode = False
'for above the if we need 3 end if to close if conditions
End If
End If
'to activate sheet1 for searching the matched data
Sheets("Unit2Data").Activate
'continue for look until above matched found
Next i
End Sub
Date Data
01/01/2019 2
02/02/2019 3
First you should avoid using Select in VBA. There, almost always, are better ways to achieve whatever you are using Select for.
In your case, and regarding only the specific error/question raised, delete the error-causing line and the next line (Selection.Copy) and replace with this:
With Sheets("Unit2Data")
.Range(.Cells(i, 1), .Cells(i, 73)).Copy
End With
Rewriting your entire code to avoid using Select:
Sub Unit2Data()
Dim lrow As Long, i As Long, x As Date, y As Date, erow As Long
x = TxtDateStart
y = TxtDateEnd
With Sheets("Unit2Data")
lrow = .Range("A" & .Rows.Count).End(xlUp).Row
For i = 4 To lrow
If .Cells(i, 1) * 1 >= x * 1 Then
If .Cells(i, 1) * 1 <= y * 1 Then
With Sheets("Graphing Sheet")
erow = .Cells(.Rows.Count, 1).End(xlUp).Offset(1, 0).Row
End With
.Range(.Cells(i, 1), .Cells(i, 73)).Copy _
Destination:= Sheets("Graphing Sheet").Cells(erow, 1)
End If
End If
Next i
End With
End Sub

How to delete all rows of a multiple entry even if just one row meets defined criteria

Below is the current (incomplete) code I'm using which works fine to delete any one given row, but what I really need to do is identify rows which meet certain criteria:
Cell Value in Column L > 90%
OR
Cell Value in Column M > 90%
Then if either of those is true I need to find the Cell Value in same row Column G and delete all rows which contain that same Value in Column G.
Sub sbDelete_Rows_Based_On_Multiple_Criteria()
Dim lRow As Long
Dim iCntr As Long
lRow = Cells(Rows.Count, "G").End(xlUp).Row
For iCntr = lRow To 2 Step -1
If Cells(iCntr, "L") > 0.90 OR Cells(iCntr, "M") > 0.90 Then
Cells(iCntr, "G").EntireRow.Delete
End If
Next iCntr
End Sub
--
What I hope to accomplish in my example would result in the only Serial # which is NOT deleted would be 1910910
thank you in advance for your assistance.
Sub ToDelete()
Dim last_row&
'// NOTE! The code assumes that range:
'// 1) starts in column A
'// 2) ends in column O
last_row = Cells(Rows.Count, "G").End(xlUp).Row
'// Helper column 1
With Range("P2:P" & last_row)
.Formula = "=IF(OR(M2>0.9,L2>0.9),1,0)"
.Value = .Value 'Overwrite formula
End With
'// Helper column 2
With Range("Q2:Q" & last_row)
.Formula = "=IF(SUMIF(G:G,G2,P:P)>0,1,0)"
.Value = .Value 'Overwrite formula
End With
Rows(1).CurrentRegion.AutoFilter Field:=17, Criteria1:=1
Rows("2:" & last_row).EntireRow.Delete
ActiveSheet.AutoFilterMode = False 'Remove filter
Columns("P:Q").Delete 'Remove helper columns
End Sub

If Statement comparing strings in different rows but the same column

I'm attempting to combine 2 rows on my excel spreadsheet into 1 row based on a particular condition being true.
I would like for my vba code to determine whether or not the string of characters in row 2 = the string of characters in row 3.
If they are equal, I would like to copy all of row 3 to column Q in row and then continue on comparing the string values of rows 3 and 4, 4 and 5, etc to the last used row of the spreadsheet.
I've attempted to modify code I've found on Stack Overflow but still can't get my macro to run. Any help with this would be greatly appreciated.
Here's a link to a similar situation I found in Stack Overflow while I was researching how to create my VBA code but I couldn't get the sample code to work for me. Not sure why. vba - excel - if value = next row value then copy another value
Here's part of the Excel worksheet I'm working with. I did have to modify the information on the spreadsheet so that it wouldn't be too wide to paste.
Member Data spreadsheet
Something like:
Public Sub ArrangeData()
Dim i As Long, unionRng As Range, lastRow As Long, counter As Long
Application.ScreenUpdating = False
With ThisWorkbook.Worksheets("Data") 'change as appropriate
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
.Range("A1:G" & lastRow).Sort Key1:=.Range("G2:G" & lastRow), Order1:=xlAscending, Header:=xlYes ' 'Sort to ensure in order (and blanks will be at end
For i = 3 To .Range("G1").End(xlDown).Row + 1
If .Cells(i, "G") = .Cells(i - 1, "G") Then
counter = counter + 1
.Cells(i, "A").Resize(1, 6).Copy .Cells(i - counter, .Cells(i - counter, .Columns.Count).End(xlToLeft).Column + 1)
Else
counter = 0
End If
Next i
For i = 3 To .Range("G1").End(xlDown).Row + 1
If IsEmpty(.Cells(i, "H")) Then
If Not unionRng Is Nothing Then
Set unionRng = Union(unionRng, .Cells(i, "H"))
Else
Set unionRng = .Cells(i, "H")
End If
End If
Next i
If Not unionRng Is Nothing Then unionRng.EntireRow.Delete
End With
Application.ScreenUpdating = True
End Sub
Before:
After:

Resources