Workset Editability

Hi all, just wondering if there is any custom node or scripts that could toggle the workset editability? Basically i need to lock some workset so that my guys wont be able to edit it.


any help is appreciated :slight_smile:

So basically, the code below is what i came out with, which i will like temporary rename my workset name to get it “lock” under my name but it has an error that says no transaction is open at the moment, mind looking through my scripts? thanks

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import Element wrapper extension methods
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)

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

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

if isinstance(IN[0], list):
files = IN[0]
else:
files = [IN[0]]

typelist= []

TransactionManager.Instance.ForceCloseTransaction()

for file in files:
newdoc = app.OpenDocumentFile(file)
TransactionManager.Instance.EnsureInTransaction(newdoc)
Viewwss = FilteredWorksetCollector(newdoc).OfKind(WorksetKind.ViewWorkset)
Viewwss_ns = [Viewws.Name for Viewws in Viewwss]
Userwss = FilteredWorksetCollector(newdoc).OfKind(WorksetKind.UserWorkset)
Userwss_ns = [Userws.Name for Userws in Userwss]
for View_ws,View_ws_n in zip(Viewwss,Viewwss_ns):
if "02_RVT LINK_" in View_ws_n:
Autodesk.Revit.DB.Transaction(newdoc, "Rename_Workset").Start
WorksetTable.RenameWorkset(newdoc,View_ws.Id,View_ws_n + "1");
WorksetTable.RenameWorkset(newdoc,View_ws.Id,View_ws_n);
Autodesk.Revit.DB.Transaction(newdoc).Commit
else:
continue
TransactionManager.Instance.TransactionTaskDone()
typelist.append([newdoc,Viewwss,Viewwss_ns,Userwss,Userwss_ns])
OUT = typelist

Sorry with the coding format, didnt know what is wrong with it…

FWIW, every time I’ve seen a method used to ‘lock out’ worksets I’ve seen a resulting corruption issue leading to downtime and/or data loss. Permanently locking worksets isn’t something I would recommend as a result. Copy monitor, pinning elements, and utilizing links are all vastly more stable.

Anyway what does “FWIW” means?

I can agree with you to a certain extend but as a company with internal and external modelers/drafters, i do feel the importance of locking certain worksets, for example revit links and certain sets of view template.

With BIM technologies advancing so rapidly, clients had request for model upgrades to keep up with the availability of technologies, hence my query on this topic.

I do hope that someone could enlighten me with this topic.

FWIW = For what it’s worth

A little update, so i have found out a way to hold onto worksets via “WorksharingUtils.CheckoutWorksets” from the revit API. However I am having this error and have no clue onto how to proceed on with the scripts. Below is the screenshot of my graphs(with error) and the script i had used.

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import Element wrapper extension methods
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)

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

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

if isinstance(IN[0], list):
IDs = IN[0]
Names = IN[1]
else:
IDs = [IN[0]]
Names = [IN[1]]

typelist,checkedout_ws= [], []

checkedout_ws = WorksharingUtils.CheckoutWorksets(doc,IDs)
typelist.append([Names, checkedout_ws])
OUT = typelist

So i tried adding a for loop into the script and i got this error

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import Element wrapper extension methods
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)

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

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

if isinstance(IN[0], list):
IDs = IN[0]
Names = IN[1]
else:
IDs = [IN[0]]
Names = [IN[1]]

typelist,checkedout_ws= [], []

for ID in IDs:
checkedout_ws = WorksharingUtils.CheckoutWorksets(doc,ID)
typelist.append([Names, checkedout_ws])
OUT = typelist

The main problem is that you are inserting a dynamo type into a command that needs a Revit type. You have to unwrap the object in order to use with API.

UnwrapElement(putObjectHere)

and then it can be used with the commands. Although I don’t know the output of Workset.Id as a node, but it looks like it returns an int. A better way might be to use the Select.GetAllWorksetByKind’s workset output, bring it into Python, UnwrapElement(workset).Id and use that as the checkedout_ws = WorksharingUtils.CheckoutWorksets(doc,IDs)'s IDs

Hey @kennyb6

i followed your advise and there is still an error, but this time it says contain worksetID. See below’s screenshot and code


image

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import Element wrapper extension methods
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)

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

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

if isinstance(IN[0], list):
Wss = IN[0]
else:
Wss = [IN[0]]

typelist,checkedout_ws= [], []

for ws in UnwrapElement(Wss):
Userwss_ns = ws.Name
Userwss_id = ws.Id
checkedout_ws = WorksharingUtils.CheckoutWorksets(doc,Userwss_id)
typelist.append([Userwss_ns, checkedout_ws])
OUT = typelist

Oh I remember that error now. Instead of going thru the list, it wants the list itself, but as an ICollection which is not the same as Python’s lists, if I remember correctly. Try following this thread and see if it works: How to create an icollection to work with revit api

Try adding the following references to the top:

clr.AddReference(“System”)
from System.Collections.Generic import List

Then put in:

ws = List[WorksetId](UnwrapElement(Wss))

and use ws in WorksharingUtils.CheckoutWorksets(doc,ws)

Might need to mess with the unwrapping or looping if that doesn’t work right away.

thank you @kennyb6.
my issue have been solved :slight_smile: Do you want me to post the codes here for your future reference?

1 Like

Sure! It can help out others too who come across the same issue.

@kennyb6 there you go :slight_smile:

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import Element wrapper extension methods
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)

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

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

# Import system library
clr.AddReference('System.Core')
from System.Collections.Generic import *

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application


if isinstance(IN[0], list):
	newdocs = UnwrapElement(IN[0])
	IDs = UnwrapElement(IN[1])
	Names = UnwrapElement(IN[2])

else:
	newdocs = UnwrapElement([IN[0]])
	IDs = UnwrapElement([IN[1]])
	Names = UnwrapElement([IN[2]])

typelist, iDs = [],[]

TransactionManager.Instance.ForceCloseTransaction()

try:
	if IN[3]:
		x = 0
		for newdoc in newdocs:
			iDs = IDs[x]
			names = Names[x]
			Ids = List[WorksetId](iDs)
			try:
				checkedout_ws = WorksharingUtils.CheckoutWorksets(newdoc,Ids)
				typelist.append([newdoc,names,checkedout_ws])
			except Exception,e:
				typelist.append(str(e))
			x=x+1			
	else: 
		typelist.append("Please toggle to True to continue this process")
except Exception,e:
	typelist.append(str(e))
OUT = typelist
2 Likes

I’m getting an error :

Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed.
Traceback (most recent call last):
File “”, line 35, in
IndexError: index out of range: 1

Kindly assist…

i think it is because you are feeding a single file. And at that point of me posting my code, im still a python noobie. :smiley: so the new and improve code will be like this.

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import Element wrapper extension methods
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)

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

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

# Import system library
clr.AddReference('System.Core')
from System.Collections.Generic import *

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

def ToList(x):
    if isinstance(x,list):
        return UnwrapElement(x)
    else:
        return [UnwrapElement(x)]

newdocs= ToList(IN[0])
worksets = ToList(IN[1])
typelist = []
TransactionManager.Instance.ForceCloseTransaction()
for newdoc,workset in zip(newdocs,worksets):
    IDs = [ws.Id for ws in workset ]
    Ids = List[WorksetId](IDs)
    try:
        checkedout_ws = WorksharingUtils.CheckoutWorksets(newdoc,Ids)
    except Exception,e:
        checkedout_ws = str(e)
    typelist.append(checkedout_ws)
OUT = typelist

EDIT: try this instead, i remembered the type of list structured that is required for this script to work

2 Likes

Thanks will try this out.

I’m getting this error now :

Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed.
unindent does not match any outer indentation level

basically your IN[0] is the document and IN[1] is the worksets you want to checkout in each document

maybe you can show me your workflow, then i can try my best to cater to above code to your needs. Cause my codes are based on my specific workflow which might not be suitable for your case

I re-create this code and put your revised phyton code