Excel VBA 438 Ошибка возникла на ПК, но не на Mac - PullRequest
2 голосов
/ 11 июня 2019

У меня есть код VBA, который добавляет пользовательский объект класса Edge в словарь словарей.Я использую этот словарь класса .

Это работает, как и ожидалось, на Mac, но когда я пытаюсь запустить свою команду электронной таблицы на ПК, я получаю ошибку 438: Object doesn't support this property or method.

Строка кода, вызывающая ошибку: edges_dict(user)(Provider) = created_edgeгде edges_dict(user) - словарь, Provider - строка и creaded_edge - край.

Если я вместо этого использую edges_dict(user).Add Provider, created_edge, все работает хорошо, но я хочу возможность перезаписи первого вызова.Дополнительно работает edges_dict(key) = value.Кажется, проблема возникает из моего вложения.

Вот код, в котором я создаю словарь словарей:

Public edges_dict As New Dictionary 'Stores in degrees
Public s_array() As String

Public single_node As Dictionary 'Dictionary keyed by source node holding in degree edges for a certain node

Sub Generate_Matrix()


    'Code to populate s_array() here

    'Populate dictionary with key as node, value as array of inbound edges to be filled
    Set single_node = New Dictionary

        edges_dict.Add s_array(I), single_node 

    Next I

End Sub

1 Ответ

5 голосов
/ 11 июня 2019
edges_dict(user)(Provider) = created_edge

Там много происходит, втиснутый в эту маленькую инструкцию. Если поиск ключа не удается, как вы узнали, какой ключ не удалось? Вы не знаете, и вы не можете знать.

Разделите это, нет смысла пытаться объединить как можно больше функциональных возможностей в одну инструкцию.

Dim providers As Dictionary
Set providers = edges_dict.Item(user)

В качестве бонуса вы получаете IntelliSense и раннее связывание!

creaded_edge a Edge.

Предполагая, что Edge является объектом, ошибка не в том, что код Win32 взрывается с ошибкой 438 - ошибка в том, что код Mac "работает", когда он должен абсолютно жаловаться на отсутствующий элемент по умолчанию на Edge класс.

Ошибка косвенно говорит вам, что вам нужно ключевое слово Set, чтобы назначить ссылку на этот объект:

Set providers(provider) = created_edge

Без ключевого слова Set вы разрешаете принудительно вызывать объект created_edge, что означает, что элемент словаря, связанный с этим ключом, НЕ является объектом в «работающем» коде Mac, но независимо от того, какой тип данных является классом по умолчанию member ... при условии, что имеет элемент по умолчанию (а его нет ... так что неясно, как / почему код Mac не взрывается) - вот ваша "вложенная" инструкция с неявный код в квадратных скобках:

[Let] edges_dict[.Item](user)[.Item](Provider) = created_edge[.DefaultMember]

Причина, по которой .Add работает в обоих случаях, заключается в том, что в этом случае не происходит принудительного приведения: сама ссылка на объект добавляется в качестве значения.

Выдается ошибка 438, поскольку при принудительном приведении объекта, у которого нет к элементу по умолчанию (как это имеет место), предполагается неуспешным.

Добавление Set перед назначением исправило бы это ... но не ведет себя так же, как .Add: .Add выдаст ошибку дубликата ключа , если вы попытаетесь повторно добавьте существующий ключ, при назначении значения ключа, как вы это сделаете, заменит значение, связанное с существующим ключом.

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