I regularly rely on pyRevit scripts that modify parameters across multiple elements in a workshared Revit model. The trouble is that the elements I’m modifying have sometimes been checked out already, which causes Revit to throw a warning and roll back all the changes in the transaction. Is there a solution to this? I see add-ins like RFTools which regularly edit parameters with no trouble, so I’m thinking I need a new approach. My current method has a slow version which checks if the elements are checked out first, and a fast version which does not check, but is at risk of getting rolled back if it encounters a worksharing clash.
def update_string_param(elem, param, new_string, fast_mode = False):
"""
Updates string parameter if it doesn't match new_string.
"""
# Assumes param is already confirmed to exist
x = param.AsString()
if x == new_string or (x == "" and new_string == None):
return False
else:
# print(param.Definition.Name, x, type(x), new_string, x==new_string)
print("Data has changed, updating '{}' (old, new): {}".format(param.Definition.Name, (x, new_string)))
if fast_mode == False:
if retrieve_data.is_not_available(elem.Id):
print('This element {} has been checked out by another user and cannot be edited at this time.'.format(elem.Id))
return False
try:
DB.WorksharingUtils.CheckoutElements(doc,List[DB.ElementId]([elem.Id]))
except:
print('This element {} was unable to be checked out and cannot be edited at this time.'.format(elem.Id))
return False
if new_string == None and param.HasValue == True:
param.Set("")
else:
param.Set(new_string)
# print(':white_heavy_check_mark: Updated: {}'.format(new_string))
return True
def is_not_available(elem_id):
if DB.WorksharingUtils.GetCheckoutStatus(doc,elem_id) == DB.CheckoutStatus.OwnedByOtherUser:
return True
status = DB.WorksharingUtils.GetModelUpdatesStatus(doc,elem_id)
if status == DB.ModelUpdatesStatus.DeletedInCentral or status == DB.ModelUpdatesStatus.UpdatedInCentral:
return True
return False