Thursday, April 13, 2017

Revit 2018 Export Warnings from Model to Excel

Revit 2018 has added a great new addition to the API that allows you to collect all of the Warnings that exist in the model. Previously, you could only export this list by using the builtin "Export" button in the Warnings dialog, that exported to a HTML file.

The new addition is the following:

IList<FailureMessage> warnings = doc.GetWarnings();

The following macro will export all the warnings in your model to Excel:

public void ExportWarningsToExcel()
{
 // make sure to add a reference to Excel Object Library
 // put the following (minus the // into your using statements)
 // using xls = Microsoft.Office.Interop.Excel;
 // using System.Reflection;
 
 // create a new Excel connection
 xls.Application xlApp = new xls.Application();   
 
 // make sure you have access to Excel
 if (null == xlApp)
 {
  TaskDialog.Show("Error", "Failed to start or access Excel");
  
  return;
 }
 
 // get the current model
 Document doc = this.ActiveUIDocument.Document;
 
 // get a list of all the model's warnings
 IList<FailureMessage> warnings = doc.GetWarnings();
 
 try
 {
  // show the Excel window
  xlApp.Visible = true;
  
  // create a new Workbook in Excel
  xls.Workbook workbook = xlApp.Workbooks.Add(Missing.Value);
  
  // create a new Worksheet in Excel
  xls.Worksheet worksheet = (xls.Worksheet)workbook.Worksheets.Item[1];
  
  // name the Worksheet with the model name
  worksheet.Name = doc.Title;
      
  // create a header row
  worksheet.Cells[1,1] = "Warning Description";
  worksheet.Cells[1,2] = "Elements";
  
  // count the number of warnings
  int numWarnings = 0;
  // start on row 2 for warnings
  int row = 2;
  
  // loop through each warning
  foreach (FailureMessage fmsg in warnings)
  {
   // add the warning desciption to cell in Excel
   worksheet.Cells[row, 1] = fmsg.GetDescriptionText();
   
   // create a string to hold element info
   string elements = "";
        
   // loop through the element ids
   foreach (ElementId eid in fmsg.GetFailingElements())
   {
    // get the element
    Element e = doc.GetElement(eid);
    
    // add the element category
    elements += e.Category.Name + " : ";

    // some elements fail when getting their family type, so skip getting type if it fails
    try
    {
     // get the element family type
     elements += e.LookupParameter("Family").AsValueString() + " : ";
    }
    catch
    {
     
    }
          
    // add the element name
    elements += e.Name + " : ";
    
    // add the element id
    elements += "id " + eid.ToString() + System.Environment.NewLine + System.Environment.NewLine;
   }
   
   // add elements to cell in Excel
   worksheet.Cells[row, 2] = elements;
   
   // go to next row to Excel
   ++row;
   
   // increment number of warnings
   numWarnings++;
  }
  // expand columns to fit text
  xls.Range col1 = worksheet.get_Range("A1", Missing.Value);
  xls.Range col2 = worksheet.get_Range("B1", Missing.Value);
  col1.EntireColumn.ColumnWidth = 70;
  col1.EntireColumn.WrapText = true;
  col2.EntireColumn.ColumnWidth = 25;
  
  // show dialog for results
  TaskDialog.Show("Success", "Exported " + numWarnings.ToString() + " warnings to Excel!!!");
 }
 catch (Exception ex)
 {
  TaskDialog.Show("Error", "Something bad happened!!!" + System.Environment.NewLine
      + System.Environment.NewLine + ex.Message);    
 }
 
}

1 comment:

  1. hey Troygates, what using statement do I need? I've got O365 installed (Office 16) and when I build its not picking up the XLS commands.

    ReplyDelete