分类:数据导入导出
导入一列 Excel 的构件 ID,过滤无效 ID 并生成可点击的 ID 列表;点击后自动框选构件并生成局部三维视图。功能灵感来源于 Navisworks 导出的碰撞报告转换成 Excel,然后导入 Revit 检查碰撞位置。系统会自动验证 ID 有效性,记录上次查看的序号,并创建带有剖面框的三维视图以快速定位构件。
FileTools.ExcelFile(仅显示 .xlsx、.xls 等 Excel 格式文件)。ExcelPath = filename。OnExcelPathChanged事件,加载上次记录的序号:var index = ExcelRecordStore.LoadIndex(value);if (index.HasValue){ LastIndexText = $"上次记录序号:{index}";}var rows = MiniExcel.Query<ElementIdItem>(filename).ToList();ElementIdItemIndex(序号)、Id(ID)、Name(项目名称)。[ExcelColumnName]属性映射 Excel 列名到类属性。Items.Clear()。var doc = XmlDoc.Doc。foreach (var row in rows){if (row.Id.IsNullOrWhiteSpace()) {continue; // 跳过空ID }if (row.Id.ToElementId().ToElement(doc) isnotnull) { Items.Add(row); // ID有效,添加到列表 }else { XmlDoc.Logger.Info("跳过异常ID:" + row.Id); // ID无效,记录日志 }}row.Id.ToElementId()ElementId对象。.ToElement(doc)Id字段为空或空白,跳过该行。CanCreate = Items.Count > 0。if (list == null || list.Count == 0)。var temp = list.Cast<ElementIdItem>().ToList()。List<Element> els = [];var doc = XmlDoc.Doc;foreach (var item in temp){var el = item.Id.ToElementId().ToElement(doc); els.Add(el);}ElementId,再获取对应的Element对象。var lastIndex = ExcelRecordStore.LoadIndex(ExcelPath);var index = temp.Max(o => o.Index);ExcelRecordStore.SaveIndex(ExcelPath, index);LastIndexText = $"上次记录序号:{index}";temp.Max(o => o.Index))。excel_records.json),下次打开同一 Excel 文件时显示此序号。XmlDoc.RevitTaskService.RunAsync)执行视图创建和切换。doc.Transaction(t => {...})),事务名称为"局部三维框"。Create3DSectionBox(doc, els)方法创建局部三维视图:var view = new FilteredElementCollector(doc) .OfClass(typeof(View3D)) .Cast<View3D>() .FirstOrDefault(v => !v.IsTemplate && v.Name == "构件定位");!v.IsTemplatev.Name == "构件定位"var xyzs = new List<XYZ>();foreach (var el in elements){var boundingBox = el.get_BoundingBox(null); xyzs.Add(boundingBox.Min); xyzs.Add(boundingBox.Max);}get_BoundingBox(null)xyzs.Count == 0),返回现有视图(不更新)。var min = new XYZ(xyzs.Min(p => p.X), xyzs.Min(p => p.Y), xyzs.Min(p => p.Z));var max = new XYZ(xyzs.Max(p => p.X), xyzs.Max(p => p.Y), xyzs.Max(p => p.Z));minmaxview == null,创建新的三维视图:view = doc.Create3DView("构件定位");Create3DView方法创建默认方向的三维视图。var of = 500d.MMToFeet()(500毫米转换为英尺)。XYZ offset = new XYZ(of, of, of)。BoundingBoxXYZ box = new BoundingBoxXYZ { Min = min - offset, Max = max + offset };view.SetSectionBox(box);view.IsSectionBoxActive = true;SetSectionBoxIsSectionBoxActive = trueview3D != null),切换到该视图:XmlDoc.UIdoc.ActiveView = view3D;var uiview = XmlDoc.UIdoc.ActiveUIView()。uiview.ZoomToFit()。XmlDoc.UIdoc.SetElementIds(els)。IsSectionBoxActive = false)。of = 500d.MMToFeet()的值。excel_records.json文件中。若需清除记录,可手动删除该文件,或使用不同的 Excel 文件名。[ExcelColumnName("ID")]属性映射列名,Excel 中的列名必须精确匹配"ID"(大小写敏感)。若列名为"id"、"Id"或其他变体,将无法读取数据。IsSectionBoxActive = true),仅显示框内内容。若需查看完整模型,需手动关闭剖面框或调整其范围。XmlDoc.Doc)中查找元素,不包括链接模型中的元素。若 Excel 中包含链接模型的 ID,将被视为无效 ID 并跳过。.xlsx 和 .xls 格式,但不支持加密的 Excel 文件或包含宏的文件。若读取失败,请检查文件格式是否正确。excel_records.json文件保存在缓存目录中,即使关闭 Revit 也会保留。若需清除所有记录,可手动删除该文件,但会影响所有 Excel 文件的序号记录。Q1:为什么加载Excel后列表为空?A1:可能原因包括:①Excel 文件中没有名为"ID"的列(大小写敏感),MiniExcel 无法映射数据;②所有 ID 都是空的或无效的(不对应当前项目中的元素);③Excel 文件格式不正确(如加密文件、损坏文件),MiniExcel 读取失败;④Excel 文件路径包含特殊字符,导致读取错误。请检查 Excel 文件的列名是否正确,ID 是否有效,并查看输出窗口的日志确认具体原因。
Q2:为什么某些ID被跳过?A2:ID 被跳过的原因包括:①ID 字段为空或空白(IsNullOrWhiteSpace检查);②ID 字符串无法转换为有效的ElementId(格式错误);③ID 对应的元素在当前项目中不存在(可能已被删除、或来自其他项目)。系统会在日志中记录"跳过异常ID:{ID}",可查看日志了解具体哪些 ID 被跳过。
Q3:能否自定义视图名称而不是固定的"构件定位"?A3:当前版本视图名称硬编码为"构件定位"。若需自定义名称,需修改源码中的Create3DSectionBox方法,将"构件定位"替换为用户输入的名称,或通过 UI 让用户指定名称。但需注意,若每次使用不同名称,会创建大量视图,可能影响项目性能。
Q4:生成的局部三维视图为什么看不到构件?A4:可能原因包括:①构件位于剖面框之外,500mm 的偏移量不足以包含构件;②构件被视图过滤器隐藏,需在视图可见性/图形替换(VV/VG)中检查;③构件在链接模型中,而剖面框仅针对当前文档的元素计算;④视图的裁剪区域或远裁剪平面排除了构件。解决方法:①手动调整剖面框大小(在视图属性中编辑 SectionBox);②检查视图可见性设置;③确保构件在当前项目中而非链接模型中。
Q5:上次记录序号是如何计算的?有什么作用?A5:系统会记录每次查看时选中 ID 的最大序号(temp.Max(o => o.Index)),并保存到缓存文件(excel_records.json)。下次打开同一 Excel 文件时,会显示"上次记录序号:{index}",帮助用户知道已经查看到哪个位置,避免重复检查或遗漏。这对于处理大量 ID(如数百个碰撞点)特别有用,可以分多次查看,每次从上次中断的位置继续。
Q6:能否一次性查看所有ID而不是逐个选择?A6:可以。在 ID 列表表格中,按 Ctrl+A 全选所有 ID,然后点击"创建局部三维框"。系统会计算所有元素的总体包围盒,创建一个包含所有构件的局部视图。但需注意,若元素分布在不同区域,剖面框会非常大,可能失去"局部"的意义,且视图可能过于拥挤,不利于观察细节。建议分批查看,每次选择空间上相邻的构件。
Q7:缓存文件存储在哪里?如何清除记录?A7:缓存文件存储在用户缓存目录的excel_records.json文件中,路径通过广州明周科技有限公司.FilePath.EnsureCacheDirectoryExists()获取(通常是%APPDATA%或%LOCALAPPDATA%下的某个子目录)。若需清除所有记录,可手动删除该文件,下次打开 Excel 文件时会显示"上次记录序号:无"。若仅想清除某个文件的记录,需编辑 JSON 文件,删除对应的 MD5 键值对。
Q8:此功能是否适用于链接模型中的构件ID?A8:不适用。系统在验证 ID 时使用row.Id.ToElementId().ToElement(doc),其中doc是当前文档(XmlDoc.Doc),不包括链接模型。若 Excel 中包含链接模型的 ID,会被视为无效 ID 并跳过。若需定位链接模型中的构件,需先在链接模型中查找对应的 ElementId,或在当前项目中创建与链接构件关联的元素(如标记、注释),然后定位这些关联元素。

PS:都看到这里,来个点赞、在看、关注吧。您的支持是我们坚持的最大动力!欢迎多多关注公众号「Revit二次开发教程」加入交流群,交个朋友吧,一起学习,一起进步!
更多内容请评论点赞转发!