Copies the list settings of folders, link containers, and resource planning views
Copies the list setting of a folder, LinkContainer, or Resource Planning view.
a dialog appears where one of the following actions can be selected:

YYYYMMDD-Containername-ObjID. This can also be overwritten if necessary.CAUTION: It is important to pay careful attention to what is being transferred. Transfer List settings to locations where they do not fit can cause Vertec to crash.
Therefore, we recommend that you do not register the script, but use it via the Script Editor.
You can also define list settings that you want to use for all lists of a class (e.g. all address lists) as default. See the article about list settings – button Als Standard speichern.
| Vertec version | Specificity version | Script |
|---|---|---|
| From Vertec 6.8 | Uses the english data model | Transferlistsettings.py |
The script must be run on the folder/LinkContainer. Select it and then open the Script Editor. Run the script in it.
Copying list settings is done on the Resource Planning View definition. Select it and then open the Script Editor. Run the script in it.
# coding: windows-1252 # # Name: Transfer list settings # Classes: Entry # CondExpression: None # Selectedobjectsscript: Y # Condexpression: self->size = 1 # ExtendedRights: N # # Description: Copies list settings in Vertec or to / from a file. # # 2025-03-06, CBR: Created. # 2026-08-21, CBR: Updated for concept. # # Version = 101 import vtcapp import traceback import json import re # region constants LANGUAGES = vtcapp.evalocl("Language.allInstances.languagename->asSet") + ["NV"] TITLE = vtcapp.translate("Transfer list settings") MEMBERS_SOURCE = ["tabsPerClass", "controllerClassName"] MEMBERS_GRIDDEF = ["rowHeight", "ghostrow", "fontColor", "color", "editing", "class"] MEMBERS_GRIDCOL = ["writeableExpression", "alignment", "orderIdx", "color", "fontColor", "controlName", "rendererName", "totals", "controlDefinition", "expression", "readOnly", "sortOrder", "tabstop", "width", "isFixed", "remarks", "isDynamic", "enableSpellCheck", "spellCheckLanguageExpression", "visibleExpression", "title"] MEMBERS_ML = ["title"] # region action functions def transfer_from_list(target): "Copy another lists settings to this list." # Select source source = select_folder(target, False) if not source: return # Source to dict source_settings = to_dict(source) if not source_settings: return # Dict to target from_dict(target, source_settings) def transfer_to_list(source): "Copy this lists settings to another list." # Select target target = select_folder(source, True) if not target: return # Source to dict source_settings = to_dict(source) if not source_settings: return # Dict to target from_dict(target, source_settings) def load_from_file(target): "Updates the current list settings from a file." # Select file try: filename, file = vtcapp.requestfilefromclient(TITLE, "", "JSON|*.json") except RuntimeError: return # Source to dict source_settings = json.loads(file.decode('utf-8')) if not source_settings: return # Dict to target from_dict(target, source_settings) def save_to_file(source): "Saves the current list setttings to a file." # Source to dict settings_dict = to_dict(source) # Save file filename = settings_dict.get('filename', '') file = json.dumps(settings_dict).encode('utf-8') vtcapp.sendfile(file, filename, True, False) # region internal functions def _save_getattr(vtc_object, member, settings): "Savely gets an attribute." normalized_member = member.lower() if hasattr(vtc_object, normalized_member): try: if normalized_member in MEMBERS_ML: settings[normalized_member] = {} for language in LANGUAGES: settings[normalized_member][language] = vtc_object.getmlvalue(normalized_member, language) else: settings[normalized_member] = getattr(vtc_object, normalized_member) except Exception: traceback.print_exc() return settings def _save_setattr(vtc_object, member, settings): "Savely sets an attribute." normalized_member = member.lower() if normalized_member not in settings.keys(): return try: if normalized_member in MEMBERS_ML: for language in LANGUAGES: vtc_object.setmlvalue(normalized_member, settings[normalized_member][language], language) else: setattr(vtc_object, normalized_member, settings[normalized_member]) except Exception: traceback.print_exc() def _get_filename(source): "Returns the filename for the given source." date_string = vtcapp.currentdate().strftime('%Y%m%d') source_string = source.evalocl("asstring") source_reference = source.evalocl("objid") filename = "{}_{}_{}.json".format(date_string, source_string, source_reference) # Replace invalid characters with underscore and replace consecutive underscores. filename = re.sub(r'[\\/:*?"<>|]', '_', filename) filename = re.sub(r'_+', '_', filename) return filename def _source_to_dict(source): "Translate the source to a settings dict." source_settings = { 'griddefs': [], 'filename': _get_filename(source), } for member in MEMBERS_SOURCE: source_settings = _save_getattr(source, member, source_settings) return source_settings def _dict_to_target(target, target_setting): "Translate the settings dict to the target" for member in MEMBERS_SOURCE: _save_setattr(target, member, target_setting) def _griddef_to_dict(griddef): "Translate the grid def to a settings dict." griddef_settings = { 'gridcols': [] } for member in MEMBERS_GRIDDEF: griddef_settings = _save_getattr(griddef, member, griddef_settings) for gridcol in griddef.evalocl("gridcols->orderby(orderidx)"): griddef_settings['gridcols'].append(_gridcol_to_dict(gridcol)) return griddef_settings def _dict_to_griddef(griddef, griddef_setting): "Translate the settings dict to a grid def ." for member in MEMBERS_GRIDDEF: _save_setattr(griddef, member, griddef_setting) for gridcol_setting in griddef_setting.get('gridcols', []): gridcol = vtcapp.createobject('GridColDef') griddef.gridcols.append(gridcol) _dict_to_gridcol(gridcol, gridcol_setting) def _gridcol_to_dict(gridcol): "Translate the grid col def to a dict." gridcol_settings = {} for member in MEMBERS_GRIDCOL: gridcol_settings = _save_getattr(gridcol, member, gridcol_settings) return gridcol_settings def _dict_to_gridcol(gridcol, gridcol_setting): "Translate the grid col def to a settings dict." for member in MEMBERS_GRIDCOL: _save_setattr(gridcol, member, gridcol_setting) # region helper functions def to_dict(source): "Transfers the list settings to a dict." if not source: return None if source.evalocl("oclIsKindOf(LinkContainer)"): source = source.rolle # Save global settings source_settings = _source_to_dict(source) # Save griddefs for griddef in source.evalocl("griddefs"): source_settings['griddefs'].append(_griddef_to_dict(griddef)) return source_settings def from_dict(target, target_setting): "Transfers the list settings from a dict." if not target: return if target.evalocl("oclIsKindOf(LinkContainer)"): target = target.rolle # Restore global settings _dict_to_target(target, target_setting) # Remove old grids for griddef in list(target.evalocl("griddefs")): target.griddefs.remove(griddef) # Create new griddefs for griddef_setting in target_setting.get('griddefs', []): griddef = vtcapp.createobject("GridDef") target.griddefs.append(griddef) _dict_to_griddef(griddef, griddef_setting) def select_folder(base, base_is_source=True): "Lets the user select a destination or target." title = "{} {}: '{}'".format(TITLE, vtcapp.translate("from" if base_is_source else "to"), base) return vtcapp.selectobjectintree(title, [], "", "AbstractFolder, LinkContainer, ViewType") def select_action(): "Lets the user select which action should be performed." dlgDefinition=""" <Dialog Title="Transfer list settings" Width="500"> <Group Label="Select action" ShowLabel="True"> <ListBox Name="AuswahlBox" Lines="4"/> </Group> <Dialog.Buttons> <Button Text="OK" IsAccept="True" Command="{Binding OkCommand}" /> <Button Text="Cancel" IsCancel="True" Command="{Binding CancelCommand}" /> </Dialog.Buttons> </Dialog> """ initValues = {} action = None initValues["AuswahlBox.Items"] = (vtcapp.translate("Transfer settings from another list"), vtcapp.translate("Transfer this list settings"), vtcapp.translate("Load settings from file"), vtcapp.translate("Save settings to file")) ok, values = vtcapp.showcustomdialog(dlgDefinition, initValues) if ok: actions = {0: 'transfer_from_list', 1:'transfer_to_list', 2: 'load_from_file', 3: 'save_to_file'} action = actions.get(values["AuswahlBox"]) return action # region main function # We cannot use normal main entry, because we need locals() source = argobject # type: ignore # noqa # Check conditions if not source.eval("oclisKindOf(AbstractFolder) or oclisKindOf(LinkContainer) or oclisKindOf(ViewType)"): raise Exception(vtcapp.translate("This script only works for Folders, Link Containers and Ressource Planning views.")) # Select action action = select_action() if action: # Execute action try: locals()[action](source) # Catch error. Display short message and print long message. except Exception as e: traceback.print_exc() message = "{}\n\n{}\n\n({})".format(vtcapp.translate("An error occurred."), e, vtcapp.translate("See Python console for more information")) vtcapp.msgbox(message)