Python script doesn't work in Revit 2023

Hi guys,

Is there something change inside Revit 2023 at the BuiltinCategorys?
This script works fine in R20-22 but it is broken in R23.

I created this script in IronPython2.

import clr #.NET Laden
import sys #sys is de fundamentele Python bibliotheek
#de standaard IronPython-bibliotheken
#sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib') #Imports the
#standaard IronPython-bibliotheken, die alles dekken, van servers en
#encryptie tot reguliere expressies.
import System #The System namespace in de hoofdmap .NET
from System import Array #.NET class voor het verwerken van array-informatie
import System.Collections.Generic as MGen #Module kan nu benaderd worden met MGen.xxxx
#from System.Collections.Generic import * #Hiermee kunt u generieke afhandelen. Revit's API
#soms wil hard-getypte 'generieke' lijsten, genaamd ILists. Als je niet nodig hebt
#deze kunt u deze regel verwijderen.
clr.AddReference('ProtoGeometry')  #Een Dynamo-bibliotheek voor zijn proxygeometrie
#classes. Je hebt dit alleen nodig als je interactie hebt met geometrie.
import Autodesk.DesignScript.Geometry as AGeo #Module kan worden opgeroepen a=met AGeo.xxxx
#from Autodesk.DesignScript.Geometry import * #Laadt alles in Dynamo's
#geometriebibliotheek
clr.AddReference("RevitNodes") #Dynamo's nodes voor Revit
import Revit #Laad in de Revit-namespaces in RevitNodes
clr.ImportExtensions(Revit.Elements) #Meer laden van Dynamo's Revit-bibliotheken
clr.ImportExtensions(Revit.GeometryConversion) #Meer laden van Dynamo's
#Revit-bibliotheken. Je hebt dit alleen nodig als je interactie hebt met geometrie.
clr.AddReference("RevitServices") #Dynamo's classes voor het omgaan met Revit-documenten
import RevitServices 
from RevitServices.Persistence import DocumentManager #Een interne Dynamo class
#dat het document bijhoudt waaraan Dynamo momenteel is gekoppeld
from RevitServices.Transactions import TransactionManager #Een Dynamo class voor
#transacties openen en sluiten om de database van het Revit-document te wijzigen

clr.AddReference("RevitAPI") #Verwijzing naar Revit's API DLL's toevoegen
clr.AddReference("RevitAPIUI") #Verwijzing naar Revit's APIUI DLL's toevoegen

import Autodesk #Loads the Autodesk namespace
import Autodesk.Revit.DB as RDB #Loading Revit's API UI classes module kan nu worden aangeroepen met RDB.xxxx
#from Autodesk.Revit.DB import * #Loading Revit's API UI classes
import Autodesk.Revit.UI as RUI # Loading Revit's API UI classes als RUI.xxxx
#from Autodesk.Revit.UI import * #Loading Revit's API UI classes

doc = DocumentManager.Instance.CurrentDBDocument #Dit is het actieve Revit document
uiapp = DocumentManager.Instance.CurrentUIApplication #Een handle instellen voor het actieve Revit UI-document
app = uiapp.Application  #Een handle instellen op de momenteel geopende instantie van de Revit-toepassing
uidoc = uiapp.ActiveUIDocument #Een handle instellen op de momenteel geopende instantie van de Revit UI-toepassing

# einde code omrekenen revit feet naar huidig ingestelde document units
# Hieronder kan je dan gaan programmeren
# Gebruik boiler template


cat_list = [RDB.BuiltInCategory.OST_ElectricalFixtureTags, RDB.BuiltInCategory.OST_DataDeviceTags, RDB.BuiltInCategory.OST_CommunicationDeviceTags]
typed_list = MGen.List[RDB.BuiltInCategory](cat_list)
filter = RDB.ElementMulticategoryFilter(typed_list)
elementen = RDB.FilteredElementCollector(doc).WherePasses(filter).WhereElementIsNotElementType().ToElements()

EFT = RDB.FilteredElementCollector(doc).OfCategory(RDB.BuiltInCategory.OST_ElectricalFixtureTags).WhereElementIsNotElementType().ToElements() #ElectricalFixtureTags ophalen in filter


#Start Transaction
TransactionManager.Instance.EnsureInTransaction(doc)

#bestemming tags
EFTag_bestemming = []
for e in elementen:
	familynaam_type = e.get_Parameter(RDB.BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM).AsValueString()
	if familynaam_type == "63_EFT_UN_MC_1.8_t: bestemming" or familynaam_type == "64_DDT_UN_MC_1.8_t: bestemming" or familynaam_type == "64_CDT_UN_MC_1.8_t: bestemming" : 
		EFTag_bestemming.append(e)
#circuitnumber tags
EFTag_circuitnumber = []
for e in elementen:
	familynaam_type = e.get_Parameter(RDB.BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM).AsValueString()
	if familynaam_type == "63_EFT_UN_MC_1.8_t: circuit number" or familynaam_type == "63_LFT_UN_MC_1.8_t: circuit number": 
		EFTag_circuitnumber.append(e)
#montagehoogte tags		
EFTag_montagehoogte = []
for e in elementen:
	familynaam_type = e.get_Parameter(RDB.BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM).AsValueString()
	if familynaam_type == "63_EFT_UN_MC_1.8_t: montagehoogte" or familynaam_type == "63_LFT_UN_MC_1.8_t: montagehoogte": 
		EFTag_montagehoogte.append(e)

	
#Eind Transactie
TransactionManager.Instance.TransactionTaskDone()

OUT = EFTag_bestemming, EFTag_circuitnumber,  EFTag_montagehoogte 

Hi,

There is an error or your elementen list is empty ?

Hi @c.poupin ,

The elementen list is okay:

The script is not giving any error.

seems to work fine :thinking:

the only API change regarding Tags that I know of is this property ( deprecated )

but this property is not used in your code snippet

@c.poupin

I have seen it, i use it in an other part of the script but this is strange.

Any thoughts what I can do?

if you have an empty OUT list with this code, there may be a problem with your equality comparators (check values)

Code
import clr #.NET Laden
import sys #sys is de fundamentele Python bibliotheek
#de standaard IronPython-bibliotheken
#sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib') #Imports the
#standaard IronPython-bibliotheken, die alles dekken, van servers en
#encryptie tot reguliere expressies.
import System #The System namespace in de hoofdmap .NET
from System import Array #.NET class voor het verwerken van array-informatie
import System.Collections.Generic as MGen #Module kan nu benaderd worden met MGen.xxxx
#from System.Collections.Generic import * #Hiermee kunt u generieke afhandelen. Revit's API
#soms wil hard-getypte 'generieke' lijsten, genaamd ILists. Als je niet nodig hebt
#deze kunt u deze regel verwijderen.
clr.AddReference('ProtoGeometry')  #Een Dynamo-bibliotheek voor zijn proxygeometrie
#classes. Je hebt dit alleen nodig als je interactie hebt met geometrie.
import Autodesk.DesignScript.Geometry as AGeo #Module kan worden opgeroepen a=met AGeo.xxxx
#from Autodesk.DesignScript.Geometry import * #Laadt alles in Dynamo's
#geometriebibliotheek
clr.AddReference("RevitNodes") #Dynamo's nodes voor Revit
import Revit #Laad in de Revit-namespaces in RevitNodes
clr.ImportExtensions(Revit.Elements) #Meer laden van Dynamo's Revit-bibliotheken
clr.ImportExtensions(Revit.GeometryConversion) #Meer laden van Dynamo's
#Revit-bibliotheken. Je hebt dit alleen nodig als je interactie hebt met geometrie.
clr.AddReference("RevitServices") #Dynamo's classes voor het omgaan met Revit-documenten
import RevitServices 
from RevitServices.Persistence import DocumentManager #Een interne Dynamo class
#dat het document bijhoudt waaraan Dynamo momenteel is gekoppeld
from RevitServices.Transactions import TransactionManager #Een Dynamo class voor
#transacties openen en sluiten om de database van het Revit-document te wijzigen

clr.AddReference("RevitAPI") #Verwijzing naar Revit's API DLL's toevoegen
clr.AddReference("RevitAPIUI") #Verwijzing naar Revit's APIUI DLL's toevoegen

import Autodesk #Loads the Autodesk namespace
import Autodesk.Revit.DB as RDB #Loading Revit's API UI classes module kan nu worden aangeroepen met RDB.xxxx
#from Autodesk.Revit.DB import * #Loading Revit's API UI classes
import Autodesk.Revit.UI as RUI # Loading Revit's API UI classes als RUI.xxxx
#from Autodesk.Revit.UI import * #Loading Revit's API UI classes

doc = DocumentManager.Instance.CurrentDBDocument #Dit is het actieve Revit document
uiapp = DocumentManager.Instance.CurrentUIApplication #Een handle instellen voor het actieve Revit UI-document
app = uiapp.Application  #Een handle instellen op de momenteel geopende instantie van de Revit-toepassing
uidoc = uiapp.ActiveUIDocument #Een handle instellen op de momenteel geopende instantie van de Revit UI-toepassing

# einde code omrekenen revit feet naar huidig ingestelde document units
# Hieronder kan je dan gaan programmeren
# Gebruik boiler template


cat_list = [RDB.BuiltInCategory.OST_ElectricalFixtureTags, RDB.BuiltInCategory.OST_DataDeviceTags, RDB.BuiltInCategory.OST_CommunicationDeviceTags]
typed_list = MGen.List[RDB.BuiltInCategory](cat_list)
filter = RDB.ElementMulticategoryFilter(typed_list)
elementen = RDB.FilteredElementCollector(doc).WherePasses(filter).WhereElementIsNotElementType().ToElements()

EFT = RDB.FilteredElementCollector(doc).OfCategory(RDB.BuiltInCategory.OST_ElectricalFixtureTags).WhereElementIsNotElementType().ToElements() #ElectricalFixtureTags ophalen in filter


#Start Transaction
TransactionManager.Instance.EnsureInTransaction(doc)

#bestemming tags
EFTag_bestemming = []
for e in elementen:
	familynaam_type = e.get_Parameter(RDB.BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM).AsValueString()
	if familynaam_type == "63_EFT_UN_MC_1.8_t: bestemming" or familynaam_type == "64_DDT_UN_MC_1.8_t: bestemming" or familynaam_type == "64_CDT_UN_MC_1.8_t: bestemming" : 
		EFTag_bestemming.append(e)
#circuitnumber tags
EFTag_circuitnumber = []
for e in elementen:
	familynaam_type = e.get_Parameter(RDB.BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM).AsValueString()
	if familynaam_type == "63_EFT_UN_MC_1.8_t: circuit number" or familynaam_type == "63_LFT_UN_MC_1.8_t: circuit number": 
		EFTag_circuitnumber.append(e)
#montagehoogte tags		
EFTag_montagehoogte = []
for e in elementen:
	familynaam_type = e.get_Parameter(RDB.BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM).AsValueString()
	if familynaam_type == "63_EFT_UN_MC_1.8_t: montagehoogte" or familynaam_type == "63_LFT_UN_MC_1.8_t: montagehoogte": 
		EFTag_montagehoogte.append(e)

	
#Eind Transactie
TransactionManager.Instance.TransactionTaskDone()

OUT = EFTag_bestemming, EFTag_circuitnumber,  EFTag_montagehoogte

@c.poupin

That’s the strange thing, this works for me. As soon as I apply the for loop and want to append the elements, then I suddenly get an empty list. The family has not changed from r20

Really strange, nothing is changed but when I use the .Contains() it works fine…
Well fixed for now, next point is this.

1 Like

maybe you have an extra space character (at the end) in your Type Family Name

1 Like

@c.poupin , No I don’t have, but this way is alot saver.
I take all the duplicated tags also with .Contains()

1 Like

Solution for the TaggedElementId Property:

revit_version = int(doc.Application.VersionNumber)

def TaggedElement(tag):
    if revit_version >= 2022:  	
    	return tag.GetTaggedLocalElements()
    else:
    	return tag.GetTaggedLocalElement()

A little improvement :wink:

revit_version = int(doc.Application.VersionNumber)

def TaggedElements(tag):
	"""
	-description:
		Get the tagged local elements
	-Parameters:
		tag : RDB.IndependentTag
	-Return:
		Collection of Elements
	"""
	if revit_version >= 2022:  	
		return tag.GetTaggedLocalElements()
	else:
		return List[RDB.Element]([tag.GetTaggedLocalElement()])
2 Likes

@c.poupin Haha yes you are alright, I had seen the ICollection function, but it did work without it :see_no_evil:

Can you explain me what the IList and ICollection do in the Revit API?

IList and ICollection are part of .Net. They are not really part of Revit - just the way .Net manages lists and collections.

ICollection Interface (System.Collections.Generic) | Microsoft Learn

IList Interface (System.Collections) | Microsoft Learn

3 Likes

yes, but this improvement allows you to return a collection all the time regardless of the version of Revit, this avoids testing the returned object later in the code (list or element ?)

1 Like