Konvertierung in Masse – *.xls zu *.xlsx

Problemstellung

Strukturen sind oft über Jahre wenn nicht Jahrzehnte gewachsen. So auch Datenmengen und deren Formatierungen. Damit nun alle ein einheitliches Format haben und auch in der Cloud besser alle Office-Dokumente im OpenXML-Format vorliegen, sollten diese nun konvertiert werden.

Lösungsansatz

Schritt für Schritt

Aufgrund der Masse der Dateien macht es Sinn, sich mal kurz ein Tool zu basteln. Bei wenigen Dateien ist das vielleicht etwas oversized, aber bei <Öffnen – Speichern unter – Format wählen – Speichern> von immerhin (wenn man fix ist) 30sec. sind das bei 10 Dateien schon 5min+. Sind es mehr als 40-50 Dateien mit dem gleichen Problem lohnt sich der Programmieraufwand.

Nach kurzer Suche stößt man auf zB excellent-conversions-and-downloads und damit auf die etwas schnellere Möglichkeit zur Konvertierung (hier mit Excel und unter Windows):

"<path to file>/excelcnv.exe" -oics "<quelldatei.xls>" "<zieldatei.xlsx>"

Immerhin kann so das Öffnen von und geklickere in Excel eingespart werden, doch richtig smart ist das noch nicht. Also diesen Ansatz ab in einen Batch und um Schleifen (siehe zB. tutorial-zur-for-schleife) und Abfragen erweitert.

Das ganze geht aber auch mit Opensource, zB. mit LibreOffice. Je nach System muss noch der Pfad angegeben werden:

#Windos
"<path to file>\soffice.exe" --convert-to xlsx "<quelldatei.xls>" -outdir "<zielpfad>"
#Linux
libreoffice --convert-to xlsx ./<quelldatei.xls> --outdir <zielpfad>
Weiterlesen

Projektvorlagen und Basisprojekte

Der kleine Unterschied (war einmal)

Projektvorlagen waren in EPlan bis Eplan P8 Version 2.9 nur eine Hülle eines Projektes, welches keine Stammdaten eingelagert, sondern nur referenziert hatte. Übrigens ähnlich zu den Projekten damals in Eplan5 und der Grund bei Problemen der Migration alter Projekte.

Basisprojekte hingegen haben alles direkt an Bord, was man eben braucht (oder eben auch nicht mehr braucht, aber nicht bereinigt wurde).

Projektvorlagen ade – noch schnell umsteigen

Packen wir erstmal das Scheidende an. In 2022 und neuer wird das leider nicht mehr nutzbar sein. Aber es lässt sich mit der Action XPrjConvertBaseProjectsAction und dem Parameter /Folder:<Folder> einfach in ein Basisprojekt konvertieren. Entweder wie in der Beschreibung im Link, oder als kleines Script (ehrlich gesagt: Im Consulting hätte ich mir die Schweizer Taschenmesser-Ribbon-Bar gebastelt, die das direkt mit drin hätte… Als Admin reicht es auch manuell in die Menüleiste gezogen, ausgeführt und wieder gelöscht.

XPrjConvertBaseProjectsAction /Folder:$(MD_TEMPLATES) // Übernommen aus der Anleitung von EPlan

Basisprojekte und wie ich sie automatisiert ausschreibe

Weiterlesen

PDFs Exportieren

Die einfache Variante

Wenn beim Schließen des Projektes einfach nur das PDF ausgeschrieben werden soll? Kein Problem, denn das hat Johann Weiher schon als schönes Beispiel dargestellt. Nun soll das PDF nicht einfach nur den Projektordner abgelegt werden, sondern in einen bestimmten Ordner in der zentralen Datenverwaltung auf einem Netzlaufwerk. Basis ist das verlinkte Script mit ein paar kleinen Anpassungen. Die Zentrale Funktion ist die EXPORT-Funktion.

Weiterlesen

Projektnummern mit RegularExpressions finden

Problemstellung

Folgendes Szenario dürften so einige Sachbearbeiter kennen: Es gibt ein Sammelbecken mit Dateien, die unter anderem eine Projektnummer oder Auftragsnummer beinhalten. Ziel für diese Dateien sind die entsprechenden Projektordner in einer zentralen Struktur. Auch die Projektordner beinhalten die Projektnummer oder Auftragsnummer. So eine Struktur dürfte in vielen Unternehmen, ob Old School auf einem Serverlaufwerk oder etwas aktueller in der Cloud.

Lösungsansatz

Doch wie findet man nun 1. die Nummer in dem Dateinamen und 2. den korrekten Zielordner(besonders wenn der nicht direkt im Stammverzeichnis liegt)? Das Stichwort ist hier RegularExpressions oder eben Reguläre Ausdrücke. Damit lassen sich aber nicht nur Nummernfolgen finden sondern komplexe Ausdrücke, Passwörter auf Konformität prüfen (min x Stellen, Groß/Kleinbuchstaben, Sonderzeichen, etc.), oder auch ganze Formelparser bauen. Soweit soll es hier aber nicht gehen.

Ok, wir nehmen mal an, dass unsere Auftragsnummer, nach der wir suchen möchten, beispielsweise folgendes Format hat: P<Jahreszahl>-<fortlaufende Nummer, 5 Stellen>. Um mal ohne viel Aufwand RegExs zu testen, eignet sich regex101.com super und soll hier auch zum Einsatz kommen. Als Testobjekte sollen dafür mal P2023-45627, P2015-33456, P1999-11223 und P1976-00132 dienen. Damit das nun nicht zu leicht wird, könnte vor/hinter der Projektnummer nichts, Unterlagen, Rev.B, Zeichnung-12345 stehen.

Um nun den Suchbegriff abzubilden, braucht es eigentlich nur folgendes:

([pP][0-9]{4}-[0-9]{5})
(        : Öffnet die Matchgruppe
[pP]     : Ein p oder P
[0-9]{4} : 4 Zeichen, alles von 0-9 erlaubt
-        : Trennzeichen (ggf. auch [-_] möglich, wenn Fehleingaben berücksichtigt werden sollen
[0-9]{5} : 5 Zeichen, alles von 0-9 erlaubt
)        : Schließt die Matchgruppe
Weiterlesen

Marcos in Office durch aufnehmen?

Soll ich, oder besser nicht?

Schickt sich das, als Entwickler für ein Macro wirklich den Aufnahme-Button zu nutzen? Warum denn eigentlich nicht? Es ist ja immerhin nicht gleich das Endergebnis, oder? Es geht doch manchmal nur darum schnell mal einen groben Ansatz zu haben, oder nicht wieder länger nach Funktionen und deren Verwendungsmöglichkeiten zu googlen. Mit wenigen klicks kann wenigstens schon mal der grobe Rahmen erzeugt werden.

Aufgezeichnet und dann?

Das ist eben der spannende Teil: Die Aufzeichnung ist beispielsweise in Excel schnell mal 20-30 Zeilen lang und oft absolut zu einer Zelle bezogen. Nun beginnt das filtern:

  • Was muss denn wirklich sein?
  • Welcher Bezug macht Sinn? Relativ zur Selektion, absolut zu einer Spalte, ein mix?
  • Wie geht’s nun daraus weiter?
  • Welche möglichen Fehleingaben und Fehlinterpretationen sollen abgefangen werden?

Führt das immer schneller ans Ziel?

Das sicherlich nicht, denn existieren vielleicht schon fast fertige Funktionen, die nur noch modifiziert werden müssen, bringt die Aufzeichnung meist nur mehr Chaos in die Lösung. Aber auch da: es gibt kein Schwarz oder Weiß: Fehlt ein Puzzlestück, eine Funktion, dann ist’s manchmal hilfreich sich anzusehen, was Office selbst bauen würde. Man muss es ja nicht zwingend auch übernehmen…

Semantic Model in Openhab

Hintergrund und Nutzen

Am Semantic Model kommt man in Openhab kaum vorbei und wenn man sich einmal damit beschäftigt hat, wird auch schnell der Nutzen klar. Mit dem Semantic Model wird das eigene Haus als Struktur abgebildet, samt aller Ebenen, Räume, Geräte und deren Funktionen. Damit ist von einer kleinen 3-Zimmer Wohnung bis zur mehrgeschossigen Stadtvilla oder zu mehreren Standorten alles möglich.

Wird das Modell sauber aufgebaut, könnte mit Scripten und Regeln durch das ganze Haus navigiert werden. Das kann für komplexere Funktonen interessant sein, zum Beispiel beim generieren von Seiten.
Apropos Seiten: Auf diesen sollen die jeweiligen Steckdosen/Lampen/Sensoren/Lautsprecher etc. des Raumes dargestellt werden. Mit Widgets lassen sich dann Gruppen von Lampen oder Steckdosen dynamisch darstellen.

Tipps zum Aufbau

Wie schon beschrieben, wird das Modell immer von der größten Einheit zur kleinsten aufgebaut, hier mal als Beispiel für ein kleines Eigenheim:

Weiterlesen

How I start with Rules – Openhab und Regeln

First Steps

Eure Wahl des SmartHome ist auf Openhab gefallen? Sehr gut! Ihr könnt zumindest etwas Blockly gemacht und versteht grundsätzlich das Zusammenspiel von Bedingungen, Objekten, Variablen, Funktionen und Schleifen? Dann wird das ganze recht simple, denn je nach Tiefgang der Regeln und Scripte reicht das teilweise absolut schon aus.

Ich bin auch ganz ehrlich: Ich nutze gerne mal für den ersten Wurf, die ersten Ideen eben Blockly und baue mir dann nachher erst den Code so um, wie ich es wirklich schick finde. Denn die Regeln mögen gut laufen und auch noch sicher. Aber viel Code kann eben auch bedeuten, dass die Regel unnötig lange je Triggerung braucht. Je nachdem, wie die Trigger gesetzt und nicht vor gefiltert werden, kann das auch durchaus zu einer beachtlichen CPU-Last werden.

Openhab und Dokumentation

Aber gut: Die ersten Ideen kommen schnell und es kommt auch schon vor den ersten Versuchen etwas mal zu implementieren die Frage: Was kann geht denn da alles. Hier hilft die Doku wahnsinnig weiter. Es wird, zumindest meiner Meinung nach, sehr viele Zusammenhänge und Co beschrieben, und eben auch, was jedes Objekt kann, oder wie man Daten rein, bzw. raus bekommt.

Neben der Doku gibt’s auch massenweise Foren, in denen andere User helfen. Nicht alles steht in der Doku, manches lässt sich auch nicht immer abbilden. Und manchmal gibt es auch eben nicht den einen anderen User, der die komplette Antwort hat, aber wenigstens ein weiteres Puzzlestück.

ECMAScript vs. ECMAScript-2021

Im laufe der Programmierung in Openhab werdet ihr früher oder später auf die Unterschiede stoßen. Aktuell sind die Blockly-Blöcke alle als ECMAScript hinterlegt. Das Unterscheidet sich teils deutlich von ECMAScript-2021. Beispielsweise im Zugriff auf die Items:

//ECMAScript
var myItem = itemRegistry.getItem('Itemname');
if (myItem.state == '123') { ...; }
events.sendCommand(myItem.name, '456');

//ECMAScript-2021
var myItem = items.getItem('Itemname');
if (myItem.state == '123') { ...; }
myItem.sendCommand('456');

Daher nochmal der Tipp: Beim Blick in Foren immer auch schauen, mit welcher Version die Lösung geschrieben ist. Denn JavaScript ist beides, nur auf den Umgang mit Funktionen, Klassen und Objekten ist etwas anders.

How to start with EPLAN Scripting

Gehen wir mal davon aus: C# ist bekannt und auch Programmabläufe müssen wir hier nicht mehr reden. Für den ersten Start, sollte man die entsprechende Hilfe-Seite von EPlan kennen. Auch die Seiten von Johann Weiher ist immer unheimlich hilfreich und sein Buch kann ich sehr empfehlen (besonders für den Einstieg). Übrigens: Die API-Hilfe von EPlan ist an einigen Stellen umfangreicher und genauer.

Zum einfachen Testen einer Funktion ist die Vorlage hier gut geeignet (direkt mit ActionCallingContext, kann weg gelassen werden, wenn es keine Parameter gibt):

// Angelehnt an https://eep8a.de/v3/scripts/02_Actions_ausfuehren/#03-action-mit-parameter
using Eplan.EplApi.ApplicationFramework;
using Eplan.EplApi.Scripting;

public class test_nuttshell {
  [Start]
  public void myfuction() {
    CommandLineInterpreter cli = new CommandLineInterpreter();
    ActionCallingContext   acc = new ActionCallingContext();

    acc.AddParameter("<Parametername #1>", "<Parameterwert #1>");
    acc.AddParameter("<Parametername #2>", "<Parameterwert #2>");
    //...
    acc.AddParameter("<Parametername #n>", "<Parameterwert #n>");
    
    cli.Execute("XGedStartInteractionAction", acc);
  }
}

Das ganze einfach in einer Textdatei mit der Endung „*.cs“ speicher und testen. Es reicht nun das Script zu starten, dann wird die Funktion nach dem Triggerwort für das Event Start ausgeführt. Das ist allerdings eher für seltener gebrauchte Tools sinnvoll. Später macht es Sinn dann die Funktionen über Menüs oder Events wie OnMainStart zu triggern:

// Angelehnt an https://eep8a.de/v3/scripts/02_Actions_ausfuehren/#03-action-mit-parameter
using Eplan.EplApi.ApplicationFramework;
using Eplan.EplApi.Scripting;

public class test_nuttshell {
  [DeclareAction(ACTION_NAME)]
  public void myfuction() {
    CommandLineInterpreter cli = new CommandLineInterpreter();
    ActionCallingContext   acc = new ActionCallingContext();

    acc.AddParameter("<Parametername #1>", "<Parameterwert #1>");
    acc.AddParameter("<Parametername #2>", "<Parameterwert #2>");
    //...
    acc.AddParameter("<Parametername #n>", "<Parameterwert #n>");
    
    cli.Execute("XGedStartInteractionAction", acc);
  }
}

Alternativ können Scripte und Funktionen auch über die Befehlszeile mit den entsprechenden Parametern ausgeführt werden. Im-/Exporte aus anderen Tools lassen sich so einfach realisieren, wenn das entsprechende Eplan installiert ist:

"<Pfad zur w3u.exe>" /NoSplash /Quiet /Auto /Variant:electric /NoLoadWorkspace ....