def pick_stylesheet(self, sender, args): """Callback method for picking custom style sheet file """ new_stylesheet = forms.pick_file(file_ext='css') if new_stylesheet: self.cur_stylesheet_tb.Text = os.path.normpath(new_stylesheet)
def _change_kfile(self): kfile = forms.pick_file('txt') if kfile: logger.debug('Setting keynote file: %s' % kfile) try: with revit.Transaction("Set Keynote File"): revit.update.set_keynote_file(kfile, doc=revit.doc) self._kfile = revit.query.get_keynote_file(doc=revit.doc) # attempt at opening the selected file. try: self._conn = kdb.connect(self._kfile) except Exception as ckf_ex: forms.alert( "Error opening seleced keynote file.", sub_msg=str(ckf_ex), expanded="{}::_change_kfile() [kdb.connect]".format( self.__class__.__name__) ) return self._kfile except Exception as skex: forms.alert(str(skex), expanded="{}::_change_kfile() [transaction]".format( self.__class__.__name__))
def get_generic_template_path(): fam_template_folder = __revit__.Application.FamilyTemplatePath ENG = "\Metric Generic Model.rft" FRA = "\Modèle générique métrique.rft" GER = "\Allgemeines Modell.rft" ESP = "\Modelo genérico métrico.rft" RUS = "\Метрическая система, типовая модель.rft" if ("French") in fam_template_folder: generic_temp_name = FRA elif ("Spanish") in fam_template_folder: generic_temp_name = ESP elif ("German") in fam_template_folder: generic_temp_name = GER elif ("Russian") in fam_template_folder: generic_temp_name = RUS else: generic_temp_name = ENG gen_template_path = fam_template_folder + generic_temp_name from os.path import isfile if isfile(gen_template_path): return gen_template_path else: forms.alert(title="No Generic Template Found", msg="There is no Generic Model Template in the default location. Can you point where to get it?", ok=True) fam_template_path = forms.pick_file(file_ext="rft", init_dir="C:\ProgramData\Autodesk\RVT "+HOST_APP.version+"\Family Templates") return fam_template_path
def get_mass_template_path(): fam_template_folder = __revit__.Application.FamilyTemplatePath ENG = "\Conceptual Mass\Metric Mass.rft" FRA = "\Volume conceptuel\Volume métrique.rft" GER = "\Entwurfskörper\Entwurfskörper.rft" ESP = "\Masas conceptuales\Masa métrica.rft" RUS = "\Концептуальные формы\Метрическая система, формообразующий элемент.rft" if ("French") in fam_template_folder: mass_temp_name = FRA elif ("Spanish") in fam_template_folder: mass_temp_name = ESP elif ("German") in fam_template_folder: mass_temp_name = GER elif ("Russian") in fam_template_folder: mass_temp_name = RUS else: mass_temp_name = ENG mass_template_path = fam_template_folder + mass_temp_name from os.path import isfile if isfile(mass_template_path): return mass_template_path else: forms.alert(title="No Mass Template Found", msg="There is no Mass Model Template in the default location. Can you point where to get it?", ok=True) fam_template_path = forms.pick_file(file_ext="rft", init_dir="C:\ProgramData\Autodesk\RVT "+HOST_APP.version+"\Family Templates") return fam_template_path
def _change_kfile(self): kfile = forms.pick_file('txt') if kfile: logger.debug('Setting keynote file: %s' % kfile) try: with revit.Transaction("Set Keynote File"): revit.update.set_keynote_file(kfile, doc=revit.doc) self._kfile = revit.query.get_keynote_file(doc=revit.doc) except Exception as skex: forms.alert(str(skex)) return
def background_open(audit=bool, detachFromCentral=bool, preserveWorksets=bool): """Opens a model in the background without Revit Interface""" filePath = forms.pick_file() app = __revit__.Application openOpts = OpenOptions() openOpts.Audit = audit if detachFromCentral == False: openOpts.DetachFromCentralOption = DetachFromCentralOption.DoNotDetach else: if preserveWorksets: openOpts.DetachFromCentralOption = DetachFromCentralOption.DetachAndPreserveWorksets else: openOpts.DetachFromCentralOption = DetachFromCentralOption.DetachAndDiscardWorksets modelPath = ConvertUserVisiblePathToModelPath(filePath) background_doc = app.OpenDocumentFile(modelPath, openOpts) return background_doc
def import_keynotes(self, sender, args): # verify existing keynotes when importing # maybe allow for merge conflict? kfile = forms.pick_file('txt') if kfile: logger.debug('Importing keynotes from: %s' % kfile) res = forms.alert("Do you want me to skip duplicates if any?", yes=True, no=True) try: kdb.import_legacy_keynotes(self._conn, kfile, skip_dup=res) except System.TimeoutException as toutex: forms.alert(toutex.Message) except Exception as ex: logger.debug('Importing legacy keynotes failed | %s' % ex) forms.alert(str(ex)) finally: self._update_ktree(active_catkey=self._allcat) self._update_ktree_knotes()
def pick_files(files_filter): logger.debug(files_filter) result = [] for i in range(10): paths = forms.pick_file(files_filter=files_filter + "|All files (*.*)|*.*", restore_dir=True, multi_file=True) if not paths: break result += list(paths) logger.info("Files selected: " + "\n".join(paths)) form_result = forms.alert("Add more files?", yes=True, cancel=True) if not form_result: break return set(result)
def import_keynotes(self, sender, args): # verify existing keynotes when importing # maybe allow for merge conflict? kfile = forms.pick_file('txt') if kfile: if not coreutils.check_revittxt_encoding(kfile): logger.debug('Incorrect file encoding: %s' % kfile) forms.alert("File must be encoded in UTF-16 (UCS-2 LE)") else: logger.debug('Importing keynotes from: %s' % kfile) res = forms.alert("Do you want me to skip duplicates if any?", yes=True, no=True) try: kdb.import_legacy_keynotes(self._conn, kfile, skip_dup=res) except System.TimeoutException as toutex: forms.alert(toutex.Message) except Exception as ex: logger.debug('Importing legacy keynotes failed | %s' % ex) forms.alert(str(ex)) finally: self._update_ktree(active_catkey=self._allcat)
def read_from_csv(csv_path=None): """ Retrieve shared parameters from a csv file. csv file need to be formatter this way : <Parameter Name>, <ParameterType>, <DefinitionGroup>, (Optional)<Guid>,(Optional)<Description>, (Optional)<UserModifiable> True or False, (Optional)<Visible> True or False :param csv_path: absolute path to csv file """ if not csv_path: csv_path = forms.pick_file(file_ext="csv") if not csv_path: raise ValueError("No file selected") shared_parameter_list = [] with open(csv_path, "r") as csv_file: file_reader = csv.reader(csv_file) file_reader.next() for row in file_reader: shared_parameter_list.append(SharedParameter(*row, new=True)) return shared_parameter_list
def get_config_file(): # Get parameter definition yaml file from user return forms.pick_file(file_ext='yaml')
if a1 == None and a2 ==None: break else: data1.append(a1) data2.append(a2) sheets = {"sheetNumbers" : data1, "sheetNames" : data2} return sheets # Function to create sheets def createSheet(number, name, titleBlockId): sheet = DB.ViewSheet.Create(doc, titleBlockId) sheet.SheetNumber = number sheet.Name = name # Prompt user to specify file path pathFile = forms.pick_file(files_filter='Excel Workbook (*.xlsx)|*.xlsx|''Excel 97-2003 Workbook|*.xls') # Prompt user to select titleblock titleBlock = forms.select_titleblocks(doc=doc) # Create Excel object excel = Excel.ApplicationClass() excel = Marshal.GetActiveObject("Excel.Application") workbook = excel.Workbooks.Open(pathFile) ws = workbook.Worksheets[1] # Read data sNumber = ws.Range["A1", "A1000"] sName = ws.Range["B1", "B1000"] sheetNumbers = [str(x) for x in retData(sNumber.Value2, sName.Value2)["sheetNumbers"][1:]] sheetNames = [str(x) for x in retData(sNumber.Value2, sName.Value2)["sheetNames"][1:]]
forms.alert(msg="No rooms", sub_msg = "There are no placed rooms in model", ok=True, warn_icon=True, exitscript=True) element_parameter_set = good_rooms[0].Parameters room_params = [p.Definition.Name for p in element_parameter_set if p.StorageType.ToString() == "Double" and p.IsReadOnly == False and p.Definition.Name not in ["Limit Offset", "Base Offset"]] if not room_params: forms.alert(msg="No suitable parameter", \ sub_msg="There is no suitable parameter to use for Minimal Area Requirement. Please add a parameter 'Area Requirement' of Area Type", \ ok=True, \ warn_icon=True, exitscript=True) # pick excel file and read path = forms.pick_file(file_ext='xlsx',init_dir="M:\BIM\BIM Manual\Minimal area requirement table") book = xlrd.open_workbook(path) worksheet = book.sheet_by_index(0) # create dictionary with min requirements, of format [unit type][room name] : min area area_dict = {} for i in range(1, worksheet.ncols): area_dict[worksheet.cell_value(0, i)] = {} for j in range(1, worksheet.nrows): area_dict[worksheet.cell_value(0, i)][worksheet.cell_value(j, 0)] = worksheet.cell_value(j, i) # a list of variations for Living / Dining / Kitchen room name lkd_var = ["LKD", "LDK", "KLD",
parts = field_def.split('|') parts_count = len(parts) if parts_count == 1: if parts[0]: field_defs.append((parts[0], DB.ParameterType.Text)) elif parts_count == 2: field_defs.append( (parts[0], coreutils.get_enum_value(DB.ParameterType, parts[1]))) # return field definitions, and data return (field_defs, csv_lines[1:]) if __name__ == '__main__': # ask user for source CSV file source_file = forms.pick_file(file_ext='csv') if source_file: fname = op.splitext(op.basename(source_file))[0] # as user for target key schedule category key_sched_cat = forms.SelectFromList.show( revit.query.get_key_schedule_categories(), name_attr='Name', multiselect=False, title="Select Key-Schedule Category", ) if key_sched_cat: # read the csv data param_defs, param_data = read_csv_typed_data(source_file) # grab the param names param_names = [x[0] for x in param_defs] # start transaction
from pyrevit import revit, DB, forms import xlrd from rpw.ui.forms import (FlexForm, Label, ComboBox, Separator, Button) def convert_to_internal(from_units): # convert project units to internal d_units = DB.Document.GetUnits(revit.doc).GetFormatOptions( DB.UnitType.UT_Area).DisplayUnits converted = DB.UnitUtils.ConvertToInternalUnits(from_units, d_units) return converted # pick excel file and read path = forms.pick_file(file_ext='xlsx') book = xlrd.open_workbook(path) worksheet = book.sheet_by_index(0) # create dictionary with min requirements, of format [unit type][room name] : min area area_dict = {} for i in range(1, worksheet.ncols): area_dict[worksheet.cell_value(0, i)] = {} for j in range(1, worksheet.nrows): area_dict[worksheet.cell_value(0, i)][worksheet.cell_value( j, 0)] = worksheet.cell_value(j, i) coll_rooms = DB.FilteredElementCollector(revit.doc).OfCategory( DB.BuiltInCategory.OST_Rooms).ToElements() # take only placed rooms
inner_diameter, outer_diameter, used_in_size_lists, used_in_sizing, ) size_set.Add(mep_size) return size_set def convert_to_internal(value, unit="mm"): return UnitUtils.ConvertToInternalUnits( float(value), LENGTH_UNIT ) csv_path = forms.pick_file(file_ext="csv") if csv_path: with revit.Transaction("Create PipeType from csv"): name = forms.ask_for_string( default="ScheduleName", prompt="Enter a schedule name eg. SDR6 or EN10217-1 serie 2", title="PipeTypeCreation", ) schedule_id = PipeScheduleType.Create(doc, name).Id size_set = read_csv(csv_path) materials = [ (material.Name, material.Id) for material in FilteredElementCollector(doc).OfClass(Material)
elif n[-1] == "\'": return float(n[0:-1]) else: return None except: return None t = Transaction(doc, 'Add CLash Points') t.Start() #CreateStraightDuct("test", 48/12, 72/12, XYZ(6427332.2082 - 6427300, 1844136.7557-1844100, 306.927-300), XYZ(6427332.2082 - 6427300, 1844136.7557-1844100, 306.927-300-7), 7) # Documentation of work\ points = {} file = forms.pick_file(file_ext='xml', multi_file=False, unc_paths=False) fileCSV = forms.pick_file(file_ext='csv', multi_file=False, unc_paths=False) pressureCSV = forms.pick_file(file_ext='csv', multi_file=False, unc_paths=False) wallThicknesses = {} with open(pressureCSV, "r") as f: # Read each line in the file, readlines() returns a list of lines content = f.readlines() # Combine the lines in the list into a string for line in content: lineData = line.split(",") name = lineData[0] description = lineData[1]
yAdjust = -1844100 zAdjust = -300 xSurveyAdjust = -6426808.660 ySurveyAdjust = -1843624.760 zSurveyAdjust = 0 t = Transaction(doc, 'Add CLash Points') t.Start() #CreateStraightDuct("test", 48/12, 72/12, XYZ(6427332.2082 - 6427300, 1844136.7557-1844100, 306.927-300), XYZ(6427332.2082 - 6427300, 1844136.7557-1844100, 306.927-300-7), 7) # Documentation of work\ points = {} fileCSV = forms.pick_file(file_ext='txt', multi_file=False, unc_paths=False) wallThicknesses = {} with open(fileCSV, "r") as f: # Read each line in the file, readlines() returns a list of lines content = f.readlines() # Combine the lines in the list into a string for line in content: lineData = line.split(",") name = lineData[0] print(name) dataLine = lineData[1:] data = {} for d in dataLine: #print(d)
from pyrevit import forms import pyrevit import ConfigParser from os.path import expanduser clr.AddReferenceByPartialName('PresentationCore') clr.AddReferenceByPartialName('PresentationFramework') clr.AddReferenceByPartialName('System.Windows.Forms') uidoc = __revit__.ActiveUIDocument doc = __revit__.ActiveUIDocument.Document __doc__ = 'Show All recorded items in Navisworks' outprint = script.get_output() path = r'\\stvgroup.stvinc.com\v3\DGPA\Vol3\Projects\3019262\3019262_0001\90_CAD Models and Sheets\17017000\_PIM\Data\NavisData' filePath = forms.pick_file(file_ext='txt', multi_file=False, init_dir=path, unc_paths=False) # print(script.get_all_buttons()) openedFile = open(filePath) # lets create that config file for next time... home = expanduser("~") cfgfile = open(home + "\\STVTools.ini", 'w') Config = ConfigParser.ConfigParser() # add the settings to the structure of the file, and lets write it out... Config.add_section('NavisFilePath') Config.set('NavisFilePath', 'DataPath', filePath) Config.write(cfgfile) cfgfile.close() print("Data File Set to: " + filePath)
"""Get information from a RVT file.""" #pylint: disable=E0401,C0103 from pyrevit import forms from pyrevit.labs import TargetApps rvt_file = forms.pick_file(files_filter='Revit Files |*.rvt;*.rte;*.rfa|' 'Revit Model |*.rvt|' 'Revit Template |*.rte|' 'Revit Family |*.rfa') if rvt_file: mfile = TargetApps.Revit.RevitModelFile(rvt_file) print("Created in: {0} ({1}({2}))".format(mfile.RevitProduct.Name, mfile.RevitProduct.BuildNumber, mfile.RevitProduct.BuildTarget)) print("Workshared: {0}".format("Yes" if mfile.IsWorkshared else "No")) if mfile.IsWorkshared: print("Central Model Path: {0}".format(mfile.CentralModelPath)) print("Last Saved Path: {0}".format(mfile.LastSavedPath)) print("Document Id: {0}".format(mfile.UniqueId)) print("Open Workset Settings: {0}".format(mfile.OpenWorksetConfig)) print("Document Increment: {0}".format(mfile.DocumentIncrement)) print("Project Information (Properties):") for k, v in sorted(dict(mfile.ProjectInfoProperties).items()): print('\t{} = {}'.format(k, v)) if mfile.IsFamily: print("Model is a Revit Family!") print("Category Name: {0}".format(mfile.CategoryName)) print("Host Category Name: {0}".format(mfile.HostCategoryName))
import RevitServices from RevitServices.Persistence import DocumentManager from RevitServices.Transactions import TransactionManager import Autodesk.Revit.DB as DB from Autodesk.Revit.DB import FilteredElementCollector, BuiltInCategory, BuiltInParameter, Transaction, TransactionGroup, Workset, SpatialElement from Autodesk.Revit.DB import FilteredWorksetCollector, WorksetKind, Element doc = __revit__.ActiveUIDocument.Document uidoc = __revit__.ActiveUIDocument #################################################################################################################### logger = script.get_logger() # if__name__ == '__main__': source_file = forms.pick_file(file_ext='xls') #################################################################################################################### # Reading an excel file using Python import xlrd from xlrd import open_workbook # Give the location of the file loc = source_file # To open Workbook wb = xlrd.open_workbook(loc)
else: openOpt.Audit = False openOpt.DetachFromCentralOption = DetachFromCentralOption.DetachAndPreserveWorksets wsopt = WorksetConfiguration(WorksetConfigurationOption.CloseAllWorksets) # wsopt.Open(worksetList) openOpt.SetOpenWorksetsConfiguration(wsopt) modelPath = ModelPathUtils.ConvertUserVisiblePathToModelPath(oFile) currentdoc = app.OpenDocumentFile(modelPath, openOpt) try: DialogBoxShowingEventArgs.OverrideResult(1) except: pass return currentdoc collectorCSVFile = forms.pick_file(file_ext='csv', multi_file=False, unc_paths=False) # Main uidoc = __revit__.ActiveUIDocument doc = __revit__.ActiveUIDocument.Document __doc__ = 'Extract information from csv file and batch apply parameter value changes.'\ 'Format of csv: "model name, element Id, parameter name, new parameter value".'\ 'Step 1: Select the csv File'\ 'Step 2: Select the Revit Files'\ 'Step 3: Select the directory new models to be placed.' uiapp = UIApplication(doc.Application) application = uiapp.Application t = Transaction(doc, "Apply Parameters") t.Start() print(str(doc.Title) + ' Opened')
(meta[prop_name][locale_code], locale_str)) else: print('adding locale \"%s\" -> \"%s\"' % (locale_code, locale_str)) meta[prop_name][locale_code] = locale_str yaml.dump_dict(meta, meta_file) if bcomp.is_container: for child_comp in bcomp: update_bundle_property(bdata, child_comp, prop_name) # 1) ========================================================================== # update title locales in bundle files from input csv file csv_file = forms.pick_file(files_filter='CSV Title Locale File |*.csv') if not csv_file: script.exit() # load, parse and prepare the bundle local data title_locales_data = {} csv_data = script.load_csv(csv_file) # translate language names in csv header to language codes locale_code_fields = [] for locale_name in csv_data[0][1:]: # grabs first csv line and columns 1: logger.debug('finding locale codes for \"%s\"', locale_name) applocale = applocales.get_applocale_by_lang_name(locale_name) if applocale: locale_code_fields.append(applocale.locale_codes[0]) else: logger.error('can not determine langauge code for \"%s\"', locale_name)
def main(): location = doc.ActiveProjectLocation activeview = uidoc.ActiveView project_position = location.get_ProjectPosition(XYZ.Zero) project_angle = project_position.Angle origin = location.GetTotalTransform().Origin # Search for any 3D view or a Plan view cl = FilteredElementCollector(doc) views = cl.OfCategory( BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements() q = TaskDialog.Show( __title__, "Link CAD to current view only?", TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No | TaskDialogCommonButtons.Cancel) if str(q) == "No": this_view_only = False target_view = None elif str(q) == "Yes": this_view_only = True target_view = activeview else: return rotate = False if not target_view: target_view_project = None target_view_3d = None for v in views: if v.IsTemplate: continue if type(v) == ViewPlan: orientation = v.get_Parameter(BuiltInParameter.PLAN_VIEW_NORTH) if orientation.AsInteger() == 1: target_view = v break else: if not target_view_project: target_view_project = v if type(v) == View3D and not target_view_3d: target_view_3d = v if not target_view: rotate = True if target_view_project: target_view = target_view_project elif target_view_3d: target_view = target_view_3d if not target_view: logger.error( "Please create 3D view or a PlanView in a project to place CAD correctly" ) return path = pick_file( files_filter= "DWG files (*.dwg)|*.dwg|DXF files (*.dxf)|*.dxf|DGN files (*.dgn)|*.dgn|All files (*.*)|*.*" ) if not path: return 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)] t = Transaction(doc) t.Start(__title__) try: status, e_id = link_func( path, o, target_view, ) except Exception as e: logger.error("Unable to import CAD") logger.error(e) status = False # 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()
clr.AddReference("System") from Autodesk.Revit.DB import FilteredElementCollector, Transaction, ImportInstance, \ OpenOptions,WorksetConfiguration, WorksetConfigurationOption, DetachFromCentralOption,\ ModelPathUtils, SaveAsOptions, WorksharingSaveAsOptions, RevitLinkType, ViewFamilyType, \ ViewFamily, View3D, IndependentTag from System.Collections.Generic import List from Autodesk.Revit.UI.Events import DialogBoxShowingEventArgs from Autodesk.Revit.UI import UIApplication from Autodesk.Revit.ApplicationServices import Application clr.AddReferenceByPartialName('PresentationCore') clr.AddReferenceByPartialName('PresentationFramework') clr.AddReferenceByPartialName('System.Windows.Forms') clr.AddReference('RevitAPIUI') # Collect Save location and Rvt Files collectorFiles = forms.pick_file(file_ext='rvt', multi_file=True, unc_paths=False) destinationFolder = forms.pick_folder() def RVTFileCollector(dir): files = [] for file in os.listdir(dir): if file.endswith(".rvt"): #print(str(file)) files.append(str(file)) return files def OpenFiles(oFile, app, audit): openOpt = OpenOptions()
from Helper import * uidoc = __revit__.ActiveUIDocument doc = __revit__.ActiveUIDocument.Document hostapp = _HostApplication(__revit__) print(hostapp.app.Language) if hostapp.app.Language.ToString() == "English_USA": ParameterName = LG_EUN() elif hostapp.app.Language.ToString() == "Chinese_Simplified": ParameterName = LG_CHS() #RhToRe.rhMeshToMesh(1) #Read Rhino File finlename = forms.pick_file(file_ext='3dm', files_filter='', init_dir='', restore_dir=True, multi_file=False, unc_paths=False) Materials = rpw.db.Collector(of_category='OST_Materials', is_type=False).get_elements(wrapped=False) Materials_options = {t.Name: t for t in Materials} CategoryID_options = { "常规模型": DB.BuiltInCategory.OST_GenericModel, "墙": DB.BuiltInCategory.OST_Walls } #信息输入部分 components = [ Label('材质'), ComboBox('Material', Materials_options), Label('类型'),
def change_definition_file(cls): path = forms.pick_file(file_ext="txt") if path: HOST_APP.app.SharedParametersFilename = path return cls.get_definition_file()
def get_files(): return forms.pick_file(file_ext='pat', multi_file=True)
def load_log_file(self, sender, args): selected_file = forms.pick_file('log') if selected_file: self._append_log_file(selected_file)
"""API change in Revit 2016 makes old method throw an error""" try: # Revit 2016 return [doc.GetElement(id) for id in __revit__.ActiveUIDocument.Selection.GetElementIds()] except: # old method return list(__revit__.ActiveUIDocument.Selection.Elements) from System import EventHandler, Uri from pyrevit import framework from pyrevit import script from pyrevit import DB, UI from Autodesk.Revit.DB import TextNoteType from System import EventHandler, Uri from Autodesk.Revit.UI.Events import ViewActivatedEventArgs, ViewActivatingEventArgs, IdlingEventArgs clr.AddReferenceByPartialName('System.Windows.Forms') from System.Windows.Forms import SendKeys __doc__ = 'Export element id of selected element(s) to an existing txt file' collectorFile = forms.pick_file(file_ext='txt', multi_file=False, unc_paths=False) updateLine = "" for ele in get_selected_elements(doc): updateLine += str(ele.Id) updateLine += "," updateLine = updateLine[0:len(updateLine)-1] f = open(collectorFile, "w") f.write(updateLine) f.close()