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
相关产品推荐
相关产品推荐

