Issue in Comparing and updating Sheet Number Parameter in Revit

Issue in Comparing and updating Sheet Number Parameter in Revit

j_sunny9PYH6
Observer Observer
222 Views
1 Reply
Message 1 of 2

Issue in Comparing and updating Sheet Number Parameter in Revit

j_sunny9PYH6
Observer
Observer

I am trying to develop an add-in which exports Revit schedule to Excel and import it back to update the changes made in Excel. Before importing back I am checking whether the existing parameter value is same as that in excel . If its same I will ignore updating the parameter value.

Below is the code I am using for excel import. While looking at Revit Lookup I found 2 sheet Number parameter. So I modified the code to access the built-in sheet number. Also I am attaching the snapshot of excel I am importing. Even when I am not changing any value of sheet numbers , Code is trying to update the sheet number and gives me an error saying sheet number is already in use instead of bypassing the update of sheet number parameter. 

j_sunny9PYH6_3-1744777240171.png

 

 

j_sunny9PYH6_1-1744777076764.png

 

 private void Import_Excel_File_Click(object sender, RoutedEventArgs e)
 {
     OpenFileDialog openFileDialog = new OpenFileDialog();
     openFileDialog.Filter = "Excel files (*.xlsx)|*.xlsx";
     openFileDialog.Title = "Select Excel File to Import";

     if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
     {
         string filePath = openFileDialog.FileName;

         using (SpreadsheetDocument doc = SpreadsheetDocument.Open(filePath, false))
         {
             WorkbookPart workbookPart = doc.WorkbookPart;
             Sheet sheet = workbookPart.Workbook.Sheets.Elements<Sheet>().FirstOrDefault();
             WorksheetPart worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);
             SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().FirstOrDefault();

             var rows = sheetData.Elements<Row>().ToList();
             if (rows.Count < 2)
             {
                 System.Windows.MessageBox.Show("The Excel file doesn't contain enough data.");
                 return;
             }

             List<string> headers = rows[0].Elements<Cell>()
                 .Select(c => GetCellValue(c, workbookPart))
                 .ToList();

             int elementIdIndex = headers.FindIndex(h => h.Equals("Element ID", StringComparison.OrdinalIgnoreCase));
             if (elementIdIndex == -1)
             {
                 System.Windows.MessageBox.Show("The Excel file must contain an 'Element ID' column.");
                 return;
             }

             using (Transaction trans = new Transaction(doc1, "Update Parameters from Excel"))
             {
                 trans.Start();

                 for (int i = 1; i < rows.Count; i++)
                 {
                     Row row = rows[i];
                     var cells = row.Elements<Cell>().ToList();

                     if (cells.Count <= elementIdIndex) continue;

                     string idText = GetCellValue(cells[elementIdIndex], workbookPart);
                     if (!int.TryParse(idText, out int elemIdValue)) continue;

                     ElementId elemId = new ElementId(elemIdValue);
                     Element elem = doc1.GetElement(elemId);
                     if (elem == null) continue;

                     for (int j = 0; j < headers.Count; j++)
                     {
                         string paramName = headers[j];
                         if (paramName.Equals("Element ID", StringComparison.OrdinalIgnoreCase)) continue;

                         string paramValue = j < cells.Count ? GetCellValue(cells[j], workbookPart) : "";

                         // Special handling for Sheet Number
                         if (paramName.Equals("Sheet Number", StringComparison.OrdinalIgnoreCase))
                         {
                             ViewSheet sheetElem = elem as ViewSheet;
                             if (sheetElem == null) continue;

                             Autodesk.Revit.DB.Parameter sheetNumberParam = sheetElem.get_Parameter(BuiltInParameter.SHEET_NUMBER);
                             if (sheetNumberParam == null || sheetNumberParam.IsReadOnly) continue;

                             string currentVal = sheetNumberParam.AsString() ?? "";
                             if (currentVal == paramValue) continue;

                             bool duplicate = new FilteredElementCollector(doc1)
                                 .OfClass(typeof(ViewSheet))
                                 .Cast<ViewSheet>()
                                 .Any(s => s.SheetNumber.Equals(paramValue, StringComparison.OrdinalIgnoreCase) && s.Id != sheetElem.Id);

                             if (duplicate)
                             {
                                 TaskDialog.Show("Duplicate Sheet Number", $"Sheet Number '{paramValue}' is already in use. Skipping sheet ID: {sheetElem.Id.IntegerValue}");
                                 continue;
                             }

                             sheetNumberParam.Set(paramValue);
                             continue;
                         }

                         // Handle all other parameters
                         Autodesk.Revit.DB.Parameter param = elem.LookupParameter(paramName);
                         if (param == null || param.IsReadOnly) continue;

                         switch (param.StorageType)
                         {
                             case StorageType.String:
                                 string stringValue = paramValue ?? "";
                                 if (param.AsString() != stringValue)
                                     param.Set(stringValue);
                                 break;

                             case StorageType.Double:
                                 if (double.TryParse(paramValue, out double dVal))
                                 {
                                     if (Math.Abs(param.AsDouble() - dVal) > 1e-6)
                                         param.Set(dVal);
                                 }
                                 break;

                             case StorageType.Integer:
                                 if (int.TryParse(paramValue, out int iVal))
                                 {
                                     if (param.AsInteger() != iVal)
                                         param.Set(iVal);
                                 }
                                 break;
                         }
                     }
                 }

                 trans.Commit();
             }

             System.Windows.MessageBox.Show("Parameter values updated from Excel.");
         }
     }
     else
     {
         System.Windows.MessageBox.Show("The Cancel button was clicked or Esc was pressed.");
     }
 }

 

0 Likes
223 Views
1 Reply
Reply (1)
Message 2 of 2

TripleM-Dev.net
Advisor
Advisor

Don't use names for parameters to retrieve (or it should be a hard reference, like if the column is called "Sheet Number" then use the builtin parameter OST_xxxx)

 

If you want to be flexibel (as we also can make or own shared parameter that's named "Sheet Number"), include the ID of the definition (second row below the column name or something like that)

 

In regards to the "Sheet Number" parameters their OST_xxx builtin enums are different and used for different purpuse,

There are several of these double builtin parameter with identical names, most of them related to views-viewports-sheets.

 

Check elements with Revit Lookup, when and where they exist and the value, also search this forum I bet there are already some posts about them.

 

- Michel

0 Likes