SolidWorks自定义属性一键删除:VBA宏实现文件级与配置特定属性批量清理
1. 自定义属性为什么需要一键删除从数据管理的角度看1.1 自定义属性在SolidWorks里到底扮演什么角色做SolidWorks相关工作的人几乎每天都跟自定义属性打交道只是很多人没意识到它的分量。打开任意一个零件、装配体或工程图按快捷键File - Properties文件 - 属性会看到两个标签页自定义和配置特定。里面存的就是这个文件的键值对信息比如材料45#钢、图号CP-2024-001、设计张三。这些字段看着不起眼但它们连接的东西非常多。工程图标题栏里的设计校对材料数量框选模板里的图号名称BOM表展开后的每一列大部分都是从这些自定义属性里取的值。SolidWorks自带的$PRP:材料链接语法本质就是告诉工程图你去读模型文件里材料这个属性。PDM系统和ERP系统对接时也要靠这些属性字段做映射。可以这么说属性就是SolidWorks模型身上贴的身份证标签几何体决定这个零件长什么样属性决定它在企业数据流里被怎么识别、归类和管理。所以删除自定义属性从来不是一个破坏操作而是数据治理的一部分。问题在于很多企业从没认真治理过这些字段等你想清理的时候积攒下来的脏数据已经多到令人头大。1.2 脏数据从哪来模板、PDM和人工录入的三条路我帮人整理模型数据时见过太多脏属性了总结下来来源基本是三条路径常常混在一起发作。第一条路是模板自带。大部分企业会做自己的零件模板、装配体模板和工程图模板工程师建模时从模板新建模板里预先塞了几十个字段。有些字段是给某个特定项目做的映射项目结束了下个项目用不上但字段还留在模板里。更麻烦的是模板里塞了字段名却没塞规则新员工看到一长串字段不知道哪些该填、哪些不该填要么全填要么全空属性表很快就成了一个没人能说清楚的杂物间。第二条路是PDM/ERP系统同步。现在很多公司上了PDM模型从PDM检入检出时系统会自动往属性里写一批内部字段比如Revision、State、CreatedDate、CheckOutUser之类。这些字段对某些下游系统有用但对纯用SolidWorks出图的工程师来说就是噪音。PDM迁移或切换系统的过程中这类字段最容易成批堆积而且字段名往往是英文或系统编码看着一头雾水。第三条路是人工录入造成的重复和错误。工程师A写材料工程师B写MATERIAL工程师C写材质同一个属性有三种名字。文档里既有旧版的版本号又有后来新加的版本两个都填了下游BOM读取时到底按哪个算这种混乱状态一旦持续两年以上想靠手工整理几乎是不可能的任务。1.3 手动删除的痛点一个文件要点的次数远超想象我自己第一次尝试手动清理属性时选了一个比较典型的零件——有12个配置每个配置下挂着8个废弃字段。逐一点开属性对话框、切到配置特定标签页、找到字段、右键删除、确认这样一个字段在单个配置里就要点四五下。12个配置乘以8个字段一个文件光点鼠标就要按将近500次还没算文件级自定义标签页里那十几个字段。搞完一个文件手指头都麻了抬头一看桌面上还有三百多个文件等着处理。同一批文件里有些属性是模板里带的在所有文件里都存在一模一样有些属性只在部分配置里出现。手动删除的问题是操作密度极高、重复性极强、极易漏掉某个配置。哪怕你细心删完一个文件再去删下一个的时候脑子里还是没办法完全记住上一个文件删到了哪里。这种场景是人最容易出错、也最容易产生抵触情绪的场景也是一键删除这类小工具能发挥最大价值的地方把重复劳动交给脚本人只需要确认结果。2. 删除属性的方案选型手动、宏、插件到底怎么选2.1 手动删除只适合一两文件的情况如果只是临时处理一两个文件比如一个零件里有一个属性写错了要删掉重写那手动删除完全够用。右键属性名、选择删除几秒钟就完事。但手动方案有个致命问题它无法应对批量和配置多这两个维度的压力。一旦文件数量超过10个或者某个文件的配置数量超过5个手动操作的时间和出错率就会成倍上升。另外手动删除也没有选择性批量的能力。你说不定会漏掉某几个配置里的那一个字段等到最后检查时才发现又得重新来一遍。2.2 VBA宏最平衡的方案SolidWorks自带一套VBA宏环境不需要安装任何第三方软件。工具 - 宏 - 新建就能打开宏编辑器写代码。宏能直接调用SolidWorks的API可以在当前文档里读取属性列表、按名称删除属性、遍历所有配置还可以在此基础上扩展成遍历整个文件夹的批处理工具。这套方案的优点是免费只要装了SolidWorks就能用可控想删哪些字段改一下数组里的属性名列表就行可扩展从单文件做成文件夹批量处理代码结构和核心函数都可以复用可绑定界面宏可以挂到工具栏、快捷键上真正做到一键缺点当然也有需要一点VBA基础API在不同SolidWorks版本之间有细微差异宏只能处理它能打开的文件文件路径过长或文件损坏时也会报错。但总的来说对工程师个人和小团队而言VBA宏是性价比最高的方案。2.3 插件和批处理工具企业级数据清理的兜底选择说到企业级方案很多人第一反应是SolidWorks自带的Task Scheduler任务调度器。我试过用它来做一些批量操作比如批量转换文件格式。但至少在我用过的版本里Task Scheduler对删除自定义属性这种操作的支持很弱它更多是用来做文件转换、打印、更新视图等批量任务的。指望它来删属性大概率会卡在没有对应模板或脚本这一步。商业插件或自研PDM工具倒是能完成这种全库级别的属性清理但成本也摆在那里要采购、要部署、要培训而且如果PDM系统本身还在用这些属性做映射清理前必须做大量沟通和验证。对多数情况来说用VBA宏批量处理已经能解决九成问题。我的建议是先做宏宏解决不了或需要长期统一管理时再考虑上插件级方案。方案对比可以看下面这张表方案上手门槛批量能力灵活程度适合场景手动删除无极差低一两个文件应急VBA宏中中可扩展高日常清理与批量处理商业插件/PDM工具低高中企业全库数据治理3. 一键删除核心宏实现文件级与配置特定属性一起清3.1 宏的逻辑先明白要删几层写宏之前先想清楚SolidWorks自定义属性在API层面有两层第一层是文件级自定义属性对应属性对话框里的自定义标签页。这一层属性跟配置无关是挂在文档本身上的键值对。API里获取这一层属性管理器的方法是ModelDocExtension.CustomPropertyManager()注意参数是空字符串代表文件级。第二层是配置特定属性对应属性对话框里的配置特定标签页。这一层挂在每个配置下面不同配置可以有不同的值。同一个属性名可能在默认配置里有值在其他配置里也有值删的时候必须把每个配置都过一遍漏掉任何一个都会留下残留。所以宏的核心逻辑其实只有三步取当前激活的SolidWorks文档删除文件级自定义标签页里指定的属性遍历所有配置删除每个配置下配置特定标签页里指定的属性想删哪些属性直接在代码里维护一个数组列表以后换项目、换规则改数组内容就行不用动其他代码。3.2 完整VBA代码可直接粘贴运行下面这段代码我在SolidWorks 2018 SP5上跑通过API的大逻辑在2016到2023这些版本上是通用的。如果是更老的版本个别方法名可能有差异到时候以本地API帮助为准。Option Explicit Dim swApp As SldWorks.SldWorks Dim swModel As SldWorks.ModelDoc2 Dim swExt As SldWorks.ModelDocExtension Dim swCfgMgr As SldWorks.ConfigurationManager Dim swCfg As SldWorks.Configuration Dim swPropMgr As SldWorks.CustomPropertyManager Sub DeleteSelectedCustomProperties() Dim targetNames As Variant Dim vCfgNames As Variant Dim cfgName As String Dim errMsg As String Dim i As Long 获取SolidWorks应用对象和当前激活文档 Set swApp Application.SldWorks Set swModel swApp.ActiveDoc 如果没有打开任何文档直接提示并退出 If swModel Is Nothing Then MsgBox 请先打开一个 SolidWorks 零件、装配体或工程图文件。, vbExclamation Exit Sub End If 在这里修改你要删除的属性名列表按需增删 targetNames Array(材料, 表面处理, 工艺路线, 备注, 版本号, ProjectID) Set swExt swModel.Extension errMsg 第一遍清理文件级自定义属性对应“自定义”标签页 Set swPropMgr swExt.CustomPropertyManager() DeleteProps swPropMgr, targetNames, errMsg 第二遍遍历所有配置清理“配置特定”标签页 Set swCfgMgr swModel.ConfigurationManager vCfgNames swCfgMgr.GetConfigurationNames GetConfigurationNames 在只有一个配置时可能返回单个字符串而不是数组这里统一处理 If IsArray(vCfgNames) Then For i 0 To UBound(vCfgNames) cfgName CStr(vCfgNames(i)) Set swCfg swCfgMgr.ConfigurationByName(cfgName) Set swPropMgr swCfg.CustomPropertyManager DeleteProps swPropMgr, targetNames, errMsg Next i Else If Len(CStr(vCfgNames)) 0 Then cfgName CStr(vCfgNames) Set swCfg swCfgMgr.ConfigurationByName(cfgName) Set swPropMgr swCfg.CustomPropertyManager DeleteProps swPropMgr, targetNames, errMsg End If End If 输出结果 If Len(errMsg) 0 Then MsgBox 清理完成目标属性已全部删除。, vbInformation Else MsgBox 清理完成但以下属性删除失败 vbCrLf errMsg, vbWarning End If End Sub Sub DeleteProps(ByVal propMgr As SldWorks.CustomPropertyManager, ByVal targetNames As Variant, ByRef errMsg As String) Dim vNames As Variant Dim i As Long, j As Long Dim propName As String Dim tmp(0 To 0) As Variant 获取当前属性管理器下所有属性名 vNames propMgr.GetNames 如果没有属性直接返回 If IsEmpty(vNames) Then Exit Sub 属性数量较少时GetNames 可能返回单个字符串而不是数组这里统一转成数组处理 If Not IsArray(vNames) Then tmp(0) vNames vNames tmp End If 遍历所有属性如果命中目标列表就删除 For i 0 To UBound(vNames) propName CStr(vNames(i)) For j 0 To UBound(targetNames) If targetNames(j) propName Then If Not propMgr.Delete(propName) Then errMsg errMsg propName ; End If Exit For End If Next j Next i End Sub3.3 代码里的关键细节说明第一次写这类宏的人最容易踩的坑是GetNames的返回值类型。在VBA里CustomPropertyManager.GetNames返回的是Variant理论上是一个字符串数组但实际运行时有个很坑的行为当属性数量是0时返回Empty当属性数量只有1个时它可能返回单个字符串而不是数组。如果你直接拿For i 0 To UBound(vNames)去遍历在属性数量为1或0的时候会直接报下标越界。所以我在DeleteProps里专门做了两段防护先判断IsEmpty再用IsArray判断是不是数组如果不是数组就把它包装成单元素数组再进入循环。这个处理在GetConfigurationNames那里同样适用因为配置数量很少的文件也可能碰到单值返回的情况。其次是属性名的匹配问题。SolidWorks里的属性名本质上是字符串比较大小写敏感。也就是说材料和MATERIAL会被当成两个不同的属性。如果你希望做大小写不敏感匹配可以在比较时统一转成LCase再比比如If LCase(targetNames(j)) LCase(propName) Then。我代码里默认用的是精确匹配因为实际项目中同名不同大小写的脏数据往往是需要单独处理的混在一起反而容易误删。最后是Delete方法在不同版本里的可用性问题。就我用过的版本来说CustomPropertyManager.Delete一直可以正常工作但如果你用的是特别老的SolidWorks版本API里可能只有Remove方法而没有Delete。遇到这种情况把代码里的propMgr.Delete(propName)改成propMgr.Remove(propName)即可。这个我专门在文末提醒是因为确实有朋友拿老版本跑宏报编译错误翻API文档才发现版本差异。4. 宏的运行流程与验证从新建宏到确认删干净4.1 新建宏和粘贴代码的完整步骤这段是针对没写过SolidWorks宏的朋友的老手可以直接跳到后面。打开SolidWorks后依次点击菜单栏的工具 - 宏 - 新建会弹出一个保存宏文件的对话框。给宏起个名字比如DeleteCustomProps.swp保存后会自动打开VBA编辑器。在编辑器里把刚才那整段代码粘贴进去替换掉默认生成的空白模块内容。这里有个小提示宏文件默认保存位置可能不是你想放的地方我习惯把所有自用宏统一放到一个专门的宏目录里比如D:\SW_Macros这样后面绑定工具栏按钮时好找重装系统后也方便一起迁移。接下来是宏安全设置。默认情况下SolidWorks的宏安全级别可能比较高直接运行会提示宏已被禁用之类的信息。到工具 - 宏 - 安全性里把安全级别设为启用所有宏。这个操作会降低安全性所以自己电脑上可以这么干公司统一管控的电脑建议走IT审批流程。设置完成后重启SolidWorks让设置生效。运行宏有两种方式。第一种是工具 - 宏 - 运行选择刚才保存的宏文件点运行。第二种适合调试阶段先在宏编辑器里把光标放到DeleteSelectedCustomProperties这个子程序里按F5直接运行。第二种方式对排查代码问题更方便因为出错能直接定位到行号。4.2 删除结果怎么验证宏运行完毕弹窗提示清理完成并不代表一定删干净了验证这一步不能省。最直接的验证方法是打开属性对话框也就是文件 - 属性先看自定义标签页再看配置特定标签页确认目标属性都已经消失。这里尤其要注意配置特定标签页因为宏遍历了所有配置你也要跟着把所有配置都点一遍才敢确认结果。配置多的文件一个一个点确实烦但这是最可靠的检查方式。如果你懒得手动点配置也可以写一个调试小宏把文档里所有属性名全部打印出来。大概思路是循环遍历GetNames把结果输出到VBA的立即窗口Dim i As Long Dim names As Variant Set swPropMgr swModel.Extension.CustomPropertyManager() names swPropMgr.GetNames If IsArray(names) Then For i 0 To UBound(names) Debug.Print names(i) Next i End If立即窗口里如果还有目标属性名说明删除逻辑有问题如果只剩你不想删的属性那就干净了。这个调试宏在多个配置的情况下尤其好使比手动切标签页快得多。4.3 保存与恢复为什么撤销在这里不靠谱宏删除属性和手动删除有一个关键区别宏执行完SolidWorks的撤销队列通常不会记录这些API操作。也就是说你按了CtrlZ属性不一定能变回来甚至可能把别的操作也一起撤销掉结果更乱。这一点必须提前知道不能指望反悔。正确的做法是跑宏之前先把要处理的文件复制一份到临时目录。如果文件数量少直接复制到桌面如果文件多就用SolidWorks自带的Pack and Go功能打包一份副本或者把整个文件夹复制到其他盘。操作完了确认没问题再删除备份如果出了问题把备份覆盖回去就行。还有一个必须强调的点宏删完属性之后文档处于已修改状态不保存的话等于白干。如果你只是删完了属性不保存就关文件SolidWorks会弹出保存提示选择是才会写入文件如果你在宏后面接上其他操作然后直接关SolidWorks很可能忘记保存。我的习惯是宏跑完、验证通过之后立刻按CtrlS保存保存完再做下一步。4.4 进阶把宏变成真正的一键按钮标题叫一键删除那宏总不能用一次就去菜单里找一次吧把宏绑到工具栏上才是真正体验一键的姿势。操作路径是工具 - 自定义 - 命令在命令类别列表里找到宏这一类右侧会出现一个新建宏按钮的图标把它拖到任意工具栏上。松开鼠标后会弹出一个设置框选择宏文件、指定要运行的宏过程名再选一个按钮图标。确定之后工具栏上就会出现一个按钮以后打开任何SolidWorks文档点一下这个按钮宏就跑了属性删完、弹窗提示全程不需要打开宏编辑器。还有一个办法是给宏绑定快捷键。在自定义窗口的键盘选项卡里搜索宏名指定快捷键比如CtrlShiftD。不过多按钮的操作有一个风险误触。本来就是删除操作没有撤销机制如果按钮放在顺手的位置又经常误点到那就尴尬了。我的建议是按钮图标换个醒目的颜色且只在确实需要清理属性的时候才去点它平时把鼠标移开。5. 文件夹批量清理把单文件删除能力扩展到整个目录5.1 批量处理的思路与核心代码片段单个文件删属性只是开胃菜真正折磨人的是几十上百个文件一起处理。好在核心删除逻辑已经在前面封装成了DeleteProps子程序批量处理只需要在外面套一层遍历文件夹、打开文件、调用删除、保存关闭的壳就行。文件夹遍历我习惯用VBA的FileSystemObject它处理递归子目录比较方便。核心片段长这样Sub ScanFolder(ByVal rootPath As String) Dim fso As Object Dim rootFolder As Object Set fso CreateObject(Scripting.FileSystemObject) Set rootFolder fso.GetFolder(rootPath) DoScan rootFolder End Sub Sub DoScan(ByVal fld As Object) Dim f As Object Dim subFld As Object 处理当前目录下所有SolidWorks文件 For Each f In fld.Files If LCase(f.Name) Like *.sldprt Or _ LCase(f.Name) Like *.sldasm Or _ LCase(f.Name) Like *.slddrw Then ProcessFile CStr(f.Path) End If Next f 递归处理子目录 For Each subFld In fld.SubFolders DoScan subFld Next subFld End Sub在ProcessFile这个函数里逻辑就是用OpenDoc6打开文件获取文档对象调DeleteProps删除目标属性最后保存关闭。这里注意一点OpenDoc6的打开类型要根据扩展名区分.sldprt对应零件文档.sldasm对应装配体.slddrw对应工程图三个类型用的是不同的枚举常量。这种批处理脚本建议不要一上来就全库跑先在指定测试文件夹里放两三个文件跑一遍确认没问再扩大到真实目录。5.2 后台打开文件让批处理提速的几个设置批量处理最怕的就是一个文件一个文件地在屏幕上跳来跳去又慢又烦还容易打断你干别的活。SolidWorks API里有个很实用的属性叫DocumentVisible把文档可见性设为False文件就在后台打开屏幕上看不到处理速度会明显提升。swApp.DocumentVisible False 执行打开、删除、保存、关闭一系列操作 swApp.DocumentVisible True这个属性在宏里可以直接赋值但要注意过程结束后要记得改回True不然用户会误以为SolidWorks坏了屏幕上什么都点不了。还有一个提速点是用轻化模式或只读模式打开文件。如果文件只是被读取属性再删属性理论上不需要完整加载几何只加载属性数据就够了。但这里有个矛盾点文件已经做好了删属性操作保存的时候需要写权限。如果你用只读模式打开编辑完会发现保存失败或者保存路径变成另存为。所以批处理时我一般用不可见模式打开但不用只读模式要保证能正常保存。大装配体是批处理的性能杀手。一个总成文件可能有几百兆打开一次就要几十秒甚至几分钟再加上保存就更慢。我的经验是先按文件大小排序把小文件先处理完大文件放到后面这样即使中途出错也已经完成了大部分文件的清理。另外处理大装配体时内存占用很高最好分批跑比如每处理30个文件就重启一次SolidWorks避免内存一点点吃满导致程序崩溃。5.3 批处理场景的异常兜底损坏文件和写日志批处理跑到一半遇到一个损坏的、被占用的、或者版本太老打不开的文件是再正常不过的事。如果脚本没有异常处理报错弹窗会直接卡住整个批处理流程你人又不可能一直守在电脑前结果就是一晚上过去它停在第3个坏文件上再没动过。所以批处理脚本一定要加错误处理。VBA里的做法是On Error Resume Next配合一个独立的日志字符串变量或者直接用文件系统写一个日志文件。每次打开失败、删除失败、保存失败都把文件路径和错误描述记下来全部跑完之后集中弹窗或写入文本文件。日志文件我建议写成一行一条的格式附带时间戳。比如[2025-01-10 14:32:01] 删除失败 - D:\projects\PartA.sldprt - 属性:ProjectID [2025-01-10 14:32:05] 文件无法打开 - D:\projects\损坏装配体.sldasm这样处理完之后扫一眼日志就知道哪些文件需要人工介入不会漏。还有一点批处理脚本运行过程中尽量不要操作电脑至少不要打开或关闭其他SolidWorks文件否则容易触发API调度冲突。6. 删除属性前必须确认的五件事别让工程图标题栏变成空白6.1 确认属性到底被谁引用删除属性最大的风险不是删除这个动作本身而是删除之后下游引用链条的断裂。工程图标题栏里的$PRP:设计、BOM表里的材料列、装配体工程图里的数量和代号这些引用的源头可能就是你要删的那个属性。一旦属性被删工程图再打开时标题栏对应位置就是空白甚至可能连$PRP变量本身都显示成错误字符串。所以在删属性之前一定要先搞清楚这个属性名有没有被以下类型的文件引用工程图模板.drwdotBOM表模板自定义属性模板方程式里SW-Specific之外的字符串引用PDM或内部工具的属性映射表最笨但也最稳妥的办法是在SolidWorks中打开对应的工程图模板检查标题栏里有没有用到目标属性名再打开一张典型的工程图文件看看属性值还有没有显示。模板里如果有引用清理的范围就要把模板也包含进去否则下次新建工程图空白又回来了。6.2 装配体嵌套里的属性归属一个装配体文件里可能嵌套了几十层子装配体和几百个零件但装配体文件自己的属性和子零件的属性是两套独立数据。删除顶层装配体的材料属性绝不会顺带把下面所有零件的材料属性都删掉反过来也一样。这意味着你的批量清理方案必须明确目标层级是要清理所有零件、所有装配体、所有工程图还是只清理某个顶层总成如果项目要求是全库清理那脚本里的文件过滤条件就要把.sldprt和.sldasm和.slddrw都包含进去并且按目录递归处理如果只清理当前选中的几个顶层装配体那就只处理那几文件。这个决定必须在脚本运行之前就做好不然结果永远跟预期对不上。6.3 模板会不会把属性重新长回来这是我踩过最深的坑之一。第一次做属性清理的时候我高高兴兴把某零件模板里那一大串废弃字段全删了还批量处理了所有从该模板新建的零件。结果过了两天新员工从原模板新建了一批零件打开属性一看那串废弃字段又齐刷刷出现了。原因很简单我清理的是零件文件但最初的根源在模板里模板没改源头还在。要根治脏数据必须同时清理三类模板零件模板.prtdot、装配体模板.asmdot、工程图模板.drwdot。方法跟清理普通文件一样用宏打开模板文件删除指定属性保存。模板文件一般都放在SolidWorks安装目录的data\templates下或者你自己指定的模板路径里。清理模板之前一定记得先备份因为模板坏了影响的不只是一个文件而是以后所有新文件。6.4 性能与内存大文件批清理要预留的时间很多人以为删除属性只是个轻量操作点一下按钮就完事。实际上每删除一个属性SolidWorks都要更新文档的属性缓存、标记文件已修改如果文件还开着还会触发界面上的属性表刷新。上百个文件处理下来累计耗时是相当可观的。我实测过一组数据一个中等复杂度的零件文件50MB左右删除5个属性、保存关闭完整流程大约需要10到20秒。如果是大型装配体时间翻几倍很正常。按这个估算100个文件的中型项目批处理至少需要预留半小时到一小时。这不是bug是SolidWorks保存文件时的固有开销。所以批量处理时不要中途关机、不要强制终止安排好时间再跑。6.5 备份优先删除属性没有后悔药再强调一遍这是我用了很多年宏之后最深刻的体会API层面的删除操作不进撤销队列。手动删属性CtrlZ还能就回来宏删属性CtrlZ不一定有效甚至可能把别的操作一起撤销掉造成更大的混乱。批量清理前一定要做备份。文件数量少的时候直接复制整个项目文件夹文件多的时候可以用SolidWorks自带Pack and Go把整个树打包到新目录。PDM环境下的项目清理前确保所有文件都已经检入这样至少还有版本历史可以回溯。备份做完再动手哪怕删错了也能几分钟内恢复到原状这个习惯能省下无数次差点晕过去的瞬间。结合实际操作来看我个人现在处理属性清理流程时总会先拿一个测试文件跑一遍宏边看日志边确认引用关系确认无误后再放批处理脚本跑全量。这种先小后大、先备份再动手的方式看着保守但恰恰是处理数据类操作最稳妥的做法。工具只是帮你按下了那个按钮按得值不值得全看动手之前你有多谨慎。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →