Excel VBA Duplicates in one columns unique in another - vba

I have been attempting to solve this for a couple of days and have been able not come up with or find a similar solution. I am trying to highlight duplicates in a single column where their are distinct values in another.
For example occasionally in column G there are duplicate names but they only need to be marked(highlighted) when the value column D is unique. So using the example below the end result should only highlight Elizabeth Moore.
Column D Column G
116023339 Alan Fluder
116023339 Alan Fluder
116023347 Elizabeth Moore
116025757 Elizabeth Moore
116025048 A. Lavoie
If it helps below is the code I used as my starting point.
Sub test()
Dim cel As Variant
Dim myCell As Variant
Dim myrng As Range
Dim myRange As Range
Dim CellValue As Long
Set myrng = Range("G2:G" & Range("G" & Rows.Count).End(xlUp).Row)
Set myRange = Range("D2:D" & Range("D" & Rows.Count).End(xlUp).Row)
For Each cel In myrng
If Application.WorksheetFunction.CountIf(myrng, cel) > 1 Then
For Each myCell In myRange
If Application.WorksheetFunction.CountIf(myRange, myCell) = 1 Then
myCell.Offset(0, 3).Interior.ColorIndex = 6
End If
Next myCell
End If
Next cel
End Sub
I should add that my current solution now is to separate the loops where one highlights all the column G dups then the second loop unhighlights where column D is duped.

If you can use formulas #Tim's suggestion works well. To fix the VBA:
Option Explicit
Sub test()
Const ROW_OFFSET As Byte = 2
Dim cel As Range
Dim rng1 As Range
Dim rng2 As Range
Dim cRow As Long
Dim lRow As Long
Set rng1 = Range("G" & ROW_OFFSET & ":G" & Range("G" & Rows.Count).End(xlUp).Row)
Set rng2 = Range("D" & ROW_OFFSET & ":D" & Range("D" & Rows.Count).End(xlUp).Row)
With Application.WorksheetFunction
For Each cel In rng1
If .CountIf(rng1, cel) > 1 Then
If .CountIf(rng2, rng2.Cells(cel.Row - (ROW_OFFSET - 1), 1)) = 1 Then
cel.Interior.ColorIndex = 6
End If
End If
Next cel
End With
End Sub
The inner For is not needed if columns are synchronized
I used the ROW_OFFSET constant to emphasize the alignment between columns
.

Related

Copying a cell from a selected range of columns to a specific column while keeping the same row

I've been trying to organise my data that all of the similar data (found in several column) can be copied to a single column. Here is simplified version of the script I wrote so far (the range includes more column, but I reduced it for visual reasons here). I'm not sure how to tell that I want that i want to copy in this the row where the selected cell is. I hope I'm being clear enough.
Dim value As String
Dim rngTemp1 As Range
Dim rngTemp2 As Range
Dim rngTemp3 As Range
Dim rngTemp4 As Range
Dim rngTemp5 As Range
With Workbooks("ExploringTheRelation.xlsx").Sheets("ExploringTheRelation")
Lastrow = .Cells(Rows.Count, 1).End(xlUp).Row
Set rngTemp1 = .Range("W2:W" & Lastrow & ", AB2:AB" & Lastrow)
Set rngTemp2 = .Range("X2:X" & Lastrow & ", AC2:AC" & Lastrow)
For Each cell In rngTemp1
cell.Copy
cell(18, **Row**).Paste
Next cell
For Each cell In rngTemp2
cell.Copy
cell(18, **Row**).Paste
Next cell
End With
Thank you for your help
If I'm reading this right, you're trying to consolidate data across columns into one column? If so, adjust this as needed:
Dim rowStart as long
Dim cell as variant
Dim rngTemp1 as excel.range
rowStart = 2
With ActiveSheet
For Each cell In rngTemp1
If Len(cell.Value) > 0 Then
.Cells(rowStart, 6).Value = cell.Value
rowStart = rowStart + 1
End if
Next cell
End With
Here's how I would do it. Just adding in another variable to count the previous row that a value was added into.
With Workbooks("ExploringTheRelation.xlsx").Sheets("ExploringTheRelation")
'finds the bottom row of data
Dim lastRow As Long
lastRow = .Cells(Rows.count, 1).End(xlUp).row
Dim rngTemp1 As Range
Set rngTemp1 = .Range("W2:W" & lastRow & ", AB2:AB" & lastRow)
Dim rngTemp2 As Range
Set rngTemp2 = .Range("X2:X" & lastRow & ", AC2:AC" & lastRow)
'keeps track of the last row that a value was put into
Dim currRow As Long
currRow = 1
'loops through a range and puts each value into column "R" one after another
Dim cel As Range
For Each cel In rngTemp1
.Cells(currRow, "R").Value2 = cel.Value2
currRow = currRow + 1
Next cell
For Each cel In rngTemp2
.Cells(currRow, "R").Value2 = cel.Value2
currRow = currRow + 1
Next cell
End With

Trying to look at values in one column and update value in anotehr column

I'm trying create a macro to look at column F and then update Column I all the way down from the first row until the last.
so read column F for SBS and then update the corresponding row on column I with "National"
THis is my code.
Dim LastRow As String
Dim d As String
LastRow = Range("F" & Rows.Count).End(xlUp).Row
For d = SBS To LastRow
If Not IsEmpty(Range("F" & d).Value) Then
Range("I" & d).Value = "National"
End If
Next d
Made minor changes in your macro in Dim statement for d and if condition. Also not empty condition is not required:-
Sub Macro1()
Dim LastRow As Long
Dim d As Long
LastRow = Range("F" & Rows.Count).End(xlUp).Row
For d = 1 To LastRow
If Range("F" & d).Value = "SBS" Then
Range("I" & d).Value = "National"
End If
Next d
End Sub
Here is quick example
Option Explicit
Public Sub Example()
Dim Sht As Worksheet
Dim Rng As Range
Set Sht = ThisWorkbook.Sheets("Sheet1")
For Each Rng In Sht.Range("F1", Sht.Range("F9999").End(xlUp))
If Rng.Value = "SBS" Then
Rng.Cells.Offset(0, 3).Value = "National"
End If
Next
End Sub

Apply formula to a range of cells

I have some code which I know works, I am applying a SUMIF formula to a range of cells. It works but it add a load of extra row at the bottom that shouldn't be there. I tried adding in a do until loop but it gets stuck in an infinite loop and crashes.
This is my first lot of code which works but adds the extra row in only on the columns which have been copied over.
Dim z As Workbook 'Budget Workbook
Dim y As Workbook 'Formatted - current workbook
Dim lastRow As Integer
Dim budgLastRow As Integer
Dim rng As Range
Set y = Workbooks("DLT.xlsm")
Set z = Workbooks.Open("C:\Reports\Budget.xlsx")
'Apply function to columns to pull costing data
With y.Worksheets("DLT")
lastRow = Cells(Rows.Count, 5).End(xlUp).Row
For Each rng In .Range("AI22:AI" & lastRow)
rng.Formula = "=SUMIF('[Budget.xlsx]DynamicReport'!$C:$C,$E" & rng.Row & ",'[Budget.xlsx]DynamicReport'!H:H)"
rng.Value = rng.Value
Next rng
For Each rng In .Range("AJ22:AJ" & lastRow)
rng.Formula = "=SUMIF('[Budget.xlsx]DynamicReport'!$C:$C,$E" & rng.Row & ",'[Budget.xlsx]DynamicReport'!I:I)"
rng.Value = rng.Value
Next rng
For Each rng In .Range("AN22:AN" & lastRow)
rng.Formula = "=SUMIF('[Budget.xlsx]DynamicReport'!$C:$C,$E" & rng.Row & ",'[Budget.xlsx]DynamicReport'!E:E)"
rng.Value = rng.Value
Next rng
For Each rng In .Range("AO22:AO" & lastRow)
rng.Formula = "=SUMIF('[Budget.xlsx]DynamicReport'!$C:$C,$E" & rng.Row & ",'[Budget.xlsx]DynamicReport'!G:G)"
rng.Value = rng.Value
Next rng
End With
I think the other additional rows have been copied because the budget workbook contains more data then the formatted work book. I have know thought to possibly delete the other unnecessary row which have been copied cross.
So I have added this small piece of code in
With y.Worksheets("Formatted")
lastRow = Cells(Rows.Count, 5).End(xlUp).Row - 1
budgLastRow = Cells(Rows.Count, 35).End(xlUp).Row
Rows("AI" & lastRow & ":AO" & budgLastRow).EntireRow.Delete
End With
I get an application-defined error Object defined error on the line
Rows("AI" & lastRow & ":AO" & budgLastRow).EntireRow.Delete
This is probably not the most efficient way to do this, but its the only way I could think of. I am fairly new to VBA only been coding a couple of months so mostly just try out different ways and see what works. Can anyone help me please.
You didn't properly qualify the ranges for the lastRow variable:
lastRow = .Cells(.Rows.Count, 5).End(xlUp).Row
Note the dots before Cells and Rows.
A couple of additional points:
Always use Long rather than Integer for row variables as there are more rows in a sheet than an Integer can hold.
You don't need to loop to put the same formula in a column of cells.
Dim z As Workbook 'Budget Workbook
Dim y As Workbook 'Formatted - current workbook
Dim lastRow As Long
Dim budgLastRow As Long
Set y = Workbooks("DLT.xlsm")
Set z = Workbooks.Open("C:\Reports\Budget.xlsx")
'Apply function to columns to pull costing data
With y.Worksheets("DLT")
lastRow = .Cells(.Rows.Count, 5).End(xlUp).Row
With .Range("AI22:AJ" & lastRow)
.Formula = "=SUMIF('[Budget.xlsx]DynamicReport'!$C:$C,$E22,'[Budget.xlsx]DynamicReport'!H:H)"
.Value2 = .Value2
End With
With .Range("AN22:AN" & lastRow)
.Formula = "=SUMIF('[Budget.xlsx]DynamicReport'!$C:$C,$E22,'[Budget.xlsx]DynamicReport'!E:E)"
.Value2 = .Value2
End With
With .Range("AO22:AO" & lastRow)
.Formula = "=SUMIF('[Budget.xlsx]DynamicReport'!$C:$C,$E22,'[Budget.xlsx]DynamicReport'!G:G)"
.Value2 = .Value2
End With
End With

Excel vba copy Row from one sheet to another and past it in the same Position

I am Trying to build a vba script for excel with to check if value (ex: First and Last Name) in sheet1 exist in sheet2 then if exist copy the entire row from sheet1 and past it in sheet2 in the same position where it find it
i succeeded to check if the Name exist and past it but in the end table not where it find it
Sub test()
Dim LR As Long, i As Long
LR = Range("C" & Rows.Count).End(xlUp).Row
LR2 = ThisWorkbook.Sheets("Feuil2").Range("C" & Rows.Count).End(xlUp).Row
For i = 14 To LR
For j = 14 To LR2
If Range("C" & i).Value = ThisWorkbook.Sheets("Feuil2").Range("C" & j).Value Then Rows(i).Copy Destination:=Sheets("Feuil2").Range("A" & Rows.Count).End(xlUp).Offset(1)
Next j
Next i
End Sub
any ideas ?? Thank you !
You can also use find to find the value and get the row number.
Sub test2()
Dim Rws As Long, rng As Range, c As Range, sh As Worksheet, Fx As Range
Rws = Cells(Rows.Count, "A").End(xlUp).Row
Set rng = Range(Cells(14, "C"), Cells(Rws, "C"))
Set sh = Sheets("Feuil2")
For Each c In rng.Cells
With sh
Set Fx = .Columns(3).Find(what:=c, lookat:=xlWhole)
If Not Fx Is Nothing Then
c.Offset(0, -2).Range("A1:B1").Copy sh.Range("A" & Fx.Row)
End If
End With
Next c
End Sub

Excel VBA - Check Values in Sheet1 Against Sheet2, then Copy Notes If Matching

I have two sheets. I want to check the value in one column against the value in the same column in the second sheet. If they match, then I want to migrate the string data from the Notes column to the new sheet. (essentially I'm seeing if last week's ticket numbers are still valid this week, and carrying over the notes from last week).
I am trying to do this with the following code (using columns Z for the data, BE for the notes):
Sub Main()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set ws1 = Sheets("Sheet1")
Set ws2 = Sheets("Sheet2")
Dim partNo2 As Range
Dim partNo1 As Range
Dim partNo3 As Range
For Each partNo2 In ws1.Range("Z1:Z" & ws1.Range("Z" & Rows.Count).End(xlUp).Row)
For Each partNo1 In ws2.Range("Z1:Z" & ws2.Range("Z" & Rows.Count).End(xlUp).Row)
For Each partNo3 In ws1.Range("BE1:BE" & ws2.Range("BE" & Rows.Count).End(xlUp).Row)
If StrComp(Trim(partNo2), Trim(partNo1), vbTextCompare) = 0 Then
ws2.Range("BE" & partNo1.Row) = partNo3
End If
Next
Next
Next
'now if no match was found then put NO MATCH in cell
For Each partNo1 In ws2.Range("E1:F" & ws2.Range("A" & Rows.Count).End(xlUp).Row)
If IsEmpty(partNo1) Then partNo1 = ""
Next
End Sub
Untested:
Sub Main()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim rng1 As Range, rng2 As Range
Dim c As Range, f As Range
Set ws1 = Sheets("Sheet1")
Set ws2 = Sheets("Sheet2")
Set rng1 = ws1.Range("Z1:Z" & ws1.Range("Z" & Rows.Count).End(xlUp).Row)
Set rng2 = ws2.Range("Z1:Z" & ws2.Range("Z" & Rows.Count).End(xlUp).Row)
For Each c In rng1.Cells
Set f = rng2.Find(c.Value, , xlValues, xlWhole)
If Not f Is Nothing Then
f.EntireRow.Cells(, "BE").Value = c.EntireRow.Cells(, "BE").Value
End If
Next c
'now if no match was found then put NO MATCH in cell
For Each c In ws2.Range("E1:F" & ws2.Range("A" & Rows.Count).End(xlUp).Row)
If Len(c.Value) = 0 Then c.Value = "NO MATCH"
Next
End Sub
This accomplishes the same result (maybe with the exception of the columns E & F at the bottom with NO MATCH). It's just a different way of going about it. Instead of using ranges, I'm just looking at each cell and comparing it directly.
TESTED:
Sub NoteMatch()
Dim lastRow1 As Long
Dim lastRow2 As Long
Dim tempVal As String
lastRow1 = Sheets("Sheet1").Range("Z" & Rows.Count).End(xlUp).row
lastRow2 = Sheets("Sheet2").Range("Z" & Rows.Count).End(xlUp).row
For sRow = 2 To lastRow1
tempVal = Sheets("Sheet1").Cells(sRow, "Z").Text
For tRow = 2 To lastRow2
If Sheets("Sheet2").Cells(tRow, "Z") = tempVal Then
Sheets("Sheet2").Cells(tRow, "BE") = Sheets("Sheet1").Cells(sRow, "BE")
End If
Next tRow
Next sRow
Dim match As Boolean
'now if no match was found, then put NO MATCH in cell
For lRow = 2 To lastRow2
match = False
tempVal = Sheets("Sheet2").Cells(lRow, "Z").Text
For sRow = 2 To lastRow1
If Sheets("Sheet1").Cells(sRow, "Z") = tempVal Then
match = True
End If
Next sRow
If match = False Then
Sheets("Sheet2").Cells(lRow, "BE") = "NO MATCH"
End If
Next lRow
End Sub