Excel VBA присваивает значения многомерному массиву, используя сериалы с критериями - PullRequest
1 голос
/ 27 июня 2019

Я ищу способ в VBA для Excel, который быстрее, чем массивы для присвоения серий, которые находятся в group 1 или 2, в массиве match для каждого значения в зависимости от значения group и значения match(a,2).

Критерии / процесс сопоставления:

  1. match массив изначально пуст
  2. серийный номер из списка serial1 должен совпадать с серийным номером в списке serial2.
  3. значение match(a,2), которое соответствует списку serial1, должно быть пустым (т. Е. Vbnullstring) для рассмотрения, в противном случае рассматривается следующее значение match(a,2).
  4. если в списке serial2 серийный номер имеет соответствующее значение 1 для group, то позиция этого группового значения - pos устанавливается в match(a,1), соответствующем списку serial1.
  5. если в списке 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

1 Ответ

0 голосов
/ 27 июня 2019

Являются ли данные строки 3 неверными в ожидаемом примере вывода?

Если это так, вы сможете легко решить эту проблему, используя формулы, а не VBA. Например, если предположить, что строка заголовка существует, а данные начинаются со строки 2, тогда код для столбцов первой строки будет ...

=IF(E2=1,"",MATCH(C2,D:D,0)-1)        =IF(E2=2,"",MATCH(C2,D:D,0)-1)
...