How do I identify identical rows in Excel or VBA

twinkle99

Board Regular
Joined
Aug 7, 2005
Messages
240
I have a large data file which has thousands of rows of data.

In Column A is a text string which is the reference number followed by an element. In Column C is the amount of that element and Column D is the date of that element.

I have written a macro which reads through the data file and finds the data which is relevant to the reference number and date both of which are inputted on another sheet (not supplied).

The problem I have is that in Column A, there may be rows which are identical. The macro looks for the text string, however, I dont know how to get the Macro to distinguish between the identical rows - i.e. 1021#INCV.

An example of the VBA for one input is:

With Application.WorksheetFunction
a.Range("C10") = .Index(b.Range("C:C"), .Match(b.Range("C11").Value & "#INCV", s, 0))

C:C - is the result that I want - the amount
C11 - is the reference number
s - is Column A:A where the text string will be

Basically, the macro should find the text string, check whether the date in D:D is before the calculation date (input on another sheet) and if it isnt, it should move to the next string and check the date etc until it finds the one which is before. However, it doesnt work because the macro just finds the first line every time (because the other INCV's are identical)

Is there a way of either writing an excel formula in Column B which will rename the identical rows when they occur i.e. 1021#INCV2, then 1021#INCV3 etc. Note that the elements for each member can appear in any row and are not necessarily in the same place, The dates and amounts will also be different. So members may return more rows than others. If this is possible I can just look for the different text strings in the macro.

Alternatively, is there a way of doing something in the Macro?

I have supplied a very short piece of the data file.

Thanks
vba test.xls
ABCD
11021#INCV160018/09/2005
21021#CA042018/09/2005
31021#ADP62018/09/2005
41021#INCV145220/09/2004
51021#CA041520/09/2004
61021#ADP8820/09/2004
71021#CA049017/09/2003
81021#ADP3317/09/2003
91021#INCV120017/09/2003
101021#INCV116616/08/2002
111021#INCV102015/08/2001
121021#INCV95016/01/2000
131569#INCV156018/09/2005
141569#CA0520018/09/2005
151569#ADP61518/09/2005
161569#INCV150020/09/2004
171569#CA0515020/09/2004
181569#ADP59520/09/2004
191569#CA059017/09/2003
201569#ADP50017/09/2003
211569#INCV140017/09/2003
221569#INCV133312/08/2002
Sheet1
 
why not sort both the sheets on the same criteria so that row to row correspondence in the two sheets is not lost. The sorting may be required to find the mutiple values of the same e.g. INCV. anoher way without sorting I can attempt somesort of filter. . I shall think abut all these thingsmeanwhiel post an extract of the other sheet also.
venkat
 
Upvote 0

Excel Facts

How to show all formulas in Excel?
Press Ctrl+` to show all formulas. Press it again to toggle back to numbers. The grave accent is often under the tilde on US keyboards.
twinkle99,

Don't wish to step on any toes here so, just ignore if you want.

It seems to me that you want to end up with a list that looks like this.
1) Give me the unique values in column A in one column.
2) Give me the amount associated with the first column that meets a date criteria in the fourth column.

If you generate the unique list or have it already and you have the date criteria in the fourth column, you can use a formula to find the corresponding amount like so.

=SUMPRODUCT(--($A$2:$A$27=F2),$C$2:$C$27*1,--($D$2:$D$27=I2))

Assume your original data is in columns A:D and the unique list is in column F and the date you want is in column I and you enter the formula in column H. Copy the formula down.

Dufus
 
Upvote 0
please find sheet 1 which is an extract of the data file for the first 26 rows.

Dufus, thanks for your input
vba test.xls
ABCD
11569INCV156018/09/2005
21569CA0520018/09/2005
31569ADP61518/09/2005
41569INCV150020/09/2004
51569CA0515020/09/2004
61569ADP59520/09/2004
71569INCV140017/09/2003
81569CA059017/09/2003
91569ADP50017/09/2003
101569INCV133312/08/2002
111021INCV160018/09/2005
121021CA042018/09/2005
131021ADP62018/09/2005
141021INCV145220/09/2004
151021CA041520/09/2004
161021ADP8820/09/2004
171021CA049017/09/2003
181021ADP3317/09/2003
191021INCV120017/09/2003
201021INCV116616/08/2002
211021INCV102015/08/2001
221021INCV95016/01/2000
2356233INCV23318/09/2005
2456233ADP5018/09/2005
2556233INCV20017/09/2004
2656233INCV16316/09/2003
Sheet1
 
Upvote 0
Sorry, what I meant to do is like this with your first sample data.
Can you post the desired result out of your last sample?
Code:
Sub test()
Dim a, i As Long, dic As Object, txt As String, myNum As Long
a = Range("a1",Range("a" & Rows.Count).End(xlUp)).Value
Set dic = CreateObject("Scripting.Dictionary")
dic.CompareMode = vbTextCompare
With CreateObject("VBScript.RegExp")
   For i = 1 To UBound(a,1)
      If Not IsEmpty(a(i,1)) Then
         .Pattern = "\d+$"
         txt = .replace(Trim(a(i,1)),"")
         If .test(a(i,1)) Then
            myNum = .execute(Trim(a(i,1)))(0)
         Else
            myNum = 0
         End If
         If Not dic.exists(txt) Then
            dic.add txt, myNum
         Else
            a(i,1) = txt & dic(txt) + 1
            dic(txt) = dic(txt) + 1
         End If
      End If
   Next
End With
Range("a1").Resize(UBound(a,1),UBound(a,2)).Value = a
Set dic = Nothing
End Sub
 
Upvote 0
try this macro. if there is any bug in using this macro in your extended sheet let me know.

first run the macro on the extact you have sent and if it is ok do it for exteded sheet.( naturally you must keep the orginal sheet somewhere safe)

If you want to see my line of thinking do step by step debugging. That means keep the cursor within the macro and succesively hit F8. (while doing this keep the sheet and macro side by side to see what happens in the sheet at sucessive steps)

the macro is
Code:
Sub serialnos()
Dim rng, rng1, c As Range
Dim i, j, k As Integer
Columns("e:e").Delete
i = 0
Set rng = Range([B1], [B1].End(xlDown))
'MsgBox rng.Address
For Each c In rng
i = i + 1
c.End(xlToRight).Offset(0, 1) = i
Next c
Set rng1 = Range([a1], [a1].End(xlDown).End(xlToRight))
'MsgBox rng1.Address
rng1.Sort order1:=xlAscending, key1:=Range("B1"), order2:=xlDescending, _
    key2:=Range("D1"), order3:=xlAscending, key3:=Range("c1"), header:=xlNo
    i = 0
j = ActiveSheet.UsedRange.Rows.Count
'MsgBox j
For k = 1 To j
If Cells(k, "b") = Cells(k + 1, "b") Then
i = i + 1
 Cells(k, "f") = Cells(k, "b") & " " & i
Else
Cells(k, "f") = Cells(k, "b") & " " & i + 1
 i = 0
 End If
 Next
 Set rng1 = Range([a1], [a1].End(xlDown).End(xlToRight))
 rng1.Sort key1:=Range("E1")
Columns("e:e").Delete
MsgBox "the macro is over"
End Sub
 
Upvote 0
Thanks guys,

Jindon, your code works as intended except where the text string ends in a number. see below, I have provided the actual data in Column A, the expected results in column B and the your code results in Column C. As you can see, the elements of CA05 and CA04 have given incorrect results. INCV and ADP are all correct.

Could you please take a look at this.
vba test.xls
ABCD
1ActualDataExpectedResultJindonResult
21569#INCV1569#INCV1569#INCV
31569#CA051569#CA051569#CA05
41569#ADP1569#ADP1569#ADP
51569#INCV1569#INCV11569#INCV1
61569#CA051569#CA0511569#CA6
71569#ADP1569#ADP11569#ADP1
81569#INCV1569#INCV21569#INCV2
91569#CA051569#CA0521569#CA7
101569#ADP1569#ADP21569#ADP2
111569#INCV1569#INCV31569#INCV3
121021#INCV1021#INCV1021#INCV
131021#CA041021#CA041021#CA04
141021#ADP1021#ADP1021#ADP
151021#INCV1021#INCV11021#INCV1
161021#CA041021#CA0411021#CA5
171021#ADP1021#ADP11021#ADP1
181021#CA041021#CA0421021#CA6
191021#ADP1021#ADP21021#ADP2
201021#INCV1021#INCV21021#INCV2
211021#INCV1021#INCV31021#INCV3
221021#INCV1021#INCV41021#INCV4
231021#INCV1021#INCV51021#INCV5
2456233#INCV56233#INCV56233#INCV
2556233#ADP56233#ADP56233#ADP
2656233#INCV56233#INCV156233#INCV1
2756233#INCV56233#INCV256233#INCV2
test


venkat1926, I am testing your code and will get back to you.

Thanks
 
Upvote 0
I see
This should work
Code:
Sub test()
Dim a, i As Long, dic As Object, txt As String, myNum As Long
a = Range("a1",Range("a" & Rows.Count).End(xlUp)).Value
Set dic = CreateObject("Scripting.Dictionary")
dic.CompareMode = vbTextCompare
   For i = 1 To UBound(a,1)
      If Not IsEmpty(a(i,1)) Then
         If Not dic.exists(a(i,1)) Then
            dic.add a(i,1), 0
         Else
            a(i,1) = a(i,1) & dic(a(i,1)) + 1
            dic(a(i,1)) = dic(a(i,1)) + 1
         End If
      End If
   Next
Range("a1").Resize(UBound(a,1)).Value = a
Set dic = Nothing
End Sub

Alternatively following formula should populate the same results

=If(CountIf(A$1:A1,A1)>1,A1&CountIf(A$1:A1,A1)-1,A1)

and copy down
 
Upvote 0
Hi Jindon

The Excel formula works ok.

The Macro is still not quite working (expected and your results below)

However, thats ok I can use the excel formula, will this work for 22,000 rows??

Thanks
vba test.xls
ABCD
1ActualDataExpectedresultJindonResult
21569#INCV1569#INCV1569#INCV
31569#CA051569#CA051569#CA05
41569#ADP1569#ADP1569#ADP
51569#INCV1569#INCV11569#INCV1
61569#CA051569#CA0511569#CA051
71569#ADP1569#ADP11569#ADP1
81569#INCV1569#INCV21569#INCV1
91569#CA051569#CA0521569#CA051
101569#ADP1569#ADP21569#ADP1
111569#INCV1569#INCV31569#INCV1
121021#INCV1021#INCV1021#INCV
131021#CA041021#CA041021#CA04
141021#ADP1021#ADP1021#ADP
151021#INCV1021#INCV11021#INCV1
161021#CA041021#CA0411021#CA041
171021#ADP1021#ADP11021#ADP1
181021#CA041021#CA0421021#CA041
191021#ADP1021#ADP21021#ADP1
201021#INCV1021#INCV21021#INCV1
211021#INCV1021#INCV31021#INCV1
221021#INCV1021#INCV41021#INCV1
231021#INCV1021#INCV51021#INCV1
2456233#INCV56233#INCV56233#INCV
2556233#ADP56233#ADP56233#ADP
2656233#INCV56233#INCV156233#INCV1
2756233#INCV56233#INCV256233#INCV1
Sheet3
 
Upvote 0
Formula should work with any length of the row
How about?
Code:
Sub test()
Dim a, i As Long, dic As Object
a = Range("a1",Range("a" & Rows.Count).End(xlUp)).Value
Set dic = CreateObject("Scripting.Dictionary")
dic.CompareMode = vbTextCompare
   For i = 1 To UBound(a,1)
      If Not IsEmpty(a(i,1)) Then
         If Not dic.exists(a(i,1)) Then
            dic.add a(i,1), 0
         Else
            dic(a(i,1)) = dic(a(i,1)) + 1
            a(i,1) = a(i,1) & dic(a(i,1))
         End If
      End If
   Next
Range("a1").Resize(UBound(a,1)).Value = a
Set dic = Nothing
End Sub
 
Upvote 0

Forum statistics

Threads
1,215,035
Messages
6,122,785
Members
449,095
Latest member
m_smith_solihull

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top