Создание коллекции как ценность словаря - PullRequest
1 голос
/ 09 июля 2019

Я пытаюсь создать словарь, который содержит коллекцию в качестве значения, потому что у меня есть несколько переменных, которые имеют разное количество свойств.Я надеялся избежать создания класса.

Sub test()

    Set dict = CreateDict()

    Debug.Print "Done!"
End Sub

Private Function CreateDict() As Scripting.Dictionary
    Set dict = New Scripting.Dictionary
    dict.CompareMode = vbTextCompare


    Set wb = CreateObject("excel.Application").Workbooks.Open("S:\filename.xlsx")
    Set wks = wb.Worksheets(1)

    Row = 2
    Do While IsEmpty(wks.Cells(Row, 1)) = False

        key = wks.Cells(Row, 1)
        value = wks.Cells(Row, 3)

        'Debug.Print key, value

        If dict.Exists(key) Then
            dict(key).Add value
        Else
            Dim col As New Collection
            col.Add value
            dict.Add key, col
        End If

        Row = Row + 1
    Loop

    Workbooks("filename.xlsx").Close savechanges:=False

    Dim key1 As Variant
    For Each key1 In dict.Keys
        Debug.Print key1, dict(key1)(1)
    Next key1

    Set CreateDict = dict
End Function

Мои ключи добавлены правильно, но когда я пытаюсь получить доступ к первому значению своей коллекции, он пуст, даже если я печатаю value до того, какне пустой.

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

Заранее спасибо

РЕДАКТИРОВАТЬ:

Для тех, кто интересуется, к сожалению, это не работает, как указано выше, поскольку VBA не создает новую коллекцию каждый раз, когда применяется Dim col As New Collection.Вместо этого все значения просто добавляются в одну коллекцию col.Однако я нашел обходной путь, так как динамические имена переменных в VBA невозможны, согласно этому посту Установить имя переменной с помощью строковой переменной в VBA .

Однако я только что создал функцию, которая создает и возвращает коллекцию.Мой код выглядит следующим образом:

Sub test()

    Set dict = CreateDict()

    Debug.Print "Done!"
End Sub

Private Function CreateDict() As Scripting.Dictionary
    Set dict = New Scripting.Dictionary
    dict.CompareMode = vbTextCompare


    Set wb = CreateObject("excel.Application").Workbooks.Open("S:\filename.xlsx")
    Set wks = wb.Worksheets(1)

    Row = 2
    Do While IsEmpty(wks.Cells(Row, 1)) = False

        key = wks.Cells(Row, 1)
        value = wks.Cells(Row, 3)

        'Debug.Print key, value

        If dict.Exists(key) Then
            dict(key).Add value
        Else
            dict.Add key, CreateCollection()
            dict(key).Add value
        End If

        Row = Row + 1
    Loop

    Workbooks("filename.xlsx").Close savechanges:=False

    Set CreateDict = dict
End Function

Private Function CreateCollection() As Collection
    Dim col As New Collection
    Set CreateCollection = col
End Function

1 Ответ

2 голосов
/ 09 июля 2019

Вместо dict(key1)(0) разверните код следующим образом:

Dim c as Collection
Set c = dict(key1)
Debug.Print c(1)    ' or c.item(1)

Два выпуска:

  • Коллекции индексируются, начиная с 1 & dagger;
  • VBA иногда не может должным образом разрешить цепочечные вызовы методов, если у него нет информации о типе.

& dagger; https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/item-method-visual-basic-for-applications

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