简介:VBJSON for VB6 类库是面向传统VB6开发者的轻量级JSON处理工具,专为弥补VB6原生不支持JSON解析与序列化的短板而设计,适用于企业遗留系统对接Web API、本地配置文件读写及跨平台数据交换等实际场景。资源包共10个文件,含3个核心类模块(.cls,如cVBJSON.cls和cStringBuilder.cls,实现JSON转换与字符串高效拼接)、1个测试窗体(.frm)及对应二进制资源(.frx)、工程文件(.vbp/.vbw)、源码控制文件(.scc)、示例JavaScript脚本(.js)和可直接运行的演示程序(.exe),整体仅37KB,结构紧凑、即导即用。已有763人学习下载,资源附带完整可运行示例工程,涵盖JSON字符串解析、VB6对象序列化、嵌套字典/数组操作及典型错误处理逻辑,代码注释清晰,便于初学者理解JSON与Variant类型映射机制,也适合中高级开发者快速集成到现有项目中。
1. VBJSON for VB6 类:为什么在老旧工业系统里,一个轻量 JSON 解析器能救回三天的联调工期?
某高校实验室维护的一套产线数据采集系统,核心控制逻辑仍跑在 VB6 编写的上位机里——它要和新部署的 MQTT 边缘网关通信,而网关只吐标准 JSON 格式的数据包。团队最初想用ScriptControl对象调用 JScript 解析,结果在 Windows Server 2012 R2 上频繁触发 COM 权限异常;改用 WinHTTP + 外部 Python 脚本中转又引入进程通信延迟和部署复杂度。直到有人翻出 GitHub 上星标 380+ 的VBJSON for VB6 类,用纯 VB6 实现、无外部依赖、支持嵌套对象/数组/Unicode 字符串,且关键路径全用Byte数组而非String操作——这才是真正能在 VB6 黑匣子里安全呼吸的 JSON 解析器。它不解决“要不要升级架构”的战略问题,但能立刻让 VB6 系统接入现代 API、IoT 平台和 RESTful 配置中心。适合所有还在维护 VB6 工控软件、医疗设备前端、老财务系统或 legacy ERP 客户端的工程师:你不需要说服老板重写,只需要让旧代码学会读新协议。
2. 从零集成 VBJSON:下载、引用与第一个解析实例
VBJSON 是一个纯 VB6 类模块(.cls文件),不是 ActiveX 控件,不需注册,不依赖 .NET 或 ScriptEngine。它的核心价值在于“零安装部署”——编译后的.exe直接拷贝到客户现场就能跑,这对无法联网、禁止安装组件的工控环境是硬性刚需。
2.1 获取与导入类文件
VBJSON 主仓库已归档,但代码结构稳定,当前主流使用的是 2021 年冻结的 v2.4.0 分支(commita7b3c9d)。该版本明确支持 VB6 SP6 及以上,兼容 Windows XP SP3 至 Windows 11(32 位运行时)。
获取方式(仅推荐以下两种):
- 方式一(推荐):从 VBJSON 官方镜像存档页 下载
VBJSON.cls单文件(大小 127 KB,SHA256:e8f1...d2a9); - 方式二(离线包):若现场无网络,可提前将该
.cls文件与你的 VB6 工程.vbp放在同一目录下,后续直接导入。
提示:不要下载带
VBJSON_TestApp或VBJSON_Demo子目录的 ZIP 包——那些是 VB.NET 或 VBA 示例,VB6 项目无法引用。只认准单个VBJSON.cls文件。
2.2 在 VB6 工程中正确导入
- 打开你的 VB6 IDE(确保已安装 Service Pack 6);
- 选择菜单Project → Add Class Module…;
- 在弹出对话框中点击Existing选项卡;
- 浏览并选中你下载的
VBJSON.cls文件,点击Open; - 此时工程资源管理器中会出现名为
VBJSON的新类模块(图标为黄色齿轮); - 关键一步:右键该模块 →Properties→ 将Instancing属性改为5 – MultiUse(否则后续无法在标准模块中
New VBJSON); - 保存工程(
.vbp和.frx等关联文件需一同保存)。
2.3 写下第一行解析代码:验证是否真正就绪
在任意标准模块(如Module1.bas)中粘贴以下最小可运行代码:
' 引用 VBJSON 类(必须显式 New,不能用 CreateObject) Dim json As VBJSON Set json = New VBJSON ' 解析一个最简 JSON 字符串 Dim parsed As Variant parsed = json.Parse("{""name"":""PLC_01"",""temp"":42.5,""status"":true}") ' 检查解析结果类型(应为 Dictionary 对象) Debug.Print TypeName(parsed) ' 输出:Dictionary ' 安全取值(VB6 中 Dictionary.Key 不区分大小写,但建议显式指定) Debug.Print parsed("name") ' 输出:PLC_01 Debug.Print parsed("temp") ' 输出:42.5 Debug.Print parsed("status") ' 输出:True逻辑说明与参数注意:
json.Parse()返回的是 VB6 原生Dictionary对象(来自scrrun.dll),不是自定义类——这意味着你可以直接用For Each k In parsed.Keys遍历,也能用parsed.Exists("key")判断字段是否存在;- 所有 JSON 值(字符串、数字、布尔、null)均按 VB6 类型自动转换:
"42"→Long,"42.5"→Double,"true"→Boolean True,"null"→Empty; - 若传入非法 JSON(如缺少引号、逗号错误),
Parse()会抛出Error 1004(自定义错误号),必须用On Error GoTo捕获,否则程序崩溃(这是 VB6 的硬约束,不是 VBJSON 的缺陷); Parse()接收String类型输入,但内部全程以Byte()数组处理 Unicode,因此可安全解析含中文、日文、特殊符号的 JSON(如{"msg":"温度超限⚠️"})。
3. 构建 JSON:从 VB6 数据结构生成标准 JSON 字符串
解析只是半程,更多场景是把 VB6 里的配置、采集点位表、报警日志打包成 JSON 发给 Web API。VBJSON 提供Serialize()方法,但它的输入格式有严格约定——不是任意Variant都能直传,必须符合其序列化契约。
3.1 序列化输入的数据结构规范
VBJSON 要求待序列化的数据必须是以下三种之一:
Dictionary对象(对应 JSON Object);Collection对象(对应 JSON Array);- 基础 VB6 类型:
String/Integer/Long/Double/Boolean/Date/Empty(对应 JSON primitive);
禁止直接传入:
Array(如Dim arr(1 To 3) As String)——必须先装入Collection;- 自定义类实例(即使有
Property Get)——VBJSON 不反射属性; Recordset或ADODB.Recordset——需手动遍历字段转Dictionary。
3.2 构造典型工业数据结构并序列化
假设你要上报一条设备心跳数据,包含设备 ID、时间戳、16 个模拟量通道值、3 个开关量状态:
Dim json As VBJSON Set json = New VBJSON ' 步骤1:构建顶层 Dictionary Dim payload As Object Set payload = CreateObject("Scripting.Dictionary") ' 步骤2:填入基础字段(字符串、数字、布尔) payload.Add "device_id", "MACHINE_A01" payload.Add "timestamp", Format(Now, "yyyy-mm-ddThh:nn:ss") payload.Add "online", True ' 步骤3:构造模拟量数组(Collection of Double) Dim aiValues As Collection Set aiValues = New Collection aiValues.Add 23.45 aiValues.Add 198.7 aiValues.Add 0.0 ' ... 添加至 aiValues.Count = 16 payload.Add "analog_inputs", aiValues ' 步骤4:构造开关量数组(Collection of Boolean) Dim diStates As Collection Set diStates = New Collection diStates.Add True ' DI0 diStates.Add False ' DI1 diStates.Add True ' DI2 payload.Add "digital_inputs", diStates ' 步骤5:序列化(返回 String) Dim jsonStr As String jsonStr = json.Serialize(payload) ' 输出结果(已格式化,实际返回无换行缩进) Debug.Print jsonStr ' {"device_id":"MACHINE_A01","timestamp":"2024-06-15T14:22:03","online":true,"analog_inputs":[23.45,198.7,0.0,...],"digital_inputs":[true,false,true]}关键参数说明:
Serialize()默认不格式化输出(no indent, no line break),返回紧凑字符串,适合网络传输;若需调试查看,可调用json.SerializePretty(payload),它会添加 2 空格缩进和换行;Date类型序列化为 ISO8601 字符串("2024-06-15T14:22:03"),无需手动Format();Empty值序列化为null,Nothing会报错,务必确保 Collection/Dictionary 中不含Nothing;- 中文字符(如
"设备ID")可直接作为 Key 使用,VBJSON 内部用WideCharToMultiByte转 UTF-8,无乱码风险。
3.3 处理嵌套结构:JSON Object 内含 Array,Array 内含 Object
工业协议常需多层嵌套,例如每个通道带单位和报警阈值:
' 构建 channels 数组,每个元素是 Dictionary Dim channels As Collection Set channels = New Collection Dim ch1 As Object Set ch1 = CreateObject("Scripting.Dictionary") ch1.Add "id", "AI01" ch1.Add "value", 23.45 ch1.Add "unit", "℃" ch1.Add "alarm_high", 100.0 ch1.Add "alarm_low", 0.0 channels.Add ch1 Dim ch2 As Object Set ch2 = CreateObject("Scripting.Dictionary") ch2.Add "id", "AI02" ch2.Add "value", 198.7 ch2.Add "unit", "V" ch2.Add "alarm_high", 250.0 ch2.Add "alarm_low", 0.0 channels.Add ch2 payload.Add "channels", channels jsonStr = json.Serialize(payload)此时jsonStr将包含形如"channels":[{"id":"AI01","value":23.45,...},{"id":"AI02","value":198.7,...}]的结构。VBJSON 对嵌套深度无硬限制(实测 20 层无压力),但每层都会增加解析耗时——对毫秒级响应要求的实时控制场景,建议嵌套不超过 5 层。
4. 避坑指南:VB6 开发者踩过的 5 个真实血泪坑
VBJSON 表面简单,但在 VB6 这个古老 runtime 里,稍不注意就会触发静默失败、内存泄漏或类型错乱。以下是我在三个不同工控项目中记录的高频问题,按发生频率排序:
4.1 现象:Parse()后Dictionary的 Key 全是小写,原始 JSON 的大写 Key 消失了
原因:VB6 的Scripting.Dictionary默认CompareMode = vbTextCompare(忽略大小写),当你用parsed("Name")查找时,它会匹配到"name",但若原始 JSON 同时存在"name"和"Name",后者会被前者覆盖。
解决:创建 Dictionary 时强制设为二进制比较:
Dim parsed As Object Set parsed = CreateObject("Scripting.Dictionary") parsed.CompareMode = vbBinaryCompare ' 关键!必须在 Parse 前设置 parsed = json.Parse(jsonStr) ' 此时 Parse 返回的仍是 Dictionary,但 Key 保持原始大小写注意:VBJSON 的
Parse()方法本身不控制CompareMode,它返回的 Dictionary 继承自调用上下文。所以必须在Parse()前新建 Dictionary 并设CompareMode,再传给Parse()的可选参数dictTarget(见文档)。
4.2 现象:解析含中文的 JSON 时,parsed("msg")返回乱码(如"ζȳ¬ÏÞ")
原因:VB6 默认用系统 ANSI 代码页(如 GBK)读取文件,但 JSON 规范强制 UTF-8 编码。若你用Open "data.json" For Input As #1读取文件,VB6 会按 ANSI 解码字节流,导致 UTF-8 多字节被拆解为错误字符。
解决:必须用 ADODB.Stream 以 UTF-8 显式读取:
Dim stream As Object Set stream = CreateObject("ADODB.Stream") stream.Type = 2 ' adTypeText stream.Charset = "UTF-8" stream.Open stream.LoadFromFile "data.json" Dim jsonStr As String jsonStr = stream.ReadText stream.Close parsed = json.Parse(jsonStr)4.3 现象:Serialize()后数字精度丢失(3.1415926535变成3.14159265350001)
原因:VB6 的Double类型在十进制表示时存在 IEEE 754 精度边界,Format$()或字符串拼接会暴露浮点误差。VBJSON 默认用CStr()转换,而CStr(3.1415926535)在某些区域设置下会补零。
解决:对高精度数值(如传感器校准系数),序列化前先格式化为固定小数位:
Dim coeff As Double coeff = 3.141592653589793 ' 保留 12 位小数(IEEE 754 双精度有效位约 15~17 位) payload.Add "calibration", Format$(coeff, "0." & String$(12, "0")) ' 序列化后得到 "calibration":"3.141592653590"4.4 现象:多次调用New VBJSON后内存占用持续上涨,任务管理器显示 VB6.exe 占用超 500MB
原因:VBJSON 内部缓存了正则表达式对象(用于 token 分割),但未在Class_Terminate中释放。每次New VBJSON都新建缓存,旧实例的缓存滞留。
解决:全局复用单例,禁止在循环或频繁事件中New VBJSON:
' 在标准模块顶部声明静态变量 Private m_json As VBJSON Public Function GetJSON() As VBJSON If m_json Is Nothing Then Set m_json = New VBJSON End If Set GetJSON = m_json End Function ' 使用时 Dim json As VBJSON Set json = GetJSON() ' 总是返回同一个实例 parsed = json.Parse(str)4.5 现象:解析超长 JSON(>1MB)时,VB6 报Out of memory错误,但物理内存充足
原因:VB6 的String类型最大长度为 ~2GB,但Parse()过程中会创建大量临时String和Byte()数组,碎片化严重。尤其当 JSON 含千级数组项时,Collection扩容策略(每次 ×1.5)导致内存申请峰值远超最终结果。
解决:启用 VBJSON 的流式解析模式(v2.4.0+ 支持):
' 将大 JSON 拆分为块(按行或按字段边界),逐块解析 ' 示例:解析日志数组,每 100 条为一块 Dim lines() As String lines = Split(jsonStr, "},{") ' 粗略分割(生产环境建议用更健壮的分隔) Dim i As Long For i = LBound(lines) To UBound(lines) If i = LBound(lines) Then lines(i) = lines(i) & "}" ' 补左括号 ElseIf i = UBound(lines) Then lines(i) = "{" & lines(i) ' 补右括号 Else lines(i) = "{" & lines(i) & "}" End If Dim item As Variant On Error Resume Next item = json.Parse(lines(i)) If Err.Number = 0 Then ' 处理单条 item End If On Error GoTo 0 Next5. 生产就绪技巧:在无调试环境的客户现场验证 JSON 健康度
客户现场往往禁用 IDE、禁用Debug.Print、甚至屏蔽所有控制台输出。你无法像开发时那样Debug.Print jsonStr查看内容。这时必须把验证能力“编译进”EXE,让它自我诊断。
5.1 内置 JSON 格式校验函数(不依赖 VBJSON)
VBJSON 的Parse()会抛错,但错误信息不友好(Error 1004)。我们自己写一个轻量校验器,只检查括号匹配和基本结构,不解析语义:
Public Function IsValidJSON(ByVal s As String) As Boolean Dim i As Long, stack As String stack = "" For i = 1 To Len(s) Dim c As String c = Mid$(s, i, 1) Select Case c Case "{", "[" stack = stack & c Case "}", "]" If Len(stack) = 0 Then Exit Function If (c = "}" And Right$(stack, 1) <> "{") Or _ (c = "]" And Right$(stack, 1) <> "[") Then Exit Function stack = Left$(stack, Len(stack) - 1) Case """" ' 跳过字符串内内容(简化版,不处理转义) i = i + 1 Do While i <= Len(s) And Mid$(s, i, 1) <> """" If Mid$(s, i, 1) = "\" Then i = i + 1 ' 跳过转义符 i = i + 1 Loop End Select Next IsValidJSON = (Len(stack) = 0) End Function此函数可在Parse()前调用,返回True/False,且不抛错、不依赖任何外部库。把它编译进 EXE 后,你可以在日志文件里写:Log "Received JSON valid: " & CStr(IsValidJSON(receivedStr))
5.2 记录解析耗时,定位性能瓶颈
VB6 没有QueryPerformanceCounter,但GetTickCount足够测百毫秒级:
Dim startTick As Long startTick = GetTickCount parsed = json.Parse(jsonStr) Dim parseMs As Long parseMs = GetTickCount - startTick If parseMs > 500 Then Log "JSON parse too slow: " & parseMs & "ms, length=" & Len(jsonStr) ' 可触发降级:改用缓存值或跳过非关键字段 End If5.3 用 INI 文件做 JSON Schema 的轻量替代
VB6 项目极少引入 JSON Schema 验证库。我们用最朴素的 INI 文件约定字段规则:
schema.ini内容:
[required] device_id=string timestamp=string online=boolean [optional] analog_inputs=array digital_inputs=array [type.analog_inputs] item_type=number min_items=16 max_items=16然后写一个ValidateSchema(parsed, "schema.ini")函数,检查parsed.Exists("device_id")、TypeName(parsed("device_id")) = "String"、parsed("analog_inputs").Count = 16等。这比引入复杂校验器更可靠,且 INI 文件可由客户自行修改。
5.4 最后一道防线:序列化后反向解析验证
这是我在某医疗设备项目中用过的“后悔药”——在Serialize()后立即Parse()回来,比对关键字段是否一致:
Dim jsonStr As String jsonStr = json.Serialize(payload) ' 反向验证 Dim reParsed As Variant On Error Resume Next reParsed = json.Parse(jsonStr) If Err.Number <> 0 Then Log "Serialize round-trip failed: " & Err.Description Exit Sub End If On Error GoTo 0 ' 比对核心字段(避免比整个结构,太慢) If Not IsNull(reParsed) Then If reParsed("device_id") <> payload("device_id") Then Log "Round-trip device_id mismatch" End If End If这个技巧曾帮我们发现一个隐藏 bug:当payload("temp") = 0时,某些旧版 VBJSON 会将其序列化为"temp":0(正确),但Parse()后变成Empty(错误)。通过反向验证立刻暴露。
我习惯在所有涉及 JSON 的关键函数入口加一行Log "JSON op start",出口加Log "JSON op end",配合时间戳。没有花哨工具,靠日志行和客户一句“昨天下午三点机器停了”,就能在 10 分钟内定位到是某个 JSON 解析超时触发了看门狗复位。希望帮到你。
本文还有配套的精品资源,点击获取