Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VBA集合和赋值之间的差异_Vba_Parsing - Fatal编程技术网

VBA集合和赋值之间的差异

VBA集合和赋值之间的差异,vba,parsing,Vba,Parsing,我正在阅读VBA-JSON的源代码,它位于: 在将JSON对象(以“{”字符开头)转储到内存中的函数中: Private Function json_ParseObject(json_String As String, ByRef json_Index As Long) As Dictionary Dim json_Key As String Dim json_NextChar As String Set json_ParseObject = New Dictionary json_Skip

我正在阅读VBA-JSON的源代码,它位于:

在将JSON对象(以“{”字符开头)转储到内存中的函数中:

Private Function json_ParseObject(json_String As String, ByRef json_Index As Long) As Dictionary
Dim json_Key As String
Dim json_NextChar As String

Set json_ParseObject = New Dictionary
json_SkipSpaces json_String, json_Index
If VBA.Mid$(json_String, json_Index, 1) <> "{" Then
    Err.Raise 10001, "JSONConverter", json_ParseErrorMessage(json_String, json_Index, "Expecting '{'")
Else
    json_Index = json_Index + 1

    Do
        json_SkipSpaces json_String, json_Index
        If VBA.Mid$(json_String, json_Index, 1) = "}" Then
            json_Index = json_Index + 1
            Exit Function
        ElseIf VBA.Mid$(json_String, json_Index, 1) = "," Then
            json_Index = json_Index + 1
            json_SkipSpaces json_String, json_Index
        End If

        json_Key = json_ParseKey(json_String, json_Index)
        json_NextChar = json_Peek(json_String, json_Index)
        If json_NextChar = "[" Or json_NextChar = "{" Then
            Set json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
        Else
            json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
        End If
    Loop
End If
End Function
以及以下一项:

json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
我在SO中搜索并找到了这篇文章,但这并不能消除混淆:

通过阅读代码,我了解到如果解析器读取一个“{”或“[”,那么它需要使用一个字典来保存“{”和“}”之间的内容,使用一个集合来保存“[”和“]”之间的内容,如果解析器读取的不是这两个内容,那么它只是一个值,可以是布尔值、字符串或整数,等等


我不明白的是Set和Assignment之间的区别。“Set”将复制json_ParseValue返回变量的地址,Assignment只是复制返回变量的另一个副本。这是因为在第一种情况下,还需要修改返回对象,因此必须通过地址传递它吗就像在C++中,我们使用& &

< P>作为链接的问答,在代码中使用“代码> SET < /C>”来分配对象引用。<代码>让关键字可以赋值,但是<代码>让关键字非常过时/冗长。

这就是为什么在属性变量定义中有这些关键字的原因:

Private mSomething As Variant

Public Property Let Something(ByVal value As Variant)
    mSomething = value ' value is a primitive
End Property

Public Property Set Something(ByVal value As Variant)
    Set mSomething = value ' value is an object reference
End Property
到目前为止,一切都很好。这两者之间的区别是:

这是:

这是因为
json\u ParseValue
返回一个
变量
,该变量可以保存任何内容,包括对象引用或简单值,因此它需要在分配引用时使用
Set
关键字,而在分配值时将其省略(或使用
Let
关键字)


如果不查看实现细节并准确查看返回的内容,就无法判断,但也有可能
Let
分配会分配给默认成员,而默认成员调用是隐式的,而且确实令人费解

这与在Excel VBA中指定单元格值时完全相同:

Dim r As Range
Set r = ActiveSheet.Range("A1")
vs

这两条指令看起来不同,只是因为一条指令有一个
Set
关键字,而另一条指令没有,但是真正的区别是对名为
[\u Default]的隐藏属性的隐式成员调用
,它有一个
VB\u UserMemId=0
属性,该属性使该成员成为类的默认成员

这种混淆源于隐式的默认成员调用,它使代码说了些什么,实际上做了些别的事情

(我管理的OSS VBIDE外接程序项目)具有代码检查功能,可在早期绑定代码中查找隐式默认成员分配:

隐式默认成员分配

这些赋值看起来像是将对象变量赋给表面上的值类型,但实际上是隐式地分配对象的默认成员。考虑显式地引用默认成员,以提高可读性。


您所指的三种类型是字典集合数组。基本上,这些类型的任何组合都可以构成JSON结构

有更多时间的人可能会给出更好的答案,但其要点是(在我过于简化的解释中)

  • 将一个值赋给一个变量会复制该值

  • Set
    用于对象,因为它不复制对象,而是创建对对象的引用

通常,当使用Set为变量指定对象引用时,不会为该变量创建对象的副本。相反,会创建对该对象的引用。多个对象变量可以引用同一对象。因为这些变量是对该对象的引用,而不是对象的副本,any对象中的更改将反映在引用它的所有变量中。。但是,在Set语句中使用New关键字时,实际上是在创建对象的实例。()


更多信息:
  • w3resource:✴ ✴

  • MSDN:

  • MSDN:

  • MSDN:

  • 维基百科:

  • 堆栈溢出:


稍后我将展开讨论,但我需要重新开始工作,巧合的是我自己的基于Excel的JSON解析器,因为我从来都不是
VBA-JSON
的粉丝。感谢您的回复!我现在明白了
Set
=
之间的区别。让我困惑的是,作者为什么在需要解析JSON时使用
Set
对象/数组?我将删除它,看看会发生什么。顺便问一句,您不喜欢VBA-JSON的原因是什么?@Nicholas-好了,我告诉过您,有人会很快发布一个比我更深入的答案……这个答案只花了“–14秒”。这很快。@ashleedawg实际上,我看了一下代码,它与隐式默认成员分配无关-简单地说,函数返回一个变量,该变量可能包含一个值或一个对象引用。
Set
是分配引用所必需的,…这就是它的全部内容。仍然是隐式默认值成员赋值很好,我猜=)@MathieuGuindon谢谢!哦,现在我知道了,因为如果解析器需要解析JSON对象/数组,它需要用字典/集合来保存它,字典/集合必须是
。对于其他情况(JSON整型/字符串/布尔型/等等)返回的变量是原始的,不能是代码> SET @ AsHeLeDavg:D我仍然非常想阅读JSON解析器的实现。我很早以前就自学了C++和一些数据结构,但是我每天都使用VBA,所以用VBA深入CS是有意义的。(然而,无法访问C/C++指针确实让我感到烦恼)。
Set json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
Dim r As Range
Set r = ActiveSheet.Range("A1")
Dim r As Double
r = ActiveSheet.Range("A1") 'implicit call to ActiveSheet.Range("A1").[_Default]