I am attempting to write a Python script to run as a macro. I am wanting to select all views and then filter out only one based on the “View Name” Parameter.
I am getting an error that certain views do not have the parameter “View Name” or that the values are null.
I had tried to handle the exception using …
for view in _view_list:
try:
if view.GetParameterValueByName("Type") == "02 Shared" and view.GetParameterValueByName("View Name") == "3D - IFC (2019)":
pass
else :
view_list.append(view)
except (TypeError, AttributeError):
view_list.append(view)
However this is catching all views.
Also i understand from reading around that the built in parameters underlying the user displayed parameter names are different. And the following page mentions to use the LabelUtils class to find the list of parameters and their corresponding built in parameter names.
I had thought that
view.LabelUtils.GetLabelFor(BuiltInParameter) #(view being a single view iterated from view_list)
would give me a list of the various user and correspnding built in parameters, however I am getting an AttributeError
’View’ Object has no attribute “LabelUtils”
Could anyone help. Its my first foray into the API which has been going quite well up to now.
How are you selecting your views? I’m guessing that your method is also including View Templates which don’t have Types and that’s causing the error. You’ll have to filter out view templates before searching by Type.
Edited file attached above - remove a repeated bit of code I had commented out (assumed i’d made a syntax error while writing it, deleted to avoisd confusion of repeated code blocks
I replaced the view.GetParameterValueByName method with a simple view.Name, split some of your arguments into two lines, and removed a space from the beginning of 3D - IFC (2019). That got it working.
for view in _viewlist:
try :
if view.Name == "3D - IFC (2019)":
ifc_view.append(view)
else:
viewlist.append("view")
except AttributeError :
viewlist.append("Caught")
Just an FYI. There are nodes in various packages that allow you to do some very specific parameter value extraction, Take for example the BuiltInParameter name nodes in Archi-lab.net.
Can i ask purely out of interest. Why is using BIP’s not safe / bad. Simply these are intended to run in the background and shouldn’t be altered or another reason?
Using BIP is neither unsafe nor bad. It is definitely a lot better than using the (system) parameter names that are exposed in the Revit UI since those are localized (i.e. language-specific) labels. However, if the parameter is mapped to an element property that is exposed in the Revit API, it makes more sense to use that property directly. View names may serve as a good example here: Sheets are a subclass of the view class, yet they have their own BIP mapped to the Name property (SHEET_NAME) whereas all other views (at least I think it’s all other views) use another BIP (VIEW_NAME). If you wanted to get the name of other elements as well, you would have to accomodate for even more BIPs while simply using the Name property would work in most cases. Element level is a similar case, btw.
So back again out of hours trying to work on this stuff (I really should sort out a licence for home!!) - I do have a beer at least
Anyway, the goal posts have slightly shifted. In that I am wanting to try to filter by “Type” Parameter. And keep all the views which have a Type value of “00 MASTER”
Following what I have learned from this thread. I have been using the GetParameters() method, not GetParameterValueByName
When i using
view.GetParameters("Type")
Some views seem to have one parameters - others three.
I cannot use
view.GetParameters("Type").AsString()
because sometimes it is a list and sometimes a single value. I am going to now test for lists then iterate through them for their name and then clean the list (in the case of three values) it seems two are null and often [1] is the entry i am looking for.
Following Konrad’s advice I tried to see if using the bipParameter would work - it seems either “ALL_MODEL_ELEM_TYPE” or “ELEM_TYPE_PARAM” would be the ones I am after - however these produce empty lists.
This seems much more complicated to have to go back and check for list - then iterate through, just because extra nulls are being created.