Waiting for a model to open to make an action

Hi All,

Trying to run a very basic script that exports the count and name of categories used in the model. However, what I am trying to ultimately do is open a model and then run the script after it has opened. At the moment the script runs in a model before the next model is open, so if I am in an empty model it will return an empty excel sheets as there are no categories in the model. In addition hopefully do this with several models. Any help is appreciated. Thanks

import os
import sys
import clr
from Autodesk.Revit.UI import *
from Autodesk.Revit.DB import ModelPathUtils, OpenOptions, BuiltInCategory, FilteredElementCollector, Transaction
from pyrevit import forms
clr.AddReference('Microsoft.Office.Interop.Excel')
from Microsoft.Office.Interop import Excel
from System import EventHandler, Uri
from Autodesk.Revit.UI.Events import ViewActivatedEventArgs, ViewActivatingEventArgs


app = __revit__.Application
doc = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
uiapp = __revit__

openOptions = OpenOptions()

dir_path = os.path.dirname(os.path.realpath(__file__))
local_path = forms.pick_file(file_ext='rvt', multi_file=False)

if not local_path:
	print("No file chosen!")
	sys.exit()

if local_path:
	if os.path.exists(local_path):
		uiapp.OpenAndActivateDocument(ModelPathUtils.ConvertUserVisiblePathToModelPath(local_path), openOptions, False)
	else:
		print("File does not exist: {0}".format(local_path))

    
categories = [BuiltInCategory.OST_GenericModel, BuiltInCategory.OST_SpecialityEquipment, BuiltInCategory.OST_Casework, BuiltInCategory.OST_Ceilings, BuiltInCategory.OST_Railings, BuiltInCategory.OST_Columns, BuiltInCategory.OST_CurtainWallMullions, BuiltInCategory.OST_Doors, BuiltInCategory.OST_Entourage, BuiltInCategory.OST_Floors, BuiltInCategory.OST_Furniture, BuiltInCategory.OST_FurnitureSystems, BuiltInCategory.OST_ElectricalCircuit, BuiltInCategory.OST_MEPSpaces, BuiltInCategory.OST_Planting, BuiltInCategory.OST_Railings, BuiltInCategory.OST_Roads, BuiltInCategory.OST_Roofs, BuiltInCategory.OST_Site, BuiltInCategory.OST_Stairs, BuiltInCategory.OST_Walls, BuiltInCategory.OST_Windows, BuiltInCategory.OST_CableTrayFitting, BuiltInCategory.OST_CableTray, BuiltInCategory.OST_CommunicationDevices, BuiltInCategory.OST_ConduitFitting, BuiltInCategory.OST_Conduit, BuiltInCategory.OST_DataDevices, BuiltInCategory.OST_DuctAccessory, BuiltInCategory.OST_DuctFitting, BuiltInCategory.OST_DuctSystem, BuiltInCategory.OST_DuctCurves, BuiltInCategory.OST_ElectricalEquipment, BuiltInCategory.OST_ElectricalFixtures, BuiltInCategory.OST_FireAlarmDevices, BuiltInCategory.OST_FlexDuctCurves, BuiltInCategory.OST_FlexPipeCurves, BuiltInCategory.OST_LightingDevices, BuiltInCategory.OST_LightingFixtures, BuiltInCategory.OST_MechanicalEquipment, BuiltInCategory.OST_PipeAccessory, BuiltInCategory.OST_PipeFitting, BuiltInCategory.OST_PipeCurves, BuiltInCategory.OST_PipingSystem, BuiltInCategory.OST_PlumbingFixtures, BuiltInCategory.OST_SecurityDevices, BuiltInCategory.OST_Sprinklers, BuiltInCategory.OST_SwitchSystem, BuiltInCategory.OST_TelephoneDevices, BuiltInCategory.OST_Wire, BuiltInCategory.OST_BoundaryConditions, BuiltInCategory.OST_RebarShape, BuiltInCategory.OST_StructuralColumns, BuiltInCategory.OST_StructuralFoundation, BuiltInCategory.OST_StructuralFraming, BuiltInCategory.OST_StructuralStiffener, BuiltInCategory.OST_StructuralTruss]
cat = []
elements = []

for i in categories:
	lst = FilteredElementCollector(doc).WhereElementIsNotElementType().OfCategory(i).WhereElementIsViewIndependent().ToElements()
	if len(lst) > 0:
		cat.append(i.ToString()[4:])
		elements.append(len(lst))

used_categories = [i for i in zip(cat, elements) if i[1] > 0]

t = Transaction(doc, "Excel Export")

t.Start()
# Create a new Excel Workbook
xl = Excel.ApplicationClass()
xl.Visible = True
xl.DisplayAlerts = False
workbook = xl.Workbooks.Add()
sheet = workbook.ActiveSheet
sheet.Name = "Export Categories"

# Create a header
header = ["Categories", "Count"]
for x in range(2):
	sheet.Cells(1, x + 1).Value = header[x]
	sheet.Cells(1, x + 1).Font.Bold = True

# Fill the rest of the cells with the data
for y in range(len(cat)):
	sheet.Cells(y + 2, 1).Value = cat[y]
	sheet.Cells(y + 2, 2).Value = elements[y]

# Save the file
workbook.SaveAs(r'C:\Users\helmy\Desktop\test2.xlsx')
t.Commit()

Figured a way to just use pyRevit CLI to open the model and run the script as I want, unfortunately still stuck with having multiple models to open and do the task. The error im getting is “Error: File is not a structured storage file”. Any help is appreciated. Thanks

Hi Ahmed,

It sounds like this would be a good script to use the hooks system. I think the doc-opened hook would work. So copy-paste or save-as your current script into a python file called doc-opened.py in a hooks subfolder in your main extension folder. See Notion – The all-in-one workspace for your notes, tasks, wikis, and databases. for more info.

Hope this helps!

Hi Stewart,

Thanks for your response. This would definitely work as intended :). Im still discovering the notion docs been using pyRevit without ever looking at most of it :smile:. The cli works fine with creating the same actions however getting to have this working for multiple models is still an issue. Ill probably open another thread for it if im unable to get it working.