☰
SolidWorks二次开发入门:宏录制+Python自动化脚本实战
2026/9/29 18:56:28 网站建设 项目流程

用SolidWorks做结构设计的人,十有八九都遇到过类似的场景:一个装配体里几十个零件要挨个导出PDF,材料属性要批量统一,工程图文件名要按清单重排。这些活儿本身不需要创造力,但每件都吃时间,来来回回点鼠标能点得人手腕发酸。我最初也以为只能靠加班解决,直到认真把SolidWorks的宏录制功能用了一遍,又尝试用Python通过API去调用SolidWorks底层能力,才发现这条路远比想象中顺畅。这篇文章不打算讲那种门槛极高的插件开发,而是用“录制宏→看懂宏→把宏翻译成Python自动化脚本”的完整路径,把SolidWorks二次开发的实用打法拆给你看。方案对编程基础的要求很低,更适合每天跟模型和工程图打交道的设计工程师,也适合刚接触二次开发、想找个低成本切入点的新手。

1. 方案选型:为什么是“宏录制 + Python 二次开发”这条路

1.1 重复工作量积累到一定程度,就该让软件自己干活

我一直觉得,SolidWorks这种三维设计软件最矛盾的设定就是:它提供了一大批批量操作能力,却把这些能力藏在菜单深处,普通用户根本不知道。比如你要给一个装配体里所有零件添加“材料”属性,手动做就是选中零件、打开自定义属性、逐项填写,重复五十次。而实际上SolidWorks的API里就有现成的CustomPropertyManager接口,几行命令就能完成同样的事。

问题在于,大部分工程师没有系统学过编程,打开VBA编辑器看到满屏的英文方法名就头大。这时候“宏录制”就变成了最友好的入口:你在SolidWorks界面里手动操作一遍,它会自动把你每一个点击、每一步命令翻译成VBA代码。换句话说,你不用先学会写代码,你只要会用SolidWorks,就能让SolidWorks自己把代码写出来。

1.2 三种主流二次开发方案横向对比

在我接触过的方案里,SolidWorks二次开发主流有三条路径:自带VBA宏、C#插件、Python外部脚本。三者各有适用场景,没有绝对优劣。

方案上手难度部署方式适合场景
VBA宏低SolidWorks内置,双击运行单机临时处理、记录即时操作
C#插件高编译成DLL,注册加载需要自定义界面、集成到SolidWorks菜单栏的正式工具
Python脚本中外部运行,通过COM调用批量文件处理、Excel数据联动、和日常办公脚本配合

我最终选了Python路线,核心原因有两个。一是Python脚本不用编译,改完就能跑,调试速度比C#快太多;二是它天然适合处理文件和数据,我经常需要从Excel清单读取零件号、批量替换模型属性、按规则重命名文件,这些用纯VBA做会很憋屈,但用Python再配合openpyxl、pandas这类库,写起来特别顺手。

1.3 宏录制在整条链路里的定位

这里要澄清一个很常见的误解:宏录制不是为了让你以后都用宏,它更像一个“API翻译器”和“学习工具”。你的最终目标是写Python脚本,但Python里调用的API方法名、参数个数、枚举值从哪里来?一种方式是翻SolidWorks官方API帮助,但那个文档量大、组织方式对新手并不友好;另一种就是录一段宏,看SolidWorks官方代码怎么写的,然后照搬到Python里。

所以整个技术路线可以概括为:界面操作→录制宏得到VBA参考代码→理解核心API调用→用Python重写并扩展成自动化脚本。这个方法的好处是,你永远不用担心“不知道调用哪个API”,因为只要你会在SolidWorks界面里操作,就一定能录到对应代码。

2. 准备环境:SolidWorks API 基础与 Python 连接

2.1 SolidWorks API 对象模型速览

在写任何脚本之前,先要弄明白SolidWorks API对象之间的层级关系。很多人第一次看API文档被绕晕,就是因为不懂这个层级。我用最通俗的方式描述一下:SolidWorks整个API像一棵树,树根叫SldWorks.Application,也就是SolidWorks主程序本身;往下是ModelDoc,对应当前打开的零件、装配体或工程图文档;再往下才是你操作的具体对象,比如Feature(特征)、Component2(装配体里的零部件)、SketchManager(草图管理器)、CustomPropertyManager(自定义属性管理器)。

实际开发中九成操作都逃不出这样的套路:先拿到Application,再拿到当前文档,然后通过文档对象获取子对象,最后在子对象上调用方法。比如你想读取模型的所有自定义属性,链路就是“Application→ActiveDoc→Extension→CustomPropertyManager→Get方法”。把这个层级关系记在脑子里,后面看任何宏代码或API文档都会顺畅得多。

2.2 Python侧环境搭建与COM通信核心代码

Python调用SolidWorks用的是Windows底层的COM(组件对象模型)技术,SolidWorks作为COM服务器,把自己的功能暴露给外部程序。Python这一侧只需要安装一个库:pywin32,它提供了win32com.client模块,专门用于COM通信。

安装步骤非常简单:先装好Python(建议3.8以上版本),然后在命令行执行:

pip install pywin32

连接SolidWorks的核心代码只要几行:

import win32com.client # 连接正在运行的SolidWorks实例 try: swApp = win32com.client.GetActiveObject("SldWorks.Application") except Exception: # 如果SolidWorks没开,启动一个新实例 swApp = win32com.client.Dispatch("SldWorks.Application") swApp.Visible = True print("SolidWorks版本:", swApp.RevisionNumber())

提示:GetActiveObject获取的是已经打开的SolidWorks窗口;Dispatch如果检测到没有实例,会尝试启动SolidWorks程序。实际开发时建议先手动打开SolidWorks再运行脚本,避免程序启动阶段出现权限弹窗挡住自动化流程。

2.3 连接前必须确认的3个细节

第一,Python位数必须和SolidWorks位数一致。现在主流SolidWorks都是64位,你就要装64位Python,否则COM调用会报错或者找不到ActiveX控件;第二,开发调试环境尽量使用正版授权且安装完整的SolidWorks,组件库缺失会直接影响API方法调用;第三,Windows的COM机制要求脚本运行环境和SolidWorks登录用户在同一个会话窗口下,远程桌面、计划任务里运行脚本经常连不上,就是栽在这个地方。

这些细节网上很少有教程会专门提,但实际踩坑概率极高。我见过太多人代码写得没问题,卡在环境上,最后还以为是API调用方式错了。所以请务必先跑通这段连接代码,再做后续开发。

3. 宏录制实战:先让软件帮你写一遍代码

3.1 录制宏的操作步骤与录制对象选择

连接好环境后,先别急着写代码,打开SolidWorks开始录宏。菜单路径是“工具→宏→录制”,SolidWorks会提示准备开始记录操作,你继续做想自动化的手动操作,做完后点“工具→宏→停止”保存宏文件,随后它会自动跳出VBA编辑器,把刚才所有操作翻译成代码。

录制时有个技巧:不要一次性录制太多操作,最好一个脚本只录一个功能模块。比如今天想解决批量导出PDF,就新建一个文档,手动执行一次“另存为PDF”,然后停止录制。这样的宏短小精悍,解读起来一目了然。如果你把打开文件、改属性、导出PDF、关闭文件全部录在同一个宏里,生成的代码会杂乱无章,关键API调用反而难找。

3.2 解读一段典型的VBA宏代码

以下是一段录制生成的真实VBA代码,功能是导出当前文档为PDF:

Dim swApp As Object Dim Part As Object Dim longstatus As Long Sub main() Set swApp = Application.SldWorks Set Part = swApp.ActiveDoc Part.SaveAs3 "C:\Temp\输出文件.pdf", 0, 2 End Sub

这段代码只有四行,信息量却很大。第一行拿到SolidWorks主程序对象;第二行拿到当前活动文档;最关键的是第三行SaveAs3,它有三个参数:第一个是文件路径,第二个是保存选项标志,第三个是文件类型枚举值。这里第三个参数为2,表示导出PDF格式,这个值不是我们记住的,而是录制宏帮我们生成的。

很多人在这个阶段容易犯一个错误:拿到宏代码就直接复制进Python用,结果发现报错。原因在于VBA的语法和Python不同,而且录制宏生成的代码里往往夹杂着大量冗余的对象获取过程。所以正确的做法是:把宏代码当作“API参数字典”,重点提取关键方法名和参数值,再按Python语法重新组织。

3.3 宏代码转Python的三条翻译规则

第一条规则,对象获取方式对应转换。VBA里的“Set swApp = Application.SldWorks”在Python里就是“swApp = win32com.client.GetActiveObject("SldWorks.Application")”,后续所有对象都不需要Set关键字,直接等号赋值。

第二条规则,方法调用直接平移,但要注意参数类型。VBA中常见的True/False可以直接写成True/False,字符串参数用双引号包住,整数参数直接写数字。COM接口对大小写不敏感,所以Python里写成SaveAs3、saveas3都可以。

第三条规则,遇到枚举值不要猜,回头录一段宏。SolidWorks有大量枚举类型,比如文件类型、重建选项、选择模式,这些数值在不同版本里可能不同,最稳妥的方式就是录制宏去看官方生成的结果,然后把它定义成Python变量,便于复用和修改。

4. Python 自动化脚本开发:把宏翻译成可用工具

4.1 脚本骨架设计:从连接、处理到释放

写Python自动化脚本不追求代码花哨,但追求结构清晰、能复现。我习惯把脚本分成四段:连接SolidWorks、获取需要处理的文档、执行具体操作、释放COM对象。这样做的好处是,后续想增加新功能,只需要在“执行具体操作”段添加新函数,其余部分基本不用动。

一个基本的脚本骨架长这样:

import win32com.client import os def connect_solidworks(): try: app = win32com.client.GetActiveObject("SldWorks.Application") except Exception: app = win32com.client.Dispatch("SldWorks.Application") app.Visible = True return app def main(): swApp = connect_solidworks() swDoc = swApp.ActiveDoc if swDoc is None: print("当前没有打开的SolidWorks文档") return # 在这里添加你的处理逻辑 print("处理完成") if __name__ == "__main__": main()

注意:脚本运行完建议让SolidWorks继续开着,不要调用Quit方法关闭程序。因为自动化脚本往往需要人工确认结果,某些操作还需要用户在弹窗上点击确认,贸然自动关闭程序很容易丢工作数据。这一点和很多人想的不一样,但实践中非常重要。

4.2 批量导出PDF的完整实现

批量导出PDF是最常用的自动化场景,应用场景包括:整机方案评审前给团队成员发图纸、归档前生成整套PDF文档、客户需要纸质签署版。实现思路很简单:遍历指定文件夹下的所有SolidWorks文档,逐个打开,再逐个另存为PDF,关闭文档。

import win32com.client import os swApp = win32com.client.GetActiveObject("SldWorks.Application") src_folder = r"D:\项目文件\装配体模型" dst_folder = r"D:\项目文件\PDF输出" # swDocPART = 1, swDocASSEMBLY = 2, swDocDRAWING = 3 doc_types = [1, 2, 3] ext_map = {1: "sldprt", 2: "sldasm", 3: "slddrw"} for root, dirs, files in os.walk(src_folder): for f in files: ext = f.rsplit(".", 1)[-1].lower() if ext not in ["sldprt", "sldasm", "slddrw"]: continue file_path = os.path.join(root, f) doc_type = [t for t in doc_types if ext_map[t] == ext][0] open_err = swApp.OpenDoc6( file_path, doc_type, 1, "", 0, 0 ) swDoc = swApp.ActiveDoc if swDoc is None: print(f"打开失败:{file_path}") continue pdf_name = os.path.splitext(f)[0] + ".pdf" pdf_path = os.path.join(dst_folder, pdf_name) # 第三个参数是文件类型枚举,PDF为2,本机录制宏得到 swDoc.SaveAs3(pdf_path, 0, 2) print(f"已导出:{pdf_name}")

这段代码看起来不复杂,但有几个细节值得展开。OpenDoc6的第一个参数是完整路径,第二个是文档类型,第三个是打开模式,1代表正常打开。SaveAs3的第二个参数0代表不弹出选项对话框,默认确定保存。你完全可以把这些参数理解为“录宏时你点了什么按钮、选了哪个选项,代码里就对应什么数值”。

4.3 自定义属性批处理:从组件遍历到写入

自定义属性是SolidWorks里工程图标题栏、BOM表自动关联的数据源头。很多企业图纸规范都要求零件必须有“图号”“材料”“设计者”等属性,但历史模型往往属性不全。手动补全一个装配体的属性很容易消耗一上午,用脚本可以做到几分钟完成。

# 遍历装配体所有组件并修改自定义属性 swDoc = swApp.ActiveDoc if swDoc.GetType() != 2: # 2 代表装配体 print("请先打开装配体文档") else: comps = swDoc.GetComponents(True) # True代表包括所有层级的子装配 for comp in comps: compDoc = comp.GetModelDoc2() if compDoc is None: # 组件没加载时,先通过路径打开 comp_path = comp.GetPathName() if comp_path: compDoc = swApp.OpenDoc6(comp_path, 1, 1, "", 0, 0) if compDoc is None: continue propMgr = compDoc.Extension.CustomPropertyManager("") if propMgr: propMgr.Set("材料", "45钢") propMgr.Set("表面处理", "发黑") print(f"已处理:{comp.Name}")

这里有两个坑。第一个是GetComponents(True)和GetComponents(False)的区别,True会递归返回所有子装配里的所有零部件,False只返回顶层组件。如果你只改直属零件,用False就够了;要全装配体统一处理,必须用True。第二个坑是轻化状态组件,GetModelDoc2()拿不到文档对象,必须先获取路径再手动打开。这个问题在大型装配体上极易出现,排查的时候要第一时间想到。

4.4 与Excel数据表联动:从“跑批”到“数据驱动”

自动化脚本发展一段后,你会不满足于“对所有模型做同样的事”,而是希望“按清单对每个模型做不同的事”。这时候就需要引入Excel数据表。比如我有一个表格,里面是零件名、对应图号、材料、表面处理,脚本读取表格后,按零件名找到模型,再写入对应属性,实现数据驱动式批处理。

这个功能用openpyxl库读取Excel很合适,代码逻辑也不复杂,核心只有三步:读取Excel保存为字典、遍历模型匹配名称、写入属性。我这里不贴完整代码,主要想强调思路:先把SolidWorks的API用熟练,再把Python的数据处理能力接进来,二次开发的威力才会真正显现。很多所谓“高级插件”,本质上就是“CAD API + 数据表 + 流程控制”的组合。

5. 场景实战:一个装配体的属性统一与出图自动化

5.1 案例背景与处理目标

为了让你更直观地理解整套方法怎么落地,分享一个我实际做过的案例。当时有一套电机装配体,包含基座、端盖、轴承座、连接板等三十多个零件,问题是这批模型是从不同设计师手里汇总过来的,属性风格五花八门:有的材料写“45#”,有的写“45钢”,还有的干脆是空白;工程图模板也各有不同,归档时要求所有图纸统一导出PDF并加上日期水印。

人工处理思路是:打开装配体→逐个打开零件→修改属性→保存→关闭→再打开工程图→导出PDF,一个零件走完全流程大概要两三分钟,三十个零件就是将近一个小时,而且这种重复劳动特别容易漏改。用自动化脚本后,整个处理时间压缩到了五分钟左右。

5.2 完整实现流程拆解

我把这个案例拆成了三个脚本阶段。第一阶段处理自定义属性:遍历所有零件,统一材料写法为标准规范;第二阶段处理工程图:遍历所有工程图文档,另存为PDF;第三阶段生成处理报告:扫描模型文件夹,检查是否还有属性为空或未导出PDF的文件,形成清单。

第一阶段的核心代码可以不重复贴,把第四章那段组件遍历循环的逻辑拿过来,修改Set方法里的属性内容即可。第二阶段也类似,只是在文档类型判断时限定为工程图文档(GetType() == 3)。真正需要多写几行的是第三阶段,因为报告要检查“有没有遗漏”,需要读取属性来判断:

# 检查模型的材料属性是否为空 propMgr = doc.Extension.CustomPropertyManager("") mat_value = "" if propMgr: # SolidWorks COM接口的Get方法返回数组,这里是常见的返回值接收方式 result, mat_value = propMgr.Get2("材料", "", "") if not mat_value.strip(): missing_list.append(doc.GetTitle())

这段代码里Get2方法返回两个值,第一个是是否查到的标志,第二个才是实际属性值。这是SolidWorks COM接口的固定习惯,很多刚接触的人会在这里卡住,总觉得自己参数写错了。其实不是,只要搞清楚COM方法在Python里的返回值顺序,这类问题都能迎刃而解。

5.3 运行效果与效率对比

这个脚本我只花了大概一个下午就写完了,本质上就是把宏录制得到的代码翻译成Python,再套上循环逻辑。运行一次可以处理几十个模型,还能根据报告快速定位漏改项。和人工操作相比,节省的时间不是一点半点,更重要的是错误率大幅下降——人反复做同一件事一定会走神,程序不会。

做这个案例给我最大的感受是:二次开发的价值不在于做了多复杂的事,而在于把“确定、重复、没有技术含量”的操作批量解决,把设计工程师的时间还给他真正该花的地方。一条自动化的脚本,本质上是你把工作流程沉淀成了资产,下次遇到类似任务,拿出来改改参数就能复用。

6. 常见问题与排查技巧实录

6.1 COM连接失败与ActiveX控件找不到

这个问题排第一,因为几乎每个人刚接触Python调用SolidWorks时都会遇到。典型报错是“pywintypes.com_error: -2147418113”或“没有注册类”。排除步骤按顺序来:先确认两个软件位数一致,再确认SolidWorks是否正常启动且没有卡在授权弹窗,最后卸载重装SolidWorks时注意看COM组件有没有注册成功。很多从老版本升级上来的电脑,旧组件残留会导致新版本COM调用不稳定,这时候用SolidWorks安装程序自带的修复功能往往比手动折腾更有效。

6.2 对象获取为None时的排查顺序

脚本写完后,最常见的报错是对象为None,比如ActiveDoc是None、GetModelDoc2()是None。我的排查顺序非常固定:先看当前有没有打开文档,再看文档类型是不是自己预期的,再检查是否为轻化状态装配体,最后看是不是路径包含了中文字符导致打开失败。这四步排查完了,九成问题都能解决。

6.3 大装配体处理卡顿与超时

处理大型装配体时,脚本可能跑很久或者界面看起来像死机。原因通常是SolidWorks在自动打开、重建模型时消耗了大量资源。我的经验是:在循环里关闭“重建提示”弹窗、把图形区域显示模式临时切换为“带边线上色”,效果立竿见影。另外,不建议在一个脚本里同时打开太多文档,可以分批处理,每处理完几个文档就调用一下GarbageCollect来回收内存。

6.4 脚本运行范围与环境安全边界

这个放在最后提,是因为它往往是被忽视但最关键的。任何自动化脚本第一次运行,都应该先复制一份样件放到临时文件夹试跑,确认无误后再处理正式数据;处理前记得做好文件备份。另外,SolidWorks正版授权环境下,通过COM调用API属于官方支持的开发方式,不需要修改任何软件文件,也不涉及破解行为,可以放心使用。

在做批量属性修改时,我还会额外加一个“处理前输出待修改清单、处理后输出修改结果”的步骤,这样即使脚本中途出错,也能知道影响了哪些文件,方便恢复。这算是我从一次批量误改的教训里学到的经验——那次一个循环条件写错,导致所有零件都被写入错误的规格代码,如果没有清单备份,恢复起来会非常痛苦。

最后再多说一句个人体会:SolidWorks二次开发的门槛没有想象中那么高,你不需要成为编程高手,只要会用SolidWorks、能录一段宏、再把宏翻译成Python,就已经能解决工作中很大一部分重复操作。真要遇到搞不定的API调用,录一次宏往往比翻半天文档有用得多。把这套方法用熟之后,你会发现自动化脚本不只是省时间,更会改变你对“设计工作边界”的认知——很多看起来非做不可的手工活,其实都有一劳永逸的解法。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询