I am new to Dynamo.
I have a model contain many revit links and each link in a individual workset.
Is there any way to open or close certain worksets?
HI @raysonchan0305, Welcome to Dynamo and the Dynamo Forum!
There is no way with the OOTB Dynamo nodes that I’m aware of (although, there are most likely packages out there with these features). However, this can be done via the API relatively easily. I have created a graph for this that uses python and the Revit API to reload the chosen link with worksets chosen by the user…
Here is a quick demo…
And the Dynamo Script…
ReloadLinksWithSelectedWorksets.dyn (46.4 KB)
NOTE: Please make sure you read the comments in the graph as you will need to change some of the logic to suit your needs (which revit link you are reloading and which worksets you want to open). Hopefully my explanations are clear enough.
Suggested Improvements: As a rule, I don’t put any third party nodes in any of my graphs that I put on the forum, but a suggestion to make this more complete would be to put DataShapes UI nodes in there so user can run and Select the Revit Link and Worksets via a User Interface (rather than editing the graph directly).
Hope you find this useful and at a later date when you are more confident you can get to grips with the python.
Cheers,
Dan
Hello
just for the challenge and fun
an example with Winform
import clr
import sys
#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
#import net library
clr.AddReference('System')
from System.Collections.Generic import List
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
#Get Important vars
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
clr.AddReference('System.Drawing')
clr.AddReference('System.Windows.Forms')
import System.Drawing
import System.Windows.Forms
from System.Drawing import *
from System.Windows.Forms import *
class WksetLnkUtils(Form):
def __init__(self):
rvtLinkInst = FilteredElementCollector(doc).OfClass(RevitLinkInstance)
self._dictRvtInstance = {}
for x in rvtLinkInst:
_lkdoc = x.GetLinkDocument()
if _lkdoc.IsWorkshared:
self._dictRvtInstance[x.Name] = x
self._dictWkset = {}
self.rvtRvtlinkType = None
self.out = None
self.InitializeComponent()
def InitializeComponent(self):
self._groupBox1 = System.Windows.Forms.GroupBox()
self._checkedListBox1 = System.Windows.Forms.CheckedListBox()
self._buttonOpen = System.Windows.Forms.Button()
self._buttonClose = System.Windows.Forms.Button()
self._comboBoxRvtLink = System.Windows.Forms.ComboBox()
self._groupBox2 = System.Windows.Forms.GroupBox()
self._groupBox1.SuspendLayout()
self._groupBox2.SuspendLayout()
self.SuspendLayout()
#
# groupBox1
self._groupBox1.Controls.Add(self._checkedListBox1)
self._groupBox1.Location = System.Drawing.Point(30, 123)
self._groupBox1.Name = "groupBox1"
self._groupBox1.Size = System.Drawing.Size(361, 423)
self._groupBox1.TabIndex = 0
self._groupBox1.TabStop = False
self._groupBox1.Text = "Select Workset"
#
# checkedListBox1
self._checkedListBox1.FormattingEnabled = True
self._checkedListBox1.Items.Clear()
self._checkedListBox1.Location = System.Drawing.Point(16, 42)
self._checkedListBox1.Name = "checkedListBox1"
self._checkedListBox1.Size = System.Drawing.Size(326, 361)
self._checkedListBox1.TabIndex = 0
#
# buttonOpen
self._buttonOpen.Location = System.Drawing.Point(60, 560)
self._buttonOpen.Name = "buttonOpen"
self._buttonOpen.Size = System.Drawing.Size(300, 40)
self._buttonOpen.TabIndex = 1
if app.Language == Autodesk.Revit.ApplicationServices.LanguageType.French:
self._buttonOpen.Text = "Ouvrir les sous-projets selectionnés \n(les autres seront fermés)"
else:
self._buttonOpen.Text = "Open Selected Worksets (others will be close)"
self._buttonOpen.UseVisualStyleBackColor = True
self._buttonOpen.Click += self.ButtonOpenClick
#
# buttonClose
self._buttonClose.Location = System.Drawing.Point(60, 620)
self._buttonClose.Name = "buttonClose"
self._buttonClose.Size = System.Drawing.Size(300, 40)
self._buttonClose.TabIndex = 1
if app.Language == Autodesk.Revit.ApplicationServices.LanguageType.French:
self._buttonClose.Text = "Fermer les sous-projets selectionnés \n(les autres seront ouverts)"
else:
self._buttonClose.Text = "Close Selected Worksets (others will be open)"
self._buttonClose.UseVisualStyleBackColor = True
self._buttonClose.Click += self.ButtonCloseClick
#
# comboBoxRvtLink
self._comboBoxRvtLink.Items.AddRange(System.Array[System.Object](self._dictRvtInstance.keys()))
self._comboBoxRvtLink.FormattingEnabled = True
self._comboBoxRvtLink.Location = System.Drawing.Point(19, 41)
self._comboBoxRvtLink.Name = "comboBoxRvtLink"
self._comboBoxRvtLink.Size = System.Drawing.Size(323, 24)
self._comboBoxRvtLink.TabIndex = 2
self._comboBoxRvtLink.SelectedIndexChanged += self.ComboBoxRvtLinkSelectedIndexChanged
#
# groupBox2
self._groupBox2.Controls.Add(self._comboBoxRvtLink)
self._groupBox2.Location = System.Drawing.Point(30, 17)
self._groupBox2.Name = "groupBox2"
self._groupBox2.Size = System.Drawing.Size(361, 89)
self._groupBox2.TabIndex = 3
self._groupBox2.TabStop = False
self._groupBox2.Text = "Select Revit Link"
#
# MainForm
self.ClientSize = System.Drawing.Size(430, 700)
self.Controls.Add(self._groupBox2)
self.Controls.Add(self._buttonClose)
self.Controls.Add(self._buttonOpen)
self.Controls.Add(self._groupBox1)
self.Name = "WksetLnkUtils"
self.Text = "Manage linked model Worksets"
self._groupBox1.ResumeLayout(False)
self._groupBox2.ResumeLayout(False)
self.ResumeLayout(False)
def setLinkstatut(self, wksetsId):
if self.rvtRvtlinkType is not None:
#create WorksetConfiguration with CloseAllWorksets by default
wkstConfig = WorksetConfiguration(WorksetConfigurationOption.CloseAllWorksets)
lstWksetId = List[WorksetId](wksetsId)
wkstConfig.Open(lstWksetId)
loada = self.rvtRvtlinkType.LoadFrom(self.mpath, wkstConfig)
self.out = loada.LoadResult
wkstConfig.Dispose()
def ButtonOpenClick(self, sender, e):
wksetsId = [ self._dictWkset.get(wksetnam) for wksetnam in self._checkedListBox1.CheckedItems]
self.setLinkstatut(wksetsId)
def ButtonCloseClick(self, sender, e):
self.wksetsId = []
#get items are not checked for open others Worksets
setDiff = set(self._checkedListBox1.Items) - set(self._checkedListBox1.CheckedItems)
wksetsId = [ self._dictWkset.get(wksetnam) for wksetnam in setDiff]
self.setLinkstatut(wksetsId)
def ComboBoxRvtLinkSelectedIndexChanged(self, sender, e):
rvtLinkInstance = self._dictRvtInstance.get(sender.Text)
self.rvtRvtlinkType = doc.GetElement(rvtLinkInstance.GetTypeId())
_linkdoc = rvtLinkInstance.GetLinkDocument()
_worksetTable = _linkdoc.GetWorksetTable()
self.mpath = _linkdoc.GetWorksharingCentralModelPath()
lstPreview = WorksharingUtils.GetUserWorksetInfo(self.mpath)
self._dictWkset = {item.Name : _worksetTable.GetWorkset(item.Id).Id for item in lstPreview }
self._checkedListBox1.Items.Clear()
self._checkedListBox1.Items.AddRange(System.Array[System.Object](self._dictWkset.keys()))
objForm = WksetLnkUtils()
objForm.Show()
OUT = 0
the interface can be further improved with a TreeNode with checkbox
Very nice! I am way too lazy!
Hi Daniel,
Wonderful, this is exactly what I want.
Thanks for your help!
I still learning both dynamo and python.
cool!
You’re welcome Rayson! Happy to help!
Hi All,
I was wondering if anyone knows how to close or open worksets in the given document (current)?
I am not good with Python (started to learn, or more like beginning to learn) any any help would be appreciated.
I know I can do it manually but I need this as a part of a bigger script :). I assume this python script could be simplified to achieve what i need.
In the graph I uploaded earlier, the python it is broken down into smaller chucks as nodes. You might find these suit your requirements a little better.
Thank you for such a prompt reply.
I will give it a go and try to adjust the script once I have some time.
Will let you know if I can make it work
Hi @c.poupin impressive work! what are the modifications to make to your script so that it works with the models hosted on the cloud (BIM360)?
Hello @Dave_O
I don’t know for this, currently I don’t have BIM 360 for testing