Пересечение между списками имен с переменной типа Variant () в VBA - PullRequest
0 голосов
/ 10 ноября 2019

У меня базовый уровень с VBA, и мне нужно составить отдельный список имен на основе двух других списков. Каждый из них происходит из именованного диапазона в Excel. С помощью приведенного ниже кода я могу проверить, присутствует ли элемент в списке и является ли он уникальным, по крайней мере, я считаю его правильным. Однако я не могу собрать ту же структуру для нового списка, потому что имя становится одной строкой. Как правильно добавить новую строку в качестве элемента списка?

Dim list1 As Variant
Dim list2 As Variant
Dim list3 As Variant

list1 = [rngDistinctNames]
list2 = [rngAllNames]

Dim name As Variant
For Each name In list1
     result = Application.Match(name, list2, 0)
     If Not IsError(result) Then
        result = Application.Match(name, list3, 0)
        If IsError(result) Then
            list3 = list3 + name
        End If
     End If
Next name

Ответы [ 2 ]

0 голосов
/ 10 ноября 2019

используйте Dictionary объект и переносите его Keys() в массив вариантов:

Dim list1 As Variant
Dim list2 As Variant
Dim list3 As Variant

list1 = [rngDistinctNames]
list2 = [rngAllNames]

Dim name As Variant
With CreateObject("Scripting.Dictionary") 'instantiate and reference a Dictionary object
    For Each name In list1 ' loop through list1 names
         If Not IsError(Application.Match(name, list2, 0)) Then .Item(name) = 1 ' if current list1 name is in list2 then add it to dictionary keys (if already there it'll be simply overwritten by itself
    Next
    list3 = .keys ' take dictionary keys list3 array
End With
0 голосов
/ 10 ноября 2019

Давайте представим следующие данные:

enter image description here

  • A2:A8 = именованный диапазон rngDistinctNames
  • B2:B5 = именованный диапазон rngAllNames

Итак, теперь с помощью следующего кода мы можем проверить каждое значение в первом именованном диапазоне относительно второго:

Sub Test()

Dim list1 As Variant, list2 As Variant
Dim list3 As Object: Set list3 = CreateObject("System.Collections.ArrayList")
Dim i As Long

With Sheet1 'Change according to your sheets CodeName to avoid implicit references

    'Put named ranges into array (memory) for fast looping
    list1 = [rngDistinctNames]
    list2 = [rngAllNames]

    'Put list1 into an ArrayList
    For x = LBound(list1) To UBound(list1)
        list3.Add list1(x, 1)
    Next x

    'Check list2 against arraylist and delete values if need be
    For x = LBound(list2) To UBound(list2)
        list3.Remove list2(x, 1)
    Next x

    'Additional, write remaining values from list3
    .Range("C2").Resize(list3.Count) = Application.Transpose(list3.ToArray)

End With

End Sub

Это приведет к:

enter image description here

ArrayList - это только один из вариантов, которые вы можете попробовать. Кроме того, вы можете посмотреть Collection и Dictionary, но мне нравится использовать ArrayList, потому что вы можете проверять list2 значения и удалять их, даже если их нет в ArrayList, плюс вы можете записать их непосредственно в массив ииспользуйте это где-нибудь на вашем листе с .ToArray.

Согласно вашему комментарию, если вы хотите Array из Variant/Data Type значений, вам просто нужно использовать это же свойство: array = List3.ToArray вернет просточто:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...