VBA Excel 字典对象值

标签 vba excel oop dictionary

我试图将字典的值设置为对象,然后传入键以获取该对象及其值并将其设置为单元格值。

我创建了对象:

'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

我收到错误

Object doesn't support this property or method

Player = Players(Cells(i, 1))

但是,当我查看对象 Player 时,我可以看到一个“Player”,其值具有为以下表示的键生成的值:

Cells(i, 1)

例如:Players("LF") 存在,其中包含 Name、Position 和 WAR 属性的值。

感谢任何帮助。

最佳答案

您希望每个 Cells(i, 6) > 0 都有一个不同实例,因此设置 currentPlayer = New Player 循环内部和条件 block 。

声明玩家为新玩家并不能做到这一点。首先,避免使用类名作为局部变量标识符 - 如果您的类有一个预先声明的 ID(可能无论如何都没有),您将遮蔽它,并且您不想这样做。

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

观察那里的标识符 - PlayercurrentPlayer对象

因此,当您执行 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

删除该行。您已经有一个名为 BrewersLineupWorksheet 对象。使用它!

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

对字典填充循环中的不合格的Cells引用执行相同的操作,您的代码将开始正常工作无论当前处于事件状态的工作表..这将免去您日后无数的麻烦。


您可以进一步阅读default membershidden VB_Attribute stuff在我的 Rubberduck News 博客上,您还可以了解 Rubberduck ,我管理的一个开源 VBIDE 插件项目,具有检查功能,可以警告您有关自动实例化对象变量、隐式 ActiveSheet 引用、缺少 Set 的信息关键字,以及可能的其他潜在问题。

关于VBA Excel 字典对象值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50107905/

相关文章:

c# - 如何将 ViewModel 属性验证与 ViewModel 分离?

vba - PDF 到 Excel 转换将每个 pdf 页面放在不同的工作表中

vba - 调整 Excel 注释大小以适合特定宽度的文本

java - 从父类(super class)中调用随机生成的子类的方法

python - 使用 Pyexcel 处理 Excel 数据

validation - Excel 数据验证引用电子表格位置与静态列表

c++ - 在 C++ 中使用私有(private)类时未在此范围内声明错误

arrays - VBA 数组逆运算

vba - VBA中的自动过滤器,标准为一系列单元格

excel - 如何使用两个单元格值作为行和列坐标来引用另一个单元格?