Can I determine if an element is in open workset? Or, do I need that at all? Sry if the question is dumb. Does dynamo make changes only to those elements that are in open workset?
I believe so, as Revit allows such (open a model with all worksets closed and modify a parameter value in a schedule view).
If you want to limit things youâll have to query the worksets list, filter out inactive worksets, and test the elementâs workset against that list.
Revit 2022.1, Dynamo Revit 2.12.1
IronPython2 (Doesnât work in CPython3)
def main(element):
document = element.Document
if not document.IsWorkshared:
return "Document is not workshared!"
workset_table = document.GetWorksetTable()
workset = workset_table.GetWorkset(element.WorksetId)
return (workset.Name, workset.IsOpen, workset.IsEditable)
OUT = main(UnwrapElement(IN[0]))
Seems to be working fine for me in CPython3⌠perhaps another worksharing issue?
Hi, colleague uses both Element and Document classes with Properties and methods of some
copy the revit boiler plate code
before function definition
sincerely
christian.stan
Youâre trying to operate on a list instead of an element. Try
OUT = [main(elem) for elem in UnwrapElement(IN[0])]
Youâre trying to operate on a list instead of an element.
Truth is, I was trying to replicate a code that I donât understand.
def main(element): #defines the function
document = element.Document #gets the document the element is in
if not document.IsWorkshared: #check of the document is workshared
return "Document is not workshared!" # return a message if so
workset_table = document.GetWorksetTable() #get the workset table from the document
workset = workset_table.GetWorkset(element.WorksetId) #get workset from the workset table, using the workset id property of the element to define which workset to get
return (workset.Name, workset.IsOpen, workset.IsEditable) #return thr worksetâs name, if ithr workset is ope , and if the workset is editable, using the respective properties of each.
OUT = [main(UnwrapElement(i)) for i in IN[0] ] #uses list comprehension to iterate over the list, calling the custom function main on each item
Hopefully these comments work well for you to sort things out. I also recommend looking over the Dynamo Python Primer, and getting some basic Python education now that youâre utilizing it in one of your tools, and that technical debt is something you own maintenance on for each version of Revit until you decide to deprecate it.
Thanks for your comments. Now, I think I understand how Python finds data: TakeInput.FindAnythingRelated(ByThisCriteria) Am I right?
Iâm trying to literate myself. Is the code bellow the same as the one Tomas wrote? Please confirm.
I dont understand this:
return (workset.Name, workset.IsOpen, workset.IsEditable)
By your explanation, it is a single value, a string to be shown only if the Booleans are true. What if they are not true? What will be returned?
And, what am I going to do with a string value anyway? I needed a Boolean.
If it helps there is a node in the Crumple package for workset checkout status, could be worth interrogating.
What I posted was the same, I just added annotations to the end of each line so you could understand what each line of the code does. You appear to have edited the code to remove the annotations and modified it to another language (there was no else statement before, as itâs not required in the context).
Below is the same as Tomasâ code, but with âwhat the code is doingâ appended on the end of each line.
def main(element): #defines the function
document = element.Document #gets the document the element is in
if not document.IsWorkshared: #check of the document is workshared
return "Document is not workshared!" # return a message if so
workset_table = document.GetWorksetTable() #get the workset table from the document
workset = workset_table.GetWorkset(element.WorksetId) #get workset from the workset table, using the workset id property of the element to define which workset to get
return (workset.Name, workset.IsOpen, workset.IsEditable) #return thr worksetâs name, if ithr workset is ope , and if the workset is editable, using the respective properties of each.
OUT = [main(UnwrapElement(i)) for i in IN[0] ] #uses list comprehension to iterate over the list, calling the custom function main on each item
Not really. While the comments in the code provide the âwhatâ, they donât outline the âhowâ in any way.
I can try to outline some of this, but youâll want to do a BUNCH more research on it as this is my opinion, not hard facts.
In the context of the forum you can consider Revit, Dynamo, and Python as Object Oriented programing at their core. This means that they utilize Objects and Classes to define functions which can be called in a particular order to define what the application does.
Classes are a defined way to structure data that first defines an object (ie: a Point), then provides means for creating an object (ie: by coordinates), then allows associating properties to that object (ie: the X, Y, and Z value), and further allows modifications to that object (ie: altering the X, Y, and Z value).
- The object (the point) is an instance of the class (point).
- The means of creating it (ByCoordinates) is a constructor.
- The means of modifying is called a Method.
- The information about it is called a Property
In Dynamo:
- Classes are shown as shelfs (ie, the Point section of your library).
- Constructors are shown with a green
- Methods are shown with a red
- Properties are shown with a blue
- Instances of the class are shown in the preview of the nodes themselves
In Python:
- Classes are called by typing their name (usually start with an Uppercase letter - why we donât use upper case letters to start variables). ie:
Point
- Constructors are called by typing the name of the class, a dot, then the text of the particular constructor you are after, followed by parenthesis containing any parameters required for the function. ie:
pnt = Point.ByCoordinates(0,0,0)
- Methods are utilized by taking an instance of the class, a dot, and then the text of the particular modifier youâre after, followed by parenthesis containing any parameters required for the function. ie:
vect = pnt.AsVector()
- Properties are utilized by taking an instance of the class, a dot, and the name of the property you want to get to.
So we can start to unwind the âhowâ of the code above (new comments discussing âhowâ the Python is working instead of what the code is doing here);
def main(element): #defines the function 'main' which takes an element as the input
document = element.Document #takes the instance of the element and pulls it's document property and stores it as the 'document' variable
if not document.IsWorkshared: #if the document's IsWorkshared property is not true
return "Document is not workshared!" #return a message to the user, which ends the definition, no further code is executed
workset_table = document.GetWorksetTable() #take the Document instance stored as the document variable and use the method GetWorksetTable() which takes no overrides, returns a WorksetTable object, and store that as the workset_table variable
workset = workset_table.GetWorkset(element.WorksetId) #take the workset table and use the GetWorkset method, passing the WorksetId property of the element as the override, to return a workset object
return (workset.Name, workset.IsOpen, workset.IsEditable) #return a list consisting of the Name property of the workset variable, the IsOpen property of the workset variable and the IsEditable property of the workset variable.
OUT = [main(UnwrapElement(i)) for i in IN[0] ] #utilize list comprehension to iterate over all the items in IN[0] from the Dynamo environment, to call the definition main on the result of the element returned by calling the UnwapElement method on the Dynamo object.
I recommend typing a few of these up as they really help you understand what code is doing, and how you can write your own.
Not quite - my explaination indicated that if the document was workshared it would return the name, IsOpen, and IsEditable properties for the workset, otherwise if it was NOT worksahred it would return the message.
The results of IsEditable and IsOpen should be booleans. If you only want âIsOpenâ edit the definition to only return that property.
hi, here is at a less precise level than Mr. Jacob
import sys
import clr
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import Element,Document #Class your use
elt=UnwrapElement(IN[0])
doc=elt.Document #Class Element is use here with property Document
bool=doc.IsWorkshared # Class Document is use here with property IsWorkshared
OUT = bool
cordially
christian.stan
I wasnât asking if your code was the same as the one Tomas wrote. You only added comments. I was asking about my code.
You say that there is no need for âelseâ in âifâ statement, but then you say that one of two messages should be returned, depending on the conditions:
document.IsWorkshared
workset.IsOpen
workset.IsEditable
How is that not an if else statement?
// define the function
def main(element):
// declare variables
document = element.Document
workset_table = document.GetWorksetTable()
workset = workset_table.GetWorkset(element.WorksetId)
// if else syntax
if (not document.IsWorkshared or not workset.IsOpen or not workset.IsEditable) :
return "Document is not workshared!"
else
return workset.Name
// Execute function
OUT = [main(UnwrapElement(i)) for i in IN[0] ]
Or for my needs, it would be:
// define the function
def main(element):
// declare variables
document = element.Document
workset_table = document.GetWorksetTable()
workset = workset_table.GetWorkset(element.WorksetId)
// if else syntax
if (not document.IsWorkshared or not workset.IsOpen or not workset.IsEditable) :
return false
else
return true
// Execute function
OUT = [main(UnwrapElement(i)) for i in IN[0] ]
In a definition the lure can only be one return value; what happens after that is effectively non-functional. As such the âelseâ need not apply, because if the value is triggered the return is set. While you can ask all the things in a single if statement like you are in your example, it does become much more difficult to read as your code base grows.
Lastly, the use of // in Python indicates floor division, and is not valid for a comments. It might not toss an error in your current context, but I do not recommend it, instead utilise the # to preface the comments.
allright, thank you.