\section{Die Translator-Datenbank}



\textbf{MAKA} ist ein Unternehmen, das seine Maschinen europaweit (und einzeln auch in alle Welt) verkauft. Per Gesetz muss die bei der Maschine mitgelieferte Dokumentation in einer landestypischen Sprache verfasst sein. Für die Stückliste, als Teil der Dokumentation gilt das somit auch. Nun sind Stücklisten bei zwei Maschinen quasi nie identisch, aber auch selten komplett verschieden. Komplette Neuübersetzungen wären also Zeit- und Geldverschwendung, Wiederverwendbarkeit von Übersetzungen ist aber auch nur auf Artikelebene gegeben.

Aus diesen Gründen wurde schon vor einigen Jahren ein Access-Programm geschrieben um sprachlich angepasste Stücklisten generieren zu können. Es konnten Übersetzungen eingetragen und dann fertige Stücklisten gedruckt werden. Dieses Programm hatte gerade bei der Performance und durch die nötige Sonderbehandlung von speziellen Baugruppen so seine Probleme. Nun war es meine Aufgabe dieses Programm in PHP und MySQL neu zu schreiben und in das DBSRV-Projekt einzugliedern.

\begin{figure}[hbt]
  \centering
  \includegraphics[width=10cm]{Pics/translator-db-maske-de.png}
  \caption{Startmaske der Translator-Datenbank}
\end{figure}


Nachdem ich im Montageinformationssystem schon einige grundsätzliche Überlegungen zur Grundstruktur des Programms umsetzten konnte, aber dennoch noch stark an die vom Einkaufsinformationssystem vorgegebene Struktur angelehnt war, hatte ich nun mit der Translator-Datenbank die Möglichkeit ein Programm komplett auf ein selbst designtes Strukturkonzept aufzubauen. Diese Möglichkeit war mir sehr wichtig, da ich mir über Programmdesignfragen viele Gedanken mache und meine Überlegungen dazu natürlich auch in der Praxis erproben möchte. Zudem ist es ein unbefriedigendes Gefühl mit konzeptionell schlechten Programmstrukturen zu arbeiten. Oft finden sich die Unzulänglichkeiten von Konzepten halt erst bei ihrem Einsatz. Sie dann umzustellen erfordert (auch bei Extreme Programming) immer großen Refactoring-Aufwand. So läuft es meist darauf hinaus, dass man an der gegebenen, nicht optimalen, aber dennoch brauchbaren Programmbasis festhält. Wichtig ist dann halt, dass man beim nächsten Programmdesign die Probleme des Vorhergehenden zu eliminieren versucht.

Ich hatte nun die Gelegenheit die Erfahrungen aus EIS und MontIS mit meinem sonstigen neu erworbenen Wissen zu verschmelzen und daraus das bestmögliche Grundgerüst für die Translator-Datenbank zu kreieren. Schön war dabei, dass ich mich gleichzeitig recht wenig um die eigentliche Funktion des Programms kümmern musste, da es ein Vorgängerprogramm als Muster gab und die Programmlogik nicht besonders komplex war. Eine perfekte Ausgangssituation!



Die verschiedenen Funktionen der Translator-Datenbank wurden in drei Hauptteile gegliedert.
\begin{itemize}
  \item Stückliste generieren\\
        Hier kann eine Stückliste in der ausgewählten Sprache als PDF erzeugt werden.
  \item Stückliste übersetzen\\
        Erzeugt ein HTML-Formular mit allen noch fehlenden Übersetzungen eines Projekts, oder generiert eine Excel-Tabelle für externe Übersetzungsbüros.
  \item Datenpflege\\
        Ermöglicht die direkte Bearbeitung der Datenbank. Dies ist nur ausgewählten Personen gestattet.
\end{itemize}

Im Folgenden möchte ich nun einzelne Funktionen der Translator-Datenbank genauer erklären.





\subsection{Mehrsprachigkeit}

Eine zentrale Anforderung der Translator-Datenbank war ihre Mehrsprachigkeit. Da das Programm auch von den der Tochterfirma \textbf{MAKA-UK} und später eventuell auch von den anderen Auslandsvertretungen genutzt werden sollte, musste die Benutzeroberfläche in verschiedenen Sprachen anwählbar sein. Die Menge dieser Sprachen sollte dynamisch erweiterbar sein. Ebenso war eine beliebige Anzahl von Sprachen für Stücklistenübersetzungen gefordert.

Die Benutzeroberfläche wird mit Texten aus Sprachdateien versorgt, die mittels einer PHP-Klasse \texttt{Gettext.class.php} ausgelesen werden. Im Programmquellcode selbst stehen lediglich Textidentifikator die dem Objekt der Gettext-Klasse übergeben werden. Zurückgeliefert wird dann der betreffende Text in der Sprache mit der das Objekt initialisiert wurde. Das folgende Codebeispiel demonstriert die Verwendung:

\begin{verbatim}
<?php

  include 'Classes/Gettext.class.php';

  // the language for the translation  is taken from the session
  $gt = new Gettext($_SESSION['lang_gui']);

  echo $gt->_('hello_world');

?>
\end{verbatim}
Ausgegeben wird dabei je nach eingestellter Sprache ``Hallo Welt!'', ``Hello world!'', oder was auch immer in der jeweiligen Sprachdatei für den Identifikator \texttt{hello\_world} hinterlegt ist.

Fehlende Texte werden in der Form \texttt{\#\#identifier\#\#} zurückgegeben. Auf diese Weise bleibt das Programm jederzeit benutzbar, auch wenn Sprachdateien nicht komplett sind. Ebenso ist es möglich auch nicht vollständig übersetzte Stücklisten zu generieren; die fehlenden Bezeichnungen bleiben leer und können gegebenenfalls auch von Hand nachgetragen werden. Eine derartige Vorgehensweise ist keineswegs angestrebt, aber trotzdem ermöglicht um die reine Funktion des Programms zu erhalten.

Die Sprachen für die Programmoberfläche und für die Stücklisten kann im oberen linken Bereich der Startmaske gewählt werden. Ein Wechsel der Oberflächesprache wird sofort wirksam. Das heißt, die komplette Oberfläche ist sofort in der gewählten Sprache nutzbar. Die Sprachauswahl für die Oberfläche zeigt dabei die Sprachnamen in der jeweiligen Sprache selbst an, die Dropdownbox mit den Sprachen für die Stücklisten ist in der gewählten Oberflächensprache. Das Programmdesign sollte an jeder Stelle die erwartete Implementierung bieten --- auch \textit{Principle of least surprise} genannt.



\subsection{Standardstücklisten}

Um alte Maschinen auch nachträglich mit Stücklisten versorgen zu können, wurde diese inzwischen überholte Form der Stücklisten ebenfalls implementiert. Die Unterscheidung welcher Stücklistentyp erzeugt werden muss, geschieht automatisch anhand der Projektnummer. Die Algorithmen um die Stücklisten aufzustellen unterscheiden sich grundlegend. Wo für neue Projektstücklisten flache Datenbankabfragen genügen müssen die Standardstücklisten rekursiv als Baum aufgebaut werden. Wobei keine Baugruppe mehrfach in der Stückliste vorkommen soll, statt dessen müssen nur die Mengen angepasst werden.

Bei der Vorgängerversion der Translator-Datenbank in Access war es noch Aufgabe des Anwenders, sich um all diese Sonderfälle zu kümmern, jetzt bekommt der Benutzer von all dem gar nichts mehr mit.



\subsection{Datenpflege}

\begin{figure}[hbt]
  \centering
  \includegraphics[width=10cm]{Pics/translator-db-datenpflege-wenigerspalten.png}
  \caption{Datenpflege mit ausgeblendeten Spalten}\label{Fig:datenpflege-wenigerspalten}
\end{figure}

Im Datenpflege-Fenster werden alle Datensätze der Datenbank aufgelistet. Um die vielen Datensätze handhabbar zu halten, wurde eine seitenweise Darstellung gewählt. Die Navigation um durch die Seiten zu blättern, zeigt nur eine sinnvolle Anzahl von Seitenzahlen an. Die Tabellenspalten zeigen die in der Datenbank hinterlegten Spalten an. Um die Übersichtlichkeit zu fördern können einzelne Spalten aus und wieder eingeblendet werden, wie in Abbildung \ref{Fig:datenpflege-wenigerspalten} zu sehen ist. Die Spalten werden dynamisch verwaltet, das heißt, es werden einfach alle Spalten deren Spaltenname einem bestimmten Schema entspricht als Sprachspalten angesehen und eingefügt.

Die Datensätze können nach Artikelnummer eingeschränkt oder nach einem Begriff gefiltert werden. Zudem kann die Tabelle natürlich nach allen Spalten sortiert werden.

Die einzelnen Datensätze können hier bearbeitet, gelöscht und neue Datensätze können angelegt werden.


\subsubsection{Datensatz bearbeiten}

Beim Speichern von Übersetzungen habe ich erneut stark darauf geachtet, dass das Programm automatisch die erwartete Funktion ausführt. So werden Datensätze nur überschrieben wenn lediglich Übersetzungen angepasst wurden. Besteht allerdings die Gefahr, dass unbeteiligte Daten überschrieben werden, was bei einer falsch getippten Artikelnummer der Fall wäre, dann werden beide Datensatzversionen gegenübergestellt und dem Benutzer die Entscheidung überlassen, welche Daten gespeichert werden sollen. Dies ist in Abbildung \ref{Fig:bearbeiten-auswaehlen} zu sehen.

\begin{figure}[hbt]
  \centering
  \includegraphics[width=14cm]{Pics/translator-db-bearbeiten-auswaehlen.png}
  \caption{Zwei Übersetzungen kollidieren und der Benutzer muss entscheiden}\label{Fig:bearbeiten-auswaehlen}
\end{figure}





\subsection{Das Dictionary}

Ein für den User eigenständiges Programm, aber intern doch direkt mit der Translator-Datenbank verbunden und auch aus ihr hervorgegangen, ist das \textit{Dictionary}. Dieses ist eine Art Nachschlagewerk für übersetzte Artikelbezeichnungen und für alle Mitarbeiter zugänglich. Von einer simplen Startmaske kommt man zu einer Ansicht die der Translator-Datenbank-Datenpflege nachempfunden ist. Hier wird auf den Datenbestand allerdings nur lesend zugegriffen. Sinn des Dictionary ist es, eine Unterstützung im internationalen Kontakt zu sein, um auf einheitliche Bezeichnungen zurückgreifen zu können.

Wie auch in der Datenpflege der Translator-Datenbank können die Datensätze beliebig sortiert, gefiltert und nach Artikelnummer eingeschränkt werden. Auch lassen sich einzelne Sprachspalten ein- und ausblenden um die Übersicht zu fördern.

\begin{figure}[hbt]
  \centering
  \includegraphics[width=14cm]{Pics/dictionary-woerterbuch-frames.png}
  \caption{Typische Ansicht des Dictionary mit markierten Unstimmigkeiten}\label{Fig:dictionary-woerterbuch-frames}
\end{figure}

Da es in Abbildung \ref{Fig:dictionary-woerterbuch-frames} sehr schön sichtbar ist, möchte ich an dieser Stelle eine weitere Möglichkeit der Datenpflege-Ansicht beschreiben: Indem man nach Sprachspalten sortiert, stehen gleiche Bezeichnungen untereinander. So fallen sehr schnell Unstimmigkeiten bei den Übersetzungen auf, die in Abbildung \ref{Fig:dictionary-woerterbuch-frames} mir farbigen Rahmen hervorgehoben wurden. Diese Abweichungen können dann nach und nach ausgemerzt werden.


