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.

using System;
using System.IO;
using System.Windows.Forms;
using Eplan.EplApi.ApplicationFramework;
using Eplan.EplApi.Base;
using Eplan.EplApi.Scripting;

public class pdf_export_onclose {
  [DeclareEventHandler("Eplan.EplApi.OnUserPreCloseProject")]
  public void Function() {
    // Projektpfad nur als Backup
    string projectPath = PathMap.SubstitutePath("$(PROJECTPATH)");
    // Nehmen wir an, das Feld Projektname beinhaltet immer eine valide Projektnummer
    string projectName = PathMap.SubstitutePath("$(PROJECTNAME)");
    // Projektnummer validieren
    string komnr = getProjectNumber(projectName);
    // Der zentrale Ordner im Unternehmen für dieses Projekt
    string komfPath = getProjectPath(komnr);
    // finale Zielordner
    string dstfolder = '';
    
    // Prüfen ob der Kommissionsordner gefunden werden konnte, sonst Fallback
    if (komfPath != '') {
      dstfolder = komfPath;
    } else {
      dstfolder = projectPath;
    }
    
    DialogResult dialogResult = MessageBox.Show(
        "Soll ein PDF für das Projekt'" + "\n" + projectName + "'" + "\n" + " erzeugt werden?" +
            "\n" + "\n" + "Ziel: " + dstfolder,
        "PDF-Export", MessageBoxButtons.YesNo, MessageBoxIcon.Question
    );

    if (dialogResult == DialogResult.Yes) {
      Progress progress = new Progress("SimpleProgress");
      progress.SetAllowCancel(true);
      progress.SetAskOnCancel(true);
      progress.BeginPart(100, "");
      progress.ShowImmediately();

      CommandLineInterpreter cli = new CommandLineInterpreter();
      ActionCallingContext acc = new ActionCallingContext();

      string fullFileName = Path.Combine(dstfolder, projectName);
      acc.AddParameter("TYPE", "PDFPROJECTSCHEME");
      acc.AddParameter("EXPORTFILE", fullFileName);
      acc.AddParameter("EXPORTSCHEME", "EPLAN_default_value");
      acc.AddParameter("USEPRINTMARGINS","1");

      cli.Execute("export", acc);

      progress.EndPart(true);
    }
    return;
  }
  public string getProjectNumber (string str) {
    // RegularExpression definieren wie oben in Lösung I
    Regex obj_regex = new Regex("([pP][0-9]{4}-[0-9]{5})", RegexOptions.Compiled | RegexOptions.IgnoreCase);
    // Pattern nun gegen den String str prüfen
    Match obj_match = obj_regex.Match(str);
    // Wenn es ein Match gibt, Projektnummer zurückgeben
    if (obj_match.Length > 0) { return obj_match.Value; }
    return "";
  }
  public string getProjectPath (string str_ProjNo) {
    string str_startpath = @"\\<Server>\<sharefolder>\<projektstammordner>"
    if (str_ProjNo != "") {
      try {
        // nur in der obersten Ebene Suchen, da auch Unterordner mit einer Projektnummer existieren könnten
        string[] str_dirs = Directory.GetDirectories(str_startpath, str_ProjNo + "*", 
                            SearchOption.TopDirectoryOnly);
        return str_dirs[0];
      } catch (Exception) {
        return "";
      }
    }
    // vielleicht hier eine Fehlermeldung, weil nicht gefunden oder Problem aufgetreten
    return "";
  }
}

Als EXPORTSCHEME kann ein definiertes Schemata genutzt werden (meine Empfehlung) oder auch als Parameter weg gelassen werden (nutzt dann immer das zuletzt genutzte Schemata -> mögliche unerwünschte Effekte). Solange es nur eine Variante des Plans gibt, ist alles tuti und soweit auch völlig ausreichend.

Eine für den Kunden, eine für die Werkstatt, eine für …

Infos auf Layern ein- und ausblenden

Die Werkstatt hätte gerne Kommentare direkt im Plan stehen (Beachte dies, Abweichungen zum Standard dort, …). Sowas lässt sich gut auf einem extra Layer abbilden. Ob nun einen Ungenutzten oder einen Benutzerdefinierten, ist zweitrangig. Ein- und ausblenden lassen sich Layer über CHANGELAYER.

public void setKommentsLayer(Boolean visible) {
  CommandLineInterpreter cli = new CommandLineInterpreter();
  ActionCallingContext acc = new ActionCallingContext();
  
  acc.AddParameter("LAYER", "Layername");
  if(visible) {
    acc.AddParameter("VISIBLE", "true");
    acc.AddParameter("PRINTED", "true");
  } else {
    acc.AddParameter("VISIBLE", "false");
    acc.AddParameter("PRINTED", "false");
  }
  cli.Execute("changelayer", acc);
}

Differenzierende Auswertungen

Der Kunde soll vielleicht lieber nicht alles haben. „Alles“ bedeutet zum Beispiel eine umfangreichere Auswertungen, andere (reduzierte/erweiterte/einsprachige) Formulare. Wichtig bei diesem Ansatz: Es braucht immer zwei Auswertungen, die „richtige“ und eine „überschreibende“ Auswertung.

Die „richtige“ wird ganz regulär ausgelegt und wird in den Projektoptionen erweitert, sodass sie nur dann Aktiv ist, wenn in den Projektfilter ein bestimmtes Feld einen bestimmten Inhalt aufweist. Dagegen wird die „überschreibende“, wenn sie nicht als Alternative für die „richtige“ eingesetzt wird, in den Projektfilter Invers zur „richtigen“ gesetzt UND! die Filter werden so scharf gesetzt, dass nichts auszuwerten ist (Nur Artikel mit ERP-Nummer=“DasSollNichtAusgewertetSein“).

Wenn es nur mehrere Varianten der Auswertung gibt, also Beispielsweise Klemmenplan mit Formular A für den Kunden, mit Formular B für die Werkstatt und Formular C für alle anderen, braucht es keine „überschreibende“ Auswertung mehr.
Hintergrund: Auswertungen, die NICHT Aktiv sind, oder NICHT (mehr) in den Auswertungsvorlagen stehen, werden auch nicht neu ausgewertet und verbleiben damit unverändert im Projekt.

Das war allerdings nur der erste Schritt, denn: Der Projektfilter benötigt ja auch einen Wert auf den dieser reagiert. Zum Einsatz kommen dafür die Settings (Anwendungsbeispiel):

public void getSettings(string settingname) {
  Settings settings = new Settings();
  return settings.GetStringSetting(settingname, 0);
}
public void setSettings(string settingname, string value) {
  Settings settings = new Settings();
  return settings.SetStringSetting(settingname, value);
}

Kleine Empfehlung: Immer zwei Settings anlegen: Einen für verfügbare Optionen (kann durch den Nutzer bestimmt werden) und einen für die gewählte Option. Das eignet sich auch für sprachliche Unterscheidungen, auch wenn vielleicht die Auswertung für die Werkstatt in einer abweichenden Kundensprache nicht zwingend für die Werkstatt gebraucht werden kann.. Wichtig: Nach jeder Änderung der Projektsettings: Auswertung aktualisieren!!

public void updateReports() {
  CommandLineInterpreter cli = new CommandLineInterpreter();
  ActionCallingContext acc = new ActionCallingContext();
  
  acc.AddParameter("TYPE", "Layername");
  cli.Execute("reports", acc);
}

Sprachen differenzieren

Wie oben schon anklingen lassen, kann man auch die Sprache per Script setzen. Auch die Sprachen sollten idealerweise in den Projektsettings gesetzt werden. Und es macht Sinn die Sprachen auch nur für den Export „Kunde“ zu setzen, sonst immer de_DE, oder de_de;en_US. Achtung: Es wird nicht auf Fehlwörter geachtet!

public void setLanguage(string lang, string varlang) {
  CommandLineInterpreter cli = new CommandLineInterpreter();
  ActionCallingContext acc = new ActionCallingContext();
  
  acc.AddParameter("DISPLAY", lang);
  acc.AddParameter("VARIABLE", varlang);
  acc.AddParameter("SOURCE", "de_DE");
  cli.Execute("SetProjectLanguage", acc);
}

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert