I cannot find which is the solution to solve this warning attached in the screenshot below. The aim of this script is to rename the worksets with the information of the comments parameters.
You are trying to rename all elements in the active view, instead of renaming the worksets, for starters.
I think more clarification would be good so we know exactly what you want to do.
The idea is to rename the workset of all elements in the active view.
But you have more than a thousand elements in the view, and i assume only a couple worksets.
Can you show an example with screenshots from Revit?
It sounds like you want to change the elementâs workset to that of the matching Comments
value. If thatâs the case, you need to first get all the workset elements in your model and their names. Then you need to match the workset name to the Comments
value. The easiest way to do this is to create a dictionary of worksets/names.
As @Garbage_Collector mentioned, collecting all elements in view is probably gonna give you a bunch of extra elements that youâll need to filter. You might be better off collecting your elements another way.
Each element has a property WorksetId. Use that.
EVERYTHING has a workset and some things ARE worksets. Like views. You really need to filtere out what elements you are looking for.
- Get the comment from the element. (Done)
- From the name find the workset. To do that you first need to get a list of worksets in the project. (Yes - a dictionary would be good)
- Find the workset that matches the comment, Youâll need some error correction here. What if there si no workset? Are you going to create it? Ignore it. What if it is a close match? Change the comment to match the workset name? Maybe toss these in a QA/QC workset for further investigation?
- Get the workset by name.
- Get the Id of the workset.
- Change the WorksetId of the element.
This gets everything and displays the workset and workset ID. Then displays the user defined worksets.
everything = FilteredElementCollector(doc).WhereElementIsNotElementType().ToElements()
worksets = FilteredWorksetCollector(doc).OfKind(WorksetKind.UserWorkset).ToWorksets()
wst = doc.GetWorksetTable()
for thing in everything:
wws = wst.GetWorkset(thing.WorksetId)
print(wws.Name + " | " + str(wws.Id))
print("------------------------------------------------")
for ws in worksets:
print(ws.Name + " | " + str(ws.Id))
Just because itâs Christmas⌠Try this.
This workflow canât be completed without the use of custom packages so⌠Feel free to update the categories where needed.
Take note that if you have any model groups, it will not update those elements within the model group.
Hope that helps.
Thank you very much for your Christmas gift, but in your example the workset parameter information is inserted into âCommentsâ, I would like to get the oposite proccess. Trying the oposite proccess is still wrong:
You keep providing the workset name as the parameter name. The parameter name is Workset since thatâs the parameter you want to modify. The value should be the workset you want the element assigned to. Workset is an elementId
parameter, meaning you have to provide the elementId
of the workset you want. This is why you need to get the worksets (as an elementId
) and their names so that you can identify which Id to use as the parameter value.
Oh my mistake!
Though I kinda am worried about this workflow of constantly renaming your worksets.
It can be done but at least you should be aware of the cost of doing so.
Worksets once renamed, it affects more than what is listed on this blog.
Additionally, it causes your view template settings, any filters or rules youâve set up will be reverted to the default settings. This in my experience usually is quite damaging to a project with multiple models or coordinating with other consultants.
If youâre still keen on doing so, then by all means, can be done.
Just need to be aware of the following;
- make sure your worksets are on editable mode
- ensure the Comments include the elementID of the workset (123456_newWorksetName)
- different models depending on how youâve set up your worksets, you may end up with different elementID for the workset
- in dynamo, split the two values to ensure that you can select the workset by the elementID and then the newWorksetName
- then I believe a couple of packages that can be used but hereâs sample of what I did using archilab for a basic workset renaming.
Youâll still have to make some changes to obtain the elements that you need and pair it up with the elementCollection I showed earlier, alongside getparam and this worksetRenaming script.
If you could get there, itâd be great. Otherwise, itâs quite dangerous to be wielding Die-namo here to overwrite these crucial settings.
Hope that helps.
Ho ho hoâŚ
Brutal. Looks at everything possible.
Makes new worksets for those that donât exist. Can litter your project with worksets. Only runs on workset enabled projects. Doesnât work on elements that canât be checked out - just the nature of worksharing.
Out is two list of those that got changed and those that didnât
And rememeber⌠Worksets are NOT layers. (Infact, it is a feature that should really vanish for that very reason)
import clr
import sys
"""
Some leftover boilerplate for the newbies to tinker with.
sys.path.append('C:\Program Files (x86)\IronPython 3.4\Lib')
import System
from System import Array
from System.Collections.Generic import *
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
"""
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference("RevitAPI")
clr.AddReference("RevitAPIUI")
import Autodesk
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
uidoc = uiapp.ActiveUIDocument
everything = FilteredElementCollector(doc).WhereElementIsNotElementType().ToElements()
worksets = FilteredWorksetCollector(doc).OfKind(WorksetKind.UserWorkset).ToWorksets()
nicelist = []
naughtylist = []
def MakeWorkset(worksetname):
wst = SubTransaction(doc)
wst.Start()
newws = Workset.Create(doc, worksetname)
wst.Commit()
return newws
def GetComments(elem):
commentsparam = elem.GetParameter(ForgeTypeId("autodesk.revit.parameter:allModelInstanceComments-1.0.0"))
if commentsparam:
comments = commentsparam.AsString()
if comments:
return comments
else:
return None
def FindWorkset(worksetname):
worksets = FilteredWorksetCollector(doc).OfKind(WorksetKind.UserWorkset).ToWorksets()
for workset in worksets:
if worksetname == workset.Name:
return workset
else:
pass
def SetWorkset(elem, workset):
elemparam = elem.GetParameter(ForgeTypeId("autodesk.revit.parameter:elemPartitionParam-1.0.0"))
try:
elemparam.Set(workset.Id.IntegerValue)
except:
pass
def ReadOnly(elem):
elemparam = elem.GetParameter(ForgeTypeId("autodesk.revit.parameter:elemPartitionParam-1.0.0"))
isreadonly = elemparam.IsReadOnly
return isreadonly
if doc.IsWorkshared:
with Transaction(doc, "Comemnts to Workset") as t:
t.Start()
for thing in everything:
readonly = ReadOnly(thing)
if not ReadOnly(thing):
thingcomment = GetComments(thing)
if thingcomment:
wsexists = FindWorkset(thingcomment)
if wsexists != None:
try:
SetWorkset(thing, wsexists)
nicelist.append(thing)
except:
naughtylist.append(thing)
else:
ws = MakeWorkset(thingcomment)
try:
SetWorkset(thing, ws)
nicelist.append(thing)
except:
naughtylist.append(thing)
t.Commit()
OUT = nicelist,naughtylist
@fespinolaBBU8P, I think you need to clarify what it is exactly that youâre wanting to do. Do you want to create/edit the worksets themselves or just assign elements to the workset matching the Comments value? These are two very different scenarios.
This is how you get âone person per fileâ setups like the CAD days. Worksets are what makes worksharing work, so learning the ins and outs rather than pushing to abolish them is advisable. If there is a single benefit of Revit over the other platforms it is worksharing, so knowing âwhyâ you canât set an element to a new workset and filtering out in advance of the attempt is advisable.
That said, really good use of try and except here. Only change Iâd recommend would be to append the exception and the element to the naughty list so that users can try to understand why things fail.
Once upon a time, Revit was one file one user.
Worksets and worksharing went their separae ways once element borrowing was introduced.
In the old days, you HAD to have one workset per user. It was the first step in multiple users working in one file. That persisted until element borrowing (tangentially related to worksets) was introduced in 2011. At that point, you no longer need multiple worksets. Revit could check out elements on the fly and return them as needed on sync or later with granting of permissions. The feature was kept for its ability reduce memory requirements by being able to load and unload worksets and keep the visibility control it offered.
Today, you can now work on large projects with just user model workset. Just like the casino we are finishing up. One workset. Element borrowing has replaced workset checkout functionality. Visibility Filters were introduced (2019 as I recall) to provide a more powerful tool than what worksets offered.
So IMHO, worksets could indeed be buried with element borrowing being the default worksharing method. People only use woksets these days for all sorts of odd tasks it was never built for. I expect eventually we will see Revit more like Google docs, where multiple users work on the same file seamlessly and you can see real time what is going on. In fact, years back - Autodesk demoâed exactly that. It was cool.
So, Iâll put my Revit 2.1 disk back in its case and toss my Revit Use2009UI=1 t-shirt in the laundry. Back to work.
100% certain your âsingle user worksetâ actually has a LOT more than that. Disable the workset filter to only show user created worksets and grab a screenshot.
It only feels as if it isnât needed anymore as the complexity of worksharing was simplified to make it easier for users.
Add in the ability to only load in parts of your casino to simplify what youâre loading by managing worksets on open and suddenly the need (and value) becomes even more.
This doesnât mean there should be a thousands of worksets (Iâd try to cap at 12 typically). But there is a happy medium to be had.