Значение объекта словаря VBA Excel - PullRequest
0 голосов
/ 30 апреля 2018

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

Я создал объект:

'Class Module: Player
Public Name As String
Public Position As String
Public WAR As Double

А вот и код:

Dim Player as New Player
Dim Players As Scripting.Dictionary


For i = 4 To 29
    If Cells(i, 6) > 0 Then
        Player.Name = Cells(i, 1)
        Player.Position = Cells(i, 3)
        Player.WAR = Cells(i, 6)
        If Not Players.Exists(Cells(i, 3).Value) Then Players.Add Cells(i, 3).Value, Player
    End If
  Next i

  BrewersLineup.Activate
  For i = 4 To 11
    Player = Players(Cells(i, 1))
    Range("B" & i).Value = Player.Name
  Next i

Я получаю ошибку

Объект не поддерживает это свойство или метод

на

Player = Players(Cells(i, 1))

Однако, когда я смотрю в объекте Player, я вижу «Player» со значением, которое имеет значение, которое генерируется для ключа, представленного:

Cells(i, 1)

Например: игроки ("LF") существуют со значениями для атрибутов Name, Position и WAR.

Любая помощь приветствуется.

1 Ответ

0 голосов
/ 01 мая 2018

Вы хотите отдельный экземпляр для каждого Cells(i, 6) > 0, поэтому Set currentPlayer = New Player внутри цикла и условного блока.

Объявление Player As New Player не делает этого. Во-первых, избегайте использования имени класса в качестве идентификатора локальной переменной - если у вашего класса есть предварительно объявленный идентификатор (вероятно, не в любом случае), вы будете затенять , и вы не будете ' Я не хочу этого делать.

Dim foo As New bar создает объект с автоматическим созданием : foo по существу неразрушим, и VBA "удобно" воссоздает его, если вы попытаетесь. Другими словами, каждая итерация этого цикла перезаписывает свойства объекта Player и добавляет ту же ссылку на объект в словарь под новым ключом.

Таким образом, вы получите 25 одинаковых копий одного и того же объекта Вот как вы можете это исправить:

Dim currentPlayer As Player
For i = 4 To 29
    If Cells(i, 6) > 0 Then
        Set currentPlayer = New Player
        currentPlayer.Name = Cells(i, 1)
        currentPlayer.Position = Cells(i, 3)
        currentPlayer.WAR = Cells(i, 6)
        If Not Players.Exists(Cells(i, 3).Value) Then Players.Add Cells(i, 3).Value, currentPlayer
    End If
Next i

Смотрите там идентификаторы - Player это класс ; currentPlayer является объектом .

Поэтому, когда вы делаете Player = Players(Cells(i, 1)), VBA предполагает, что вы знаете, что вы делаете, и старается учесть ваше письмо ... и терпит неудачу.

Синтаксически, он видит это - где Player является экземпляром по умолчанию класса, если он есть:

Player.[DefaultMember] = Players(Cells(i, 1)).[DefaultMember]

Поскольку нет члена по умолчанию, он не знает, что делать, потому что нет способа сделать присваивание значения с этим оператором.

Требуется справочное назначение - и это делается с помощью ключевого слова Set:

For i = 4 To 11
    Set currentPlayer = Players(Cells(i, 1))
    Range("B" & i).Value = currentPlayer.Name
Next i

Другая проблема заключается в том, что у вас есть неявные ActiveSheet ссылки по всему.

BrewersLineup.Activate

Удалить эту строку. У вас уже есть объект Worksheet с именем BrewersLineup. Используй это!

For i = 4 To 11
    Set currentPlayer = Players(BrewersLineup.Cells(i, 1))
    BrewersLineup.Range("B" & i).Value = currentPlayer.Name
Next i

Сделайте то же самое для неквалифицированных ссылок Cells в цикле заполнения словаря, и ваш код начнет нормально работать независимо от того, какой лист в настоящее время активен .., что избавит вас от бесчисленных головных болей в будущее.


Далее вы можете прочитать о участниках по умолчанию и скрытых VB_Attribute вещей в моем блоге Rubberduck News , где вы ' Также я узнаю о Rubberduck , проекте надстройки VBIDE с открытым исходным кодом, которым я управляю, с проверками, которые предупредили бы вас об автоматической переменной объекта, неявных ссылках ActiveSheet, пропущенных Set ключевое слово и, возможно, другие потенциальные проблемы.

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