Here's a complete solution for PyRevit as of 2020.1. The API does not have an easy way to set a workset open or closed - instead you need to reload the link with a new workset configuration. This means creating a workset configuration that defaults to closing all worksets, then loading it up with all the worksets you want to remain open. Then you pass this into the LoadFrom method to reload the link.
'''
Goes to Manage > Manage Links > Manage Worksets and opens the Shared Levels and Grids workset for each LOADED link.
TESTED REVIT API: 2020
Author: Robert Perry Lackowski
'''
from pyrevit import DB
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB import FilteredElementCollector
from Autodesk.Revit.DB import Transaction
from Autodesk.Revit.DB import WorksharingUtils
from Autodesk.Revit.DB import WorksetConfiguration
from Autodesk.Revit.DB import RevitLinkType
from Autodesk.Revit.UI import TaskDialog
from pyrevit import script
output = script.get_output()
import traceback
doc = __revit__.ActiveUIDocument.Document
app = __revit__.ActiveUIDocument.Application.Application
# Set the name of the workset you would like to hide. Decide if you want to hide it or unhide it.
hide_this_workset = "Shared Levels and Grids"
hide_workset = False
for link_doc in app.Documents:
link_doc_title = link_doc.Title
print link_doc_title
# Exclude the project file itself
if not link_doc.IsLinked:
print "this one isn't linked, skip the rest of the for loop \n\n "
continue
# Get a list of the RevitLinkType elements in the active document.
revit_link_types = FilteredElementCollector(doc).OfClass(DB.RevitLinkType).ToElements()
# This finds the RevitLinkType element that matches the link_doc.
rlt = next((rlt for rlt in revit_link_types if rlt.LookupParameter("Type Name").AsString().rstrip(".rvt") == link_doc_title), None)
if not rlt:
print "No matching RevitLinkType for the link_doc."
else:
temp = "Updating workset visibility on this file: " + str(link_doc.Title)
print temp
# generate a list of the worksets in the link_doc
workset_table = link_doc.GetWorksetTable()
model_path = link_doc.GetWorksharingCentralModelPath()
lst_preview = WorksharingUtils.GetUserWorksetInfo(model_path)
# Populate list of worksets to enable
open_this_list_of_worksets = []
for objWorksetPreview in lst_preview:
wkset = workset_table.GetWorkset(objWorksetPreview.Id)
if hide_workset:
#gather a list of all the open worksets, EXCLUDING the workset we want to hide
if wkset.IsOpen and (wkset.Name != hide_this_workset):
open_this_list_of_worksets.append(wkset.Id)
else:
#gather a list of all the open worksets, INCLUDING the one we hid.
if wkset.IsOpen or wkset.Name == hide_this_workset:
open_this_list_of_worksets.append(wkset.Id)
# Set the WorksetConfiguration file to close all worksets, then open the ones from the list
workset_config = WorksetConfiguration(WorksetConfigurationOption.CloseAllWorksets)
workset_config.Open(open_this_list_of_worksets)
#reload the link with the updated workset configuration
rlt.LoadFrom(model_path, workset_config)
#delete the workset configuration after use
workset_config.Dispose()
print "Script complete."