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

VBA存储类实例到数组后所有元素均为最后一个实例故障求助

问题根源

这是VBA类实例化的典型语法坑,核心问题出在循环内实例化类对象的写法错误:
你在循环内使用Dim NewFilm As New film时,VBA不会每次迭代都生成全新的film类实例,只会在第一次用到NewFilm时实例化一次,后续所有循环迭代都是修改同一个实例的属性,你往数组里存储的也始终是指向这同一个实例的引用,自然最后所有数组元素的属性都和最后一次修改的结果一致。

另外你最初版本的代码还存在另一个问题:循环内每次执行ReDim FilmList(i)时没有加Preserve关键字,每次扩容都会清空之前存入数组的所有内容,不过你后续把ReDim移到循环外的修改已经解决了这个问题。

注:给对象变量赋值必须用Set关键字,你之前收到的错误91就是缺Set导致的,这部分写法没有问题,不是故障根源。

修正方案

只要把实例化逻辑拆分,每次循环显式生成新实例即可,正确的代码如下:

Sub main()
    Dim LineList() As String
    Dim FilmList() As film
    Dim i As Integer
    Dim NewFilm As film ' 仅声明对象类型,不在声明时实例化

    LineList = OpenAndImportTxtFile
    ' 提前按有效行数初始化数组,避免循环内反复扩容损耗性能
    ReDim FilmList(0 To UBound(LineList) - 2) 

    For i = 1 To UBound(LineList) - 1
        ' 每次循环显式生成全新的film实例
        Set NewFilm = New film
        NewFilm.initialiser LineList(i)
        Set FilmList(i - 1) = NewFilm
    Next i

    Call GlobalReport(FilmList)
End Sub
附加优化建议

你的GlobalReport过程可以优化参数声明,指定类型后运行更稳定:

Sub GlobalReport(ByRef FilmList() As film)
    Dim i As Integer
    ' 直接用LBound、UBound遍历,不用手动计算索引边界更安全
    For i = LBound(FilmList) To UBound(FilmList)
        MsgBox FilmList(i).titre
    Next i
End Sub

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 06:15:04