Warning: Element.SetParameterByName operation failed. No parameter found by that name

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.

1 Like

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?

1 Like

I need to insert the comments information (red square screenshot) inside the workset.

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.

1 Like

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))
1 Like

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.

1 Like

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;

  1. make sure your worksets are on editable mode
  2. ensure the Comments include the elementID of the workset (123456_newWorksetName)
  3. different models depending on how you’ve set up your worksets, you may end up with different elementID for the workset
  4. in dynamo, split the two values to ensure that you can select the workset by the elementID and then the newWorksetName
  5. 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.

1 Like

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
3 Likes

@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.

1 Like

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.

1 Like

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.

1 Like

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.

1 Like