I am looking for a way in VBA for Excel that's quicker than arrays for assigning serials that are in a group 1 or 2, into an array match for each value depending on the group value and value of match(a,2).
Criteria / process for matching:
matcharray is initially empty- serial from
serial1list must match serial inserial2list. - value of
match(a,2), which corresponds toserial1list, must be empty (ie vbnullstring) to be considered - otherwise next value ofmatch(a,2)is considered. - if the serial in
serial2list has a corresponding value of1for thegroup, then the position of that group value -posis set inmatch(a,1)corresponding to theserial1list. - if the serial in
serial2list has a corresponding value of2for thegroup, then the position of that group value -posis set inmatch(a,2)corresponding to theserial1list.
I have tried using scripting.dictionary but got stuck (like the linked question).
Sample data and current code that works are below.
Values for serial1 and serial2 are non-unique, and should be taken as having the same amount of values (count)
There is currently over 23000 rows of data and this is set to increase gradually over next few months.
Currently the code below under 8 mins on an i7 processor. The main aim is to reduce this time if possible. A formula might be quicker, but also looking for other solutions such as dictionaries, collections etc.
A database can't be used - client won't permit this.
This is a question following from, but unrelated to: Excel VBA updating dates efficiently with non-unique string values and boolean data
Sample input data:
match1 match2 serial1 serial2 group pos
(blank) (blank) ABC001 ABC002 1 1
(blank) (blank) ABC002 ABC004 2 2
(blank) (blank) ABC003 ABC003 1 3
(blank) (blank) ABC005 ABC006 2 4
(blank) (blank) ABC007 ABC001 2 5
(blank) (blank) ABC004 ABC005 1 6
(blank) (blank) ABC006 ABC007 1 7
Expected output data:
match1 match2 serial1 serial2 group pos
(blank) 5 ABC001 ABC002 1 1
1 (blank) ABC002 ABC004 2 2
3 (blank) ABC003 ABC003 1 3
6 (blank) ABC005 ABC006 2 4
7 (blank) ABC007 ABC001 2 5
(blank) 2 ABC004 ABC005 1 6
(blank) 4 ABC006 ABC007 1 7
Current code:
match() = sheetnm1.Range("match_nr").Value 'Here match(a,1) is first argument and match(a,2) is second argument
serial1() = sheetnm1.Range("serial_nr1").Value
serial2() = sheetnm1.Range("serial_nr2").Value
group() = sheetnm1.Range("group_nr").Value
For a = 1 To UBound(match, 1)
If match(a, 2) = Empty Then
For b = 1 To UBound(serial1, 1)
If serial2(a, 1) = serial1(b, 1) Then
If group(b, 1) = 2 Then
match(a, 2) = b
Else
match(a, 1) = b
End If
End If
Next b
End If
Next a
Attempted dictionary code - wasn't sure how to structure this
For b = 1 To UBound(serial1, 1)
If Not Dict1.Exists(serial1(b, 1)) Then
Dict1.Add serial1(b, 1), b
End If
Next b
For a = 1 To UBound(match, 1)
If Not Dict2.Exists(serial2(a, 1)) Then
Dict2.Add serial2(a, 1), a
End If
Next b