Entwickeln mehrsprachiger Anwendungen
Dieser Beitrag zeigt, wie Sie mehrsprachige Anwendungen realisieren können. Das Thema ist sehr komplex und es gibt mehrere Ansätze zur Realisierung. Ein Königsweg gibt es nicht, ich zeige Ihnen aber ein Weg, den ich für Praktikabel halte.
Zu Beginn muss man sich die Frage stellen, wie weit treibt man die Mehrsprachigkeit.
Man unterscheidet dabei grundsätzlich zwischen der mehrsprachigen Benutzeroberfläche und den mehrsprachigen Inhalte der Tabellen. letzteres ist besonders aufwendig zu realisieren, und nur mit großem Aufwand zu bewältigen. In diesem Beitrag beschränke ich mich nur auf die Benutzeroberfläche.
Die Objekte, die ein Benutzer zu Gesicht bekommt, sind Formulare und Berichte. Dabei muss noch zwischen Sprachanpassung auf Steuerelement-Ebene und auf Code-Ebene unterschieden werden.
Bei Steuerelementen:
Befehlschaltfläche => Eigenschaften Beschriftung sowie SteuerelementTip-Text
Bezeichnungsfeld => Eigenschaften Beschriftung sowie SteuerelementTip-Text
Umschaltfläche => Eigenschaften Beschriftung sowie SteuerelementTip-Text
Registerseite => Eigenschaften Beschriftung sowie SteuerelementTip-Text
Kombinationsfeld => Inhalte von Wertelisten
Listenfeld => Inhalte von Wertelisten
Bei VBA-Code:
Msgbox => Inhalte vom Text und Titel
Fehlermeldungen => individuelle Fehlertexte in Fehlerprotokollierung
Außerdem hat man noch die Bezeichnung des Formulars zu berücksichtigen. Oft werden Beschriftung z.B. von Bezeichnungsfeldern und Befehlschaltflächen per VBA-Code geändert, das ist natürlich auch zu berücksichtigen.
Jetzt haben wir mal einen groben Überblick darüber, wo wir überall Sprachänderungen vornehmen müssen. Kommen wir zum eigentlichen Konzept. Dies sieht vor, dass man die Texte bzw. Wörter in sog. Sprachtabellen ablegt, für jede Sprache eine. Jeder Text wird über eine Nummer codiert, jeder Text muss in allen Sprachtabellen die gleiche Nummer haben. (Felder ID, Wert)
Dann benötigen wir eine Tabelle wo alle installierten Sprachtabellen registriert sind. Diese dient zur Auswahl der Sprache z.b. mit einem Listenfeld. Ein Popup-Formular, das diese Auswahl enthält, wird vom Startformular geöffnet. Die Auswahl schreibt dann die Sprache in eine globale Variable. Das Feld Auswahl in der Tabelle markiert die ausgeählte Sprache, bei einem erneuten Start wird so automatisch die Sprache geladen.
Selbstverständlich ist auch das Formular zur Sprachauswahl mehrsprachig. Beim Laden des Formulars muss geprüft werden ob die Variable lang besetzt ist. wenn nicht, dann muss in der Tabelle Sprachen die markierte Sprache geholt werden. Ist keine Sprache markiert, wird als standard die Deutsche Sprache gesetzt. Nachfolgend der Code des Formular Sprachauswahl:
Private Sub Form_Load() Dim ctl As Control, db As DAO.Database, rs As DAO.Recordset Set db = CurrentDb If lang = "" Then Set rs = db.OpenRecordset("Select Tabellennamen From Sprachen Where Auswahl = true", dbOpenDynaset) If rs.RecordCount = 0 Then rs.Close db.Execute "Update Sprachen set Auswahl = True where Tabellennamen = 'Deutsch'" lang = "Deutsch" Else lang = rs!Tabellennamen rs.Close End If End If Set rs = db.OpenRecordset("Select ID, Wert From " & lang & " Order By ID", dbOpenDynaset) 'Form.caption If Left(Me.Caption, 1) = "[" Then Me.Caption = getText(rs, Me.Caption) For Each ctl In Me.Controls If ctl.Tag = "T" Then Select Case ctl.ControlType Case 104 'Buttons If ctl.Picture <> "(keines)" Then If Left(ctl.ControlTipText, 1) = "[" Then ctl.ControlTipText = getText(rs, ctl.ControlTipText) End If Else If Left(ctl.Caption, 1) = "[" Then ctl.Caption = getText(rs, ctl.Caption) End If End If Case 100 'Labels If Left(ctl.Caption, 1) = "[" Then ctl.Caption = getText(rs, ctl.Caption) End If End Select End If Next rs.Close Set rs = Nothing Set db = Nothing End Sub Private Sub OK_Click() Set db = CurrentDb lang = Me!Liste0 db.Execute "Update Sprachen set Auswahl = False" db.Execute "Update Sprachen set Auswahl = True where Tabellennamen = '" & lang & "'" DoCmd.Close acForm, Me.Name DoCmd.OpenForm "Sprachtest" End Sub
Kommen wir zur Codierung der Sprache bei den Steuerelementen. Es empfiehlt sich die Codier-Nummer mit bestimmten Zeichen einzuschließen, die sonst nicht vorkommen würden. Z.B. könnte man die Nummer 124 wie folgt kodieren: [124]. Außerdem versieht man die Steuerelemente, die mehrsprachig sind, mit der Eigenschaft Marke, und trägt bei Marke ein T ein.
Im Load-Ereignis jeden Formulars benötigen wir einen Code der die Sprachtexte lädt. db und rs sind global deklariert als DAO.Database bzw. DAO.Recordset. Die globale Variable lang beinhaltet den Namen der ausgewählten Sprachtabelle, also z.B. Deutsch. Nachfolgender Code regelt die Sprachanpassung für Bezeichnungsfelder und Befehlsschaltflächen.
Private Sub Form_Load() Dim ctl As Control Set db = CurrentDb Set rs = db.OpenRecordset("Select ID, Wert From " & lang & " Order By ID", dbOpenDynaset) 'Form.caption If Left(Me.Caption, 1) = "[" Then Me.Caption = getText(rs, Me.Caption) For Each ctl In Me.Controls If ctl.Tag = "t" Then Select Case ctl.ControlType Case 104 'Buttons If ctl.Picture <> "(keines)" Then If Left(ctl.ControlTipText, 1) = "[" Then ctl.ControlTipText = getText(rs, ctl.ControlTipText) End If Else If Left(ctl.Caption, 1) = "[" Then ctl.Caption = getText(rs, ctl.Caption) End If End If Case 100 'Labels If Left(ctl.Caption, 1) = "[" Then ctl.Caption = getText(rs, ctl.Caption) End If End Select End If Next rs.Close Set rs = Nothing Set db = Nothing End Sub
Jetzt benötigen wir eine als Public deklarierte Funktion, die aus der richtigen Sprachtabelle den Text ausliest und zurück gibt. Diese legt man in einem Modul an:
Public Function getText(rs As DAO.Recordset, lCtl As String) As String Dim lNumber As Long 'Gegenprüfung If Right(lCtl, 1) <> "]" Then getText = lCtl Exit Function End If lNumber = Mid(lCtl, 2, Len(lCtl) - 2) rs.FindFirst "id = " & lNumber If Not rs.NoMatch Then getText = rs!Wert else getText = lCtl End If End Function
Die MsgBox muss etwas separat behandelt werden. dazu erst mal folgender Code:
Private Sub Befehl1_Click() Set db = CurrentDb Set rs = db.OpenRecordset("Select * From " & lang & " order by ID", dbOpenDynaset) MsgBox (getText(rs, "[11]")) rs.Close Set rs = Nothing Set db = Nothing End Sub
Hier fügt man die Funktion getText() direkt in die MsgBox ein, und übergibt das Recordset auf die aktuelle Sprachdatei sowie die Codierte Textnummer. Das kommt jetzt vieleicht etwas übertrieben vor, extra ein Recordset zu erstellen, aber bei der MsgBox handelt es sich um ein – in einem abgeschlossenen Zeitraum – einmaliges Ereignis, da stört es kaum wenn das eine zehntel Sekunde dauert.
Zu diesem Thema habe ich ein kleines Beispiel erstellt, bei Interesse einfach per Email anfordern.
AV 2008
Hi,
mein Add-in macht genau das. Hier muss das Rad nicht „neu“ erfunden werden. Viele Entwickler arbeiten seit jahren schon damit:
http://www.abiss.de/downloads/public/atm.zip
Bin sehr interessiert an Ihrem Beispiel zur Sprachumschaltung, da ich komplette Formulare und Berichte erweiterbar mehrsprachig gestalten muss. dass heißt auch, dass auch die Datensatzinhalte mehrsprachig werden müssen. Ich bedanke mich im voraus mit freundlichen Grüßen Thomas Frey.