Darum kommt xlwings für uns nicht in Frage.
Wir verzichten seit längerem auf die Desktop App. Mit der Cloud- und Web App sind wir sehr zufrieden. Alle unsere Funktionen und angebundenen Systeme konnten webfähig gemacht werden (wir haben Vertec on premise). Dies ist besonders wichtig, das wir auch viele Mac-User haben.
Beiträge von Amadeo Vergés (Zühlke Engineering AG)
-
-
Merci für die Erläuterungen. Bei uns liegt der Fokus auf "Excel files lesen".
Das Schreiben von Excel-Files ist nicht im Fokus.
-
Wir nutzen vermehrt die Python-library openpyxl um Daten aus Excel mittels Script direkt nach Vertec zu importieren.
Dazu muss man selber die für die aktuelle Python-Version von Vertec gültige Version von openpyxl ins Vertec-Verzeichnis kopieren.Könnte Vertec diese (die jeweils gültige Version) openpyxl-lib in Vertec vorinstallieren?
Für Interessierte hier ein sehr einfaches Script mit openpyxl das ich genutzt habe ein Feld (member) auf allen Mitarbeitern unserer Firma zu aktualisieren. In diesem Fall wusste, ich in welcher Excel-Spalte (nummer) sich die Daten befinden. Man kann aber auch über den Spaltennamen zugreifen und vieles mehr.
Python
Alles anzeigen# coding: windows-1252 # # Bezeichnung: Import_BusinessTitle_From_Excel # Klassen: - # CondExpression: - # ObjectScript: N # ContainerScript: N # EventType: - # EventClass: - # EventMembers: - # ExtendedRights: N # # --- Imports the BusinessTitle from an Excel File ans writes to the corresponding user (BoldID) # --- Excel file must contain boldID as first, and Business title as second column # --- Uses openpyxl # # ---2023-04-03, av: erstellt ############################################################################################# from openpyxl import load_workbook from io import BytesIO def _get_worksheet_active(excel_file_content): # loads the active workshhet of an excel file wb = load_workbook(filename = BytesIO(excel_file_content)) ws = wb.active return ws def main(): filepath, excel_file_content = vtcapp.requestfilefromclient("Bitte Excel-File auswählen", "", "Excel-File|*.xlsx") worksheet = _get_worksheet_active(excel_file_content) dlgDefinition = ''' <Dialog Title="Import from Excel-File" Width="480"> <Group LabelWidth="200" Orientation="Vertical"> <TextBlock Text="First column is taken as boldID / objectID." Appearance="Info" /> <CheckBox Name="HasTitleRow" Label="Has title row" HorizontalAlignment="Left"/> </Group> <Dialog.Buttons> <Button Text="OK" IsAccept="True" Command="{Binding OkCommand}" /> <Button Text="Cancel" IsCancel="True" Command="{Binding CancelCommand}" /> </Dialog.Buttons> </Dialog> ''' initValues = {} initValues["HasTitleRow"] = True ok, values = vtcapp.showcustomdialog(dlgDefinition, initValues) hastTitleRow = values["HasTitleRow"] i = 0 # row counter n = 0 # count of processed rows for row in worksheet: # ignore title row? if ((i == 0) and hastTitleRow): pass else: print "{}, {}".format(row[0].value,row[1].value) user = vtcapp.getobjectbyid(int(row[0].value)) user.funktion = row[1].value n += 1 i += 1 print "Done. Processed {} lines".format(n) ### Main ##################################################### main()
-
-
Die Möglichkeit Zellen in Listen Expression-gesteuert einzufärben ist nützlich und hilfreich. Bei uns hilft dies Listenwerte die kontrolliert werden müssen, benutzerfreundlich zu gestalten (z.B. mit rot/grün-Hintergrundfarbe, etc.)
Wenn die Zellenwerte an sich eine (komplexe) OCL-Expression sind, muss man jedoch diese 1:1 die die "Farbbedingung" übernehmen, wenn diese die Einfärbung steuern sollen.
Gibt es es die Möglichkeit, über eine vordefinierte Variable einfacher auf den Wert der Zelle zuzugreifen, statt die OCL-Expression nochmals hier einzufügen?
Wenn nein, wäre das eine Anregung für die Zukunft, hilft dies doch bei der "Wartung" von Listen, da nicht die gleiche Expression an mehreren Orten angepasst werden muss.
Beispiel was ich meine (Expression an sich ist nicht von Bedeutung):
OCL-Espression für die Liste sei:(planWertExt+planAuslagenWert+planSpesenWert).round
Wenn ich nun die Hintergrundfarbe abängig von diesem Werte definiere, könnt das z.B.so aussehen:
Code
Alles anzeigenif (planWertExt+planAuslagenWert+planSpesenWert).round > 100000 then 'clRed' else if (planWertExt+planAuslagenWert+planSpesenWert).round > 5000 then 'clOrange' else if (planWertExt+planAuslagenWert+planSpesenWert).round > 1000 then 'clGreen' else '' endif endif endif
Was ich mir wünsche, wäre z.B. eine Variable "cellValue" mit der man dann die "Einfärbeexpression" so formulieren kann.
cellValue enthält das Ergenis der Spalten expression. -
Danke für die rasche Antwort! Mein Script versieht die erstellen Ordner nun mit individuellen Icons.
Gibt es eine Möglichkeit, solche Attribute selber herauszusuchen / -finden? -
Ich habe ein Excel-Import-Script geschrieben, mit dem Vertec Objekte in einen jeweils neu angelegten "Importordner" (mit der entsprechenden OCL-Klasse) abgelegt werden.
(im wesentlichen wird die boldID aus dem File gelesen und dann dass entsprechende Objekt in den Ordner gelegt. Über weitere im gleichen Excel mitgelieferte Werte kann ich dann die Objekte automatisiert in Vertec aktualisieren).
Soweit so gut. Als Zugabe fürs Auge wollte ich das Icon der neu angelegten Ordner gleich mit dem entsprechenden Icon versehen. Der scheint nicht möglich zu sein. Ich kann den IconIndex eines Ordners wohl mit Python auslesen, nicht aber setzen.
Habe ich was übersehen oder weshalb geht das nicht als einzige Ordnereigenschaft? -
-
-
-
Als Pojektleiter muss man beispielsweise die Leistungen eines MA auf seinem Projekt einsehen/prüfen können. Soll aber dessen Abwesenheiten (<> Leistungen) nicht einsehen dürfen. Darum haben wir diese entsprechend auf "deny" gesetzt. Darum überrascht es uns, das die Info trotzdem zugänglich ist.
Wie gesagt. Lösung ist möglich (Ausblenden Leistungs-Liste und Wochen Liste), erschiesst sich aber nicht direkt. Darum wollte ich darauf hinweisen.
-
Aus Datenschutzgründen in gewissen Ländern, darf/sollen die Abwesenheitsdaten eines Mitarbeiters nur für Ihn selber, den Vorgesetzten und die Personalabteilung einsehbar sein.
Wir haben das mit den "Benutzer Gruppen" / Zugriffsrechten entsprechend gelöst, haben nun aber noch folgendes festgestellt:
Sind beispielsweise für den Projektleiter die Abwesenheitsdaten eines Mitarbeiters gesperrt, sind diese trotzdem über die Wochen- und Leistungsübersicht und das i-Icon einsehbar.
Dies als Hinweis, das man in diesem Fall den Zugriff auf die entsprechenden Listen auch unterbinden muss.
-
Merci, schön das auch implies unterstützt wird!
(in der Beshreibung dazu fehlt noch das "false" meiner Meinugn) -
Vielleicht ist das allgemein schon bekannt, ich habe das erst heute herausgefunden: OCL in Vertec unterstützt weitere Operatoren, die nicht in der KB zu finden sind.
So z.B.XORDies hat mir heute geholfen, eine komplexere Abfrage einfach zu gestalten. Ev. ist dieser Tipp auch für andere hilfreich.
Gibt es eine Übersicht aller von Vertec unterstützter OCL Operatoren? -
Danke für die Bestätigung.
Ja, wir führen den sogenannten "Employee Lifecylce" wo wir auf dem Bearbeiter die historisierte Liste alle Beförderungen und Mutationen führen.
Ich muss schauen ob man da mittelfristig auch die UserRechte "loggen" kann.
Vermutlich ist in dem Fall ein Eventscript, das uns ein Email sendet, wenn ein sensitives Recht erteilt wird, die einfachste Lösung. -
Bei Zühlke definieren die verschiedenen Personalabteilungen die Benutzerrechte von (neuen) Mitarbeitern.
Nun möchten wir Admins gerne überwachen können oder infromiert werden, wenn gewisse Benutzergruppen zugewiesen wurden.Am liebsten wäre mir eine Liste welche z.B. die Zuweisung gewisser Benutzergruppen (z.B.) der letzten 24 h zeigt. Wir könnten die Daten dann per MailMonkey per Email versenden oder manuell prüfen.
Es scheint jedoch keine Möglichkeit zu geben, das Änderungsdatum eines Links (Bearbeiter <-> Benutzergruppe) abzufragen.Irre ich mich oder hat jemand einen Tipp?
Die Alternative ist ein Eventscript dass dann irgendwas macht, aber eben: Wir hätten gerne eine Liste.
-
Hier das Script das ich erstellt habe.
Anwendungszweck:- Man benötigt die Daten einer oder mehrerer Vertec-Listes (Ordner) automatisiert als CSV-Datei exportiert in einem definierten Verzeichnis
- Mittels "Geplante Aufgaben" kann das Script nach Belieben automatisch ausgeführt werden (z.B. "jeden Tag morgen um 6 Uhr")
- Im Script muss man einzig das Export-Verzeichnis und die ObjID (BoldID) der gewünschten Ordner eintragen.
Das Scritp erzeugt automatisch die Spaltenüberschriften wie sie auch im Vertec-Ordner definiert sind.
Hinweise:
- Was man im Script noch optimieren kann: Die Fehlermeldungen des Scripts werden aktuell nur auf der Konsole ausgegeben. Aber das ist ein Script, dass man nach dem Aufsetzen sicher zuerst einmal testet.
- Alternative zum Script: Man öffnet Vertec manuell, wählt den/die Ordner aus und drückt den "Export als Excel"-Knopf und speichert die Datei wo
man sie haben möchte. Ich automatisiere eben gerne Routinetätigkeiten
Python
Alles anzeigen# coding: windows-1252 # # Bezeichnung: Folders to CSV # Klassen: - # CondExpression: # ObjectScript: No # ContainerScript: No # EventType: Kein # EventClass: # EventMembers: # ExtendedRights: No # # Exports the content of multiple folders ("Vertec lists") into individual CSV-Files # - folders are defined by their objid # - one export-directory can be definied # - each folder is exported with the folder name+ datetime + datetime as filename # Histroy: # 11.10.2022/av : Script created # from VertecCSVExporterClasses import VertecCsvExporter import time #export directory (WITHOUT "\" at the end!) dir = r" (DATEI-PFAD) " #objid (boldID) of Folders that should be exported as CSV) folders = [54226830, 45637869] # process every folder for folderobjid in folders: ord = vtcapp.getobjectbyid(folderobjid) if not ord.evalocl("self->oclIsKindOf(AbstractOrdner)"): print "no folder with this ID found" else: # Load objects from folder lstobj = ord.evalocl("eintraege.list") # get columndefinitions from folder as list lstcols = ord.evalocl("gridDefs.gridcols->orderby(orderidx)") # If no column definitions are present, then there are probably no persistent ones. if not lstcols: print "The specified folder has no column definitions." else: # Prepare CSV-Export fields = [] for col in lstcols: if col.titel: titel = col.titel else: titel = "-" fields.append((titel.encode("UTF-8"), None, 'string', '')) # Create CSV-Exporter exporter = VertecCsvExporter(fields) for obj in lstobj: row = exporter.add_row(obj) for col in lstcols: value = str(obj.evalocl(col.expression)) setattr(row,col.titel,value) # Do the CSV-export # timestamp ts = time.strftime('%Y%m%d-%H%M%S',time.localtime() ) exporter.file_name = r'{}\{}-{}.csv'.format(dir,ord,ts) csv = exporter.export_rows()
-
Bevor ich das Rad nochmals neu erfinde die Frage an die Runde:
Ich weiss wie man mit einem Python-Script Vertec-Daten in ein CSV exportiert. Was ich nun gerne möchte ist ein generisches Python-Script, dass die Daten einer beliebigen Liste (z.B. definiert über die ObjID) als CSV exportiert. Im Prinzip dasselbe wie der Vertec-Button "Export to Excel" das tun, nur eben als Script.
So könnte man einen Job definieren, der eine oder mehrere Listen als CSV in ein definiertes Verzeichnis exportiert, ohne dass man für jede Liste vorher noch die Abfrage und die Felder definieren müsste. Hat jemand eine Idee oder ev. schon Code zum Teilen?
-
"Methode für die Umwandlung von Word in PDF...." und noch eine Überraschung für mich!
Andere warten auf Weihnachten, ich bis wir diesen Release installieren! -
Performance bei Vertec ist etwas, um das man sich aktiv kümmern muss. Es ist einfach, mit eigenen Konfiguration etc. Vertec langsam zu machen.
Bei uns ist das ein ständiges "Dranbleiben" (wie beim Unkraujäten). Wenn wir ein Performance-Issue haben, schauen wir uns das im Detail an, analysieren die Ursache und versuchen Optimierungen durchzuführen. Neben einer performanten Server-Umgebung (für unsere > 2000 User) gibt es eben einige von uns gewünschten Listen, bei dem man Queries optimieren konnte.
Bei uns hat es sich gelohnt, gewisse Listen auf SQL umzustellen. Und man bezahlt eben mit Performance wenn man in Listen umfangreichere Bewegungsdaten jedesmal und für jeden Eintrag "rechnen" lässt.
In einem unserer Anwendungsfälle stellen wir den Usern zwei Listen zur Verfügung:- "schnell" mit etwas weniger Detail. Details bekommt man dann schnell, wenn man einen Eintrag öffnet.
- "langsamer" mit (sehr) vielen Details wenn man wirklich alles auf einen Blick braucht
Die user haben die Wahl: Und wenn man eben die "langsame" List in diesem Fall braucht, startet man die Liste und holt sich parallel zum Aufbau einen Kaffee.