拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SolidWorks二次开发入门:从录制宏到装配自动化的VBA实践

SolidWorks二次开发入门:从录制宏到装配自动化的VBA实践

简介:一份面向SolidWorks二次开发初学者的系列教程,内容围绕宏录制、VBA编辑、API调用三大核心展开,适合具备基础建模能力、希望将重复设计流程自动化的工程师阅读学习。教程以doc文档形式整理,共1个文件,压缩包仅276KB,篇幅紧凑但覆盖完整。已有六千余人学习下载,实用价值得到验证。文档从录制第一个宏讲起,逐步演示如何回放和修改录制代码:清理自动生成但未使用的变量声明,删除旋转视角等无关注视图语句,甄别再选择与清除操作,使代码简洁可靠。随后进入VBA编辑与调试环节,介绍如何打开宏、调出最近九个编辑记录、以及旧版文件自动转换的处理方式,让新手避开常见陷阱。进阶部分则重点剖析特征选取与对象获取的两个接口,结合示例程序展示按名称选取和按索引获取两种操作方法,帮助读者理解程序如何与模型交互,并最终建立起二次开发的完整思维框架,为后续编写插件或集成设计工具打下基础。

1. 先说清这套 SolidWorks 二次开发教程:从录宏到装配自动化的一条完整链路

接触 SolidWorks 二次开发的人,十有八九是从录制宏开始的——打开宏录制,在模型上点几下,停止,满怀期待地运行。结果要么直接报错,要么视图一顿乱转,动作全不对。这套教程的起点恰好选在这里:它不教你背 API 文档,而是顺着“录一个宏 → 清理代码 → 学会选择对象 → 读取特征数据 → 修改特征 → 在装配体里插入零件并添加配合”这条链路走一遍,每一步都给了能跑的 VBA 代码。它解决的核心问题很具体:当你需要把重复设计动作变成自动化脚本时,怎么从零写出一个不翻车的宏。适合做标准件库、批量改模型、装配体自动化的工程师。

2. 录制宏不等于能跑:VBA 里先删掉这三类“垃圾代码”

2.1 录制宏之前的两个开关:自动打开 VBA 与宏格式转换

正式开始写代码之前,先把 SolidWorks 的宏环境设置好。点击菜单栏的 Tools → Options → System Options,在 General 选项卡里找到Automatically edit macro after recording。这个选项勾上之后,每次录完宏,SolidWorks 会自动打开 VBA 编辑器,让你立刻看到刚才的操作生成了什么代码。如果你打算长期做二次开发,这个开关一定要开,否则录完还要手动去 Tools → Macro → Edit 里找到那个文件,多一步操作,而且容易找不到文件位置。

宏文件有两种后缀:.swp和.swb。.swb是旧版 SolidWorks 的宏格式,当你用编辑功能打开一个.swb文件时,SolidWorks 会自动把它转换成.swp并保存。如果你从同事或者旧项目里拿到一批.swb的宏,不必手动转格式,直接编辑一次,它自己就变成.swp了。.swp本质上是 OLE 复合文档,里面承载的就是 VBA 工程代码,所以编辑宏的入口始终是 Tools → Macro → Edit。

2.2 录出来的代码里,哪些是必须删掉的

录完一个宏,打开 VBA 编辑器,你会看到 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

swApp和Part一般会用到,但FeatureData、Component、longstatus、longwarnings这些通常用不上。原则是:声明了的变量如果还没用到,先删掉,等后面真要用了再补回来。这样代码一开始就是干净的,不会出现“这个变量到底是干嘛的”这种困惑。

第二类是切换视图的代码。录制时只要旋转过模型,就会生成像Part.ActiveView().RotateAboutCenter 0.0662574, 0.0346621这样的句子。这类代码毫无业务意义,纯属视角残留,直接删。我一般用查找功能搜RotateAboutCenter,搜到就删,一个不留。

第三类是成对出现的选择/取消选择调用。录制时你每点一次对象,VBA 里就会多一组SelectByID2和ClearSelection2,经常是成对连续出现。清理时要遵循三条规则:

  • 紧跟在ClearSelection2之前的SelectByID2,删除;
  • 紧跟在ClearSelection2之后的SelectByID2,保留;
  • 紧跟在SelectByID2之前的ClearSelection2,删除。

这组规则看起来绕,实际逻辑不复杂:录制产生的选择痕迹大多是为了完成“点选”这个动作本身,而不是你的业务意图。真正有意义的保留那一次SelectByID2,其余成对冗余的取消选择、重新选择全部删掉。如果后面还要继续选中别的对象,再在合适的位置保留一次ClearSelection2清空状态。

2.3 编辑宏的入口:从模板宏切到真实场景

清理完代码,宏的骨架才勉强能跑。编辑宏的入口有两个:一是 Macro 工具栏上的 Edit Macro 按钮,二是 Tools → Macro → Edit 菜单项。编辑对话框里选择.swp文件后点击 Open,就进入 VBA 编辑器。如果你近期编辑过某个宏,Tools → Macro 菜单下面会直接列出最近 9 个宏文件,点一下就能打开,省去在文件对话框里翻路径的时间。

这里有一个真实场景要注意:VBA 编辑器打开后,你会看到Sub main()这个入口函数。SolidWorks 录制宏默认生成的入口就是main,你写的代码都放在这个 Sub 里面。这个约定在整套教程里一直延续,后面出现的所有示例代码,入口都是main或者自定义的 Sub 名称,运行方式一致。

3. 选中对象才能干活:SelectByID2 与 GetSelectedObject5 的配合

3.1 SelectByID2:七个参数里真正要紧的是前六个

在 SolidWorks 二次开发里,90% 的操作第一步都是“选中一个对象”。官方提供了两个最常用的 API:SelectByID2负责按名称选中对象,GetSelectedObject5负责把选中的对象从选择集里取出来。这两个函数一个负责“指”,一个负责“拿”,配合使用基本能覆盖特征选择、面选择、装配体组件选择这些高频场景。

先看SelectByID2的函数签名:

retval = ModelDocExtension.SelectByID2(Name, Type, X, Y, Z, Append, Mark, Callout, SelectOption)
参数含义
Name要选择的对象名称,如“拉伸 1”,或空字符串
Type对象类型,大写字符串,如BODYFEATURE,或空字符串
X, Y, Z选择位置的坐标,一般传 0
Append是否追加选择;True 表示追加到当前选择集
Mark标记值,供需要有序选择的函数使用,一般传 0
Callout关联的标注对象,一般传 Nothing
SelectOption选择选项,swSelectOptionDefault可用 0 代替

注意 Type 参数必须是大写,比如特征类型写成"BODYFEATURE",面类型写成"FACE"。如果记不住类型字符串,可以传空字符串,但传了空字符串后 SolidWorks 会按名称模糊匹配,可靠性下降。我的习惯是特征一定写BODYFEATURE,面一定写FACE,从来没出过问题。

3.2 GetSelectedObject5:从选择集里按索引取对象

SelectByID2选完了,对象进入选择集。要从选择集里把对象取出来,用SelectionMgr.GetSelectedObject5:

retval = SelectionMgr.GetSelectedObject5(AtIndex)

AtIndex是对象在当前选择列表里的索引,从 1 开始,最大值是SelectionMgr.GetSelectedObjectCount。返回的是 Dispatch 对象指针,需要Set到具体类型变量上。官方 API 里还有 GetSelectedObject2、GetSelectedObject3、GetSelectedObject4 等不同版本,数字越大通常支持的返回类型越全,教程里用的 5 是当前 SolidWorks 版本里常用的一档。如果返回 Nothing,说明这个索引位置没有对象,或者类型不支持。

3.3 选“拉伸 1”并打印特征名:一个能跑的完整宏

把两个 API 串起来,假设当前模型里有一个叫“拉伸 1”的特征,下面的宏先选中它,再从选择集里取出来,打印特征名称:

Option Explicit Dim swApp As SldWorks.SldWorks Dim Model As ModelDoc2 Dim feat As Feature Dim boolstatus As Boolean Sub main() Set swApp = Application.SldWorks Set Model = swApp.ActiveDoc ' 通过名称选择"拉伸 1"特征 boolstatus = Model.Extension.SelectByID2("拉伸 1", "BODYFEATURE", 0, 0, 0, False, 0, Nothing, 0) If boolstatus = True Then ' 从选择集里取第一个对象 Dim SelMgr As SelectionMgr Set SelMgr = Model.SelectionManager Set feat = SelMgr.GetSelectedObject5(1) Debug.Print feat.Name Else Debug.Print "Error" End If End Sub

代码逻辑说明:先通过Model.Extension.SelectByID2选中“拉伸 1”,返回 True 代表选中成功。然后拿到Model.SelectionManager这个选择管理器对象,调用GetSelectedObject5(1)把选择集里的第一个对象取出来。这里的索引 1 表示“当前选中列表里的第一项”,因为刚才是一次单选,所以索引一定是 1。最后用Debug.Print在 VBA 的立即窗口里输出特征名。

需要注意两点。第一,SelectByID2最后一个参数SelectOption,作者写的是swSelectOptionDefault,在Option Explicit模式下可以直接用 0 代替,效果完全一样,而且不用管常量定义。第二,选择完成后如果后面还有别的选择操作,要及时ClearSelection2,避免选择集越积越多,这个习惯在配合操作里尤其重要。

4. 读数据和改数据:从 GetDefinition 到 ModifyDefinition 再到装配体配合

4.1 访问特征数据的四步固定流程

能选中特征只是第一步,真正干活是读取和修改特征的数据。SolidWorks 的 API 访问特征数据有一套固定流程,四个步骤缺一不可:

  1. 定义一个特征对象变量;
  2. 通过GetSelectedObject5或SelectByID2拿到特征对象;
  3. 调用feature.GetDefinition获取特征的定义对象;
  4. 调用FeatData.AccessSelections(Model, Component)获得数据访问权限。

AccessSelections这个函数很关键,它返回布尔值,True 表示可以安全地读写特征参数了。用完还要调用ReleaseSelectionAccess释放访问权,否则特征会一直处于被占用的状态,后面再修改同一个特征时可能报错。

这里补一句:在 SolidWorks API 里,特征对象本身和特征的数据对象是分开的。特征对象是你在特征树里看到的那一项,数据对象才是里面存着的具体参数,比如拉伸深度、孔直径。理解不了这个区别,后面很容易搞混,调 API 时经常找不到属性。

4.2 读取简单直孔的深度与直径

下面这段程序演示怎么读取一个简单直孔特征的深度和直径。运行前,先在模型里手动选中一个简单直孔特征,然后再运行宏:

Option Explicit Dim swApp As SldWorks.SldWorks Dim Model As ModelDoc2 Dim curfeature As Feature Dim boolstatus As Boolean Dim featdata As SimpleHoleFeatureData2 Dim component As Component2 Dim dep As Double Dim dia As Double Dim SelMgr As SelectionMgr Dim ncount As Integer Sub getselected() Set swApp = Application.SldWorks Set Model = swApp.ActiveDoc Set SelMgr = Model.SelectionManager Set curfeature = SelMgr.GetSelectedObject5(1) ' 得到当前选中的第一个特征 MsgBox curfeature.Name Set featdata = curfeature.GetDefinition ' 得到特征的定义 boolstatus = featdata.AccessSelections(Model, component) ' 获得数据访问权限 ncount = featdata.GetFeatureScopeBodiesCount ' 获取作用范围实体数量 MsgBox ncount dep = featdata.Depth ' 读取孔深 dia = featdata.Diameter ' 读取直径 MsgBox dia & "*" & dep ' 释放访问权,重建模型 featuredata.ReleaseSelectionAccess Model.SaveModel Model.EditRebuild End Sub

这里用SimpleHoleFeatureData2类型接收特征定义,然后直接读Depth和Diameter属性。GetFeatureScopeBodiesCount返回的是这个孔特征影响的实体数量,一般是 1。这段程序是教学用的,没有做 if 容错,如果当前选中的不是简单直孔,GetDefinition返回的类型对不上,后面读属性就会报错。实际写代码时,必须在Set featdata = curfeature.GetDefinition前后加类型判断,下面例子会演示完整写法。

4.3 修改基体拉伸长度:从 GetDepth 到 ModifyDefinition

读数据只是热身,修改才是重头戏。下面的例子把基体拉伸凸台的长度翻倍,这是教程里最完整的一段,容错机制很全,可以直接拿来改成自己的宏:

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 = CreateObject("sldWorks.application") Set Model = swApp.ActiveDoc ' 确保当前文档是零件或装配体 If Model.GetType <> 1 And Model.GetType <> 2 Then MsgBox "仅允许在零件或装配体上运行", vbOKOnly, "Error" 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 swApp.SendMsgToUser2 "无法访问特征数据", swMbWarning, swMbOk Exit Sub End If ' 确保是基体拉伸(第一个拉伸特征) If Not FeatData.IsBaseExtrude Then swApp.SendMsgToUser2 "请选择基体拉伸", swMbWarning, swMbOk FeatData.ReleaseSelectionAccess Exit Sub End If ' 读取当前深度并翻倍 Depth = FeatData.GetDepth(True) FeatData.SetDepth True, Depth * 2 ' 应用修改 isGood = CurFeature.ModifyDefinition(FeatData, Model, Component) If Not isGood Then swApp.SendMsgToUser2 "无法修改特征数据", swMbWarning, swMbOk FeatData.ReleaseSelectionAccess End If End Sub

这段代码有几个要点值得说透。

CreateObject("sldWorks.application")和Application.SldWorks都能拿到 SolidWorks 应用对象,区别在于前者会在内存里创建一个新的 SolidWorks 实例(如果已经有运行中的实例则复用),后者直接拿当前运行的实例。在宏里推荐用Application.SldWorks,因为宏本身就是运行在 SolidWorks 进程内的。

文档类型判断这里有个真实的坑。教程作者在写If Model.GetType <> swDocPART And Model.GetType <> swDocASSEMBLY时,swDocPART和swDocASSEMBLY在他的 VBA 环境里没有通过编译。他用了一个笨办法:MsgBox Model.GetType把实际数值弹出来,发现零件是 1,装配体是 2,于是直接用数字判断。如果你写的代码也遇到枚举常量未定义,照这个方法查数值,比去翻类型库定义快得多。

类型名判断同样有坑。作者原本写If Not CurFeature.GetTypeName = swTnExtrusion,环境里swTnExtrusion也没通过,改成字符串"Extrusion"就正常了。原因是 VBA 环境没有正确加载 SolidWorks 类型库的常量定义,直接用字符串最省事。

写这段代码时还遇到了特征“退回”状态的问题:修改完特征后模型没有自动更新,我是在代码末尾手动调用Model.Rebuild和Model.Save强制重建。这个现象后面放在避坑章节细说。

4.4 装配体里插入零部件:先 OpenDoc6 再 AddComponent4

往装配体里插入零部件,用的函数是AddComponent4。它的签名是:

retval = AssemblyDoc.AddComponent4(compName, configName, x, y, z)
参数含义
compName要插入的零件或装配体的完整路径
configName要加载的配置名称
x, y, z组件中心点坐标

这个函数有个非常容易踩的前提条件:指定的文件必须先被加载到内存中。官方备注说得很清楚,文件只有在当前 SolidWorks 会话中被打开过(比如用OpenDoc6打开过文档,或者打开过包含该文件的装配体),才算在内存里。直接给一个硬盘路径是插不进去的。第一次用这个函数的人,十有八九都会在这里卡一下。

正确顺序是先打开文件,再插零件。下面这段就是完整的插入流程:

Dim swApp As SldWorks.SldWorks Dim Model As ModelDoc2 Dim YSBmodel 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 pth As String) Dim newswapp As SldWorks.SldWorks Set newswapp = Application.SldWorks Set YSBmodel = newswapp.OpenDoc6(pth, 1, 0, "", nErrors, nWarnings) YSBmodel.Visible = False ' 不让零件窗口显示出来 End Sub

OpenDoc6的参数含义如下:第一个是文档完整路径;第二个是文档类型,0 表示非 SolidWorks 文件、1 表示零件、2 表示装配体、3 表示工程图;第三个是打开模式,0 表示静默打开,不带界面;第四个是配置名,空字符串表示按默认配置打开;最后两个是错误码和警告码的输出参数,打开失败时能从里面看到具体原因,比如文件不存在、版本不兼容。打开后把Visible设为 False,这样零件不会弹出窗口打断操作,但已经加载到内存里,AddComponent4就能顺利拿到它。

实际项目里,我习惯把OpenDoc6单独封装成一个函数,传入路径和文档类型,返回 ModelDoc2 对象。这样后面在装配体里插入多个零件时,只需要循环调用这一个函数,代码干净不少。

4.5 添加配合的标准时序:ClearSelection2 必须管好开头和结尾

在装配体里添加配合是整套教程里最折腾的部分,作者在文章开头直接说了“折腾了三天”。做配合时,主要的难点在于选择配合实体(面、线、基准面等),以及配合函数AddMate2的参数时序。

做配合的标准顺序是这样:

' 第 1 步:取消所有选择,清空选择集 Model.ClearSelection2 True ' 第 2 步:选择需要配合的实体 ' 比如选择两个零件的面,用 SelectByID2 按名称选中 ' 或者用遍历面的方式选出符合条件的面 ' 第 3 步:调用 AddMate2 添加配合 ' AddMate2 参数较多,不同配合类型传入的参数不同 ' 第 4 步:再次取消所有选择,避免影响后续操作 Model.ClearSelection2 True

为什么开头和结尾都要ClearSelection2?因为AddMate2会把当前选择集里的实体拿去做配合运算,如果选择集里有历史残留的选中项,配合可能做错对象。开头清一次是确保干净起点,结尾清一次是给后续操作让路。

选面这个环节,教程明确不建议用SelectByID2按名称选。原因很现实:面的命名没有规律,很多是系统自动生成的,你根本猜不到名字;用坐标值选面更糟糕,模型稍微调整一下坐标就变了。正确的思路是遍历。拿到一个组件(Component2)后,先GetBody拿到实体,再通过GetFirstFace、GetNextFace遍历实体的所有面,按类型(平面、圆柱面、圆弧面)和位置条件筛选出需要的面。虽然写起来比按名字选复杂,但胜在稳定,不依赖命名的偶然性。

5. 常见问题与避坑记录:五条最常见的翻车现场

这套教程里出现的坑,我几乎都踩过一遍。下面这五条是出现频率最高的,按“现象 → 原因 → 解决”的顺序记下来,希望你能绕开。

5.1 录制的宏一运行就报错

  • 现象:刚录完的宏,直接运行,VBA 报“运行时错误 91”或者“对象变量或 With 块变量未设置”。
  • 原因:录制宏里残留了大量视图切换代码和冗余的SelectByID2/ClearSelection2调用,这些调用在模型状态和录制时不一致时就会失败。
  • 解决:严格按第二章的三类清理规则删代码:删掉没用的变量声明、删掉RotateAboutCenter这类视图残留、删掉成对冗余的选择调用。清理完再运行。

5.2 特征改了但模型不变,出现“退回”状态

  • 现象:用ModifyDefinition修改特征数据后,特征树里的特征进入“退回”状态,模型没有按新参数更新。
  • 原因:ModifyDefinition只是把数据写进了特征定义对象,但没有触发模型重建。SolidWorks 不会自动帮你 Rebuild,特征退回状态就是数据已改、模型未更新的表现。
  • 解决:在ModifyDefinition之后手动调用Model.Rebuild和Model.Save。教程作者当时的原话是“只能在代码执行到最后调用这两个函数来自动更新”。我现在的习惯是写完修改逻辑后,立刻补Rebuild,确认无误再Save。

5.3 AddComponent4 提示文件不存在或插入失败

  • 现象:用AddComponent4往装配体里插零件,提示找不到文件,或者函数返回 Nothing。
  • 原因:AddComponent4要求文件必须先加载到内存。直接传一个硬盘路径,SolidWorks 根本不去磁盘上找。
  • 解决:先调用OpenDoc6把零件打开,Visible设 False 隐藏,再调用AddComponent4。顺序不能反。

5.4 swDocPART、swTnExtrusion 这类常量在 VBA 里未定义

  • 现象:代码里写了Model.GetType <> swDocPART或者CurFeature.GetTypeName = swTnExtrusion,编译时报“变量未定义”。
  • 原因:VBA 环境没有正确加载 SolidWorks 类型库的枚举常量,或者当前版本 API 里常量定义变了。
  • 解决:用MsgBox把实际数值弹出来,比如MsgBox Model.GetType,得知零件是 1、装配体是 2,然后直接用数字。类型名判断则直接用字符串,swTnExtrusion改用"Extrusion"。这是最土但最可靠的办法,不依赖任何常量定义。

5.5 用 SelectByID2 选面总是失败

  • 现象:按名称调用SelectByID2选面,返回 False,选不中。
  • 原因:面的命名没有规律,很多是程序自动生成的,名称会随模型版本变化。
  • 解决:改用遍历策略。拿到组件后GetBody取实体,再用GetFirstFace、GetNextFace遍历所有面,按面的类型和几何条件筛选。虽然代码量多一些,但胜在稳定,不会因为名字变化就废掉。

6. 一个让宏更稳的收尾习惯:Rebuild 和 Save 的顺序不要搞反

6.1 我用的收尾套路:ModifyDefinition、Rebuild、Save、弹窗的固定顺序

写到这里,说说我每次完成宏之后的固定动作。修改特征数据的宏,最后三件事的顺序一定是:ModifyDefinition → Rebuild → Save,弹窗提示放最后。

具体来说,ModifyDefinition负责把新参数写进特征定义,Rebuild让模型按新参数重建,Save把结果写盘。如果先Save再Rebuild,保存的是旧模型;如果先弹窗再Rebuild,VBA 弹窗期间程序停住,模型处于一个未定义状态,你手动点掉弹窗后才继续,多了一道人工干预。正确做法是把弹窗放到所有操作完成之后,作为最终反馈。

' 正确收尾顺序 isGood = CurFeature.ModifyDefinition(FeatData, Model, Component) If Not isGood Then swApp.SendMsgToUser2 "无法修改特征数据", swMbWarning, swMbOk Exit Sub End If Model.Rebuild Model.Save swApp.SendMsgToUser2 "修改完成", swMbInformation, swMbOk

这套顺序看起来简单,但实际项目里救过我好几次。早期我做装配体自动配合功能时,每次跑完宏去看装配体,配合关系要么没更新,要么模型处于退回状态。排查了很久才发现是少了Rebuild。从那以后,我每次写完宏都强制走一遍这个收尾顺序,再也没出过这类问题。

6.2 用窗口弹出替代 Debug.Print,把宏交给别人用

调试时用Debug.Print在立即窗口输出没问题,但宏最终要交给不写代码的人用,就得把反馈改成弹窗。教程里有用swApp.SendMsgToUser2的做法,这个函数会弹出一个 SolidWorks 风格的消息框,比MsgBox更专业。它有两个常用参数:swMbWarning表示黄色警告图标,swMbOk表示确定按钮。

这个改动量不大,但体验差很多。我见过太多宏,功能没毛病,就是失败时啥都不提示,操作者以为成功了,最后图纸出错。加一个SendMsgToUser2的失败分支,成本极小,回报极高。希望帮到你。

本文还有配套的精品资源,点击获取

返回列表