Я ищу способ в VBA для Excel, который быстрее, чем массивы для присвоения серий, которые находятся в group
1 или 2, в массиве match
для каждого значения в зависимости от значения group
и значения match(a,2)
.
Критерии / процесс сопоставления:
match
массив изначально пуст
- серийный номер из списка
serial1
должен совпадать с серийным номером в списке serial2
.
- значение
match(a,2)
, которое соответствует списку serial1
, должно быть пустым (т. Е. Vbnullstring) для рассмотрения, в противном случае рассматривается следующее значение match(a,2)
.
- если в списке
serial2
серийный номер имеет соответствующее значение 1
для group
, то позиция этого группового значения - pos
устанавливается в match(a,1)
, соответствующем списку serial1
.
- если в списке
serial2
серийный номер имеет соответствующее значение 2
для group
, то позиция этого группового значения - pos
устанавливается в match(a,2)
, соответствующем списку serial1
.
Я пытался использовать scripting.dictionary, но застрял (например, связанный вопрос).
Ниже приведены примеры данных и текущий код, который работает.
Значения для serial1
и serial2
не являются уникальными и должны приниматься как имеющие одинаковое количество значений (количество)
В настоящее время существует более 23000 строк данных, и в ближайшие несколько месяцев этот показатель будет постепенно увеличиваться.
В настоящее время код ниже под 8 минут на процессоре i7. Основная цель - сократить это время, если это возможно. Формула может быть быстрее, но также искать другие решения, такие как словари, сборники и т. Д.
База данных не может быть использована - клиент этого не разрешит.
Это вопрос, вытекающий из, но не связанный с: Даты обновления Excel VBA эффективно с неуникальными строковыми значениями и логическими данными
Пример входных данных:
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
Ожидаемые выходные данные:
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
Текущий код:
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
Попытка кода словаря - не был уверен, как структурировать это
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