
简介SolidWorks二次开发全教程系列面向需要利用API与VBA实现设计自动化的机械工程师、三维CAD二次开发初学者系统讲解从录制宏到代码调整的完整路径。这份笔记为单个doc文件压缩包仅276KB内容覆盖录制宏的基本操作、使用Microsoft VBA编辑与调试宏时需要注意的清理事项包括删除未使用的变量声明、删除切换视图代码以及精简SelectByID2与ClearSelection2调用等关键规范同时深入剖析SelectByID2和GetSelectedObject5两个核心API的应用场景配有可直接运行的VBA示例代码帮助掌握通过对象名称与索引选取特征的方法。已有6196人学习适合希望快速上手SolidWorks参数化建模、批量操作与自定义功能开发的读者按教程步骤练习即可少走弯路。全文分节明确、要点突出是一份实用的入门到进阶笔记。1. 什么才是靠谱的 SolidWorks 二次开发入门路径刚接触 SolidWorks 二次开发的人最容易踩的坑就是辛辛苦苦录了一个宏结果完全跑不起来也不知道那句代码干了什么。这个教程系列最大的价值在于它不教你怎么背 API 手册而是带着你从录制宏→看代码→删冗余→改参数→自己写这条路径走下来。你会先学会用录制宏的方式让程序生成骨架再用 VBA 编辑器把它打磨成真正能用的自动化工具。这个方法对新手非常友好因为你不必从零开始记几百个 API对熟手来说本系列关于特征选择、数据修改、装配体插入和配合的代码模板也能直接抄作业。如果你需要用 SolidWorks 做批量建模、自动装配、参数化设计这篇笔记值得照着走一遍。2. 把录制宏变成能用的程序VBA 编辑与三类必须清理的代码2.1 录制宏的正确姿势从录制到自动打开 VBA 编辑器录制宏是二次开发最快的起点但它只解决产生代码这一步不解决代码能用。SolidWorks 会把你的每一步操作原封不动翻译成 API 调用但由于录制过程中包含大量视角变化、临时选择、撤销缓冲等动作生成的代码里充满了无用信息。所以第一件事不是急着看代码而是先规划好录制之前想清楚自己要执行哪些操作操作过程中尽量不做多余动作比如不要缩放视角、不要临时选中其他对象、不要在特征树里乱点。录制完成后SolidWorks 默认不会自动打开宏编辑器。你需要在“工具 → 宏 → 编辑”里手动打开刚录制的.swp文件。如果希望录制完直接进入编辑状态可以在“工具 → 选项 → 系统选项 → 常规”里勾选Automatically edit macro after recording。这个选项是持久的对后续所有录制会话都生效。我一般会开着它因为录完马上看代码才能把操作和代码对应上。另外要注意旧版本的宏文件后缀是.swb当你用 VBA 编辑器打开.swb文件时SolidWorks 会自动把它转换并保存为.swp。你编辑的还是那个宏但文件格式会变成新版。如果团队里有同事还在用旧版 SolidWorks这个转换可能会带来兼容性问题最好先确认对方的版本。2.2 录制代码里必须删掉的三种冗余录制宏打开之后你会看到 VBA 自动生成了一段看着挺完整的代码里面有各种Dim声明、视图变换、选择调用。但这段代码直接跑通常是不行的或者运行结果不对。根据这个教程系列的实践经验有三种代码必须手动清理。第一种是未使用的变量声明。SolidWorks 录制宏时会在最前面自动声明一批对象例如Dim swApp As Object Dim Part As Object Dim boolstatus As Boolean Dim longstatus As Long, longwarnings As Long Dim FeatureData As Object Dim Feature As Object Dim Component As Object这些声明来自录制模板不是根据你的操作生成的。如果你的宏里根本没用上FeatureData和Component留着它们反而容易让人误以为代码里存在隐藏的对象引用。删掉与业务无关的声明只保留你实际用到的对象代码的可读性和稳定性都会提升。录制宏里的swApp基本都会被用到boolstatus如果你后面不检查选择结果也可以删掉。第二种是切换视角的代码。录制过程中你几乎肯定会动鼠标滚轮或者旋转模型SolidWorks 会把这些动作录成视图变换语句典型的样子是Part.ActiveView().RotateAboutCenter 0.0662574, 0.0346621这种代码毫无保留价值它在不同的模型状态下可能让视图乱跳甚至在某些情况下直接报错。录完之后先把所有RotateAboutCenter、ViewZoomTo2这类视图操作全部删掉。第三种是冗余的选择配对调用。录制宏里经常出现SelectByID2和ClearSelection2成对出现的情况。这里的规则是如果SelectByID2出现在ClearSelection2之前它的选择结果会被清空这属于无效操作可以删掉前一个SelectByID2反过来如果SelectByID2出现在ClearSelection2之后说明这个选择是后续操作真正依赖的必须保留。另外紧挨着ClearSelection2前面的SelectByID2调用基本都可以删除因为它马上就被清掉了。 无用先选中再立刻清除等于没选 boolstatus Model.Extension.SelectByID2(拉伸1, BODYFEATURE, 0, 0, 0, False, 0, Nothing, 0) Model.ClearSelection2 True 有用清除之后再重新选中这个选择会被后续代码使用 Model.ClearSelection2 True boolstatus Model.Extension.SelectByID2(拉伸1, BODYFEATURE, 0, 0, 0, False, 0, Nothing, 0)逻辑说明第一组代码里SelectByID2选中了拉伸1但紧接着ClearSelection2就把所有选择清空了这一选一清等于白做。第二组代码顺序反过来清除是为了让选择列表干净后面的SelectByID2才是真正生效的操作。 参数说明ClearSelection2 True中的True表示同时清除所有视图中的选择标记。如果你的宏接下来要做特征修改这个顺序建议保留否则被选中的特征可能因为历史选择残留而定位错乱。2.3 常见问题排查录制宏异常的三个表现现象一录制完成的宏运行后报错 Invalid procedure call or argument。原因是录制宏里包含了视图操作或某些环境相关的调用在非交互式运行比如从按钮触发宏时SolidWorks 的视图状态不同导致 API 参数失效。解决方法是先按前面说的删除所有视角变换代码然后逐行执行VBA 里按 F8定位到具体报错行。现象二宏运行了但模型没有变化。原因是选择配对顺序错误SelectByID2的结果被后面隐藏的ClearSelection2清掉了或者你修改的是特征对象但没调用ModifyDefinition。先检查代码里是否还有被误留的ClearSelection2再确认特征修改后有没有执行重建。现象三宏文件编辑时提示格式不兼容。原因是打开的是旧版.swb文件或者你的 SolidWorks 版本与宏录制时的版本不一致。.swb会自动转换但转换后的代码可能包含旧版 API 名称。把报错行对照 API 帮助在 VBA 编辑器里光标停在函数名上按 F1检查一下即可。3. 选择与识别对象SelectByID2 和 GetSelectedObject5 两个 API 吃掉一半需求3.1 SelectByID2 的完整参数拆解名称、类型、坐标和 Append 行为SelectByID2是 SolidWorks 二次开发里出镜率最高的 API它的作用是通过名字和类型选中模型中的对象。对于有规律命名的特征比如拉伸1、切除-旋转2这是最直接的选择方式。它的完整签名是retval ModelDocExtension.SelectByID2(Name, Type, X, Y, Z, Append, Mark, Callout, SelectOption)实际调用中的一个例子Dim boolstatus As Boolean Set swApp Application.SldWorks Set Model swApp.ActiveDoc 选中名为拉伸1的实体特征BODYFEATURE boolstatus Model.Extension.SelectByID2(拉伸1, BODYFEATURE, 0, 0, 0, False, 0, Nothing, swSelectOptionDefault) If boolstatus True Then Debug.Print 选中成功 Else Debug.Print 选中失败请检查特征名称或类型 End If逻辑说明这段代码先把swApp指向 SolidWorks 应用再通过ActiveDoc拿到当前打开的模型文档然后调用SelectByID2按名字和类型选中特征。最后的swSelectOptionDefault是默认选择选项等价于传 0。注意 Type 参数是必须的且要传大写字符串。 参数说明Name 传入特征名或空字符串Type 是对象类型常见值有BODYFEATURE特征、FACE面、EDGE边X/Y/Z 在按名字选择时通常传 0只有当名字为空、靠坐标选择时才有效Append 参数控制是否追加到当前选择列表True且对象未被选中时追加True且对象已被选中时取消选择False时会先清空选择列表再选中目标。这点非常容易踩坑——在循环里连续选择多个对象时Append 传False会把前一个选择清掉导致只留下最后一个。如果要批量选择面或边Append 要传True。3.2 GetSelectedObject5 与 SelectionMgr从当前选择里反向拿对象SelectByID2解决的是我告诉你名字你帮我选中GetSelectedObject5解决的是我已经在界面上手动选了对象程序怎么知道选的是谁。后者在自动装配、批量改特征这类场景中更常用因为你不需要提前知道特征名。Dim SelMgr As SelectionMgr Dim feature As Feature 获取当前选择管理器 Set SelMgr Model.SelectionManager 取出选择列表中的第一个对象 Set feature SelMgr.GetSelectedObject5(1) If Not feature Is Nothing Then Debug.Print feature.Name Else Debug.Print 当前没有选中任何特征 End If逻辑说明SelectionManager是当前文档的选择管理器它维护着一个选择列表。GetSelectedObject5(1)拿到的是列表中第一个被选中的对象。返回的是通用对象指针可以进一步赋给Feature、Face2、Edge等具体类型。 参数说明AtIndex 从 1 开始上限是GetSelectedObjectCount的返回值。索引越界会返回 NULL。如果你在代码里先用了SelectByID2选中了对象紧接着用GetSelectedObject5(1)就能拿到那个刚选中的对象这就是教程里先选择、再获取的标准配合用法。在Option Explicit声明下SelectByID2的最后一个参数swSelectOptionDefault可以直接用0替换效果等同。3.3 避坑记录选择操作失败时的三类现象与处理现象一运行时提示 Object variable or With block variable not set。原因ActiveDoc返回了 Nothing说明当前 SolidWorks 里没有打开任何文档或者打开的文档未被激活。解决在宏开头加一个文档存在性判断用If Model Is Nothing Then提前退出并提示用户打开模型。现象二SelectByID2返回False但特征明明存在。原因Type 参数写错了。比如特征拉伸1的 Type 是BODYFEATURE而面是FACE两者混用会导致选择失败。另一个常见原因是特征名里有空格或中文你手工输入的名称和实际名称不一致。解决先在 SolidWorks 里右键特征查看准确的名称然后把 Type 和 Name 都用常量字符串传进去。现象三连续执行多次宏之后模型处于退回状态特征无法被选中。原因前一次宏运行没有正确结束比如没有调用Model.Save和Model.EditRebuild导致模型处于编辑中间态。解决宏执行到最后强制调用保存和重建教程中给的修复组合是Model.Save Model.EditRebuild这两个调用顺序最好不要反过来。先保存保证文件状态落地再重建保证特征数据更新。如果你在修改多个特征最后统一保存一次即可不要每个特征都保存否则大型装配体里会明显卡顿。4. 特征数据的读与改从 GetDefinition 到 ModifyDefinition 的完整链路4.1 访问简单直孔特征数据从选中特征到读出直径和深度特征对象本身只是一个外壳真正的参数藏在 FeatureData 里。无论是读取孔直径、修改拉伸深度还是调整阵列数量都要走拿特征对象 → GetDefinition → AccessSelections → 读写数据 → ReleaseSelectionAccess这条链路。下面以简单直孔为例演示完整读取流程Option Explicit Dim swApp As SldWorks.SldWorks Dim Model As ModelDoc2 Dim curfeature As Feature Dim featdata As SimpleHoleFeatureData2 Dim component As Component2 Dim dep As Double Dim dia As Double Dim SelMgr As SelectionMgr Sub getselected() Set swApp Application.SldWorks Set Model swApp.ActiveDoc Set SelMgr Model.SelectionManager Set curfeature SelMgr.GetSelectedObject5(1) If curfeature Is Nothing Then MsgBox 请先选中一个孔特征 Exit Sub End If 拿到特征的定义对象 Set featdata curfeature.GetDefinition 授权访问特征数据 boolstatus featdata.AccessSelections(Model, component) If Not boolstatus Then MsgBox 无法访问特征数据 Exit Sub End If 读取直径和深度 dia featdata.Diameter dep featdata.Depth MsgBox 直径: dia 深度: dep 释放访问权限 featdata.ReleaseSelectionAccess End Sub逻辑说明GetDefinition返回的是一个通用定义对象具体类型取决于特征类型。这里声明为SimpleHoleFeatureData2表示当前选中特征是一个简单直孔。AccessSelections的意思是告诉 SolidWorks 我接下来要读写这个特征的参数这一步会锁定该特征的数据访问权。读完参数后务必调用ReleaseSelectionAccess释放否则后续操作这个特征时会遇到模型冻结或数据访问冲突。 参数说明AccessSelections(Model, component)的第一个参数是当前文档对象第二个参数在装配体环境下是组件上下文在零件环境下可以传 Nothing。教程里 Diameter 代表孔径Depth 代表孔深单位与文档设置的单位制一致通常默认是毫米。这个例子没有做容错处理——如果用户没选中特征或选中的不是孔GetDefinition会返回 Nothing后续代码直接崩溃。实际项目中建议在每个关键步骤后面加上If ... Is Nothing或If Not ... Then的判断。4.2 修改拉伸深度并重建一份可以直接抄的完整宏模板读取之外二次开发更大的价值是批量修改参数。教程里给了一个把基体拉伸长度翻倍的完整示例这个示例比前面的代码多了完整的容错检查和分支处理是理想的模板。我把它整理成可以直接作为宏运行的版本Dim swApp As SldWorks.SldWorks Dim Model As ModelDoc2 Dim Component As Component2 Dim CurFeature As Feature Dim isGood As Boolean Dim FeatData As Object Dim Depth As Double Dim SelMgr As SelectionMgr Sub doubleBE() Set swApp Application.SldWorks Set Model swApp.ActiveDoc 检查文档类型1零件2装配体 If Model.GetType 1 And Model.GetType 2 Then MsgBox 只能在零件或装配体中使用 Exit Sub End If Set SelMgr Model.SelectionManager Set CurFeature SelMgr.GetSelectedObject3(1) If CurFeature Is Nothing Then swApp.SendMsgToUser2 请选择一个拉伸特征, swMbWarning, swMbOk Exit Sub End If 检查特征类型是否是拉伸 If Not CurFeature.GetTypeName Extrusion Then swApp.SendMsgToUser2 请选择拉伸特征, swMbWarning, swMbOk Exit Sub End If Set FeatData CurFeature.GetDefinition isGood FeatData.AccessSelections(Model, Component) If Not isGood Then MsgBox 无法访问特征数据 Exit Sub End If 读取当前深度并翻倍 Depth FeatData.GetDepth(True) FeatData.SetDepth True, Depth * 2 提交修改 isGood CurFeature.ModifyDefinition(FeatData, Model, Component) If Not isGood Then MsgBox 修改失败 FeatData.ReleaseSelectionAccess Exit Sub End If 保存并重建避免退回状态 Model.Save Model.EditRebuild End Sub逻辑说明这段代码覆盖了完整的异常链路——没有文档、没有选中对象、选中的不是拉伸特征都会给出明确提示而不是默默崩溃。核心操作是三次调用GetDefinition获取定义对象、AccessSelections授权访问、ModifyDefinition提交修改。前两步缺一不可ModifyDefinition是真正让修改生效的接口。 参数说明GetTypeName返回的字符串在部分环境里可能不是swTnExtrusion常量。原教程作者遇到过swTnExtrusion识别不了的情况改成直接比较字符串Extrusion才解决问题。建议先用MsgBox CurFeature.GetTypeName打印一下当前拉伸特征的类型名再据此写死字符串判断。GetDepth(True)里的 True 表示返回的是当前配置下的深度值如果模型有多个配置传 False 拿到的可能是其他配置的值这一点在多配置设计时要特别小心。4.3 常见问题排查特征修改不生效、模型崩溃和数据访问冲突现象一ModifyDefinition返回 True但模型里的特征深度没变化。原因AccessSelections之后没有正确设置新值就调用了ModifyDefinition或者设置的值类型不对比如在需要 Double 的 Depth 里传了 Integer。解决在ModifyDefinition前用 Debug.Print 打印一下FeatData.GetDepth(True)确认新值确实写进去了。现象二宏执行后模型进入退回状态特征树出现红色图标。原因特征修改后没有及时更新几何SolidWorks 的求解器没收到重建指令。这是教程作者明确踩过的坑目前最稳妥的解法就是每次修改完都强制调用Model.Save和Model.EditRebuild。注意如果有装配体关联关系重建可能因为配合参考失效而报错这时候把修改范围限制在顶层文档的特征上尽量不要跨装配体改子零件特征。现象三AccessSelections返回 False。原因该特征的数据正在被其他操作占用或者当前模型处于只读状态。解决确保没有打开特征编辑对话框关闭左侧特征树里的退回控制棒再重新运行宏。如果是在装配体里访问子零件的特征必须把第二个参数Component正确传入不能传 Nothing。5. 装配体自动化OpenDoc6、AddComponent4 与 AddMate2 串起自动装配流程5.1 AddComponent4 的隐藏前置条件文件必须先加载进内存在装配体中插入零部件API 是AddComponent4看起来很简单Model.AddComponent4 pth, 配置1, 0, 0, 0但这个函数有一个很容易被忽略的硬性要求要插入的文件必须在调用前已加载到内存中。文档里的原文是 The specified file must be loaded in memory加载方式有两种要么你自己用OpenDoc6打开过这个文件要么当前打开的装配体里已经包含了这个零件。如果你直接拿一个从资源管理器里找来的路径去调用AddComponent4大概率插入失败或者插入的是一个空引用。正确的流程是先打开零件、再插入装配体Dim swApp As SldWorks.SldWorks Dim Model As ModelDoc2 Dim pth As String Dim strpath As String Dim nErrors As Long Dim nWarnings As Long Sub insertpart() Set swApp Application.SldWorks strpath swApp.GetCurrentWorkingDirectory Set Model swApp.ActiveDoc pth strpath 零件1.SLDPRT 先打开零件但设为不可见 openpart pth 再加到装配体中 Model.AddComponent4 pth, 配置1, 0, 0, 0 End Sub Sub openpart(ByVal path As String) Dim newswapp As SldWorks.SldWorks Set newswapp Application.SldWorks Set YSBmodel newswapp.OpenDoc6(path, 1, swOpenDocOptions_Silent, , nErrors, nWarnings) YSBmodel.Visible False End Sub逻辑说明GetCurrentWorkingDirectory返回的是当前 SolidWorks 进程的工作目录如果零件文件不在该目录下pth 要用完整路径。OpenDoc6打开零件时会触发文件加载同时返回一个ModelDoc2对象。设置Visible False是为了避免文档窗口来回切换但不影响它的内存状态。 参数说明OpenDoc6的第二个参数是文档类型1 表示零件swDocPART2 表示装配体swDocASSEMBLY3 表示工程图swDocDRAWING0 表示未知类型swDocNONE。第四个参数是配置名称传空字符串时打开的是最近使用的配置。nErrors和nWarnings必须提前声明它们是输出参数SolidWorks 会把打开过程中的错误码写进去。5.2 装配体中添加配合选择面、遍历面、AddMate2 顺序配合Mate是实现装配体自动化最核心也最麻烦的一步。麻烦在于要添加配合你必须先选中需要配合的面、边或基准面而面的名字往往没有规律比如面1、面2这种系统自动命名的方式你用SelectByID2根本没法稳定选中。教程给出的思路是遍历——在拿到一个组件对象后用GetBody获取实体再用GetFirstFace和GetNextFace遍历它包含的所有面通过判断面的几何类型来决定选哪个面。Private Function selectface(dcom As SldWorks.Component2, tp As Integer) As Boolean Dim swdowelbody As SldWorks.Body2 Dim swface As SldWorks.Face2 Set swdowelbody dcom.GetBody() If swdowelbody Is Nothing Then selectface False Exit Function End If 遍历所有面 Set swface swdowelbody.GetFirstFace() Do While Not swface Is Nothing tp 是面类型标志可以按面积、法向等条件筛选 If swface.GetType tp Then swface.Select4 False, Nothing selectface True Exit Function End If Set swface swface.GetNextFace() Loop selectface False End Function逻辑说明GetBody()返回组件关联的实体GetFirstFace()拿到第一个面GetNextFace()遍历下一个面。每次拿到面对象后可以调用GetType()判断面的类型比如平面、圆柱面、球面也可以读取面的面积来排除小碎面。筛选出目标面之后调用Select4选中它这个函数是面级别的选择方法参数比SelectByID2简单第一个参数False表示不追加选择Nothing表示没有关联的标注。如果你要同时选择两个面做配合第一次调用传False第二次传True。 参数说明tp的值对应swFaceType_e枚举平面一般为 1圆柱面一般为 2。实际使用前可以用MsgBox swface.GetType打印出来确认因为不同版本的 SolidWorks 对这些枚举值的数值定义不完全相同。选出两个面之后才能调用AddMate2添加配合。官方推荐的配合流程是先ClearSelection2清空选择然后选第一个面再选第二个面最后调用AddMate2。如果顺序反了或者中间某个面没选中配合类型和参考会错乱。5.3 避坑记录自动装配过程中常见的四个报错与对策现象一AddComponent4插入失败返回 Nothing。原因最常见的是零件没有被加载进内存。另一个可能是路径包含了中文或空格某些环境下 SolidWorks 对这类路径解析异常。解决先用OpenDoc6打开零件确认返回的ModelDoc2不为 Nothing 再执行插入路径尽量使用英文。现象二AddMate2返回错误码配合没有生成。原因选择面之前没有清空选择列表或者面没有被正确选中。AddMate2要求当前选择列表里恰好包含配合需要的实体对多了会报错少了也会报错。解决每次配合前强制调用Model.ClearSelection2 True配合完成后再次调用为下一个配合做准备。现象三装配体里一直弹出是否保存零件的对话框。原因被插入的零件在OpenDoc6后被修改过但没有保存。解决在宏开头记录原始文档路径结束后统一保存所有改动过的文档或者干脆在OpenDoc6之后立即保存一次避免后续流程触发存储提示。现象四配合方向反了。原因AddMate2的配合模式参数没传对或者选择的两个面的法向方向不一致。解决先手动在 SolidWorks 里试好这两个面的配合方向确认后把对应的配合模式常量同向/反向写死在代码里。不要指望程序自动判断方向几何方向判断的逻辑会消耗大量时间且不一定可靠。6. 三个越早知道越好的调试习惯从打印返回值到强制重建这套教程看下来你会发现一个规律所有失败案例几乎都出在同一个地方——没有检查 API 的返回值或者没有在修改后重建模型。第一个值得养成的习惯是每个关键调用都要接住返回值并打印出来。无论是SelectByID2返回的boolstatus还是AccessSelections返回的isGood你都不要假设它一定成功。最直接的办法是在 VBA 编辑器里用Debug.Print把值输出到立即窗口或者在关键分支里加MsgBox。这样可以在一开始就定位是选择失败、访问失败还是修改失败而不是对着一个整体报错信息瞎猜。第二个习惯是遇到枚举常量报错时不要死磕常量名直接用数值代替。教程作者在swDocPART、swDocASSEMBLY、swTnExtrusion上都碰到过环境不识别的问题他当时的做法是MsgBox Model.GetType把数值打出来然后直接写死成 1 和 2。这看起来不优雅但在实际工程里是最节省时间的办法。你可以在代码开头统一把关键枚举值打印一遍然后注释掉打印语句保留数值常量。这样既保留了可读性又绕开了版本兼容问题。第三个习惯是把Save和EditRebuild当作特征修改的标准收尾动作。很多看起来是玄学的崩溃问题比如模型退回到某个历史状态、特征树报红、宏第二次运行就失败本质上都是因为没有正确收尾。从那以后我每次写完修改类宏都会强制走一遍Model.Save和Model.EditRebuild哪怕当前只是读取参数也顺手加上因为读取场景下无所谓但修改场景下这招能省掉大量排查时间。把这个习惯当作模板的一部分能帮你避开一半以上的运行期故障。希望这些踩过的坑能让你在 SolidWorks 二次开发这条路上少绕几次弯。本文还有配套的精品资源点击获取