Check if you are the owner

I have a few pyrevit scripts that alter a lot of elements or groups. Works fine.

But in a central model environment something might go wrong: I’m not the owner.

So lets assume you have a bunch of elements which you are going to change (1000 elements).
The scripts loops each element, transaction etc. is done properly. BUT revit says: you don’t own the element, grant acces is sent to user x.
… for element 1… element 2 … element 3 … element 4… etc.

I have to alter my scripts to check if I can bulk change those elements.

This I have so far, but I’m unsure if this waterproofs my script. How do you guys handle these kind of situations?

if not revit.doc.IsWorkshared:
	sys.Exit()

print '- Reload latest model'
revit.doc.ReloadLatest(DB.ReloadLatestOptions())
if not revit.doc.HasAllChangesFromCentral():
	revit.doc.ReloadLatest(DB.ReloadLatestOptions())
print '\tdone'

# next bulk checkout elements
Try:
     DB.WorksharingUtils.CheckoutElements(doc, [element_ids])
Except Exception as e:
    print e

# then check if element was checkout 
status = DB.WorksharingUtils.GetCheckoutStatus(element)
if not OwnedByOtherUser:
     # rest of code.

This may point you in a helpful direction… It tries to check out all elements before modifying them. It succeeds for any elements that you already own. If it fails on any elements, then the script exits and displays an error to the user. Once you have them checked out successfully, you can then run your element modifying code.

#populate this list with your elements
elements_to_checkout = [] 

typed_list_of_elements_to_check_out = List[DB.ElementId](elements_to_checkout)

checked_out_elements = DB.WorksharingUtils.CheckoutElements(revit.doc, typed_list_of_elements_to_check_out)

log.info("Trying to check out " + str(len(elements_to_checkout)) + " elements.")
log.info("Successfully in possession of " + str(len(checked_out_elements)) + " elements.")

#this does the comparison of the attempted set vs the successful set
missing_element_ids = []
for element_id in elements_to_checkout:
    if element_id not in checked_out_elements:
        missing_element_ids.append(element_id)

if(len(missing_element_ids) > 0):
    log.error("Failed to check out the following elements:")
    log.error("; ".join(missing_element_ids))

    for missing_element_id in missing_element_ids:
        log.error("Element is owned by someone else: " + str(element.id) + ". That person is: " + str(element_owner) + ". Element type is: " + str(element_type))

    log.info("Because you were not able to check out some of the required elements, the script was aborted (data was not sync'd).")
    log.info("To resolve the worksharing conflicts (by having element owners sync team syncing) then try again.")

    script.exit()

Hey, I use the below code to create a list of elements I can alter, and which I can not.
This way I know which weren’t changed by my script.
Another benefit is you don’t have to become the owner of these elements or check them out. When other people are working on the model, they won’t notice it as much.

  for element in elements_to_change:
        worksharingStatus = WorksharingUtils.GetCheckoutStatus(doc, element.Id)
        if not worksharingStatus == CheckoutStatus.OwnedByOtherUser:
            owned_elements.append(element)
        else:
            unownedElements.append(element)

Thanks.

Tiny Python tip:
if(len(missing_element_ids) > 0):

is equals to:
if missing_element_ids:

Yup, I might end with creating two functions.

One that MUST own all elements else it simply can’t do stuff.

def checkout(elements):
	if revit.doc.IsWorkshared:
			
		elids = [el.Id for el in elements]		
		
		revit.doc.ReloadLatest(DB.ReloadLatestOptions())
		if not revit.doc.HasAllChangesFromCentral():
			revit.doc.ReloadLatest(DB.ReloadLatestOptions())
		

		# next bulk checkout elements. 
		# returns: the ids of all specified elements that are now owned (but possibly out of date), including all that were owned prior to the function call.
		try:
			checkoutelements = DB.WorksharingUtils.CheckoutElements(revit.doc, List[DB.ElementId](elids) )
		except Exception as e:
			print e

		# reload latest due possible out of date
		if not revit.doc.HasAllChangesFromCentral():
			revit.doc.ReloadLatest(DB.ReloadLatestOptions())
		
		return checkoutelements
	
	else:
		return elements

Catching not owned elements has to be added btw.

And one that TRIES to get the elements needed if you can’t: skip those ones (and catch those to notify the user using the script).