SetParameterByName to wall object in Python

I just tested you actually dont need to load anything, the below worked fine for me

elements = IN[0]
for element in elements:
    element.SetParameterByName('Comments', 'test')
OUT = 'done'
1 Like

I have just tested this

elements = IN[0]
for element in elements:
    level = element.GetParameterValueByName('Base Constraint')
    if '1' in level.Name:
        element.SetParameterByName('Comments', 'test')
OUT = 'done'

and without understanding Spanish, then I suppose something like this will work

elements = IN[0]
rebar_cover = IN[1]
rebar = rebar_cover[8]
for element in elements:
    level = element.GetParameterValueByName('Base Constraint')
    if 'FUNDACION' in level.Name:       
        element.SetParameterByName("Rebar Cover - Exterior Face", rebar)
        element.SetParameterByName("Rebar Cover - Interior Face", rebar)
        elementelement.SetParameterByName("Rebar Cover - Other Faces", rebar)
OUT = 'done'
1 Like

Thanks, @erfajo! It works like you said. But, I doing the collector to avoid putting the nodes “Categories” and “All Elements of Category”. I want to do this process in Python.
More similar to what I did in the first post.

Is it possible?

Thanks in advance!

That should be doable. This example is the same as I have been testing on, just collecting the elements inside the python script.

# Common Language Runtime modules
import clr
clr.AddReference('RevitAPI')
clr.AddReference('RevitServices')
clr.AddReference('RevitNodes')

# Revit and Dynamo modules
from Autodesk.Revit.DB import BuiltInCategory, FilteredElementCollector
from RevitServices.Persistence import DocumentManager
import Revit
clr.ImportExtensions(Revit.Elements)

doc = DocumentManager.Instance.CurrentDBDocument

# collect walls
walls = (
    FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls)
    .WhereElementIsNotElementType().ToElements())

# turn into dynamo type
elements = []
for wall in walls:
    elements.append(wall.ToDSType(True))

for element in elements:
    level = element.GetParameterValueByName('Base Constraint')
    if '1' in level.Name:
        element.SetParameterByName('Comments', 'test')

OUT = 'done'

…or joined in one loop

elements = (
    FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls)
    .WhereElementIsNotElementType().ToElements())

for element in elements:
    element = element.ToDSType(True)
    level = element.GetParameterValueByName('Base Constraint')
    if '1' in level.Name:
        element.SetParameterByName('Comments', 'test')

WOW! Great! Thanks a lot @erfajo . I didn’t know about the “WhereElementIsNotElementType()” method. Also, I think the “ToElements()” was the stumbling rock here. I’ll adjust my script using your recommendations.

Thanks a lot.

Hi @erfajo:

I managed to adjust my code using you directions:

import clr

clr.AddReference('RevitAPI')
clr.AddReference('RevitServices')
clr.AddReference('RevitNodes')

#Importar el Docuement Manager y Transacciones
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# Revit and Dynamo modules
from Autodesk.Revit.DB import BuiltInCategory, FilteredElementCollector
from RevitServices.Persistence import DocumentManager
import Revit
clr.ImportExtensions(Revit.Elements)

# Datos de entrada
EntradaTonta = IN[0]		#Solo se deja para que funcione el Passthrough.

# Hacer referencia al documento activo.
doc = DocumentManager.Instance.CurrentDBDocument

# Crear un colector de los elementos para ciertas categorias (http://www.revitapidocs.com/2017.1/ba1c5b30-242f-5fdc-8ea9-ec3b61e6e722.htm)
Niveles = (FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).WhereElementIsNotElementType().ToElements())
Muros = (FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToElements())
RebarCover = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_CoverType).ToElements()

# Inicia la transaccion
TransactionManager.Instance.EnsureInTransaction(doc)

# Corrige el nombre de los niveles de acuerdo al criterio indicado en el manual.
for i in Niveles:
    if 'FUNDACION' in i.Name:
        i.Name = 'PLANTA DE FUNDACIONES'
    elif ' ' in i.Name:
        i.Name = (i.Name).Replace(' ', '')



# Finaliza la transaccion
TransactionManager.Instance.TransactionTaskDone()

# Aplica recubrimientos en todos los elementos muro.

for wall in Muros:
    muro = wall.ToDSType(True)
    muro.SetParameterByName('Rebar Cover - Exterior Face', RebarCover[8])
    muro.SetParameterByName('Rebar Cover - Interior Face', RebarCover[8])
    muro.SetParameterByName('Rebar Cover - Other Faces', RebarCover[8])

OUT = 'Nombres de pisos corregidos y parametros asignados correctamente.'

But now, if I want to assign a RebarCover Type to the corresponding parameter, the error says: “No parameter found by that name”.

This is weird, because If I look for Element.Parameters, I get the desired Parameter.

Any thoughts?

Thanks in advance for your time.

do you have a sample file?
Your previously uploaded graph contained other elements/nodes I do not have, so I cant really use that as it is. What I have done is creating “clean” scenario for my tests.

Do you think it looks like this Subcategory problem, where the problems were to find the subcategory to a category? just a thought

Hi,

I don’t think it is a SubCategory issue.

Here I made a simple example. I couldn’t replicate the exact error that I’m witnessing:

https://drive.google.com/open?id=1orXqYYt8SvyzkWArdRys_4h5k80NEOHb

Now, I’m getting this error:

image

Thanks in advance!

I found your problem, remember that everything you collect is Revit elements, not dynamo elements.
change this line so it fits to your purpose -> cover_type_ds = cover_types_ds[1]

# Common Language Runtime modules
import clr
clr.AddReference('RevitAPI')
clr.AddReference('RevitServices')
clr.AddReference('RevitNodes')

# Revit and Dynamo modules
from Autodesk.Revit.DB import BuiltInCategory, FilteredElementCollector
from RevitServices.Persistence import DocumentManager
import Revit
clr.ImportExtensions(Revit.Elements)

doc = DocumentManager.Instance.CurrentDBDocument

# collect walls
walls = (
    FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls)
    .WhereElementIsNotElementType().ToElements())

# turn into dynamo type
walls_ds = []
for wall in walls:
    walls_ds.append(wall.ToDSType(True))

# get rebar cover types
cover_types = (
    FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_CoverType)
    .ToElements())

# turn into dynamo type
cover_types_ds = []
for cover_type in cover_types:
    cover_types_ds.append(cover_type.ToDSType(True))

cover_type_ds = cover_types_ds[1]

for wall in walls_ds:
    level = wall.GetParameterValueByName('Base Constraint')
    if '1' in level.Name:
        wall.SetParameterByName('Rebar Cover - Exterior Face', cover_type_ds)
        wall.SetParameterByName('Rebar Cover - Interior Face', cover_type_ds)
        wall.SetParameterByName('Rebar Cover - Other Faces', cover_type_ds)

OUT = 'done'
1 Like

@erfajo I found the missing piece for the “No parameter found by that name” error. The model had some architectural walls which I couldn’t see in my Structural view. This walls didn’t have the “Structural” option enabled, therefore, they didn’t have Rebar Cover parameters.

The solution you recommended was accurate. So, the problem now is the one explained in my previous post. Is the one from the example provided.

image

Thanks in advance for your time!

That is what i solved with the previous post…

# turn into dynamo type
cover_types_ds = []
for cover_type in cover_types:
    cover_types_ds.append(cover_type.ToDSType(True))
1 Like

Thanks @erfajo! I really appreciate your help. For me was very illustrative this thread!

you are welcome, remember to post what you end up doing, others might be able to reuse it :slight_smile:

My final code is like this:

import clr

clr.AddReference('RevitAPI')
clr.AddReference('RevitServices')
clr.AddReference('RevitNodes')
clr.AddReference('RevitAPIUI')

from Autodesk.Revit.UI import TaskDialog

#Importar el Docuement Manager y Transacciones
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# Revit and Dynamo modules
from Autodesk.Revit.DB import BuiltInCategory, FilteredElementCollector
from RevitServices.Persistence import DocumentManager
import Revit
clr.ImportExtensions(Revit.Elements)

# Hacer referencia al documento activo.
doc = DocumentManager.Instance.CurrentDBDocument

# Crear un colector de los elementos para ciertas categorias (http://www.revitapidocs.com/2017.1/ba1c5b30-242f-5fdc-8ea9-ec3b61e6e722.htm)
Niveles = (FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).WhereElementIsNotElementType().ToElements())
Muros = (FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToElements())
RebarCover = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_CoverType).ToElements()

# Inicia la transaccion
TransactionManager.Instance.EnsureInTransaction(doc)

# Corrige el nombre de los niveles de acuerdo al criterio indicado en el manual.
for i in Niveles:
    if 'FUNDACION' in i.Name:
        i.Name = 'PLANTA DE FUNDACIONES'
    elif ' ' in i.Name:
        i.Name = (i.Name).Replace(' ', '')

# Finaliza la transaccion
TransactionManager.Instance.TransactionTaskDone()

# Aplica recubrimientos en todos los elementos muro.

# transformar a elementos de Dynamo
coverTypes = []
for cover in RebarCover:
    coverTypes.append(cover.ToDSType(True))

indice = []
for i in range(len(Muros)):
    muro = Muros[i].ToDSType(True)
    if muro.GetParameterValueByName('Structural') == 1:
        muro.SetParameterByName('Rebar Cover - Exterior Face', coverTypes[8])
        muro.SetParameterByName('Rebar Cover - Interior Face', coverTypes[8])
        muro.SetParameterByName('Rebar Cover - Other Faces', coverTypes[8])
    else:
        indice.append(i)

if indice:
    contador = str(len(indice))
else:
    contador = str(0)

OUT = 'Nombres de pisos corregidos y parametros asignados correctamente. Hay ' + contador + ' muros arquitectonicos! Revisar!'
# OUT = indice

Hope it will be useful!

1 Like

just to explain a bit more about the code

this is not good coding style

Muros = (FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToElements())

this is more readable, and according to PEP8 (the python style)

Muros = (
    FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls)
    .WhereElementIsNotElementType().ToElements())

when you split a long line of code, then you add parenthesis -> Muros = ( xx )
if you dont split it, but gives a very long line (do never do that) then -> Muros = xx

you can verify you code on http://pep8online.com

Thanks for the advice! I’ll keep it in mind.

Hi @erfajo,

As you suggested this solution (which works just fine!) I’m trying to replicate this procedure directly as a revit plug-inn (C#). I made almost the same, but in this case, it shows me an error saying “the parameter is read-only”.

Do you know why through dynamo I can do it withoput a problem, but through the API I can’t?

This is the thread: https://forums.autodesk.com/t5/revit-api-forum/rebar-cover-types-collector/m-p/7780511/highlight/false#M28680

Thanks in advance for your time!

I am not sure, I am not an expert in C#… in that language am I a novice :slight_smile:

As you have I started to investigate the zerotouch environment. I have started to code some new nodes but unfortunately, cant IronPython read the COM-object. So I have to learn C# :slight_smile:

1 Like

:smile: I understand (I’m also a novice in C# and I think zero-touch nodes is a pretty good start!). I think that maybe is when you transform the object into a Dynamo object when the “read-only” option is disabled. I’m just guessing here…

Hope if someone comes with a proper explanation of this phenomena.

Cheers!