夜雨聆风学习资料网

ARTICLE · 1319060

iLogic + Excel:数据驱动建模

iLogic + Excel:数据驱动建模

Inventor 二次开发入门系列 · 第 17 篇

开篇:参数表该放哪里

做参数化产品时,你迟早要回答一个问题:规格参数表放哪里。

可选方案有三个: 1. 放在 iLogic 规则代码里——简单,但改规格要改代码,非技术人员无法维护 2. 放在模型参数表——只能存数值,无法存"规格名→尺寸映射" 3. 放在 Excel 表里——最灵活,业务人员能直接改,iLogic 读取

显然第三种是生产环境的标准做法。iLogic 内置了 GoExcel 对象,专门处理 Inventor 与 Excel 之间的数据交互。

本篇讲透 GoExcel 的核心用法:打开文件、按条件查行、读写单元格、数据驱动建模,以及从外部程序调用 GoExcel 的进阶技巧。


一、GoExcel 能做什么

GoExcel 是 iLogic 封装的 Excel 操作对象,底层调用的是 Excel COM API。它提供这些核心功能:

功能
函数
说明
打开 Excel
GoExcel.Open
指定文件和工作表
按条件查行
GoExcel.FindRow
多条件查找匹配行
读当前行某列
GoExcel.CurrentRowValue
配合 FindRow 用
写单元格
GoExcel.CellValue
直接定位单元格
获取列名
GoExcel.ColumnName
按表头名定位列

相比直接用 Excel COM API,GoExcel 的优势是代码量少 70%,且自动处理 Excel 进程的启动和关闭。


二、基础用法:打开 + 查行 + 读值

假设有一个 Excel 规格表 C:\Data\parts.xlsx:

零件号
直径
长度
材料
A001
10
50
钢
A002
12
60
铝
A003
16
80
钢

需求:根据用户输入的直径和长度,查到对应的零件号和材料,填到模型参数和 iProperties 里。

' 打开 Excel 文件和工作表GoExcel.Open("C:\Data\parts.xlsx", "Sheet1")' 多条件查找:直径=10 且 长度=50Dim rowNum As Integer = GoExcel.FindRow( _    "C:\Data\parts.xlsx", _    "Sheet1", _    "直径", "=", 10, _      ' 第一个条件    "长度", "=", 50)          ' 第二个条件If rowNum > 0 Then    ' 找到了,读取该行的其他列    Dim partNumber As String = GoExcel.CurrentRowValue("零件号")    Dim material As String = GoExcel.CurrentRowValue("材料")    ' 填到模型里    Parameter("Dia") = 10    Parameter("Length") = 50    iProperties.Value("Project", "Part Number") = partNumber    iProperties.Value("Project", "Material") = material    InventorVb.DocumentUpdate()    MessageBox.Show("已加载: " & partNumber & " / " & material, "完成")Else    MessageBox.Show("未找到匹配的规格", "提示")End If

关键点: - FindRow 的参数是成对出现的:列名 + 操作符 + 值 - 操作符支持 =, <, >, <=, >=, <> - CurrentRowValue 只在 FindRow 成功后有效,读取的是刚刚匹配到的那行 - FindRow 返回 0 或负数表示没找到。


三、FindRow 的坑:TitleRow 和 FindRowStart

GoExcel 默认假设你的 Excel 表是这样布局的:

  • 第 1 行:可能有些标题或说明  

  • 第 2 行:列头("零件号""直径"等)

  • 第 3 行起:数据

如果你的表不是这个布局,FindRow 会报 "Could not match the column title" 错误。

这时候需要手动设置两个属性:

  • TitleRow:列头所在行号
  • FindRowStart:数据起始行号(通常是 TitleRow + 1)
    GoExcel.Open("C:\Data\parts.xlsx", "Sheet1")' 假设你的表:第 3 行是列头,第 4 行起是数据GoExcel.TitleRow = 3GoExcel.FindRowStart = 4' 现在就能正常查了Dim rowNum As Integer = GoExcel.FindRow( _    "C:\Data\parts.xlsx", "Sheet1", "直径", "=", 10)MessageBox.Show("找到行号: " & rowNum.ToString())

避坑提醒: - 光设 FindRowStart 不够,TitleRow 也必须设对,否则列名匹配失败 - 如果你的脚本会动态改 TitleRow 多次,每次改完都要重新设 FindRowStart——它不会自动跟着 TitleRow 变 - 默认值是 TitleRow = 2,FindRowStart = 2(注意默认 FindRowStart 不是 TitleRow+1)


四、数据驱动建模的完整闭环

把前面学的串起来,做一个完整的"选规格 → 更新模型"流程。

1. Excel 规格表

规格
Width
Height
Depth
PartNumber
小
100
50
40
S-001
中
200
100
80
M-001
大
300
150
120
L-001

2. iLogic 规则

' 配置规则:让用户选规格Sub Main()    ' 读取 Excel 里的所有规格名    GoExcel.Open("C:\Data\specs.xlsx", "Sheet1")    Dim specs As New ArrayList    Dim row As Integer = 2   ' 数据从第 2 行开始    Do        Dim name As String = GoExcel.CellValue("A" & row)        If String.IsNullOrEmpty(name) Then Exit Do        specs.Add(name)        row += 1    Loop    ' 弹窗让用户选    Dim selected As String = InputListBox( _        "请选择规格:", specs, specs(0), "规格选择", "iLogic Config")    If String.IsNullOrEmpty(selected) Then Exit Sub    ' 查到对应行,读所有尺寸    Dim rowNum As Integer = GoExcel.FindRow( _        "C:\Data\specs.xlsx", "Sheet1", "规格", "=", selected)    If rowNum <= 0 Then        MessageBox.Show("未找到规格: " & selected, "错误")        Exit Sub    End If    ' 读取并更新模型参数    Parameter("Width") = GoExcel.CurrentRowValue("Width")    Parameter("Height") = GoExcel.CurrentRowValue("Height")    Parameter("Depth") = GoExcel.CurrentRowValue("Depth")    iProperties.Value("Project", "Part Number") = _        GoExcel.CurrentRowValue("PartNumber")    ' 触发模型更新    iLogicVb.UpdateWhenDone = True    Logger.Info("已切换到规格: " & selected)End Sub

3. 挂到事件触发器

把这条规则挂到"New Document"事件,用户每次新建文档时就会弹窗选规格,选完自动更新模型。

这个闭环的价值:业务人员改 Excel 表加规格,不需要碰 Inventor;设计师只需选规格,不用手动改尺寸。真正的"数据驱动设计"。


五、写单元格:把模型数据导回 Excel

GoExcel 不只能读,也能写。常见场景:自动导出驱动尺寸的值到 Excel,做设计记录。

' 把当前模型的关键尺寸写到 Excel 记录表GoExcel.Open("C:\Data\DesignLog.xlsx", "Sheet1")' 找到下一个空行Dim nextRow As Integer = 2Do While Not String.IsNullOrEmpty(GoExcel.CellValue("A" & nextRow))    nextRow += 1Loop' 写入本次设计的参数GoExcel.CellValue("A" & nextRow) = DateTime.Now.ToString("yyyy-MM-dd")GoExcel.CellValue("B" & nextRow) = iProperties.Value("Project", "Part Number")GoExcel.CellValue("C" & nextRow) = Parameter("Width")GoExcel.CellValue("D" & nextRow) = Parameter("Height")GoExcel.CellValue("E" & nextRow) = Parameter("Depth")' 保存 ExcelGoExcel.SaveGoExcel.Close

把这个规则挂到"After Save Document"事件,每次保存 Inventor 文档时自动追加一条设计记录。


六、进阶:从外部程序调用 GoExcel

GoExcel 是 iLogic 专属对象,在 .NET Add-In 或独立 exe 里不能直接用。但有个变通方案:把 GoExcel 调用封装成带参数的外部规则。

1. 写一个带参数的外部规则

保存为 C:\iLogic\ExcelLookup.iLogicVb:

' 通过 RuleArguments 接收参数,返回结果也通过 RuleArgumentsDim filePath As String = RuleArguments("FilePath")Dim sheetName As String = RuleArguments("Sheet")Dim dia As Double = RuleArguments("Dia")Dim length As Double = RuleArguments("Length")' 用 GoExcel 查行Dim rowNum As Integer = GoExcel.FindRow( _    filePath, sheetName, "Dia", "=", dia, "Length", "=", length)If rowNum > 0 Then    ' 把结果塞回 RuleArguments,供调用方读取    Dim outputs As NameValueMap = _        ThisServer.TransientObjects.CreateNameValueMap()    outputs.Add("PartNumber", GoExcel.CurrentRowValue("PartNumber"))    RuleArguments.Arguments.Add("Outputs", outputs)End If

2. 从 .NET 程序调用这个外部规则

' 在 VB.NET Add-In 或 exe 里Public Sub LookupPartNumber()    ' m_app 是 Inventor.Application 实例    Dim arguments As NameValueMap = _        m_app.TransientObjects.CreateNameValueMap()    arguments.Add("FilePath", "C:\Data\parts.xlsx")    arguments.Add("Sheet", "Sheet1")    arguments.Add("Dia", 10)    arguments.Add("Length", 50)    Dim doc As Document = m_app.ActiveDocument    Dim externalRulePath As String = "C:\iLogic\ExcelLookup.iLogicVb"    ' 获取 iLogic 自动化对象    Dim iLogicAuto As Object = GetiLogicAutomation(m_app)    ' 运行带参数的外部规则    iLogicAuto.RunExternalRuleWithArguments(doc, externalRulePath, arguments)    ' 读取返回的结果    Dim outputs As NameValueMap = Nothing    Try        outputs = arguments.Value("Outputs")        If outputs IsNot Nothing Then            Dim partNumber As String = outputs.Value("PartNumber")            MessageBox.Show("零件号: " & partNumber, "结果")        End If    Catch ex As Exception        MessageBox.Show("查询失败: " & ex.Message, "错误")    End TryEnd Sub' 获取 iLogic Add-In 的 Automation 对象Function GetiLogicAutomation(app As Inventor.Application) As Object    Dim addIn As Inventor.ApplicationAddIn = Nothing    Try        ' iLogic Add-In 的固定 GUID        addIn = app.ApplicationAddIns.ItemById( _            "{3BDD8D79-2179-4B11-8A5A-257B1C0263AC}")    Catch        Return Nothing    End Try    Return addIn.AutomationEnd Function

这种"外部规则当桥"的思路,可以用来从 .NET 间接调用任何 iLogic 专属函数(GoExcel、GoExcel.CurrentRowValue 等)。


七、直接用 Excel COM API(替代方案)

GoExcel 有局限:它封装的是常用操作,复杂 Excel 处理(比如多表联动、公式计算、条件格式)做不了。

这时可以绕过 GoExcel,直接用 Excel COM API。iLogic 底层也是这么干的:

' 直接操作 Excel COM 对象Dim xlApp As ObjectxlApp = CreateObject("Excel.Application")xlApp.Visible = False   ' 后台运行Dim xlBook As Object = xlApp.Workbooks.Open("C:\Data\parts.xlsx")Dim xlSheet As Object = xlBook.Sheets("Sheet1")' 读取单元格Dim val As String = xlSheet.Range("B2").Value' 写入单元格xlSheet.Range("B2").Value = "新值"' 遍历行Dim row As Integer = 2Do Until String.IsNullOrEmpty(xlSheet.Range("A" & row).Value)    Logger.Info("行" & row & ": " & xlSheet.Range("A" & row).Value)    row += 1Loop' 保存并关闭xlBook.Save()xlBook.Close()xlApp.Quit()' 释放 COM 对象(重要!)System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet)System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)

注意:直接用 COM API 必须手动释放对象,否则 Excel 进程会残留。GoExcel 帮你处理了这些,但代价是灵活性降低。


八、实战要点

1. Excel 表的列头要规范。不要用"直径(mm)"这种带括号的列名,FindRow 匹配时容易出问题,用纯英文或简短中文。

2. 大表用 FindRow,小表可以遍历。几十行的表遍历也快,几千行的表一定要用 FindRow,它内部有优化。

3. Excel 文件路径用绝对路径或相对文档路径。ThisDoc.Path & "\Data\parts.xlsx" 比 C:\... 更可移植。

4. 写完 Excel 一定要 Save + Close。GoExcel 的 GoExcel.Save 和 GoExcel.Close,或者 COM 方式的 xlBook.Save() + xlApp.Quit(),漏一步就会留僵尸进程。

5. 并发访问要小心。多个用户同时改一个 Excel 文件会冲突。多人协作场景考虑用 Vault 或数据库替代 Excel。

6. FindRowStart 坑。如果你的脚本动态修改 TitleRow 多次,FindRowStart 不会自动跟着变,必须每次显式设置。


小结

场景
推荐方案
代码量
简单查行读值
GoExcel.FindRow + CurrentRowValue
少
多条件查找
FindRow 多对参数
少
非标准表头行
手动设 TitleRow + FindRowStart
少
批量导出模型数据
GoExcel.CellValue 循环写
中
复杂 Excel 操作
直接用 Excel COM API
多
从 .NET 调用 GoExcel
外部规则 + RuleArguments 桥接
中

下篇预告:《iLogic 调用 VBA 和 .NET 代码》——iLogic 规则跑到复杂逻辑就力不从心?我们讲清楚 iLogic 调用 VBA 宏、引用 .NET DLL、从外部程序反向调用 iLogic 规则的完整方案。

素材来源:Autodesk Developer Blog - Use GoExcel outside a rule (Adam Nagy, 2015)、How to use GoExcel.FindRowStart (Xiaodong Liang, 2013)、Auto export driven dimension value to Excel (Adam Nagy)。

回首页,搜索你想要的文档

在首页搜索框输入关键词,快速定位资料

文库首页搜索指引 立即搜索

相关学习资料