如何将Excel VBA Dictionary的值设为对象并读取其属性赋值给单元格
解决Excel VBA中Scripting.Dictionary存储自定义Player对象的问题
我帮你梳理下代码里容易踩的坑,然后给出完整的可运行解决方案:
首先你的Player类模块代码是没问题的,不过主代码里有几个关键问题需要修正:
常见的坑点
- 字典未初始化:如果只是
Dim Players As Scripting.Dictionary,没有用Set Players = New Scripting.Dictionary初始化,运行时会报错。 - 重复使用同一个对象实例:VBA里对象是引用类型,如果你循环里一直用同一个
Player变量,字典里所有键都会指向同一个对象,最后所有条目都会变成循环最后一次的Player数据,这是最容易出错的地方! - 代码不完整:你写到
If Not Players.Exists(Cell...就断了,需要明确用什么作为字典的键,以及添加对象到字典的逻辑。
完整修正后的代码
1. 类模块Player(保持你的代码不变)
' Class Module: Player Public Name As String Public Position As String Public WAR As Double
2. 标准模块中的主代码
Sub ProcessAndRetrievePlayers() Dim Player As Player ' 先声明,不要在这里用New Dim Players As Scripting.Dictionary Dim i As Integer Dim targetKey As Variant ' 用于遍历字典的键 ' 初始化字典 Set Players = New Scripting.Dictionary ' 遍历行,将符合条件的Player对象存入字典 For i = 4 To 29 ' 检查第6列(F列)的值大于0 If Cells(i, 6).Value > 0 Then ' 每次循环新建一个Player对象实例,避免引用重复 Set Player = New Player Player.Name = Cells(i, 1).Value ' 第1列(A列)取名字 Player.Position = Cells(i, 3).Value ' 第3列(C列)取位置 Player.WAR = Cells(i, 6).Value ' 第6列(F列)取WAR值 ' 这里用Player.Name作为字典的键(如果名字可能重复,建议用行号或其他唯一标识) If Not Players.Exists(Player.Name) Then Players.Add Key:=Player.Name, Item:=Player End If End If Next i ' 示例:将字典中的Player对象属性写入单元格(比如从第30行开始) i = 30 For Each targetKey In Players.Keys ' 从字典中取出Player对象,注意要用Set关键字 Set Player = Players(targetKey) Cells(i, 1).Value = Player.Name Cells(i, 2).Value = Player.Position Cells(i, 3).Value = Player.WAR i = i + 1 Next targetKey ' 清理对象,释放内存 Set Player = Nothing Set Players = Nothing End Sub
关键说明
- 每次循环必须用
Set Player = New Player创建新的对象实例,这样每个字典条目才会对应独立的Player数据。 - 读取字典中的对象时,一定要用
Set关键字,因为对象是引用类型,不能直接赋值。 - 键的选择要保证唯一性,如果Player.Name可能重复,可以换成
CStr(i)(行号)或者其他不会重复的字段作为键。
内容的提问来源于stack exchange,提问作者obizues
相关产品推荐
相关产品推荐

