Internationale SAP-Anwendungen muessen Texte in verschiedenen Sprachen anzeigen. ABAP Cloud bietet mehrere Mechanismen fuer Mehrsprachigkeit: Message Classes fuer Meldungen, Text Elements fuer UI-Texte und CDS Text Associations fuer Datenbanktexte. Dieser Artikel zeigt, wie du mehrsprachige Anwendungen in ABAP Cloud entwickelst.
Uebersicht der Uebersetzungsmechanismen
In ABAP Cloud gibt es verschiedene Ansaetze fuer Mehrsprachigkeit:
| Mechanismus | Verwendung | Speicherort |
|---|---|---|
| Message Classes | Meldungen (Fehler, Warnungen, Erfolg) | Nachrichtenklasse |
| Text Elements | UI-Texte in ABAP-Code | Textelemente der Klasse |
| CDS Text Associations | Datenbanktexte (z.B. Materialbezeichnungen) | Texttabellen |
| Data Elements | Feldbezeichnungen | DDIC Data Element |
| CDS Annotations | Metadata-Texte fuer Fiori | @EndUserText, @UI.* |
Message Classes - Meldungen uebersetzen
Message Classes sind der Standard fuer Fehlermeldungen, Warnungen und Informationen. In ABAP Cloud erstellst du sie im ADT unter Other ABAP Repository Objects > Message Class.
Message Class erstellen
" Definition einer Message Class (in ADT)" Message Class: ZTRAVEL_MSG" Nachrichten:" 001 - Reise & erfolgreich angelegt" 002 - Reise & bereits gebucht" 003 - Ungueltige Reisedaten: & bis &" 004 - Maximale Reisedauer von & Tagen ueberschrittenDie Platzhalter & werden zur Laufzeit durch Parameter ersetzt:
CLASS zcl_travel_validation DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. INTERFACES if_abap_behavior_handler.
ENDCLASS.
CLASS zcl_travel_validation IMPLEMENTATION.
METHOD if_abap_behavior_handler~validate. " Nachricht mit Parametern ausgeben DATA(ls_travel) = <fs_travel>.
IF ls_travel-begin_date > ls_travel-end_date. " Nachricht 003: Ungueltige Reisedaten: & bis & APPEND VALUE #( %tky = ls_travel-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = |Ungueltige Reisedaten: { ls_travel-begin_date } bis { ls_travel-end_date }| ) ) TO reported-travel. ENDIF.
" Alternative: Message Class verwenden APPEND VALUE #( %tky = ls_travel-%tky %msg = new_message( id = 'ZTRAVEL_MSG' number = '003' severity = if_abap_behv_message=>severity-error v1 = |{ ls_travel-begin_date }| v2 = |{ ls_travel-end_date }| ) ) TO reported-travel. ENDMETHOD.
ENDCLASS.Nachrichten uebersetzen
Uebersetzungen werden in ADT ueber Properties > Translations gepflegt. Die Originalsprache ist typischerweise Englisch (EN), Uebersetzungen erfolgen in die Zielsprachen.
" ZTRAVEL_MSG - Nachricht 003" EN: Invalid travel dates: & to &" DE: Ungueltige Reisedaten: & bis &" FR: Dates de voyage invalides: & a &" ES: Fechas de viaje no validas: & a &Text Elements - Programmtexte
Text Elements sind Texte, die direkt im ABAP-Code verwendet werden. In ABAP Cloud werden sie als Teil der ABAP-Klasse definiert.
Text Elements in Klassen
CLASS zcl_travel_report DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. " Text Symbols werden in der Klasse definiert " TEXT-001: Reiseuebersicht " TEXT-002: Keine Reisen gefunden " TEXT-003: Reise erstellt am
METHODS generate_report RETURNING VALUE(rv_html) TYPE string.
ENDCLASS.
CLASS zcl_travel_report IMPLEMENTATION.
METHOD generate_report. " Text Symbols verwenden DATA(lv_title) = TEXT-001. " Reiseuebersicht
" Alternativ: Inline-Text mit Uebersetzung DATA(lv_no_data) = 'No travels found'(002).
" Text mit Variablen rv_html = |<h1>{ lv_title }</h1>|.
IF lt_travels IS INITIAL. rv_html = rv_html && |<p>{ lv_no_data }</p>|. ENDIF. ENDMETHOD.
ENDCLASS.Text Pool pflegen
In ADT oeffnest du die Klasse und navigierst zu Text Elements im Outline-View. Dort werden die Texte gepflegt:
| Symbol | Text (EN) | Text (DE) |
|---|---|---|
| 001 | Travel Overview | Reiseuebersicht |
| 002 | No travels found | Keine Reisen gefunden |
| 003 | Travel created on | Reise erstellt am |
CDS Text Associations - Datenbanktexte
Fuer sprachabhaengige Stammdaten (z.B. Materialbezeichnungen, Laendernamen) verwendet ABAP Cloud CDS Text Associations. Diese verknuepfen eine Haupttabelle mit einer Texttabelle.
Texttabelle anlegen
Zuerst erstellst du eine Texttabelle mit Sprachschluessel:
@EndUserText.label : 'Produkttexte'@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE@AbapCatalog.tableCategory : #TRANSPARENT@AbapCatalog.deliveryClass : #Adefine table zproduct_text { key client : abap.clnt not null; key product_id: zproduct_id not null; key language : abap.lang not null; name : abap.char(60); description : abap.char(255);}CDS View mit Text Association
Der CDS View verbindet Stammdaten mit Texten:
@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Produkt mit Texten'define view entity ZI_Product as select from zproduct as Product association [0..*] to zproduct_text as _Text on _Text.product_id = Product.product_id{ key Product.product_id as ProductId, Product.product_type as ProductType, Product.price as Price, Product.currency as Currency,
" Text Association exponieren _Text}Text Association in Projection View
In der Projection View nutzt du @ObjectModel.text.association:
@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Produkt (Projektion)'@Metadata.allowExtensions: truedefine view entity ZC_Product as projection on ZI_Product{ key ProductId, ProductType, Price, Currency,
" Text Association mit automatischer Sprachfilterung @ObjectModel.text.association: '_Text' _Text}Automatische Sprachfilterung
Mit @Semantics.language: true markierst du das Sprachfeld:
@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Produkttext View'define view entity ZI_ProductText as select from zproduct_text{ key product_id as ProductId, @Semantics.language: true key language as Language, name as Name, description as Description}Fiori Elements filtert automatisch auf die Anmeldesprache des Benutzers.
Text Element fuer Anzeigefeld
Fuer ein einzelnes Anzeigefeld mit automatischer Uebersetzung:
@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Produkt mit Beschreibung'define view entity ZI_ProductWithText as select from zproduct as Product left outer join zproduct_text as Text on Text.product_id = Product.product_id and Text.language = $session.system_language{ key Product.product_id as ProductId, Product.price as Price,
" Text in Benutzersprache Text.name as ProductName, Text.description as ProductDescription}Die Systemvariable $session.system_language liefert die Anmeldesprache.
Data Elements - Feldbezeichnungen
Data Elements definieren Feldbezeichnungen, die automatisch in Fiori und ALV angezeigt werden.
Data Element mit Uebersetzungen
@EndUserText.label : 'Produkt-ID'@AbapCatalog.enhancement.category : #NOT_EXTENSIBLEdefine type zproduct_id : abap.char(10);Die Bezeichnungen werden in ADT unter Properties > Translations gepflegt:
| Sprache | Kurztext | Mitteltext | Langtext |
|---|---|---|---|
| EN | Product ID | Product Identifier | Product Identification Number |
| DE | Produkt-ID | Produktkennung | Produktidentifikationsnummer |
| FR | ID produit | Identifiant produit | Numero d’identification du produit |
Domain mit Festwerten
Fuer feste Wertebereiche (z.B. Status) eignen sich Domains mit uebersetzten Festwerten:
@EndUserText.label : 'Reisestatus'define domain ztravel_status : abap.char(1) { value 'N' : 'New'; " Neu value 'O' : 'Open'; " Offen value 'A' : 'Approved'; " Genehmigt value 'X' : 'Rejected'; " Abgelehnt}CDS Annotations fuer UI-Texte
Fiori Elements verwendet CDS Annotations fuer UI-Texte. Diese koennen ebenfalls uebersetzt werden.
@EndUserText Annotation
@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Travel Management'@EndUserText.quickInfo: 'Manage business travels and expenses'define view entity ZI_Travel as select from ztravel{ @EndUserText.label: 'Travel ID' @EndUserText.quickInfo: 'Unique travel identifier' key travel_id as TravelId,
@EndUserText.label: 'Agency' agency_id as AgencyId,
@EndUserText.label: 'Customer' customer_id as CustomerId,
@EndUserText.label: 'Begin Date' begin_date as BeginDate,
@EndUserText.label: 'End Date' end_date as EndDate,
@EndUserText.label: 'Total Price' total_price as TotalPrice}@UI Annotations mit Texten
@UI.headerInfo: { typeName: 'Travel', typeNamePlural: 'Travels', title: { value: 'TravelId' }, description: { value: 'Description' }}define view entity ZC_Travel as projection on ZI_Travel{ @UI.facet: [ { id: 'GeneralInfo', label: 'General Information', type: #IDENTIFICATION_REFERENCE }, { id: 'Dates', label: 'Travel Dates', type: #FIELDGROUP_REFERENCE, targetQualifier: 'Dates' } ]
@UI.identification: [{ position: 10 }] @UI.lineItem: [{ position: 10, label: 'Travel' }] key TravelId,
@UI.fieldGroup: [{ qualifier: 'Dates', position: 10, label: 'From' }] BeginDate,
@UI.fieldGroup: [{ qualifier: 'Dates', position: 20, label: 'To' }] EndDate}Translation Workflow
Der Uebersetzungsprozess in ABAP Cloud unterscheidet sich von klassischem ABAP (Transaktion SE63).
Uebersetzbare Objekte exportieren
In ADT kannst du uebersetzbare Objekte exportieren:
- Package > Export Translations waehlen
- Zielsprachen auswaehlen
- XLIFF-Datei wird generiert
<!-- Beispiel XLIFF-Export --><xliff version="1.2"> <file source-language="en" target-language="de"> <body> <trans-unit id="ZTRAVEL_MSG.001"> <source>Travel & successfully created</source> <target>Reise & erfolgreich angelegt</target> </trans-unit> <trans-unit id="ZTRAVEL_MSG.002"> <source>Travel & already booked</source> <target>Reise & bereits gebucht</target> </trans-unit> </body> </file></xliff>Uebersetzungen importieren
Nach der Uebersetzung (durch Uebersetzer oder Uebersetzungsbuero):
- Package > Import Translations waehlen
- Uebersetzte XLIFF-Datei auswaehlen
- Uebersetzungen werden ins System importiert
Fiori App: Maintain Translations
Fuer BTP-Umgebungen steht die Fiori App Maintain Translations zur Verfuegung:
- App im Launchpad starten
- Software Component und Sprache waehlen
- Texte direkt in der Oberflaeche uebersetzen
- Aenderungen speichern und aktivieren
Namenskonventionen fuer Uebersetzungen
| Objekttyp | Namenskonvention | Beispiel |
|---|---|---|
| Message Class | Z{PROJEKT}_MSG | ZTRAVEL_MSG |
| Data Element | z{bereich}_{feld} | ztravel_status |
| Domain | z{bereich}_{domain} | ztravel_status |
| Text Table | z{stamm}_text | zproduct_text |
Best Practices
1. Originalsprache festlegen
Definiere eine einheitliche Originalsprache (typischerweise EN):
" Immer englische Originaltexte verwenden" ZTRAVEL_MSG" 001 - EN: Travel & successfully created" 001 - DE: Reise & erfolgreich angelegt2. Konsistente Terminologie
Verwende ein Glossar fuer konsistente Uebersetzungen:
| Begriff (EN) | Begriff (DE) |
|---|---|
| Travel | Reise |
| Booking | Buchung |
| Customer | Kunde |
| Agency | Agentur |
| Status | Status |
3. Platzhalter sinnvoll einsetzen
" Gut: Flexibler Text mit Platzhaltern" & records were processed successfully." Es wurden & Datensaetze erfolgreich verarbeitet.
" Schlecht: Grammatik funktioniert nicht in allen Sprachen" & record(s) processed.4. Texttabellen effizient abfragen
" Performant: Join mit Fallbackdefine view entity ZI_ProductWithText as select from zproduct as Product left outer join zproduct_text as UserText on UserText.product_id = Product.product_id and UserText.language = $session.system_language left outer join zproduct_text as FallbackText on FallbackText.product_id = Product.product_id and FallbackText.language = 'E' " Englisch als Fallback{ key Product.product_id, " Benutzersprache bevorzugen, sonst Fallback coalesce( UserText.name, FallbackText.name ) as Name}5. Uebersetzungsstatus pruefen
Vor einem Release sollten alle Texte uebersetzt sein:
" CDS View fuer fehlende Uebersetzungendefine view entity ZI_MissingTranslations as select from zproduct as Product left outer join zproduct_text as Text on Text.product_id = Product.product_id and Text.language = 'D' " Deutsche Uebersetzung{ key Product.product_id, case when Text.product_id is null then 'X' else '' end as MissingDE}where Text.product_id is nullHaeufige Probleme und Loesungen
Problem: Texte werden nicht angezeigt
Ursache: Texttabelle hat keinen Eintrag fuer die Benutzersprache.
Loesung: Fallback-Logik implementieren:
coalesce( UserText.name, FallbackText.name, cast( Product.product_id as abap.char(60) )) as DisplayNameProblem: Annotation-Texte nicht uebersetzt
Ursache: @EndUserText-Annotations werden nicht automatisch uebersetzt.
Loesung: Texte aus Data Elements verwenden oder manuelle Uebersetzung pflegen.
Problem: Dynamische Texte
Ursache: Texte werden zur Laufzeit zusammengesetzt.
Loesung: Message Class mit Platzhaltern verwenden:
" Message Class statt String-KonkatenationMESSAGE e001(ztravel_msg) WITH lv_travel_id INTO DATA(lv_msg).Zusammenfassung
Mehrsprachige ABAP Cloud Anwendungen erfordern die richtige Kombination der verfuegbaren Mechanismen:
- Message Classes fuer alle Meldungen (Fehler, Warnungen, Informationen)
- Text Elements fuer statische Programmtexte
- CDS Text Associations fuer sprachabhaengige Stammdaten
- Data Elements fuer Feldbezeichnungen
- CDS Annotations fuer UI-Metadaten in Fiori
Der Uebersetzungsworkflow in ABAP Cloud nutzt XLIFF-Export/Import oder die Fiori App “Maintain Translations”. Eine konsistente Originalsprache und ein Glossar erleichtern die Uebersetzung erheblich.
Weiterführende Artikel
- Message Handling in ABAP Cloud - Nachrichten und Fehlerbehandlung
- CDS Views - Datenmodellierung mit Core Data Services
- RAP Basics - Einstieg in das RESTful ABAP Programming
- CDS Annotations - UI-Annotationen fuer Fiori Elements