一、痛点引入
上周接手同事留下的参数化模型:特征树整整齐齐,f(x) 弹窗一打开——200多个参数、30多条公式,哪些尺寸是公式算的、哪些是手敲死的,没有任何标记。评审会上客户随口问一句"这个壁厚怎么改的",你双击参数一看,数值对,公式栏却是空的——本该由公式驱动的尺寸,不知道什么时候被人手动覆盖了。
更隐蔽的是"公式停摆":有人调试时把某条公式停用了(右键Deactivate),忘了恢复。从此这个尺寸再也不会跟着源参数联动,模型看起来还是参数化的,实际已经"死"了半个。靠 f(x) 弹窗挨个双击核对,30条公式至少20分钟,还不保证不漏。
这不是你心不细,是"审计"这个动作根本不该靠眼睛。 今天用 Python 把全模型公式链路拉成一张清单:谁驱动谁、公式体是什么、有没有被停用,2秒钟全部摊开。
二、核心思路
CATIA 里所有公式、规则、检查,都登记在 Part 的 Relations 集合里,每条关系自带三份档案:叫什么(Name)、怎么算(Value,公式体)、驱动谁(GetOutParameter)。反过来,每个参数身上的 OptionalRelation 属性能查到"驱动我的公式是谁",查不到就是没人管的"裸参数"。正向查公式 + 反向查参数,两本账一对,链路全貌就出来了。
Python脚本(pywin32) COM接口 CATIA.Application
├─ ActiveDocument.Part
├─ Part.Relations 全部关系(公式/规则/检查/设计表)
│ ├─ Name 关系名(Formula.1…)
│ ├─ Value 公式体(等号右边的表达式)
│ ├─ GetOutParameter 这条公式驱动哪个参数
│ └─ Activated 激活(True) / 停用(False)
├─ Part.Parameters 全部参数
│ ├─ IsTrueParameter 过滤点线面等几何参数
│ ├─ OptionalRelation 反查驱动公式(None=裸参数)
│ └─ UserAccessMode 2=用户参数
└─ 汇总 控制台 + CSV审计清单你需要准备:
- Python 3.7+、
pywin32 - CATIA V5 已启动,打开一个带公式的 .CATPart
三、环境搭建(2分钟)
pip install pywin32验证连接,顺便看看当前模型的"家底":
import win32com.client
catia = win32com.client.GetActiveObject("CATIA.Application")
part = catia.ActiveDocument.Part
print(f"已连接:{part.Name} | 参数 {part.Parameters.Count} 个 | 关系 {part.Relations.Count} 条")输出形如:已连接:Bracket_Cover | 参数 214 个 | 关系 36 条。数字是 0 也别慌,说明当前文档没建公式,先去 f(x) 里随便建一条再跑。
四、核心代码
import csv
import datetime
import win32com.client
# ========== 第1步:连接CATIA,拿到两大集合 ==========
catia = win32com.client.GetActiveObject("CATIA.Application") # 连接正在运行的CATIA
part = catia.ActiveDocument.Part # 当前零件的Part根对象
relations = part.Relations # 全部"关系":公式/规则/检查/设计表都在这里
parameters = part.Parameters # 全部参数(含CATIA内部生成的参数)
# ========== 第2步:正向审计——每条公式是谁、驱动谁、怎么算、还活着吗 ==========
formula_rows = [] # 每行:[关系名, 被驱动参数, 公式体, 激活状态, 备注]
for i in range(1, relations.Count + 1): # COM集合下标从1开始
rel = relations.Item(i)
body = rel.Value # 公式体;设计表等非表达式关系返回空串
if not body:
continue # 空定义(如设计表)跳过,只审公式类关系
try: # 被驱动的参数:先拿Parameter对象再取名字
driven = rel.GetOutParameter(1).Name # 公式只有1个输出参数,取第1个
except Exception:
driven = "(无法解析)" # 个别关系不暴露输出参数,兜底
try: # 停用公式是断链重灾区,必须单独标记
status = "激活" if rel.Activated else "!! 已停用"
except Exception:
status = "未知"
formula_rows.append([rel.Name, driven, body, status, rel.Comment or ""])
print(f" {rel.Name:<12} {driven:<36} = {body} [{status}]")
# ========== 第3步:反向审计——哪些用户参数是"裸"的(无公式驱动) ==========
bare = []
for i in range(1, parameters.Count + 1):
param = parameters.Item(i)
if not param.IsTrueParameter: # 跳过点/线/面等几何参数,只看"真"参数
continue
if param.OptionalRelation is not None: # 有公式/规则在驱动,不算裸参数
continue
if param.UserAccessMode == 2: # 2=用户参数(可读可写可删),排除内部参数
bare.append(param.Name)
print(f"\n公式 {len(formula_rows)} 条 | 未被公式驱动的用户参数 {len(bare)} 个(硬编码尺寸)")
# ========== 第4步:导出CSV审计清单(utf-8-sig防Excel乱码) ==========
out_csv = f"./公式审计_{part.Name}_{datetime.date.today()}.csv"
with open(out_csv, "w", newline="", encoding="utf-8-sig") as f:
w = csv.writer(f)
w.writerow(["关系名", "被驱动参数", "公式体", "激活状态", "备注"])
w.writerows(formula_rows)
if bare:
w.writerow([])
w.writerow(["-- 以下为未被公式驱动的用户参数 --"])
w.writerows([[n] for n in bare])
print(f"审计清单已导出:{out_csv}")代码解析:
Part.Relations:零件全部"关系"的集合。公式(Formula)、规则(Rule)、检查(Check)、设计表(DesignTable)都是其中一条。rel.Value:关系定义体(只读),对公式就是等号右边的表达式;设计表返回空串——正好拿来过滤。GetOutParameter(1):这条公式驱动哪个参数。公式只有 1 个输出参数,所以取第 1 个。param.OptionalRelation:反向查询,返回驱动该参数的关系,没有公式时返回 None——"裸参数"识别全靠它。param.UserAccessMode == 2:只筛"用户参数"(可读可写可删),把 CATIA 自动生成的内部参数挡在外面。
五、效果对比
| 对比项 | 传统方法 | 自动化脚本 |
|---|---|---|
| 耗时 | 30条公式挨个双击,约20分钟 | 2秒出全量清单 |
| 停用公式 | 极易漏看(树里无标记) | 逐条标记"!! 已停用" |
| 谁驱动谁 | 凭记忆、翻特征树 | GetOutParameter自动写入清单 |
| 裸参数 | 无法排查 | 反向对账自动列出 |
| 可重复性 | 交接一次查一次 | 一键重跑,交付前必检 |
六、进阶用法
技巧1:交付前专查"停用公式"
评审最怕的就是带病交付。出图前跑这一段,任何停用公式都无处遁形:
for i in range(1, relations.Count + 1):
rel = relations.Item(i)
try:
if rel.Value and not rel.Activated: # 有公式体但没激活=被人为停用
print(f"[停用] {rel.Name}: {rel.Value}")
except Exception:
pass技巧2:不写文件,直接在树上高亮全部公式
想让同事在CATIA里当场看?把所有公式搜进选择集,特征树即时定位:
sel = catia.ActiveDocument.Selection
sel.Clear()
sel.Search("Knowledgeware.Formula,all") # 搜索语法:类别,范围
print(f"已在特征树上选中 {sel.Count} 条公式")关注回复「公式审计」获取完整源码 + 审计清单样例
下期预告:切换选项c「CAA C++ 踩坑记录」第6篇——Undo/Redo 事务回滚:批量改参数前,先学会给自己留后悔药。
_栏目:开发实战 | 发布日期:2026-09-16 | 字数:约 1150 字 | 系列:CATIA Python COM API 入门 #13_