Set analytical column Z Projection parameter

Hi all,

I’m trying to change the “Top z Projection” of an analytical line, the problem is that it’s not recognising strings or numbers for the parameter value. I’ve changed the “Top Alignment Method” to projection first, so it should behave properly and running the element through Object.Type shows that it’s a string, but I have the warning saying that “The parameter’s storage type is not a string”![string|690x374

Please see script below.

Thank you

The display type is a string but the internal value is something else, probably an ID. Haven’t been able to find the options yet though.

1-Make sure your parameter name is correct and match perfectly with the string you’ve written.
2-you have to check and verify if the value is a number or a string it can’t be both at the same time.

This Top z Projection parameter is read-only…

Yna_Db is correct, it’s read only and you need to use the SetProjection Method in a python node.

Here is an example of how to use the method:
element.SetProjection(AnalyticalElementSelector.EndOrTop, StickElementProjectionY.LocationLine, StickElementProjectionZ.Bottom)

Here is a complete working code:
image

import clr

# Import Revit API
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *

# Import DocumentManager and TransactionManager
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

# Input
elements = UnwrapElement(IN[0])
if not isinstance(IN[0], list):
	elements = [elements]
 #Make changes to Revit DB in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
for element in elements:
	element.SetProjection(AnalyticalElementSelector.EndOrTop, StickElementProjectionY.LocationLine, StickElementProjectionZ.Bottom)
TransactionManager.Instance.TransactionTaskDone()

OUT = 0
2 Likes

Thank you Einar,

I’ll have a look at this, thank you very much.

Einar,

I’ve tried to modify to script to suit my purpose. please see below. I essentially want to change the top and bottom justification the same time. I’ve tried to add two new variables to pump in to the set.projection routine but it’s not working. It’s probably something simple. Please ignore my ignorance with coding. What I’ve added is in yellow.

Thanks for your help.

@James_Washbourne Please paste your code as preformatted text so that it will be easier for others to test your code :slight_smile: the error you are getting, however, is because you do not need the colons in your lines 20-21

Replace them as follows:

ProjectY = IN[1]
ProjectZ = IN[2]

However you will likely receive an error afterwards that there is an expected indent for lines 28 and 29.

1 Like
import clr

Thank for your reply,

I’ve made the changes you mentioned and I’ve also indented as you suggest and I still get an error.

# Import Revit API
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *

# Import DocumentManager and TransactionManager
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

# Input
elements = UnwrapElement(IN[0])
if not isinstance(IN[0], list):
	elements = [elements]
ProjectY = IN[1]
ProjectZ = IN[2]

	
	
 #Make changes to Revit DB in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
for element in elements:
	for projectionY in ProjectY:
	for projectionZ in ProjectZ:
	element.SetProjection(AnalyticalElementSelector.EndOrTop, StickElementProjectionY.projectionY, StickElementProjectionZ.projectionZ)
	element.SetProjection(AnalyticalElementSelector.StartOrBase, StickElementProjectionY.projectionY, StickElementProjectionZ.projectionZ)
TransactionManager.Instance.TransactionTaskDone()

OUT = 0

Thank you

What is the error you receive now?

“Expected an indented block”, but it doesn’t say where.

I recommend examining some custom nodes that have Python codes within them and having a look at the structure of their codes to get a better idea on how Python codes are written, as well as some general Python tutorials (unrelated to use with Revit/Dynamo). The indented blocks that are expected are lines 28 and 29, because they are following a forloop statement. Indenting these lines, however, will not fully resolve your code.

Whenever you declare a for loop the next line of code (the loop) has to be indented.

I assume you’re inputting one ProjectY and one ProjectZ for each element from IN[0]. If this is the case you don’t actually want multiple for loops for each variable, you want them all in one.

You would use
for element, projectionY, projectionZ, in zip(elements, ProjectY, ProjectZ):
instead of the three separate for loops.

EDIT: Here you can see the difference between zipping the variables and using a loop for each one individually. It’s basically a lacing issue. The first method uses each variable once based on its index. The second method compounds the loops.

3 Likes

@James_Washbourne

Here are the relevant sections from revitapidocs:

If you want to add the Enumerations as string inputs you can use the Enum.Parse method.

image

import clr
import System
# Import Revit API
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *

# Import DocumentManager and TransactionManager
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

# Input
elements = UnwrapElement(IN[0])
topZPriojection = System.Enum.Parse(clr.GetClrType(StickElementProjectionZ),IN[1])
bottomZProjection = System.Enum.Parse(clr.GetClrType(StickElementProjectionZ),IN[2])
if not isinstance(IN[0], list):
	elements = [elements]
	
 #Make changes to Revit DB in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
for element in elements:
	element.SetProjection(AnalyticalElementSelector.EndOrTop, StickElementProjectionY.LocationLine, topZPriojection)
	element.SetProjection(AnalyticalElementSelector.StartOrBase, StickElementProjectionY.LocationLine, bottomZProjection)
TransactionManager.Instance.TransactionTaskDone()

OUT = 0
2 Likes

Einar

Thanks for this, It works perfectly.

Thank you Nick.

Solved now Amy, yes I’ll take on your advice on board and learn some python.

Thank you

2 Likes

Glad you got it solved! @Yna_Db just posted some very helpful resources for Python here: Python Nodes Basics

2 Likes

Hi Einar,

Digging a 4 year old topic, but still relevant.
I was trying to change the z Projection of floor to Center of element and it isn’t working, yk, Storage type issue, neither number nor string.

Can you help?
Thanks in advance!

Atharva