from Autodesk.Revit.DB import *
from pyrevit import forms
import clr
clr.AddReference('System')
from System.Collections.Generic import List
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
selection = uidoc.Selection
elements = FilteredElementCollector(doc).WhereElementIsNotElementType()\
.WhereElementIsViewIndependent()\
.ToElements()
from collections import defaultdict
elements_sorted_by_last_user = defaultdict(list)
for el in elements:
try:
wti = WorksharingUtils.GetWorksharingTooltipInfo(doc, el.Id)
last = wti.LastChangedBy
elements_sorted_by_last_user[last].append(el.Id)
except:
pass
selected_user = forms.SelectFromList.show(elements_sorted_by_last_user.keys(), button_name='Select User')
element_ids = elements_sorted_by_last_user[selected_user]
List_new_selection = List[ElementId](element_ids)
uidoc.Selection.SetElementIds(List_new_selection)
Explainer:
Get All Elements
➡️ First, let’s get all 3D elements in our Revit project. We’ll use the FilteredElementCollector for that
. We can apply WhereElementIsViewIndependent to get all 3D Elements and exclude view dependant elements like tags and dimensions.
elements = FilteredElementCollector(doc)\
.WhereElementIsNotElementType()\
.WhereElementIsViewIndependent()\
.ToElements()
💡 Tip: You can adapt this method to collect different types of elements depending on your needs.
Who Did That?
Now we can go through all elements and look inside who touched them last.
There is a WorksharingUtils class in Revit API that has a method - GetWorksharingTooltipInfo.
This method returns a WorksharingTooltipInfo object with these key properties:
Here is a code sample:
el = ... # Get Element Here...
# Get WorksharingTooltipInfo
wti = WorksharingUtils.GetWorksharingTooltipInfo(doc, el.Id)
# Get Properties
owner = wti.Owner
changed_by = wti.LastChangedBy
creator = wti.Creator
💡 Focus on the property that matters most to you.
Sort Elements by User
By now you have all 3D elements and you know who touched them last. Let's sort it in a dictionary sorted by LastChangedBy user.
I will use defaultdict. It allows you to specify the default value for items in case they don't exist. This will help you avoid the error and save a few lines of code so you can append items even to new keys right away.
❌ Otherwise you would need to check if user already exists in a dict, and either create an empty list or append to existing. Sounds boring, isn't it...
Here is the Code
elements = FilteredElementCollector(doc)\
.WhereElementIsNotElementType()\
.WhereElementIsViewIndependent()\
.ToElements()
from collections import defaultdict
elements_sorted_by_last_user = defaultdict(list)
for el in elements:
try:
wti = WorksharingUtils.GetWorksharingTooltipInfo(doc, el.Id)
last = wti.LastChangedBy
elements_sorted_by_last_user[last].append(el.Id)
except:
pass
👉 Select User from List
Lastly, let's create a simple UI form to choose between users to select elements.
The easiest way to do that is to use SelectFromList form from pyrevit.forms.
And that's how it will look:
from pyrevit import forms
all_users = elements_sorted_by_last_user.keys()
selected_user = forms.SelectFromList.show(all_users, button_name='Select User')
print('Selected User')
Select Elements
Now we have everything we needed. We just need to select these elements with Selection.SetElementIds().
import clr
clr.AddReference('System')
from System.Collections.Generic import List
element_ids = elements_sorted_by_last_user[selected_user]
List_new_selection = List[ElementId](element_ids)
uidoc.Selection.SetElementIds(List_new_selection)
Since it need ICollection<ElementId> we need t convert a list of items into a .NET List[ElementIds]. That's not complicated, you just need to import it and specify the right Type.
Here is the code: