0xAA55 发表于 2022-12-9 21:25:16

【VB6】VB6 读写 JSON 字符串

# VB6 JSON

针对 Visual Basic 6.0 设计的 JSON 解析/存储库

## 用法

从帖子附件或者 Gitee 链接里下载 VB6 的 JSON 库。如果无法访问 Gitee,可从帖子附件下载。

https://gitee.com/a5k3rn3l/vb6json

复制 `modJson.bas` 到你的工程里。这一个模块文件包含了全部的功能。

调用 `ParseJSONString()` 函数或者 `ParseJSONString2()` 过程来解析 JSON 字符串,得到一个返回的 `Variant` 类型的变量,里面包含了解析好了的 JSON 数据。

在解析的过程中,这个库使用以下的策略解析 JSON 到 Variant:
* 数值类型被解析为 `Long` 或者 `Currency`,取决于数值的范围,数值比较小就用 `Long`,比较大就用 `Currency`,而如果数值包含小数点或者科学计数法,则使用 `Double` 类型。
* JSON 字符串被解析为 VB 字符串,其中字符串的转义字符 `\` 会按规范进行转义。
* 列表 `[]` 被解析为 VB6 的 `Variant` 数组,每个数组元素都可以是不同的类型。
* 对象 `{}` 被解析为字典(`Scripting.Dictionary`)。**注意** 对象变量需要用 Set 来赋值。

函数 `JSONToString()` 做相反的工作:把解析出来的 `Variant` 转换回 JSON 字符串。

### 注意事项

因为字典在 VB 里是一个对象(`Object`),但别的类型(数值、字符串、数组)则不是,对于 VB6 在语法上,对象存在一个引用的概念,因此针对对象的变量赋值需要使用 `Set` 语法,而对普通变量则不需要用 `Set` 语法,这导致同一条语句在遇到不同的 JSON 内容时会因此报错,比如:

```
Dim Data As Variant

Data = ParseJSONString(" [ 114, 514, ""1919"", 8.10e2 ] ") '不需要 Set
Debug.Print Data (0); Data (1); Data (2); Data (3) '输出 114514 1919 810

Set Data = ParseJSONString("{""Mike"": 514, ""Mary"": 1919810, ""Sam"": 114}") '需要 Set
Debug.Print "Sam: "; Data("Sam") '输出 Sam: 114
Debug.Print "Mike: "; Data("Mike") '输出 Mike: 514
Debug.Print "Mary: "; Data("Mary") '输出 Mary: 1919810
```

在这种情况下建议用 `ParseJSONString2()` 过程,它使用参数来取得返回值,省去了变量赋值需要考虑要不要用 `Set` 语法的问题,例子代码如下:

```
Dim Data As Variant

Call ParseJSONString2(" [ 114, 514, ""1919"", 8.10e2 ] ", Data) '不需要 Set
Debug.Print Data (0); Data (1); Data (2); Data (3) '输出 114514 1919 810

Call ParseJSONString2("{""Mike"": 514, ""Mary"": 1919810, ""Sam"": 114}", Data) '也不需要 Set
Debug.Print "Sam: "; Data("Sam") '输出 Sam: 114
Debug.Print "Mike: "; Data("Mike") '输出 Mike: 514
Debug.Print "Mary: "; Data("Mary") '输出 Mary: 1919810
```

### 如何判断 `Variant` 的具体类型

* 先判断它是不是对象,使用 `IsObject()` 来判断。
* 如果不是对象,此时判断它是不是数组,使用 `IsArray()` 来判断。
* 如果不是数组,则需要判断它是不是字符串,先用 `VarType()` 来获取 `Variant` 的类型号,然后判断类型号是不是 `vbString`。
- 不能直接用 `IsNumeric()` 进行判断,因为它会把字符串格式存储的数值也判定为是数值。
* 如果不是字符串,那它应该是数值了。根据刚才调用的 `VarType()` 的返回值,可以判断它是否为 `Long`、`Currency`、`Double`。类型号分别为 `vbLong`、`vbCurrency`、`vbDouble`。

## 例子代码

请观察以下例子代码来学习如何使用。

### 例子代码 1

读取一个 JSON 列表。

```
Sub Example1()
Dim JsonObj As Variant
ParseJSONString2 " [ 114, 514, ""1919"", 8.10e2 ] ", JsonObj

Debug.Print JsonObj(0); JsonObj(1); JsonObj(2); JsonObj(3)
End Sub
```

输出内容:
```
114514 1919 810
```

### 例子代码 2

读取一个 JSON 对象。

```
Sub Example2()
Dim JsonObj As Variant
ParseJSONString2 "{""Mike"": 123, ""Mary"": 456, ""Sam"": 789}", JsonObj

Debug.Print "Sam: "; JsonObj("Sam")
Debug.Print "Mike: "; JsonObj("Mike")
Debug.Print "Mary: "; JsonObj("Mary")
End Sub
```

输出内容:
```
Sam:789
Mike:123
Mary:456
```

### 例子代码 3

典型例子:在调用 REST API 时,通过 REST API 返回的 JSON 数据判断 API 的执行结果,并弹窗显示。(例子代码无 REST API 调用过程)

```
Sub Example3()
Dim JsonObj As Variant
ParseJSONString2 "{""success"": true, ""data"": {""text"": ""Hello Json!"", ""title"": ""VB6 Json""}}", JsonObj
'''ParseJSONString2 "{""success"": false, ""wording"": ""API failed.""}", JsonObj

If JsonObj("success") = False Then
    MsgBox JsonObj("wording"), vbExclamation, "API failed."
Else
    MsgBox JsonObj("data")("text"), vbInformation, JsonObj("data")("title")
End If
End Sub
```

## 参考资料

看 (https://www.json.org/json-en.html)

看 (https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/vartype-function)

源码下载:

https://github.com/0xAA55/VB6JSON

系统消息 发表于 2022-12-9 22:08:55

第二个例子可以优化一下,改用VB的感叹号语法:
Sub Example2()
Dim JsonObj As Variant
ParseJSONString2 "{""Mike"": 123, ""Mary"": 456, ""Sam"": 789}", JsonObj

Debug.Print "Sam: "; JsonObj!Sam
Debug.Print "Mike: "; JsonObj!Mike
Debug.Print "Mary: "; JsonObj!Mary
End Sub
这样,就更像js里面调用json的用法了。
JS:obj.xxx 是 obj["xxx"] 的简写
VB:obj!xxx 是 obj("xxx") 的简写

Golden Blonde 发表于 2022-12-14 19:26:01

我个人还是喜欢用INI处理简单的配置和数据存储。我对大量的括号、引号有种特别的反感。

W741 发表于 2022-12-15 16:56:41

Golden Blonde 发表于 2022-12-14 19:26
我个人还是喜欢用INI处理简单的配置和数据存储。我对大量的括号、引号有种特别的反感。 ...

INI我也喜欢,但是他没有结构概念,这点不好

xiawan 发表于 2023-1-29 08:47:52


谢谢楼主无私分享
页: [1]
查看完整版本: 【VB6】VB6 读写 JSON 字符串