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

VBA类模块无法存储数组数据,JSON反序列化为对象问题

报错原因说明

  1. VBA不允许在类模块外部直接对类的公共数组成员、或存储数组的Variant成员执行ReDim操作,ReDim的操作对象只能是当前作用域内直接声明的数组变量,类的公共成员属于类的作用域,外部无权直接重定义它的维度。
  2. 你写的ReDim MyFancyCat.Socks(socksLength) As FancySocks报成员未找到,是因为你试图对Variant类型的公共字段直接指定类型重定义,Variant可以存储数组,但你不能在类外部给它重定义的时候指定强类型。

可行方案(完全满足强类型、智能提示、层级嵌套需求)

方案1:Collection封装(写法最简单,完全匹配你的调用习惯)

这种方式和C#的List用法几乎一致,智能提示完整,支持嵌套结构:

  1. FancySock类模块(你可以按需添加其他属性)
' FancySock 类模块
Public Colour As String
Public Size As Long
' 嵌套属性可以用同样的逻辑实现
  1. FancyCat类模块
' FancyCat 类模块
Public Name As String
Public Age As Long
' 私有存储袜子集合
Private m_Socks As Collection

' 类初始化时自动创建集合
Private Sub Class_Initialize()
    Set m_Socks = New Collection
End Sub

' 对外暴露Socks集合,直接支持Count、按索引取值、Add等方法
Public Property Get Socks() As Collection
    Set Socks = m_Socks
End Property
  1. 调用逻辑(和你C#的伪代码逻辑完全对应)
Sub JsonToObject()
    Dim JSONData As Object ' 假设这是你解析完成的JSON对象
    Dim MyFancyCat As New FancyCat
    
    ' 基础属性赋值
    MyFancyCat.Name = JSONData("Name")
    MyFancyCat.Age = JSONData("Age")
    
    ' 填充袜子集合
    Dim sockItem As Object
    For Each sockItem In JSONData("Socks")
        Dim tmpSock As New FancySock
        tmpSock.Colour = sockItem("Colour")
        tmpSock.Size = sockItem("Size")
        ' 直接Add即可,不需要提前计算长度
        MyFancyCat.Socks.Add tmpSock
    Next sockItem
    
    ' 调用测试,全智能提示
    Debug.Print MyFancyCat.Name
    Debug.Print MyFancyCat.Socks.Count
    Debug.Print MyFancyCat.Socks(1).Colour
End Sub

方案2:私有数组+属性封装(纯强类型无隐式转换)

如果你完全不想用Collection,要纯数组实现可以用这个方案:

' FancyCat 类模块
Public Name As String
Public Age As Long
Private m_Socks() As FancySock

' 按索引取袜子元素,支持FancySock的属性智能提示
Public Property Get Socks(Index As Long) As FancySock
    Set Socks = m_Socks(Index)
End Property

' 按索引赋值袜子元素
Public Property Set Socks(Index As Long, Value As FancySock)
    Set m_Socks(Index) = Value
End Property

' 袜子总数,对应你要的Count属性
Public Property Get SocksCount() As Long
    On Error Resume Next
    SocksCount = UBound(m_Socks) - LBound(m_Socks) + 1
    If Err.Number <> 0 Then SocksCount = 0
End Property

' 初始化数组长度
Public Sub InitSocks(Length As Long)
    ReDim m_Socks(1 To Length) ' 可以根据习惯改成0到Length-1
End Sub

' 新增袜子的方法,对应List的Add
Public Sub AddSock(Sock As FancySock)
    Dim currentCount As Long: currentCount = Me.SocksCount
    If currentCount = 0 Then
        ReDim m_Socks(1 To 1)
    Else
        ReDim Preserve m_Socks(1 To currentCount + 1)
    End If
    Set m_Socks(currentCount + 1) = Sock
End Sub

嵌套数组处理

FancySock内部如果有嵌套数组/集合,完全可以用和上面相同的逻辑实现,VBA的数组/Collection都支持正常的引用传递,不会出现你担心的赋值问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 15:54:02