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
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.
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:
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
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.
@James_Washbourne Please paste your code as preformatted text so that it will be easier for others to test your code 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.
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
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.
If you want to add the Enumerations as string inputs you can use the Enum.Parse method.
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
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.