【发布时间】:2023-03-13 05:00:01
【问题描述】:
我一直在努力解决这个问题。我的问题是我有一堆 JSON 数据,我想将其表示为对象。
数组有问题。
我创建了一个类模块,例如 FancyCat,其名称为 public Name as String。
然后我可以设置这个
Dim MyFancyCat as FancyCat
Set MyFancyCat = new FancyCat
FancyCat.Name = JSONData("Name")
我是凭记忆输入的,但我认为它是正确的。 Anyhoo,它工作正常。
问题是一只花哨的猫有几双袜子。袜子的数量是可变的。
在 vba 中,由于某种原因,您不能拥有公共数组。所以这段代码是非法的:
public Socks() as FancySock 'Illegal
查看 SO,我找到了两种解决方案,一种是将其设为私有并使用属性来访问它,另一种是将其声明为 Variant,然后稍后将数组插入其中。
我填充这个数组的方法是检查 JSON 数组以获取 Count,然后到 ReDim 匹配数组,然后填充它。
问题是我的ReDim 语句拒绝工作。
似乎我无法重新调整属性,出现错误。而且我在尝试重新调整公共变体字段时也遇到错误。如果我声明一个本地数组并重新调整它,我的 ReDim 工作正常,所以我可能会这样做,然后将其分配给属性......但我无法直接重新调整它似乎很奇怪。
知道为什么它不起作用吗?
使用上面的 Variant 方法,我的代码是:
ReDim MyFancyCat.Socks(socksLength) As FancySocks
在 FancyCat 类模块中:
public Socks As Variant
我收到Method or Data Member Not Found。
另一种方法的错误不同,但我重新调整了所有代码以尝试第二种方法,所以我不确定它是什么。
编辑:我将更清楚地解释我想要做的事情。我有一些 JSON 数据进来,我想将其存储为对象层次结构。
在 C# 中我会这样做(没有 linq 快捷方式的伪代码):
var myData = ReadJsonData(); // Produces a kind of dictionary
var myFancyCat = new FancyCat();
myFancyCat.Name = myData["Name"];
myFancyCat.Age = myData["Age"];
myFancyCat.Socks = new List<FancySock>();
foreach (var sock in myData["Socks"])
{
myFancyCat.Socks.Add(sock);
}
在 excel 中我想做同样的事情。
所以我为FancyCat 和FancySock 创建了一个类模块,并为FancyCat 提供了姓名、年龄等的公共成员,但是我还想要我的猫拥有的一系列袜子。我想用强类型引用来做到这一点,例如我上面的 c# 代码我可以做到:
myFancyCat.Socks[0].Colour // Intellisense works, shows colour as a property
但是,在 excel 中,您似乎不能公开声明数组。因此,您可以根据 cmets 通过将其声明为 variant 来解决此问题,然后无论如何都粘贴一个数组,但您会失去智能感知。或者,您可以使用 get/let 属性,它有点工作,但更繁琐,因为您似乎无法使用 get/let 实际公开数组,您必须让它获取索引并单独公开元素。
所以此时我想忘记它没有发生的强类型,也许使用集合?
FancySock 类中可能有更多的嵌套数组。我读过没有ByRef 用于数组(至少,不完全 - 我认为你可以得到一个数组 ByRef 但不能设置一个?)。我不确定这是否会在尝试设置它时产生问题。
但最终,我只想以 OO 方式轻松表示我的 JSON 数据,以便在我的 excel 中最终我可以做到
myFancyCat.Name 或 myFancyCat.Socks.Count 或 myFancyCat.Socks(1).Colour 等
在 vba 中将 JSON 反序列化为“对象”似乎比看起来要困难得多。
【问题讨论】:
-
只需使用collection 而不是数组。
-
我考虑过,但我读到集合有点慢并且没有类型。我希望通过使用数组来保留智能感知。另外,我正在将特定大小的数据数组从 json 复制到数组中,因此不需要动态调整大小。然而,考虑到困难,这也许是最好的方法。
-
在您的班级中使用公共子来处理分配和调整大小,而不是使用 Property Let。有一个属性 Get 来检索它。
-
您可以尝试声明
Socks As Variant(不带括号)。然后您可以简单地将数组设置为Socks = myArray... 不需要Dim、ReDim。即使您第二次放置不同维度的数组。 -
VBA 在将变量声明为
Variant时非常灵活。或者简单的Dim Socks。Variant是隐含的。