SolidWorks自动化:VBA宏中JSON数据处理与API集成实战

📅 2026/8/13 3:22:56
SolidWorks自动化:VBA宏中JSON数据处理与API集成实战
这类工具最值得先看的不是功能列表而是能不能在普通环境里稳定跑起来。我一般会先从最小样例开始确认输入、输出和日志都正常再考虑批量任务和复杂配置。1. 先搞清楚“Sw模块JSON”到底指什么看到“Sw模块JSON”这个标题很多人第一反应是某个具体的软件模块或配置文件。但结合输入的热搜词比如“sw”、“json格式”、“sw安装”、“sw卸载”等它更可能指向一个通用场景在 SolidWorks常缩写为 SW这类三维设计软件中如何生成、解析或应用 JSON 格式的数据。这个需求在实际工程中很常见。比如你可能需要将 SolidWorks 中的零件属性如图号、名称、材料、质量批量导出为 JSON 文件供其他系统如 ERP、PDM读取。根据一个外部的 JSON 配置文件自动在 SolidWorks 中创建或修改一批特征、尺寸或装配关系。开发一个宏或插件通过 JSON 格式与外部 API如物料库、分析服务进行数据交换。所以这篇文章的核心是解决“如何在 SolidWorks 环境中可靠地处理 JSON 数据”的问题。无论你是想实现自动化、数据交换还是二次开发集成下面的步骤和避坑经验都适用。1.1 为什么 JSON 在工程软件中越来越重要JSON 格式轻量、易读、跨平台已经成为不同软件系统间传递结构化数据的首选。对于 SolidWorks 这类桌面端工程软件通过 JSON 与 Web 服务、数据库或脚本交互能极大扩展其自动化能力。例如你可以用一个 JSON 文件定义一整套参数化模型的驱动尺寸或者将一次仿真分析的结果输出为 JSON 供后续程序处理。1.2 常见误区把问题复杂化新手最容易犯的错误是一上来就试图处理最复杂的装配体或最完整的属性集。我建议先从单个零件的一个属性开始。比如先尝试把零件文件的“Description”描述属性读取出来并格式化成 JSON 字符串输出到文本文件。这个最小闭环跑通了再逐步增加属性、遍历组件、处理复杂嵌套结构。2. 环境准备与前置工具选择在 SolidWorks 中处理 JSON通常不依赖额外的插件而是利用其内置的宏功能VBA或通过 .NET API 进行二次开发。关键在于选择一个合适的 JSON 解析/生成库。2.1 开发环境搭建SolidWorks 版本确保你的 SolidWorks 版本支持宏和 API 访问。一般来说2015 及以后版本都比较稳定。注意高版本创建的宏在低版本上可能因对象模型不同而报错。编辑器选择直接在 SolidWorks 内置的 VBA 编辑器里写是最快的。你也可以使用 Visual Studio 进行独立的 .NET 项目开发通过 Add-In 形式集成这更适合大型项目。启用宏在 SolidWorks 设置中确保宏安全性设置允许运行你将要创建的宏。2.2 JSON 库的选择与引入VBA 环境本身不支持 JSON。你有几个选择纯 VBA 解析/生成对于非常简单的 JSON仅一层键值对可以自己用字符串函数拼接和分割。但我不推荐容易出错且难以维护。引用外部 COM 库例如Microsoft Scripting Runtime提供Dictionary对象结合字符串处理可以应对中等复杂度。使用开源 VBA-JSON 库这是最推荐的方式。GitHub 上有成熟的VBA-JSON项目如VBA-JSON v2.3.1它是一个纯 VBA 模块提供了JsonConverter类可以很方便地在 VBA 字典/集合与 JSON 字符串之间转换。如何引入 VBA-JSON 库从可靠来源下载JsonConverter.bas模块文件。在 SolidWorks VBA 编辑器中点击“文件” - “导入文件”选择该.bas文件。在代码中你需要额外添加对Microsoft Scripting Runtime的引用工具 - 引用 - 勾选因为该库依赖Dictionary对象。在模块顶部添加Option Explicit并确保在使用前调用JsonConverter的相关函数。注意不要从不明来源下载宏或模块。始终从项目官方仓库或信誉良好的技术社区获取。2.3 第一个验证步骤测试 JSON 库是否工作在深入 SolidWorks API 之前先在 VBA 编辑器里新建一个标准模块写一段纯粹的 JSON 测试代码。Sub TestJsonConversion() Dim dict As Object Set dict CreateObject(Scripting.Dictionary) dict.Add partNumber, SW-001 dict.Add revision, A dict.Add material, Aluminum 6061 Dim jsonText As String jsonText JsonConverter.ConvertToJson(dict, Whitespace:2) Debug.Print jsonText 预期输出一个格式化的JSON字符串 End Sub运行这段代码。如果在“立即窗口”看到格式化的 JSON 输出如{partNumber: SW-001, revision: A, material: Aluminum 6061}说明 JSON 库引入成功。如果报错“用户定义类型未定义”检查Microsoft Scripting Runtime引用是否勾选如果报错“找不到工程或库”检查JsonConverter模块是否已正确导入。3. 从 SolidWorks 对象中提取数据并生成 JSON核心流程是访问 SolidWorks API 对象 - 获取数据 - 存入字典或集合 - 转换为 JSON 字符串 - 输出到文件或发送出去。3.1 获取零件或装配体的自定义属性这是最常见的需求。以下代码演示如何获取当前活动文档的所有自定义属性。Sub ExportCustomPropertiesToJson() Dim swApp As SldWorks.SldWorks Dim swModel As SldWorks.ModelDoc2 Dim swCustPropMgr As SldWorks.CustomPropertyManager Set swApp Application.SldWorks Set swModel swApp.ActiveDoc If swModel Is Nothing Then MsgBox 请打开一个零件或装配体文档。 Exit Sub End If 获取自定义属性管理器对于配置特定属性需指定配置名 Set swCustPropMgr swModel.Extension.CustomPropertyManager() Dim propNames As Variant Dim propTypes As Variant Dim propValues As Variant Dim resolvedValues As Variant 获取所有属性 Dim vOut As Variant vOut swCustPropMgr.GetAll3(, propNames, propTypes, propValues, resolvedValues) 创建字典存储属性 Dim dictProps As Object Set dictProps CreateObject(Scripting.Dictionary) Dim i As Long If Not IsEmpty(propNames) Then For i 0 To UBound(propNames) 使用解析后的值 (resolvedValues) dictProps.Add CStr(propNames(i)), CStr(resolvedValues(i)) Next i End If 添加一些系统信息 dictProps.Add fileName, swModel.GetTitle() dictProps.Add modelType, IIf(swModel.GetType() swDocPART, Part, IIf(swModel.GetType() swDocASSEMBLY, Assembly, Drawing)) 转换为JSON Dim jsonOutput As String jsonOutput JsonConverter.ConvertToJson(dictProps, Whitespace:2) 输出到文件 Dim filePath As String filePath swModel.GetPathName() If filePath Then filePath ThisDocument.Path 如果文件未保存使用宏所在路径 filePath Left(filePath, InStrRev(filePath, \)) properties.json Dim fso As Object, ts As Object Set fso CreateObject(Scripting.FileSystemObject) Set ts fso.CreateTextFile(filePath, True, True) Unicode 编码 ts.Write jsonOutput ts.Close MsgBox 属性已导出至: filePath, vbInformation End Sub关键点解析GetAll3方法这是获取自定义属性的推荐方法它返回原始值、解析后的值等多种信息。我们通常使用resolvedValues因为它包含了评估后的结果例如如果属性值是“Width”解析值就是实际数值。配置特定属性代码中CustomPropertyManager()的空字符串参数表示获取“此配置”的属性。如果你想获取特定配置或所有配置的属性需要调整参数。这是批量处理时的一个常见坑点。文件路径处理GetPathName()在文件未保存时返回空字符串。生产代码中必须处理这种情况避免写入失败。编码使用CreateTextFile的第三个参数True指定 Unicode (UTF-16) 编码确保中文等字符正确保存。如果下游系统需要 UTF-8可能需要额外的转换步骤。3.2 处理更复杂的数据结构如特征列表、质量属性有时你需要导出嵌套的 JSON。例如一个装配体的 JSON 包含子组件列表每个子组件又有自己的属性。Sub ExportAssemblyStructureToJson() Dim swApp As SldWorks.SldWorks Dim swAssy As SldWorks.AssemblyDoc Dim swRootComp As SldWorks.Component2 Set swApp Application.SldWorks Set swAssy swApp.ActiveDoc If swAssy Is Nothing Or swAssy.GetType() swDocASSEMBLY Then MsgBox 请打开一个装配体文档。 Exit Sub End If Set swRootComp swAssy.ConfigurationManager.ActiveConfiguration.GetRootComponent3(0) Dim dictAssembly As Object Set dictAssembly CreateObject(Scripting.Dictionary) dictAssembly.Add assemblyName, swAssy.GetTitle() Dim componentsList As Object Set componentsList CreateObject(Scripting.Dictionary) 递归遍历组件 (简化版未处理大量组件时的性能优化) TraverseComponents swRootComp, componentsList, 1 dictAssembly.Add components, componentsList Dim jsonOutput As String jsonOutput JsonConverter.ConvertToJson(dictAssembly, Whitespace:2) ... (保存到文件同上) End Sub Sub TraverseComponents(ByVal comp As SldWorks.Component2, ByRef dictParent As Object, ByVal level As Long) If comp Is Nothing Then Exit Sub Dim compDict As Object Set compDict CreateObject(Scripting.Dictionary) compDict.Add name, comp.Name2 compDict.Add quantity, comp.GetQuantity(False) 不考虑子装配体内部数量 获取该组件的自定义属性需要打开组件文档 Dim swRefModel As SldWorks.ModelDoc2 Set swRefModel comp.GetModelDoc2 Dim compProps As Object Set compProps CreateObject(Scripting.Dictionary) If Not swRefModel Is Nothing Then Dim swCustPropMgr As SldWorks.CustomPropertyManager 注意这里获取的是组件引用模型的属性可能需要指定配置 Set swCustPropMgr swRefModel.Extension.CustomPropertyManager(comp.ReferencedConfiguration) ... (获取属性并存入compProps代码类似前例) End If compDict.Add properties, compProps 递归处理子组件 Dim subComps As Variant subComps comp.GetChildren() If Not IsEmpty(subComps) Then Dim subDict As Object Set subDict CreateObject(Scripting.Dictionary) Dim i As Long For i 0 To UBound(subComps) TraverseComponents subComps(i), subDict, level 1 Next i compDict.Add children, subDict End If dictParent.Add comp.Name2 _ CStr(level), compDict 使用组合键避免重名 End Sub复杂数据处理的注意事项性能递归遍历大型装配体可能很慢并可能触发 SolidWorks 重建。对于生产环境需要考虑使用GetChildren和GetParents进行非递归遍历或者使用IComponent2::GetChildren的特定标志来优化。引用与打开comp.GetModelDoc2可能会在后台打开组件文档如果尚未打开这会影响性能。comp.ReferencedConfiguration用于获取组件在当前装配体配置下引用的模型配置这对于获取正确的属性至关重要。循环引用极端情况下装配体结构可能存在循环引用尽管 SolidWorks 通常阻止此情况。稳健的代码应包含对已访问组件的检查防止无限递归。字典键名VBA 字典的键必须唯一。在添加组件到字典时使用名称和层级或唯一标识符如comp.GetID组合作为键可以避免因同名组件导致的数据覆盖。4. 读取 JSON 并驱动 SolidWorks 模型反向操作同样重要读取一个 JSON 文件根据其内容修改 SolidWorks 模型参数、属性或结构。4.1 修改自定义属性假设有一个update_properties.json文件内容如下{ Description: Updated via JSON API, Material: Stainless Steel, CostCenter: CC-2024-05 }对应的 VBA 代码Sub UpdatePropertiesFromJson() Dim swApp As SldWorks.SldWorks Dim swModel As SldWorks.ModelDoc2 Dim swCustPropMgr As SldWorks.CustomPropertyManager Set swApp Application.SldWorks Set swModel swApp.ActiveDoc If swModel Is Nothing Then MsgBox 请打开一个文档。 Exit Sub End If 1. 读取JSON文件 Dim jsonFilePath As String jsonFilePath ThisDocument.Path \update_properties.json 假设JSON文件与宏同目录 Dim fso As Object, ts As Object, jsonText As String Set fso CreateObject(Scripting.FileSystemObject) If Not fso.FileExists(jsonFilePath) Then MsgBox JSON文件未找到: jsonFilePath, vbExclamation Exit Sub End If Set ts fso.OpenTextFile(jsonFilePath, 1, False, -1) 以Unicode读取 jsonText ts.ReadAll ts.Close 2. 解析JSON为字典 Dim dictUpdates As Object Set dictUpdates JsonConverter.ParseJson(jsonText) 3. 获取属性管理器并更新 Set swCustPropMgr swModel.Extension.CustomPropertyManager() Dim key As Variant For Each key In dictUpdates.Keys Dim propName As String Dim propValue As String propName CStr(key) propValue CStr(dictUpdates(key)) 使用Set2方法如果属性存在则更新不存在则创建 swCustPropMgr.Set2 propName, propValue Next key 4. 重建模型以更新所有关联如果需要 swModel.EditRebuild3 MsgBox 属性更新完成。, vbInformation End Sub关键点解析ParseJson函数这是JsonConverter库的核心它将 JSON 字符串解析为 VBA 可以操作的Dictionary或Collection对象。Set2方法这是更新或创建自定义属性的标准方法。第三个参数可以指定属性类型如文本、数字、日期等但通常留空或使用默认值即可。重建模型修改属性后如果模型中有方程式或配置引用这些属性可能需要调用EditRebuild3来更新模型。但要注意不必要的重建会消耗时间。4.2 根据 JSON 修改模型尺寸或特征参数这属于更高级的自动化。你需要知道要修改的尺寸或特征的完整名称Full Name。JSON 文件可以这样设计{ dimensions: [ {name: D1Sketch1Part.SLDPRT, value: 50.0}, {name: D2Boss-Extrude1Part.SLDPRT, value: 20.0} ], suppressFeatures: [Fillet1Part.SLDPRT] }对应的 VBA 代码逻辑Sub ModifyModelFromJson() ... (读取和解析JSON的代码同上假设解析后的对象为dictData) Dim swModel As SldWorks.ModelDoc2 Set swModel swApp.ActiveDoc Dim swDim As SldWorks.Dimension Dim swFeat As SldWorks.Feature 处理尺寸修改 If dictData.Exists(dimensions) Then Dim dimArray As Collection Set dimArray dictData(dimensions) Dim dimItem As Variant For Each dimItem In dimArray Dim dimName As String, dimValue As Double dimName dimItem(name) dimValue CDbl(dimItem(value)) Set swDim swModel.Parameter(dimName) If Not swDim Is Nothing Then swDim.SystemValue dimValue / 1000.0 SolidWorks API中尺寸单位为米需转换 Else Debug.Print 未找到尺寸: dimName End If Next dimItem End If 处理特征压缩状态 If dictData.Exists(suppressFeatures) Then Dim featArray As Collection Set featArray dictData(suppressFeatures) Dim featName As String For Each featName In featArray Set swFeat swModel.FeatureByName(featName) If Not swFeat Is Nothing Then swFeat.Select2 False, 0 swModel.EditSuppress2 压缩特征 Else Debug.Print 未找到特征: featName End If Next featName End If swModel.EditRebuild3 MsgBox 模型修改完成。 End Sub高级修改的难点名称获取尺寸或特征的完整名称不容易直接获得。通常需要通过录制宏操作一次你想自动化的步骤然后从录制的宏代码中提取对应的名称字符串。单位转换SolidWorks API 内部使用米 (m) 作为长度单位。从 JSON 读取的数值通常是毫米需要除以 1000。重建顺序如果修改存在依赖关系如先修改草图尺寸再压缩特征需要合理安排 API 调用的顺序有时可能需要多次重建。错误处理Parameter或FeatureByName可能返回Nothing。生产代码必须包含健壮的错误处理On Error Resume Next或详细检查并记录未能找到的项目。5. 实战避坑与性能优化经验在实际项目中把 JSON 和 SolidWorks 结合起来用会遇到一些典型问题。下面是我踩过坑后总结的经验。5.1 路径、编码与文件访问相对路径与绝对路径VBA 的ThisDocument.Path在宏文档未保存时为空白。对于需要定位资源文件如 JSON 模板、输出目录的宏最好在开头让用户选择一个基准文件夹或者使用固定的绝对路径虽不灵活但稳定。文件被占用如果宏在写入 JSON 文件时崩溃或者另一个进程如文本编辑器锁定了文件会导致写入失败。代码中应包含错误处理尝试多次写入或生成带时间戳的新文件名。中文乱码确保读写文件时使用正确的编码。CreateTextFile的第三个参数设为True使用 Unicode。如果下游系统需要 UTF-8你可能需要在 VBA 中实现一个简单的 UTF-8 转换函数或者使用 ADODB.Stream 对象来读写 UTF-8 文件。5.2 SolidWorks API 的异步性与状态重建与刷新任何通过 API 对模型的修改除非调用EditRebuild3否则可能不会立即在图形界面更新。对于一系列连续操作可以在最后统一重建。但要注意某些后续操作可能依赖于前一步重建后的几何状态。选择与激活很多 API 方法要求特征或组件被选中 (Select2)。在代码中执行选择操作后有时需要插入一个短暂的延迟 (swApp.GetCurrentMacroCommandMask或SleepAPI) 或强制刷新视图 (swModel.GraphicsRedraw2) 以确保 SolidWorks 状态同步。大型装配体模式在处理大型装配体时确保 API 调用不会不必要地加载所有子组件。使用Lightweight状态、GetChildren的特定标志以及有选择地打开文档可以显著提升性能。5.3 JSON 数据结构的规划保持扁平化尽可能使用扁平化的 JSON 结构。深度嵌套的 JSON 虽然能表达复杂关系但在 VBA 中遍历和访问会变得繁琐容易出错。例如可以用“parentId”字段来表示层级关系而不是多层嵌套。数据类型明确JSON 本身不区分整数、浮点数、字符串除非在 schema 中定义。VBA 的ParseJson可能会将数字解析为Double或Long。在关键计算处使用CLng,CDbl,CStr等函数进行显式类型转换避免隐式转换错误。处理空值和缺失键在访问字典键之前始终使用Exists方法检查。对于可能为Null的 JSON 值VBA 可能会将其解析为Empty。使用IsEmpty()或IsNull()函数进行判断。5.4 宏的部署与分发库依赖如果你使用了JsonConverter.bas分发宏时必须将这个模块一并打包通常保存为.swp或.swb文件其中包含所有模块。或者你可以将关键的 JSON 序列化/反序列化代码直接嵌入你的主宏模块以减少依赖。安全性警告用户打开包含宏的 SolidWorks 文件时会收到安全警告。对于团队内部使用可以考虑将宏签名或者指导用户将宏文件位置添加到 SolidWorks 的受信任位置。错误反馈不要只用MsgBox弹出错误。对于长时间运行的批量任务应将错误日志写入一个文本文件包含时间、出错零件名、错误描述等信息方便事后排查。6. 进阶思路外部程序与 REST API 集成对于更复杂的自动化场景可能不适合将所有逻辑都写在 VBA 宏里。可以考虑以下架构SolidWorks 作为客户端VBA 宏负责收集模型数据生成 JSON然后通过WinHttp.WinHttpRequest对象发送 HTTP POST 请求到一个本地或网络服务。外部服务作为处理器使用 PythonFlask/Django、Node.js、C# 等编写一个简单的 Web 服务。这个服务接收 JSON进行复杂的计算、数据库查询、调用其他 AI 服务等然后生成包含新参数或指令的 JSON 响应。SolidWorks 接收并执行VBA 宏接收 HTTP 响应解析 JSON并驱动 SolidWorks 修改模型。这种方式的优势是逻辑分离复杂的业务逻辑放在更强大的后端语言中实现。维护性高更新后端服务无需修改和分发 SolidWorks 宏。可扩展可以轻松连接多个数据源和第三方服务。简单示例VBA 发送 HTTP 请求Sub SendDataToWebService() Dim swModel As SldWorks.ModelDoc2 ... (获取模型数据并存入字典 dictData) Dim jsonToSend As String jsonToSend JsonConverter.ConvertToJson(dictData) Dim httpReq As Object Set httpReq CreateObject(WinHttp.WinHttpRequest.5.1) On Error GoTo ErrorHandler httpReq.Open POST, http://localhost:5000/api/update-model, False httpReq.SetRequestHeader Content-Type, application/json httpReq.Send jsonToSend If httpReq.Status 200 Then Dim responseJson As String responseJson httpReq.ResponseText 解析 responseJson 并更新模型... MsgBox 与服务器交互成功。, vbInformation Else MsgBox 服务器错误: httpReq.Status - httpReq.StatusText, vbCritical End If Exit Sub ErrorHandler: MsgBox 网络请求失败: Err.Description, vbCritical End Sub这个方案要求运行一个本地服务并处理好网络超时、错误重试等问题复杂度更高但为大型自动化流程打开了大门。我个人更建议先把单任务跑稳再考虑批量和接口。这个方案真正落地时最该盯住的不是功能列表而是输入格式、资源占用和失败重试。踩过几次之后我发现很多问题不是工具能力不够而是前置环境和输入材料没有处理干净。先从导出一个零件的属性开始确保 JSON 格式正确、文件能保存、中文不乱码这个基础闭环打通了后续的复杂操作都是在这个基础上的叠加。