class Action: def __init__(self, name=None): self.transaction = Transaction(doc, name if name else DEFAULT_TRANSACTION_NAME) def __enter__(self): self.transaction.Start() return self.transaction def __exit__(self, exception, exception_value, traceback): if exception: self.transaction.RollBack() logger.error('Error in Transaction Context. Rolling back changes. | {}:{}'.format(exception, exception_value)) else: try: self.transaction.Commit() except Exception as errmsg: self.transaction.RollBack() logger.error('Error in Transaction Commit. Rolling back changes. | {}'.format(errmsg)) @staticmethod def carryout(name): from functools import wraps def wrap(f): @wraps(f) def wrapped_f(*args, **kwargs): with Action(name): return_value = f(*args, **kwargs) return return_value return wrapped_f return wrap
def printview(singlesheet, filepathname, papersizeobj, pdfprinterName, tmp_printsetupobj=createTmpPrintSetting()): # instantiate new_viewset Instance of ViewSetclass and insert single sheet new_viewset = ViewSet() #ViewSet Class new_viewset.Insert(singlesheet) printmanager = doc.PrintManager # set pdfprinterName = PDFCreator, Adobe PDF .. printmanager.SelectNewPrintDriver(pdfprinterName) # determine print range to Select option printmanager.PrintRange = PrintRange.Select # PrintRange is a own subclass # make the new_viewset current viewSheetSetting = printmanager.ViewSheetSetting viewSheetSetting.CurrentViewSheetSet.Views = new_viewset # set file path ---------------, add filend "_.pdf", "__.pdf" to fileend while os.path.exists(filepathname): filepathname = filepathname.replace(".pdf", "_.pdf") # filepathname must be different, everytime SubmitPrint() is called, # else Exception: file exists is raised printmanager.PrintToFileName = filepathname #as string, printmanager.Apply() printmanager.CombinedFile = True _printsetup = printmanager.PrintSetup page_orient = DB.PageOrientationType.Portrait t = Transaction( doc, "Testprint") #each Transaction must have a name. else: Error t.Start() _printsetup.CurrentPrintSetting = tmp_printsetupobj #needs a TransactionProcess, when changed _printsetup.CurrentPrintSetting.PrintParameters.PageOrientation = page_orient _printsetup.CurrentPrintSetting.PrintParameters.PaperSize = papersizeobj try: #if there are no changes to the PrintSetup obj (ie change to PrintParameters) # .Save() method throws an exception, catch Exc. needed. _printsetup.Save( ) #returns True or throws Exception: Save of print was unsuccessful except: pass try: #FECviewSets=FilteredElementCollector(doc).OfClass(ViewSheetSet).ToElements() #(doc.Delete(i.Id) for i in FECviewSets if i.Name =="!tmpViewSheetSet") viewSheetSetting.SaveAs("!tmpViewSheetSet") printmanager.SubmitPrint() t.RollBack() # chose to use RollBack()-Way, see ForumEntry import time # ??? Error, needed!!. time.sleep(1) # 3 sec, necessary, because PDF Printer will cause error #if too many docs submitted too fast. see ForumEntry #viewSheetSetting.Delete() # replaced with t.RollBack() errorReport = "Sucess" except: import traceback errorReport = traceback.format_exc() print(errorReport) try: t.RollBack() except: pass return errorReport
def ok_click(self, sender, e): room_doc = self.source_project.SelectedItem space_doc = self.target_project.SelectedItem room = room_doc.GetElement(self.sample_room_id) space = space_doc.GetElement(self.sample_space_id) # Try RoomToSpace with sample room and space to make sure it works before batch on all with all spaces try: t = Transaction(space_doc, "Test") t.Start() self.room_to_space(room, space) except ValueError as e: logger.info("{}".format(e.message)) t.RollBack() return except TypeError as e: logger.info("Is target parameter empty ?") t.RollBack() return t.RollBack() # Copy from values from with rpw.db.Transaction(doc=space_doc, name="RoomToSpace"): for space in FilteredElementCollector( self.target_project.SelectedItem).OfCategory( BuiltInCategory.OST_MEPSpaces): if space.Location: room = room_doc.GetRoomAtPoint(space.Location.Point) if room: self.room_to_space(room, space) self.Close()
def link_method_ifc(): files_filter = "IFC files (*.ifc)|*.ifc" files = pick_files(files_filter) for f in files: t = Transaction(doc) t.Start(__title__) f_cache = f + ".rvt" recreate = not os.path.exists(f_cache) logger.debug("Recreate ifc %s = %s" % (f, recreate)) # try: o = RevitLinkOptions(False) # create empty doc if recreate: doc_ifc = HOST_APP.app.OpenIFCDocument(f) save_options = SaveAsOptions() save_options.OverwriteExistingFile = True doc_ifc.SaveAs(f_cache, save_options) doc_ifc.Close() link_load_results = RevitLinkType.CreateFromIFC(doc, f, f_cache, False, o) # TODO log results http://www.revitapidocs.com/2019/11b095e1-24d9-91b9-ae2e-004f67c94d6e.htm logger.debug(link_load_results.LoadResult) instance = RevitLinkInstance.Create(doc, link_load_results.ElementId) status = True # except Exception as e: # logger.error("Unable to import IFC") # logger.error(e) # status = False # instance = None if status: instance.Pinned = True t.Commit() else: t.RollBack()
def createsheets(sheetlist): message = [] dic_sheetGuid = {} t = Transaction(doc, "Create SheetViews from EXCEL") try: t.Start() for j in sheetlist: try: tibl = dic_tibl[j[2]] except: mess1 = 'Error: TitleBlock1 "{}" not found'.format(j[2]) message.append(mess1) continue a = DB.ViewSheet.Create(doc, tibl.Id) # ViewSheet Class, Create Method a.SheetNumber = j[0] a.ViewName = j[1] dic_sheetGuid[a.SheetNumber] = str(a.UniqueId) #create TitleBlock2 instance try: tibl_2 = dic_tibl[j[3]] newtitleblock = doc.Create.NewFamilyInstance( XYZ(0, 0, 0), tibl_2, a) mess2 = '; TitleBlock2: {}'.format(str(j[3])) except: mess2 = '; TitleBlock2: not found' pass message.append('--> {}-{}, TiBl1: {}'.format( a.SheetNumber, a.ViewName, j[2]) + mess2) t.Commit() except: t.RollBack() import traceback print(traceback.format_exc()) return (message, dic_sheetGuid)
def link_method_ifc(): files_filter = "IFC files (*.ifc)|*.ifc" files = pick_files(files_filter) for f in files: t = Transaction(doc) t.Start(__title__) f_cache = f + ".rvt" recreate = not os.path.exists(f_cache) logger.debug("Recreate ifc %s = %s" % (f, recreate)) # try: o = RevitLinkOptions(False) # create empty doc if recreate: new_doc = doc.Application.NewProjectDocument(UnitSystem.Metric) new_doc.SaveAs(f_cache) new_doc.Close(False) link_load_results = RevitLinkType.CreateFromIFC( doc, f, f_cache, recreate, o) # TODO log results http://www.revitapidocs.com/2019/11b095e1-24d9-91b9-ae2e-004f67c94d6e.htm logger.debug(link_load_results.LoadResult) instance = RevitLinkInstance.Create(doc, link_load_results.ElementId) status = True # except Exception as e: # logger.error("Unable to import IFC") # logger.error(e) # status = False # instance = None if status: instance.Pinned = True t.Commit() else: t.RollBack()
def run(self, sender, args): text_find = self.text_find text_replace = self.text_replace count_changed = 0 t = Transaction(doc, __title__) t.Start() for e in self.selection: definition = self.parameter_to_set.Definition param = e.get_Parameter(definition) param_before = param.AsString() param_after = param_before.replace(text_find, text_replace) if param_before != param_after: count_changed += 1 self.parameter_value_set(param, param_after) if count_changed: t.Commit() TaskDialog.Show( __title__, "%d of %d elements updated" % ( count_changed, len(self.selection), )) else: t.RollBack() TaskDialog.Show(__title__, "Nothing was updated")
def link_method_rvt(): files_filter = "RVT files (*.rvt)|*.rvt" files = pick_files(files_filter) for f in files: t = Transaction(doc) t.Start(__title__) try: mp = ModelPathUtils.ConvertUserVisiblePathToModelPath(f) o = RevitLinkOptions(False) linkType = RevitLinkType.Create(doc, mp, o) instance = RevitLinkInstance.Create(doc, linkType.ElementId) status = True except Exception as e: logger.error("Unable to import RVT") logger.error(e) status = False instance = None if status: instance.Pinned = True t.Commit() else: t.RollBack()
def find_linked_elements(self): t = Transaction(doc, "Search for linked elements") t.Start() linked_element_ids = doc.Delete(self._rvt_type.Id) t.RollBack() return linked_element_ids
def process(datafile, saved_list=[], reverse=False): if not reverse: cl = FilteredElementCollector( doc).WhereElementIsNotElementType().OfCategory( BuiltInCategory.OST_Constraints) constraints = cl.ToElements() constraints_to_change = filter(lambda c: c.NumberOfSegments == 0, constraints) constraints_to_change = list( filter(lambda c: c.IsLocked, constraints_to_change)) td_text = "%d enabled Constraints found. Disable them?" % len( constraints_to_change) else: td_text = "Reverse mode.\n%d saved Constraints found. Recover them?" % len( saved_list) constraints_to_change = [] for id_int in saved_list: try: element = doc.GetElement(ElementId(id_int)) constraints_to_change.append(element) except: pass tdres = TaskDialog.Show( "Constraints", td_text, TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No) if tdres == TaskDialogResult.No: return t = Transaction(doc, __title__) t.Start() is_error = False try: for constraint in constraints_to_change: constraint.IsLocked = True if reverse else False if not reverse: saved_list.append(constraint.Id.IntegerValue) except Exception as exc: is_error = True t.RollBack() TaskDialog.Show(__title__, "Error. Changes cancelled.") else: t.Commit() result_text = "Finished." if not reverse: result_text += "\nChanged elements saved. To recover then run the same script with SHIFT button" TaskDialog.Show(__title__, result_text) if not is_error: save(datafile, saved_list) selection.set_to(map(lambda e: e.Id, constraints_to_change))
def run(self, sender, args): count_changed = 0 # find not empty parameter definition_set = self.parameter_to_set.Definition definition_get = self.parameter_to_get.Definition not_empty_list = [] skip_ids = [] for e in self.selection: param = e.get_Parameter(definition_set) param_get = e.get_Parameter(definition_get) if param.AsString() != '' and param.AsString() != None and param.AsString() != param_get.AsString(): not_empty_list.append("Target: %s, Source: %s" % (str(param.AsString()), str(param_get.AsString()))) skip_ids.append(e.Id) if len(not_empty_list) > 0: len_limit = 10 len_not_empty_list = len(not_empty_list) if len_not_empty_list > len_limit: not_empty_list = not_empty_list[:len_limit] + [' + %d more...' % (len_not_empty_list - len_limit)] text = "%d elements have values already. Replace them?:" % len_not_empty_list + "\n".join(not_empty_list) a = TaskDialog.Show(__title__, text, TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No) if str(a) == "Yes": skip_ids = [] t = Transaction(doc, __title__) t.Start() for e in self.selection: if e.Id in skip_ids: continue param = e.get_Parameter(definition_set) param_get = e.get_Parameter(definition_get) if param.AsString() == param_get.AsString(): continue self.parameter_value_set(param, param_get.AsString()) count_changed += 1 self.write_config() if count_changed: t.Commit() TaskDialog.Show(__title__, "%d of %d elements updated" % (count_changed, len(self.selection),)) else: t.RollBack() TaskDialog.Show(__title__, "Nothing was changed")
def get_line_styles(self): """Function to get available LineStyles for DetaiLines.""" # CREATE TEMP LINE t = Transaction(doc, "temp - Create DetailLine") t.Start() new_line = Line.CreateBound(XYZ(0,0,0), XYZ(1,1,0)) random_line = doc.Create.NewDetailCurve(active_view, new_line) line_styles_ids = random_line.GetLineStyleIds() t.RollBack() line_styles = [doc.GetElement(line_style) for line_style in line_styles_ids] return line_styles
class CustomTransaction: def __init__(self, name, doc): self.transaction = Transaction(doc, name) def __enter__(self): self.transaction.Start() def __exit__(self, exc_type, exc_value, exc_traceback): if exc_type: self.transaction.RollBack() return self.transaction.Commit()
def ef_Transaction(doc, title, debug=False): t = Transaction(doc, title) t.Start() try: yield t.Commit() except Exception as e: if debug: print("*" * 20) print("Exception occured - Transaction is being Rollbacked!") print(traceback.format_exc()) print("*" * 20) t.RollBack()
Angle.append(data[5]) CODIGO.append(data[a]) DESCRICAO.append(data[a + 1]) # Typical Transaction in Revit Python Shell / pyRevit doc = __revit__.ActiveUIDocument.Document transaction = Transaction(doc, 'Insert parameters') transaction.Start() try: for i in range(0, len(Elementos)): for t in range(0, len(FamilyName)): if (Parameter2[t] == '' and Parameter3[t] == '' and Parameter4[t] == '' and Angle[t] == ''): info1 = list(Parameter1[t].split('=')) if (Elementos[i].Name == FamilyName[t] and Elementos[i].LookupParameter( info1[0]).AsDouble() == float( RevitCodes(info1[1]))): Elementos[i].LookupParameter(codigo_construtora).Set( CODIGO[t]) Elementos[i].LookupParameter( descricao_construtora).Set(DESCRICAO[t]) except: transaction.RollBack() else: transaction.Commit() except: pass
def run(sel, location_option): logger.info("Location option: %s " % location_option) docs = __revit__.Application.Documents # where to copy src_doc = __revit__.ActiveUIDocument.Document docs = filter(lambda d: not d.IsLinked and d != src_doc, docs) trg_docs = forms.SelectFromList.show(docs, name_attr='Title', title='Documents to paste selection', button_name='Paste', multiselect=True) null_point_src = None null_point_cat = None if location_option == "Project Base Point": null_point_cat = BuiltInCategory.OST_SharedBasePoint elif location_option == "Shared Site Point": null_point_cat = BuiltInCategory.OST_ProjectBasePoint if null_point_cat: null_point_src = FilteredElementCollector( src_doc).WhereElementIsNotElementType().OfCategory( null_point_cat).WhereElementIsNotElementType().ToElements() if len(null_point_src) == 0: logger.warning( "Point for location option wasn't found in source document. Default alignment will be used" ) for trg_doc in trg_docs: logger.debug(trg_doc) logger.debug(len(trg_doc.Title)) s = "Copy %d elements from %s to %s" % (len(sel), src_doc.Title, trg_doc.Title) print(s) # logger.info(s) # TODO Fix - cannot log cyrylic project name # Transform transform_vector = None if null_point_src: null_point_trg = FilteredElementCollector( trg_doc).WhereElementIsNotElementType().OfCategory( null_point_cat).WhereElementIsNotElementType().ToElements( ) if len(null_point_trg) == 0: logger.warning( "Point for location option wasn't found in target document. Document will be skipped" ) continue # _transform_vector = null_point_trg[0].GetTransform().BasisX - null_point_src[0].GetTransform().BasisX print(null_point_trg[0].BoundingBox[null_point_trg[0]]) transform_vector = Transform.CreateTranslation( null_point_trg[0].BoundingBox.Min - null_point_src[0].BoundingBox.Min) t = Transaction( trg_doc, __title__ + " - %d elements from %s" % (len(sel), src_doc.Title)) t.Start() try: ElementTransformUtils.CopyElements(src_doc, List[ElementId](sel), trg_doc, transform_vector, None) t.Commit() except Exception as exc: t.RollBack() logger.error(exc)
def link_method_cad(): files_filter = "DWG files (*.dwg)|*.dwg|DXF files (*.dxf)|*.dxf|DGN files (*.dgn)|*.dgn" files = pick_files(files_filter) # preset origin = doc.ActiveProjectLocation.GetTotalTransform().Origin activeview = uidoc.ActiveView # or uidoc.ActiveView q = forms.alert("Link CAD to current view only?", yes=True, no=True) if q: this_view_only = True target_view = activeview else: this_view_only = False target_view = None logger.debug("Files") logger.debug(files) for f in files: logger.info("Process file %s ..." % f) link_func = doc.Link.Overloads[str, DWGImportOptions, View, System.Type.MakeByRefType(ElementId)] ext = f[-4:] if ext == ".dwg": o = DWGImportOptions() o.AutoCorrectAlmostVHLines = False o.Unit = ImportUnit.Meter o.OrientToView = False o.ReferencePoint = origin o.ThisViewOnly = this_view_only link_func = doc.Link.Overloads[ str, DWGImportOptions, View, System.Type.MakeByRefType(ElementId)] elif ext == ".dgn": o = DGNImportOptions() o.AutoCorrectAlmostVHLines = False o.Unit = ImportUnit.Meter o.OrientToView = False o.ReferencePoint = origin o.ThisViewOnly = this_view_only link_func = doc.Link.Overloads[ str, DWGImportOptions, View, System.Type.MakeByRefType(ElementId)] t = Transaction(doc) t.Start(__title__) try: status, e_id = link_func( f, o, target_view, ) except Exception as e: logger.error("Unable to import CAD") logger.error(e) status = False e_id = None # # # override rotation option # if __shiftclick__: # q = TaskDialog.Show(__title__, "Is it okay?\nIf not CAD will be rotated", # TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No | TaskDialogCommonButtons.Cancel) # if str(q) == "No": # rotate = True # elif str(q) == "Yes": # rotate = False # else: # return if status: l = doc.GetElement(e_id) # if rotate: # if l.Pinned: # l.Pinned = False # axis = Line.CreateBound(origin, # XYZ(origin.X, origin.Y, origin.Z + 1)) # # ElementTransformUtils.RotateElement(doc, l.Id, axis, -project_angle) l.Pinned = True t.Commit() else: t.RollBack()
family_manager = fam_doc.FamilyManager sweep_col = FilteredElementCollector(fam_doc).OfClass(Sweep).ToElements() sweep = [s for s in list(sweep_col) if s.IsSolid][0] empty_sweep = [s for s in list(sweep_col) if not s.IsSolid][0] trans1 = Transaction(fam_doc, 'Delete empty form') trans1.Start() fam_doc.Delete(empty_sweep.Id) param_ARH_l = family_manager.get_Parameter('ARH_l') if param_ARH_l: family_manager.Set( param_ARH_l, UnitUtils.ConvertToInternalUnits(1000, param_ARH_l.DisplayUnitType)) square = get_square_from_solid(sweep)[0] vol1 = get_square_from_solid(sweep)[1] vol2 = get_volume_from_bBox(sweep) trans1.RollBack() trans2 = Transaction(fam_doc, 'Set values') trans2.Start() sq = set_parameter_by_name(square, 'ARH_sr', fam_doc) volume1 = set_parameter_by_name(vol1, 'ARH_v1', fam_doc) volume2 = set_parameter_by_name(vol2, 'ARH_v2', fam_doc) trans2.Commit() fam_doc.LoadFamily(doc, FamilyOption()) fam_doc.Close(False) OUT = square, vol1
def run(self, sender, args): try: count_changed = 0 # find not empty parameter definition_set = self.parameter_to_set.Definition definition_get = self.parameter_to_get.Definition # collect ones to be updated - parameters_get which aren't empty and aren't equal not_empty_list = [] skip_ids = [] errors_list_ids = [] errors_list = [] errors_text = "" for e in self.selection: if USE_NAMES: param = e.LookupParameter(definition_set.Name) param_get = e.LookupParameter(definition_get.Name) else: param = e.get_Parameter(definition_set) param_get = e.get_Parameter(definition_get) if not param or not param_get: logger.debug("One of parameters not found for e.Id:%d" % e.Id.IntegerValue) continue if not pyap.is_empty(param) and not pyap.are_equal(param, param_get): value_get, value_set = pyap.convert_value(param_get, param, return_both=True) not_empty_list.append("Target: %s, Source: %s" % (value_set, value_get)) skip_ids.append(e.Id) if len(not_empty_list) > 0: len_limit = 10 len_not_empty_list = len(not_empty_list) if len_not_empty_list > len_limit: not_empty_list = not_empty_list[:len_limit] + [' + %d more...' % (len_not_empty_list - len_limit)] text = "%d elements have values already. Replace them?\n" % len_not_empty_list + "\n".join( not_empty_list) a = TaskDialog.Show(__title__, text, TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No) if a == TaskDialogResult.Yes: skip_ids = [] t = Transaction(doc, __title__) t.Start() for e in self.selection: if USE_NAMES: param = e.LookupParameter(definition_set.Name) param_get = e.LookupParameter(definition_get.Name) if not param or not param_get: logger.debug("One of parameters not found for e.Id:%d" % e.Id.IntegerValue) continue else: param = e.get_Parameter(definition_set) param_get = e.get_Parameter(definition_get) _definition_set = param.Definition _definition_get = param_get.Definition if e.Id in skip_ids: continue try: if pyap.copy_parameter(e, _definition_get, _definition_set): count_changed += 1 except Exception as exc: errors_list_ids.append(e.Id) errors_list.append("Id: %d, exception: %s" % (e.Id.IntegerValue, str(exc))) if errors_list: errors_text = ("\n\nErrors occurred with %d elements :\n" % len(errors_list)) + \ "\n".join(errors_list[:5]) if len(errors_list) > 5: errors_text += "\n..." errors_text += "\n\nValues weren't changed, elements with errors selected" selection.set_to(errors_list_ids) if count_changed or errors_list: t.Commit() TaskDialog.Show(__title__, "%d of %d elements updated%s" % (count_changed, len(self.selection), errors_text)) else: t.RollBack() TaskDialog.Show(__title__, "Nothing was changed") logger.debug("finished") except Exception as exc: logger.error(exc) # TODO FIX do not write config in lower versions - risk to corrupt config if pyRevitNewer4619 or ( pyapex_utils.is_ascii(self.parameterToGet.Text) and pyapex_utils.is_ascii(self.parameterToSet.Text)): try: self.write_config() except: logger.warn("Cannot save config") self.Close()
el ) # Фитинги и арматура труб, Оборудование и сантехника set_subcomponents( el) # Оборудование set_op_rf( el ) # Трубы, Фитинги и арматура труб, Оборудование и сантехника, Изоляция труб, Гибкие трубы, Воздуховоды, Гибкие воздуховоды, Изоляция воздуховодов, СДВиАВ, Воздухораспределители set_symbol( el ) # Гибкие воздуховоды set_sort(el) check_cost(el) result_check_cost() except Exception: t.RollBack() print(el) print('Ошибка {}, Δ={} с'.format(time.ctime().split()[3], time.time() - startTime)) print( output.linkify( el.Id, '{}: {}: {}: id {}'.format( el.LookupParameter('Категория').AsValueString(), el.LookupParameter('Семейство').AsValueString(), el.LookupParameter('Тип').AsValueString(), el.Id, ))) output.show() raise t.SetName('Расчёт спеки {}, Δ={} с'.format(time.ctime().split()[3], time.time() - startTime))
class Action(): """ Simplifies transactions by applying ``Transaction.Start()`` and ``Transaction.Commit()`` before and after the context. Automatically rolls back if exception is raised. >>> with Action('Move Wall'): >>> wall.DoSomething() >>> with Action('Move Wall') as action: >>> wall.DoSomething() >>> assert action.status == ActionStatus.Started # True >>> assert action.status == ActionStatus.Committed # True """ def __init__(self, name=None, clear_after_rollback=False, show_error_dialog=False): self._rvt_transaction = Transaction( self.doc, name if name else DEFAULT_TRANSACTION_NAME) self._fail_hndlr_ops = self._rvt_transaction.GetFailureHandlingOptions( ) self._fail_hndlr_ops.SetClearAfterRollback(clear_after_rollback) self._fail_hndlr_ops.SetForcedModalHandling(show_error_dialog) self._rvt_transaction.SetFailureHandlingOptions(self._fail_hndlr_ops) def __enter__(self): self._rvt_transaction.Start() return self def __exit__(self, exception, exception_value, traceback): if exception: self._rvt_transaction.RollBack() logger.error( 'Error in Action Context. Rolling back changes. | {}:{}'. format(exception, exception_value)) else: try: self._rvt_transaction.Commit() except Exception as errmsg: self._rvt_transaction.RollBack() logger.error( 'Error in Action Commit. Rolling back changes. | {}'. format(errmsg)) @property def name(self): return self._rvt_transaction.GetName() @name.setter def name(self, new_name): return self._rvt_transaction.SetName(new_name) @property def status(self): return ActionStatus.from_rvt_trans_stat( self._rvt_transaction.GetStatus()) @staticmethod def carryout(name): """ Action Decorator Decorate any function with ``@Action.carryout('Action Name')`` and the funciton will run within an Action context. Args: name (str): Name of the Action >>> @Action.carryout('Do Something') >>> def set_some_parameter(wall, value): >>> wall.parameters['Comments'].value = value >>> >>> set_some_parameter(wall, value) """ from functools import wraps def wrap(f): @wraps(f) def wrapped_f(*args, **kwargs): with Action(name): return_value = f(*args, **kwargs) return return_value return wrapped_f return wrap def has_started(self): return self._rvt_transaction.HasStarted() def has_ended(self): return self._rvt_transaction.HasEnded()