如何通过Revit API读取当前项目的所有警告(无需HTML导出)
嘿,我太懂你这个困扰了!之前论坛里的方案估计是用了获取默认警告定义的API,才拿到和当前项目无关的列表。其实Revit API里有专门的方法直接读取当前项目的实际警告,完全不用导出HTML,还能轻松组织成你想要的层级结构。
正确的Revit API方案:使用
Document.GetWarnings() 这个方法是专门用来获取当前打开项目中实际存在的警告/错误的,返回的是IList<FailureMessage>集合——每个FailureMessage对象都包含了你需要的所有细节,刚好可以用来构建层级化的警告结构。
层级结构的核心信息提取
你可以从每个FailureMessage里提取这些分层级的内容:
- 第一层级:警告级别:通过
GetSeverity()获取,分为FailureSeverity.Warning(普通警告)、FailureSeverity.Error(错误)等,用来做最高级别的分类 - 第二层级:警告类型:
GetFailureDefinitionId()返回唯一的警告类型ID,配合FailureDefinition.GetName()可以得到该类警告的通用名称,比如“重叠的墙”“未连接的风管” - 第三层级:具体细节:
GetDescriptionText():针对当前项目的具体警告描述GetFailingElements():返回导致该警告的元素ID集合,还能进一步获取元素的类别、名称、ID号等信息
代码示例(C#)
下面是一个外部命令的示例,会自动遍历当前项目的所有警告,并按层级输出信息:
using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using System; using System.Collections.Generic; [Transaction(TransactionMode.ReadOnly)] public class GetProjectWarnings : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Document doc = uidoc.Document; // 获取当前项目的所有实际警告 IList<FailureMessage> warnings = doc.GetWarnings(); if (warnings.Count == 0) { TaskDialog.Show("提示", "当前项目没有任何警告或错误"); return Result.Succeeded; } // 按警告级别分组(第一层分类) var groupedBySeverity = new Dictionary<FailureSeverity, List<FailureMessage>>(); foreach (var warning in warnings) { FailureSeverity severity = warning.GetSeverity(); if (!groupedBySeverity.ContainsKey(severity)) { groupedBySeverity[severity] = new List<FailureMessage>(); } groupedBySeverity[severity].Add(warning); } // 遍历分组,输出层级化内容 foreach (var severityGroup in groupedBySeverity) { string severityName = severityGroup.Key.ToString(); TaskDialog.Show($"[{severityName}] 警告列表", BuildWarningHierarchy(severityGroup.Value, doc)); } return Result.Succeeded; } // 构建层级化的警告文本 private string BuildWarningHierarchy(List<FailureMessage> warnings, Document doc) { // 按警告类型分组(第二层分类) var groupedByDefId = new Dictionary<FailureDefinitionId, List<FailureMessage>>(); foreach (var warning in warnings) { FailureDefinitionId defId = warning.GetFailureDefinitionId(); if (!groupedByDefId.ContainsKey(defId)) { groupedByDefId[defId] = new List<FailureMessage>(); } groupedByDefId[defId].Add(warning); } string hierarchyText = ""; foreach (var defGroup in groupedByDefId) { FailureDefinition def = FailureDefinition.GetFailureDefinition(defGroup.Key); string defName = def.GetName(); hierarchyText += $"=== {defName} ===\n"; // 遍历同类型警告,输出具体细节(第三层) foreach (var warning in defGroup.Value) { string description = warning.GetDescriptionText(); hierarchyText += $"- 警告内容:{description}\n"; // 获取并输出关联元素 ICollection<ElementId> failingElements = warning.GetFailingElements(); if (failingElements.Count > 0) { hierarchyText += " 关联元素:\n"; foreach (var elemId in failingElements) { Element elem = doc.GetElement(elemId); if (elem != null) { hierarchyText += $" - {elem.Category.Name}:{elem.Name} (ID: {elemId.IntegerValue})\n"; } } } hierarchyText += "\n"; } } return hierarchyText; } }
额外注意事项
- 这个操作是只读的,所以标记
TransactionMode.ReadOnly即可,不需要开启修改事务 - 如果需要更精细的层级(比如按元素类别再分组),可以在关联元素的部分进一步扩展逻辑
FailureMessage还有GetResolutionType()方法,可以获取该警告可用的修复方式,要是你需要自动处理警告也能用上
内容的提问来源于stack exchange,提问作者Ali Asad
相关产品推荐
相关产品推荐

