Farbnamen aus dem RAL-Code ermitteln

Problemstellung

Wie war denn noch der Name für RAL3000? Oh, auch noch den englischen? Kurz in der Tabelle gesucht, oder auf Seiten wie ral-farben.de geschaut: Feuerrot / Flame red. Ok, aber das für jedes Projekt? Die gebräuchlichsten sind schnell im Kopf oder auf dem Spicker und der englische Farbname lässt sich ja in der Übersetzungsdatenbank ablegen. Aber das muss doch einfacher gehen, oder?

Problemlösung

Ok, die Frage ist hier schon etwas plakativ. Daher einfach kurz zur möglichen Ausgangslage: Im Projekt sind zB. die benutzerdefinierten Felder 90/91 für den RAL-Code und den Farbnamen der Schaltschränke, die Felder 92/93 entsprechend für die Klemmkästen. Erstmal angenommen, alle Felder sind Multilang, es kommt also ein ??_??@.. beim auslesen zurück. Daher kommt einfach die Lösung aus Multilang-Strings einfach auslesen zum Einsatz. Das Auslesen an sich ist recht einfach (Ähnlich zu Erstelldatum in Seiten manipulieren, nur über XEsGetProjectPropertyAction), wie auch das neu einschreiben (XEsSetProjectPropertyAction). Fehlt nur noch eine Liste, gegen die geprüft und aus der dann die Daten gezogen werden. Da bieten sich zwei Typen gut an:

  • *.csv – lässt sich einfach durchsuchen, Spalten sind fix definiert und es lässt sich von Nutzer einfach editieren
  • *.xml – persönlich meine bevorzuge Wahl, weil Datenwerte direkter angesprochen werden können

Das Datensammeln kann zB. auf Seiten wie oben beschrieben geschehen, oder man bereitet vorhandene Quellen passend auf. In jedem Fall sollten Daten nicht immer gleich vertraut werden.

Da ich hier XML nutze, muss ich zwar eben auch erst suchen, kann dann aber auf die Elemente direkt zugreifen. Der Aufbau der Quelldatei sieht so aus:

<?xml version"1.0" encoding="utf-16" ?>
<colors>
  <color>
    <fcode>ral3000</fcode>
    <name_de>Feuerrot</name_de>
    <name_en>Feuerrot</name_en>
    ...
  </color>
  <color>
    ...
  </color>
<colors>

Bausteine sind nun alle zusammen, dann mal ans zusammenbauen: (Umgeschrieben 23.05.2023, nun deutlich flexibler im Bezug auf Sprachen und Anzahl der Quellen/Ziele).

public void updateColorNames() {
  // Vorarbeit
  string[] src     = {"EPLAN.Project.User...90", "EPLAN.Project.User...92"}; // Quellfelder
  string[] dts     = {"EPLAN.Project.User...91", "EPLAN.Project.User...93"}; // Zielfelder
  string[] descr   = {"Farbe Schrank","Farbe Kästen"};                       // Beschreibung d. Felder
  string[] langs   = {"de_DE","en_US"};                                      // Zielsprachen
  string colorfile = @"path to XML";                                         // Pfad zur Farbdatei
  
  // Dokument definieren
  XmlDocument xmldoc   = new XmlDocument();
  xmldoc.Preservewhitespace = true;
  
  // Fehlerbehandlung
  try {
    xmldoc.load(colorfile);
    XmlNodeList colors = xmldoc.DocumentElement;
    // Loop über alle Quellen
    for (int i=0; src.Count; i++) {
      // Farbcode ziehen
      string colorkey = getnonMultilang(getProjProp(src[i]), "de_DE", false);
      // Nachbereinigung der Nutzereingabe zur Sicherheit
      colorkey        = colorkey.Relace(" ","").Relace("-","").Relace("_","").ToLower();
      try { 
        // Farbknoten finden über descendant::<Knoten Farbe>[<unterknoten>='farbcode']
        XmlNode color = colors.SelectSingleNode("descendant::color[fcode='" + colorkey +"");
        // temporäre Strings definieren
        string mcolor = "";
        string ucolor = "Farbe für " + descr[i] + " (" + colorkey + ")";
        // loop über alle Sprachen
        for (int j=0; langs.Count; j++) {
          mcolor += langs[j] + "@" + color.SelectSingleNode("name_" + langs[j]).Innertext + ";";
          ucolor += "\n" + langs[j] + " : " +  color.SelectSingleNode("name_" + langs[j]).Innertext;
        }
        // Übergeben und Meldung an Nutzer
        setProjPorp(dst[i], mcolor);
        MessageBox.Show(ucolor, "Farbnamen setzen");
      } catch (Exception e) {
        // Fehler abfangen
        MessageBox.Show("Farbe " + colorkey + " oder Farbname nicht in der Liste.", "Farbnamen setzen");
      }
    }
  } catch (Exception e) {
    MessageBox.Show("Fehler bei Zugriff auf " + colorfile, "Farbnamen setzen");
  }
}
private void setProjProp(string property, string value) {
  ActionCallingContext actionCallingContext = new ActionCallingContext();
  actionCallingContext.AddParameter("PropertyIdentName", property);
  actionCallingContext.AddParameter("PropertyIndex",     "0");
  actionCallingContext.AddParameter("PropertyValue",     value);
  try {
    new CommandLineInterpreter().Execute("XEsSetProjectPropertyAction", actionCallingContext);
  } catch (Exception e) {
    //Fehlerbehandlung
  }
}
private void getProjProp(string property) {
  ActionCallingContext actionCallingContext = new ActionCallingContext();
  actionCallingContext.AddParameter("PropertyIdentName", property);
  actionCallingContext.AddParameter("PropertyIndex",     "0");
  try {
    new CommandLineInterpreter().Execute("XEsgetProjectPropertyAction", actionCallingContext);
    actionCallingContext.GetParameter("PropertyValue", value);
  } catch (Exception e) {
    //Fehlerbehandlung
  }
  return value;
}
public string getnonMultilang(string str, string lang, bool fallback) {
  // Suchpattern
  string pattern = "(" + lang + @"|\?\?_\?\?)@([^;]*)";
  Regex regex    = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
  // Pattern auf String anwenden
  Match match    = regex.Match(str);
  // wenn was gefunden wurde (ob nun allgemein oder Zielsprache)
  if (match.Length > 0) {
    return match.Groups[2].Value;
  }
  // Fallbacklösung, wenn fallback true und Zielsprache nicht vorhanden
  else if (lang != "de_DE" && fallback) {
    return getnonMultilang(str, "de_DE", false);
  }
  // wenn nichts verfügbar ist ""
  return "";
}

Wie gesagt, es hört sich meist komplizierter an, als es am ende ist. Dies wäre auch mit etwas Modifikation eben mit CSV möglich. Ob nun XML soviel einfacher ist, mag jeder für sich entscheiden.

Schreibe einen Kommentar

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