To help BIM Managers train or punish their Revit users, I was asked at RTC in Delft if we can use the API to figure out which users are responsible for each warning in your Revit file.
Here’s how that can be done by writing all warnings to a log file and then comparing warnings in the current file with those in the log.
public void RegisterFailureReporter()
{
Application app = this.Application;
Document doc = this.ActiveUIDocument.Document;
if (doc.PathName == "")
{
TaskDialog.Show("Error","Please save the file and then repeat this command.");
return;
}
app.FailuresProcessing += FailureReporter;
}
private void FailureReporter(object sender, Autodesk.Revit.DB.Events.FailuresProcessingEventArgs args)
{
FailuresAccessor fa = args.GetFailuresAccessor();
Document doc = fa.GetDocument();
using (StreamWriter sw = new StreamWriter(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), Path.GetFileName(doc.PathName) + " Warning Creation Log.csv"), true))
{
foreach (FailureMessageAccessor fma in fa.GetFailureMessages(FailureSeverity.Warning))
{
sw.Write(DateTime.Now + "," + fa.GetDocument().Application.Username + ",");
sw.Write(fma.GetDescriptionText().Replace(Environment.NewLine,"") + "," );
foreach (ElementId id in fma.GetFailingElementIds())
{
// use UniqueId instead of ElementId because the UniqueId is stable across Save To Central while the ElementId property may change.
sw.Write(doc.GetElement(id).UniqueId + ",");
}
sw.Write(Environment.NewLine);
}
}
}
public void CheckCurrentWarningsInLog()
{
Document doc = this.ActiveUIDocument.Document;
if (doc.PathName == "")
{
TaskDialog.Show("Error","Please save the file and then repeat this command.");
return;
}
using (StreamReader warningsHTMLReader = new StreamReader(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), Path.GetFileNameWithoutExtension(doc.PathName) + "_Error Report.html")))
{
string line = "";
while ((line = warningsHTMLReader.ReadLine()) != null)
{
if (!line.Contains(": id "))
continue;
string[] row = System.Text.RegularExpressions.Regex.Split(line, "id ");
string id1 = row[1].Split(' ')[0];
string uniqueId1 = doc.GetElement(new ElementId(int.Parse(id1))).UniqueId;
string uniqueId2 = null;
if (row.Count() == 3) // there are two element ids in this row
{
string id2 = row[2].Split(' ')[0];
uniqueId2 = doc.GetElement(new ElementId(int.Parse(id2))).UniqueId;
}
using (StreamReader warningLogReader = new StreamReader(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), Path.GetFileName(doc.PathName) + " Warning Creation Log.csv")))
{
string lineLog = "";
while ((lineLog = warningLogReader.ReadLine()) != null)
{
if (lineLog.Contains(uniqueId1) || (uniqueId2 != null && lineLog.Contains(uniqueId1) && lineLog.Contains(uniqueId2)))
{
using (StreamWriter sw = new StreamWriter(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), Path.GetFileName(doc.PathName) + " Current Warnings With User Info.csv"), true))
{
sw.WriteLine(lineLog);
}
break;
}
}
}
}
}
}