You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VBA循环中为数组赋值对象异常:所有元素指向同一对象

解决VBA循环中数组元素指向同一对象的问题

嘿,这个问题我太熟了——你踩中了VBA里Dim...As New这个经典的“坑”!咱们一步步拆解原因和解决办法:

为什么输出全是3?

VBA里的Dim obj As New Class1和其他语言的声明实例化逻辑不一样,它是延迟实例化的:只有当你第一次引用obj的时候,VBA才会创建一个Class1的实例。在你的循环里,第一次循环触发了实例创建,后续循环再用obj时,VBA不会新建对象,而是直接复用之前那个已经存在的实例。所以你每次循环都是给同一个对象的name属性赋值,最后一次赋值成3,数组里的所有元素自然都指向这个唯一的对象,输出全是3。

为什么去掉Set会报错?

因为Class1是对象类型,不是普通的值类型(比如Integer、String)。在VBA中,给对象类型的变量/数组元素赋值时,必须用Set关键字来建立引用关系;直接赋值是给值类型用的,所以会抛出“Object variable or with block variable not set”的错误。

正确的写法

要在循环里创建独立的对象,必须每次显式实例化新对象,把Dim和实例化操作分开:

Sub foo()
 Dim Arr(1 To 3) As Class1
 Dim i As Integer
 Dim obj As Class1 ' 先声明对象变量,不立即实例化
 For i = 1 To 3
 Set obj = New Class1 ' 每次循环都创建一个全新的Class1实例
 obj.name = i
 Set Arr(i) = obj ' 用Set把新对象的引用存入数组
 Next
 For i = 1 To 3
 Debug.Print Arr(i).name
 Next
End Sub

运行这段代码,就能得到预期的1 2 3输出了。

你也可以把Dim obj As Class1放到循环内部(VBA允许在循环里声明变量),效果是完全一样的:

Sub foo()
 Dim Arr(1 To 3) As Class1
 Dim i As Integer
 For i = 1 To 3
 Dim obj As Class1
 Set obj = New Class1
 obj.name = i
 Set Arr(i) = obj
 Next
 For i = 1 To 3
 Debug.Print Arr(i).name
 Next
End Sub

关键要点总结

  • 避免在VBA中用Dim...As New的写法创建需要多次实例化的对象,它会复用同一个实例。
  • 对象类型的赋值必须使用Set关键字,值类型则不需要。
  • 循环中创建独立对象,一定要每次用Set obj = New 类名显式新建实例。

内容的提问来源于stack exchange,提问作者Christian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 00:17:36