Check for duplicates sum - excel

I want to check for duplicates in a column and my code is able to do so. But when it finds a duplicate in column L i want it to add "+1" to the integer in column c. So if "L5 and L6" are the same, I want "C5" to be "C5+1". But I have not been able to figure out how to do so.
Sub check_duplicates()
Dim x As Long
Dim LastRow As Long
LastRow = Range("L65536").End(xlUp).Row
For x = LastRow To 1 Step -1
If Application.WorksheetFunction.CountIf(Range("L2:L" & x), Range("L" & x).Value) > 1 Then
Range("C" & x).Formula = "=LEFT(x) + 1"
End If
Next x
End Sub

That should solve your problem:
Sub check_duplicates()
Dim x As Long
Dim LastRow As Long
LastRow = Range("L65536").End(xlUp).Row
For x = LastRow To 1 Step -1
If Application.WorksheetFunction.CountIf(Range("L2:L" & x), Range("L" & x).Value) > 1 Then
Range("C" & x) = Left(Range("C" & x), 1) + 1 & Mid(Range("C" & x), 2)
End If
Next x
End Sub

Replace Range("C" & x).Formula = "=LEFT(x) + 1" with something like Range("C" & x)=Range("C" & x) + 1. Making the formula in C5=C5+1 would be circular and would cause an error. Alternatively, set a variable equal to range C5, add 1 to it, then set range C5 to this variable. I'm assuming column C is a set of integers here and not formulas.

You can increment the value by wrapping the Left function (VBA version) around the cell value to get the value to increment by one and then use the space to extract the value to the right `"P" in your example, then bring them back together.
See the code below. It will work for instances where the number increments above single digits and it also assumes there will always be a space after the number and before the text.
Sub check_duplicates()
Dim x As Long
Dim LastRow As Long
LastRow = Range("L65536").End(xlUp).Row
For x = LastRow To 1 Step -1
If Application.WorksheetFunction.CountIf(Range("L2:L" & x), Range("L" & x).Value) > 1 Then
Dim y As Long, x As String
'increment left number by 1
y = Left(Range("C" & x).Value, InStr(1, Range("C" & x).Value, " ") - 1) + 1
'extract text after space
x = Mid(Range("C" & x).Value, InStr(1, Range("C" & x).Value, " "))
Range("C" & x).Value = y & x ' bring together and set the cell value to new incremented value
End If
Next x
End Sub

Related

Copy-Paste above row's Range if a specific range is empty and another is not

I have a table in an active worksheet.
I am trying to:
Scan Columns(A:M) of Row 6 to see if all cells are empty
If yes, then scan Columns (N:R) of Row 6 to see if all cells are empty
If 2. is false, then copy above row's Columns (A:I) in Row 6
Repeat 1-3 but on Row 7
This process should repeat until the rows of the table end.
I would like to incorporate ActiveSheet.ListObjects(1).Name or something similar to duplicate the sheet without having to tweak the code.
How I can make this as efficient and as risk free as possible? My code works but it's really too much.
Sub CopyPasteRow()
Dim lr As Long
Dim x As Long
Dim y As Long
Dim a As Long
lr = Cells(Rows.Count, 1).End(xlUp).Row
a = 0
For x = 6 To lr
For y = 1 To 13
If Not IsEmpty(Cells(x, y)) Then
a = a + 1
End If
Next y
If a = 0 Then
For y = 14 To 18
If Not IsEmpty(Cells(x, y)) Then
a = a + 1
End If
Next y
Else
a = 0
End If
If a <> 0 Then
For y = 1 To 13
Cells(x, y).Value = Cells(x - 1, y).Value
Next y
End If
a = 0
Next x
End Sub
This is the final code based on #CHill60 code. It got me 99% where I wanted.
Sub CopyPasteRow()
Dim lr As Long
Dim x As Long
Dim a As Long
Dim r As Range, r2 As Range, r3 As Range
lr = Cells(Rows.Count, 1).End(xlUp).Row
For x = 6 To lr
'check columns A to M for this row are empty
Set r = ActiveSheet.Range("A" & CStr(x) & ":M" & CStr(x))
'check columns N to R for this row are empty
Set r2 = ActiveSheet.Range("N" & CStr(x) & ":R" & CStr(x))
If WorksheetFunction.CountA(r) = 0 And WorksheetFunction.CountA(r2) <> 0 Then
'copy the data into columns A to M
Set r3 = ActiveSheet.Range("A" & CStr(x) & ":I" & CStr(x))
r3.Value = r3.Offset(-1, 0).Value
End If
Next x
End Sub
Instead of looking at individual cells, look at Ranges instead. Consider this snippet of code
Sub demo()
Dim x As Long
For x = 6 To 8
Dim r As Range
Set r = Sheets(1).Range("A" & CStr(x) & ":M" & CStr(x))
Debug.Print r.Address, MyIsEmpty(r)
Next x
End Sub
I have a function for checking for empty ranges
Public Function MyIsEmpty(rng As Range) As Boolean
MyIsEmpty = WorksheetFunction.CountA(rng) = 0
End Function
I use this because the cell might "look" empty, but actually contain a formula.
Note I've explicitly said which sheet I want the Cells from - users have a habit of clicking places other than where you think they should be! :laugh:
Edit after OP comment:
E.g. your function might look like this
Sub CopyPasteRow()
Dim lr As Long
Dim x As Long
Dim a As Long
Dim r As Range, r2 As Range
lr = Cells(Rows.Count, 1).End(xlUp).Row
For x = 6 To lr
a = 0
'check columns A to M for this row are empty
Set r = Sheets(1).Range("A" & CStr(x) & ":M" & CStr(x))
If Not MyIsEmpty(r) Then
a = a + 1
End If
If a = 0 Then
'check columns N to R for this row are empty
Set r2 = Sheets(1).Range("N" & CStr(x) & ":R" & CStr(x))
If Not MyIsEmpty(r2) Then
a = a + 1
End If
Else
a = 0
End If
If a <> 0 Then
'copy the data into columns A to M
'You might have to adjust the ranges here
r.Value = r2.Value
End If
Next x
End Sub
where you have a source range and a target range - you appear to be putting the values in the previous row so my value of r is probably wrong in this example - you could use r.Offset(-1,0).Value = r2.Value
I'm also not sure what you are trying to do with the variable a If that is meant to be a "flag" then consider using a Boolean instead - it only has the values True or False

VBA: How to describe row with specific string

Hi I'm trying to create a loop that identifies a specific string in column "B", and SUMs up the values in column "D" of the same row. So far I've been able to identify the "cash" but now I don't know how to describe column "D" of the SAME row and sum it up. Please help!
Below is what I've got so far for this loop.
Dim CD As Long
Dim text As String
Dim Z As Long
CD = 0
For Z = 1 To Range("B" & Rows.Count).End(xlUp).Row
text = Range("B" & Z).Value
If Left(text, 4) = "Cash" Then
Sum....
You could certainly do something like:
For Z = 1 To Range("B" & Rows.Count).End(xlUp).Row
text = cells(Z,2).Value
If Left(text, 4) = "Cash" Then
Sum.... Zum = Zum + cells(Z,4).value
However, the computation could be done with a simple worksheet formula
=SUMIF(B:B,"cash*",D:D)
Following the code you have provided, this would be what you are looking for:
Sub calculateSum()
Dim CD As Long
Dim text As String
Dim Z As Long
'Create a variable to store the sum and set its value to 0.
Dim sum As Double
sum = 0
CD = 0
For Z = 1 To Range("B" & Rows.Count).End(xlUp).Row
text = Range("B" & Z).Value
If Left(text, 4) = "Cash" Then
'Increase the sum by the value stored in column D on the same row.
sum = sum + Range("D" & Z).Value
End If
Next Z
'Display the final result (sum).
MsgBox "Sum: " & sum
End Sub

finding a matching value in column and updating by vlookup or adress match

I have a simple explanation of what I'm having trouble with.
Column A: List of 100 names (each Name exists 2 times)
Column B: Email Address associated with the names(each Name has emailadress)
Example:
A1: James B1:oldmail#hotmail.com
A10: James B10:newmail#hotmail.com
So I want to get this===>>
A1:James B1:newmail#hotmail.com
Basically i want to use vlookup or adressmatch to update the email adress, when two values in Column A match.
How can i do this?
Try with below code
Note: it will work if the column A each name have two times only
If the Column A names appear one time it will considered as the new one in B column.
Sub test()
Dim lastrow As Long
Dim incre As Long
Dim flag As String
flag = "no"
lastrow = Range("A" & Rows.Count).End(xlUp).Row
incre = 1
ReDim names(lastrow, 2) As String
For i = 1 To lastrow
names(i, 1) = Range("A" & i).Value
names(i, 2) = Range("B" & i).Value
Next i
For i = 1 To lastrow
For j = i + 1 To lastrow
If names(i, 1) = names(j, 1) Then
flag = "yes"
Range("C" & incre) = names(j, 1) & " Value: " & names(j, 2)
incre = incre + 1
End If
Next j
If flag = "no" Then
Range("C" & incre) = names(i, 1) & " Value: " & names(i, 2)
Else
flag = "no"
End If
Next i
End Sub

Run time error 13 when column doesn't have different values

Following is part of my program which does the follwoing function
It will look into column K and column L and create tabs according to the combinations. For example if column K has a cell value "Apple" and column L has one cell value "Orange" it will create a tab 1) Apple - Orange
The new tab will have all the rows with this combination
So once complete the running of macro , the whole data will get divided to different tabs according to the K - L combination
My problem is it is giving a run time error when entire column K or entire column L has only one value. For example if entire K column has 10 rows and all column k cells has value Apple it will give error. same goes for column L.
Dim m As Integer
Dim area As Range
Count = Range("K:K").SpecialCells(xlLastCell).Row
ActiveSheet.Range("K2:K" & Count).AdvancedFilter Action:=xlFilterCopy,
CopyToRange:=ActiveSheet.Range("Z2"), Unique:=True
Columns(26).RemoveDuplicates Columns:=Array(1)
Count1 = Range("L:L").SpecialCells(xlLastCell).Row
ActiveSheet.Range("L2:L" & Count1).AdvancedFilter Action:=xlFilterCopy,
CopyToRange:=ActiveSheet.Range("Y2"), Unique:=True
Columns(25).RemoveDuplicates Columns:=Array(1)
Dim arrayv As String
Dim Text1 As String
Dim arrayv1 As String
last = Range("Z2").End(xlDown).Row
arrayv = WorksheetFunction.Transpose(Sheets(1).Range("Z2:Z" & last).Value)
last1 = Range("Y2").End(xlDown).Row
arrayv1 = WorksheetFunction.Transpose(Sheets(1).Range("Y2:Y" & last1).Value)
Columns(26).EntireColumn.Delete
Columns(25).EntireColumn.Delete
Dim i As Long, j As Long
Dim flag As Variant
flag = 1
A = 1
s = 2
For c = 1 To UBound(arrayv1)
For t = 1 To UBound(arrayv)
Sheets.Add().Name = "Sheet" & s
ActiveSheet.Move After:=Sheets(ActiveWorkbook.Sheets.Count)
With Worksheets("Sheet1")
j = 2
.Rows(1).Copy Destination:=Worksheets("Sheet" & s).Range("A" & 1)
flag = 1
For i = 2 To Count
If .Cells(i, 11).Value = arrayv(t) Then
If .Cells(i, 12).Value = arrayv1(c) Then
Text = .Cells(i, 15).Value
flag = 0
.Rows(i).Copy Destination:=Worksheets("Sheet" & s).Range("A" & j)
j = j + 1
End If
End If
Next i
If flag = 1 Then
Sheets("Sheet" & s).Delete
Else
Text1 = Left(Text, 4)
Error line when column K has only one value
arrayv = WorksheetFunction.Transpose(Sheets(1).Range("Z2:Z" & last).Value)
Error line when column L has only one value
arrayv1 = WorksheetFunction.Transpose(Sheets(1).Range("Y2:Y" & last1).Value)
If there is only one value Y2 or Z2 downwards then using the Range,End property with an xlDirection of xlDown is going to reference row 1,048,576. The WorksheetFunction.Transpose method has a limit of 65,536. Anything exceeding this limit will result in,
Run-time error '13':Type mismatch.
Change the direction of the last-row-seek to look up from the bottom with xlUp.
last = Range("Z" & rows.count).End(xlUp).Row
arrayv = WorksheetFunction.Transpose(Sheets(1).Range("Z2:Z" & last).Value)
last1 = Range("Y" & rows.count).End(xlUp).Row
arrayv1 = WorksheetFunction.Transpose(Sheets(1).Range("Y2:Y" & last1).Value)

Excel macro - unable to call cell value

In my worksheet some cells values are based on other cells
Info worksheet
A1: 5
B1: =A1
Design worksheet
A1:
Is there a way to copy and read the value in B1? I'm trying to use the value in a for loop, with no luck.
Sheets("Info").Select
For i = 1 to 5
If Range("B" & i).Value <> 0 Then
Range("B" & i).Copy Destination:=Sheets("Design").Range("A" & x)
'Sheets("Design").Range("A" & x).Value = Sheets("Offerte").Range("B" & i).Value
x = x + 1
End If
Next i
Your example doesn't seem to match the code well. The line
If Range("B" & i).Value = 1 Then
means that nothing will be copied in your example. It's looking for a cell with 1 in it. Why do you need that If statement at all?
EDIT I am guessing you're just checking that there's something in the cell to copy? I would probably do it this way:
If Trim(Range("B" & i).Value) <> "" Then
Also - did you miss out setting x=1?
There is more than one way to do it. One of them is using 'offset', which is a function that really worth understand. It basically points to a amount of rows / columns from the original cell.
Sub test()
Dim oCell As Excel.Range
Dim i As Integer
Dim x As Integer
Set oCell = Sheets("Info").Range("B1")
x = 1
For i = 1 To 5
If oCell.Offset(i, 0).Value = 1 Then
oCell.Offset(i, 0).Copy Destination:=Sheets("Design").Range("A" & x)
x = x + 1
End If
Next i
End Sub
Besides, you can assert the value instead of using the copy property. Notice it won't work unless x is an integer > 0.
Sub test2()
Sheets(3).Select
x = 1
For i = 1 To 5
If Range("B" & i).Value = 1 Then
Sheets(4).Range("A" & x).Value = Range("B" & i).Value
'Sheets("Design").Range("A" & x).Value = Sheets("Offerte").Range("B" & i).Value
x = x + 1
End If
Next i
End Sub

Resources