Adobe Forms Translation and Localization in SAP Systems (A Comprehensive Guide)


Translation and localization of Adobe Forms are the standard functionalities built into SAP systems. Nonetheless the proper usage of both requires some knowledge, practice and even patience (from time-to-time). We hope this guide will help you avoid common mistakes made when creating multilingual Adobe Forms.

Translation and Localization


The translation process of a Adobe Form is quite straightforward – the systems extracts all text literals from an Adobe Form and your job is to provide a translation for each of them (you’ll find more details on the translation process further in the guide).

Localization is a broader term than translation. If you want your Adobe Form to look professional and natural in a specific country, it’s not just enough to translate it – you should also makes sure that fields like addresses, dates, decimal numbers, postal codes, telephone numbers etc. are formatted according to local rules. Formatting of such fields depends on language and country (locale).

Here are some examples of different formatting depending on locale:

Locale (Language-Country)Short DateMedium DateDecimal Number
en-US11/22/19Nov 22, 201956,482.13
en-GB22/11/201922 Nov 201956,482.13
pl-PL19-11-222019-11-2256 482,13
fr-FR22/11/1922 nov. 1956 482,13
it-IT22/11/1922/nov/1956.482,13

Locale: Language and Location


Each field on Adobe Form layout has a Locale property (pallet Object->Locale).

Locale (together with the display pattern defined in Patterns…) influences value formatting for the field. Date and time formatting conventions, monetary conventions, decimal formatting conventions, and sort order depends on Locale

NOTE

Make sure that all Layout Fields use Default locale (Locale set by the print program).

Setting Locale in a Print Program

To set Locale for an Adobe Form populate fields LANGU and COUNTRY in parameter /1bcdwb/docparams (type SFPDOCPARAMS) of the generated Form’s function module:

DATA:
  doc_params TYPE SFPDOCPARAMS.
"Set Locale
doc_params-langu = ...
doc_params-country = ...
CALL FUNCTION form_function_name
  EXPORTING
    /1bcdwb/docparams  = doc_params
    data               = form_data
  IMPORTING
    /1bcdwb/formoutput = form_output
  EXCEPTIONS
    usage_error        = 1
    system_error       = 2
    internal_error     = 3
    OTHERS             = 4.
NOTE

LANGU is a 1-char field – use SAP-language-codes during testing: ‘E’ for English, ‘D’ for German, ‘S’ – for Spanish etc. Don’t be surprised if ‘ES’ results in English-locale šŸ˜‰

Layout translation


When you save a Form Layout the first time, each text literal (all fields of type Text and Variables defined in Form Properties->Variables) is given a unique ID – attribute xliff:rid (switch to XML Source tab in Adobe LiveCycle Designer and search for xliff:rid). SAP system extracts all text literals and generates an XLIFF file from them (SAP uses XLIFF version 1.1 – XML Localization Interchange File Format). To translate an Adobe Form you take the original XLIFF file and translate its content into your target language. You can translate XLIFF directly in Form Builder (tcode SFP) or download the file locally. As this is a simple XML file you can edit it in Notepad, use a dedicated XLIFF editors or send it to a professional translator to do the job.

Original XLIFF file:

<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns:xft-xliff="http://www.xfa.org/schema/xfa-xliff/1.0/" version="1.1">
<file datatype="XDP" original="mytemplate.xdp" product-name="Adobe Designer" source-language="en" tool="AdobeDesigner">
<trans-unit id="141F40F1-8DAB-45A5-81D9-D9C61C576EEF" resname="141F40F1-8DAB-45A5-81D9-D9C61C576EEF">
Description
</trans-unit>
<trans-unit id="0A0C4EE4-503F-45E7-BD56-008A8128CDAC" resname="0A0C4EE4-503F-45E7-BD56-008A8128CDAC">
<body xmlns:xdp="http://ns.adobe.com/xdp/" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" xmlns="http://www.w3.org/1999/xhtml" xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/" xfa:APIVersion="2.7.0.0"><p style="font-family:'Nokia Pure Headline'">Billing Date<span style="xfa-spacerun:yes"> </span><span style="font-weight:bold"><span xfa:embed="#floatingField029358" xfa:embedMode="raw" xfa:embedType="uri"/></span></p></body>
</trans-unit>
<trans-unit id="EB57534F-819F-4B3E-BDD9-882933040671" resname="EB57534F-819F-4B3E-BDD9-882933040671">
Company details:
</trans-unit>
<trans-unit id="F83BFD5F-B69F-42C5-9518-082273B71EE3" resname="F83BFD5F-B69F-42C5-9518-082273B71EE3">
Additional Information
</trans-unit>
<trans-unit id="FDC217DB-94B1-4160-A1AC-BDB370BBAE2F" resname="FDC217DB-94B1-4160-A1AC-BDB370BBAE2F">
Page
</trans-unit></file></xliff>

Translated XLIFF file:

<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns:xft-xliff="http://www.xfa.org/schema/xfa-xliff/1.0/" version="1.1">
<file datatype="XDP" original="mytemplate.xdp" product-name="Adobe Designer" source-language="en" tool="AdobeDesigner">
<trans-unit id="141F40F1-8DAB-45A5-81D9-D9C61C576EEF" resname="141F40F1-8DAB-45A5-81D9-D9C61C576EEF">
DescripciĆ³n
</trans-unit>
<trans-unit id="0A0C4EE4-503F-45E7-BD56-008A8128CDAC" resname="0A0C4EE4-503F-45E7-BD56-008A8128CDAC">
<body xmlns:xdp="http://ns.adobe.com/xdp/" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" xmlns="http://www.w3.org/1999/xhtml" xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/" xfa:APIVersion="2.7.0.0"><p style="font-family:'Nokia Pure Headline'">Fecha Factura<span style="xfa-spacerun:yes"> </span><span style="font-weight:bold"><span xfa:embed="#floatingField029358" xfa:embedMode="raw" xfa:embedType="uri"/></span></p></body>
</trans-unit>
<trans-unit id="EB57534F-819F-4B3E-BDD9-882933040671" resname="EB57534F-819F-4B3E-BDD9-882933040671">
Detalles de la compaƱƭa:
</trans-unit>
<trans-unit id="F83BFD5F-B69F-42C5-9518-082273B71EE3" resname="F83BFD5F-B69F-42C5-9518-082273B71EE3">
InformaciĆ³n adicional
</trans-unit>
<trans-unit id="FDC217DB-94B1-4160-A1AC-BDB370BBAE2F" resname="FDC217DB-94B1-4160-A1AC-BDB370BBAE2F">
PƔg.
</trans-unit></file></xliff>

Translation Procedure

First check if the target language is installed in your system and add the language if missing.

Go to transaction I18N and double-click on “I18N System Configuration” node (alternatively you can call report RSCPINST directly). Search “Enter languages” list for your target language. If it’s not listed there, click “Add” button to add a new entry. Hit F4 on the new row to display the list of all available languages. Select your target language (if the target language is not on the list you need to add it first by clicking “Extend Language List” button). Activate your changes by clicking “Activate” button in the application toolbar.

To complete the language installation, open transaction SMLT and click “Classify Language (F5)” button.

In “Classify Language” popup window select the new Language (PL Polish in the screenshot ) and choose the Supplementation Language (English or German). The language i now available and can be used in translations.

Open transaction SFP and enter the name of Adobe Form you’d like to translate. Click “Change” button. Open menu Goto->Translation and enter the target language into the popup window.

On the next screen expand “Translation Objects” tree, find your Form (under <PDFB> PDF-Based Forms/<PDFA> PDF-Based Interactive Forms) and double click on it. Translation Editor will open.

Translation Editor displays the XLIFF file for Source Language at the top. At the bottom there’s an empty editor, in which you should enter the translated XLIFF. Use “Copy Source Text (Shift+F8)” button to copy the original XLIFF into the “Target Language” window. The system will format the text in the target window automatically (all elements and attributes of the XLIFF file except for the literals will be made read-only).

Replace the literals in the target window with the translations. Alternatively you can download the entire XLIFF file (button “Save as local file”) to translate it outside the system and then upload it (button “Load local file”).

Save the translation by clicking “Save object (Ctrl+S)” button on the application toolbar.

Displaying A Translated Form

To display a translated Adobe Form, call the function module generated by the system for it, passing the language (and country) in fields LANGU and COUNTRY of parameter /1BCDWB/DOCPARAMS (please check section Common Problems if the output doesn’t show the translated text – it’s probably an outdated cache/buffer issue).

Transporting Layout Translation Between Systems

When you save a translation for an Adobe Form, the system actually creates a new Layout with exactly the same arrangement of Fields but translated literals (you can check this easily by downloading any translated Adobe Form in transaction SFP – inside the file you’ll find a separate FPLAYOUTT element for each language).

If you modify a Layout in Adobe LiveCycle Designer, your changes are saved into a Workbench Transport Request. Translation is a part of the Layout so it will be transported with the same Transport.

If you provide a translation without modifying the Layout, the system won’t save your translation into a Transport Request. You have to create a Transport with the translations by yourself. Use transaction SLXT to do it as described here.

Translation for Right-to-left (RTL) Languages

For languages using right-to-left (RTL) text direction (e.g. Arabic, Hebrew, Persian), translation requires not only literals replacement but also layout transformation – it has to be mirrored vertically. Adobe Forms (SAP Interactive Forms by Adobe) are mirrored automatically by the system (with restrictions, see OSS Note 1539317 – Restrictions in form layout mirroring) if the following prerequisites are met: ADS version is at least SAP Netweaver 7.31, SAP_BASIS Release is at least 7.31.

If your system doesn’t meet the requirements specified above then you have to create a separate Adobe Form for RTL languages (it’s not as hard as it sounds – all you have to do is to move all layout objects from left to right and change Text fields alignment: left to right and vice versa).

Language variants


One language can be used in several countries. French (FR) is used (among others) in France, Canada, Switzerland, Belgium, Morocco. German (DE) is an official language in Germany, Austria, Switzerland. If, for example, the translation of an Adobe Form for Germany is different from the translation for Austria (and that’s usually the case), you have to provide 2 different translations, one for each country.

Luckily SAP system is prepared for such scenario. All you have to do is to install different variants of a language into your system.

In case of German, SAP has defined the following variants:

1G – German Austria
2G – German Liechtenstein
3G – German Luxembourg
4G – German Switzerland
DE – German Germany

Go to transaction I18N and double-click on “I18N System Configuration” node (alternatively you can call report RSCPINST directly). Click “Extend Language List” button. Select the language variant you want to install and click “Execute (F8)” button. Then add the language to the system as described in Translation Procedure.

Unfortunately all language codes used by SAP not included in ISO 639-1 specification (1G, 2G, 3N etc.) are not recognized by Adobe Document Services (ADS). SAP sends incorrect Locale to ADS – for example 1g_AT instead of the correct de_AT and as a result all dates, decimal numbers are formatted with the default Locale (in my case en_GB).  This behavior is not recognized by SAP as an error (I opened a ticket for it in OSS and it was rejected – you might have more luck).

There are 2 solutions to this problem:

  1. Define a custom Locale in ADS as recommended by SAP Support – for details see OSS Note 2696301 – Forms by Adobe: Changing or creating custom locale definitions
  2. Implement a small correction in include LFPCOMPFRM to replace SAP- language-code with ISO-language-code

As we were happy with the standard locale settings delivered by Adobe we went for the modification (it uses standard class/method CL_I18N_LANGUAGES=>sap1_to_iso639_1).

*{   REPLACE        A20K938482                                        1
*  CALL FUNCTION 'CONVERSION_EXIT_ISOLA_OUTPUT'
*    EXPORTING
*      input  = l_langu
*    IMPORTING
*      output = l_iso_langu.
*
** According to ISO 639, the language code is in lower case.
*  TRANSLATE l_iso_langu TO LOWER CASE.                    "#EC SYNTCHAR
  CL_I18N_LANGUAGES=>sap1_to_iso639_1(
    EXPORTING im_lang_sap1 = l_langu
    IMPORTING ex_lang_iso639 = l_iso_langu ).
  IF l_iso_langu is INITIAL.
    CALL FUNCTION 'CONVERSION_EXIT_ISOLA_OUTPUT'
      EXPORTING
        input  = l_langu
      IMPORTING
        output = l_iso_langu.
*   According to ISO 639, the language code is in lower case.
    TRANSLATE l_iso_langu TO LOWER CASE.
  ENDIF.
*}   REPLACE

Address Formatting


Addresses are formatted differently depending on a recipient country. The formatting rules are defined by various national and international guidelines and norms, including:

  • ISO 11180,
  • World postal association contracts (Seoul 1994),
  • World postal association international address templates
  • and various national guidelines.

The formatting logic is quite complicated even for a single country (you have to take into account that many address fields are optional e.g. address is different if PO Box is used, if District is provided etc). Don’t try to be smart and implement address-formatting logic (especially if your Adobe Form is going to be used in several countries) – you’ll regret this decision sooner than later.

SAP had put a lot of effort to do it properly. All address formatting logic is incorporated into ADDRESS_INTO_PRINTFORM function module. Use it!

Address can be inserted into an Adobe Forms in 2 ways:

  1. Add an Address node to Adobe Form’s context (function ADDRESS_INTO_PRINTFORM is called behind the scene). See Insert an Address in SAP Help for more information.

  2. Explicitly call function ADDRESS_INTO_PRINTFORM in your print program and save the formatted address into a string field and bind the field to a normal Text Field on the layout.

Check the documentation of function module (SE37) ADDRESS_INTO_PRINTFORM in the system for more details.

NOTE

Personally I prefer method 2 – the advantage is that the address is visible in the program collecting the data (easier debugging). What is more, the address can be used not only on a Form but also for other purposes (e.g. in an EDI interface sending the same data electronically).

TIP

If you want an address to contain country name, set parameter SENDER_COUNTRY. If the country of the recipient is different from the sender’s country the system will add the recipient’s country name to the address automatically.

Custom address formatting routine

If you’re not satisfied with the SAP standard address formatting you still have the option to provide your own logic. Define a new “Formatting routine key for printing addresses” in table T005A (the key is a 3-digit number). Next assign the new routine key to a country (field T005-ADDRS).

Custom address formatting logic should be implemented via a customer exit using the SAP enhancement SZAD0001 (EXIT_SAPLSADR_001, transaction CMOD). Please check the documentation of function module EXIT_SAPLSADR_001 for additional information.

Translation of PO Box Text

PO Box (Post Office Box) is an optional field that can be entered into an address. If it’s provided “PO Box” text appears in the formatted address. To translate “PO Box” into another language run transaction SE37, enter ADDRESS_INTO_PRINTFORM into Function Module field and click “Display” button (F7). Next open menu Goto->Text elements->Text Symbols. On the next screen open menu Goto->Translation. Choose a target language in the displayed popup window. Provide the translation for each Text element and save it with “Save (Ctrl+S)” button.

To transport the translated text to another system use transaction SLXT as described in here.

Translation of countries names

Countries names should be translated in the system if they are a part of the address. The names are stored in table T005T which is included in the standard maintenance view V_T005. To translate a country name, open transaction SM30, enter V_T005 into Table/View field and click “Maintain” button. On the Change View screen select one or several countries and open menu Goto->Translation. Choose your target language in the popup. Fill in the translated countries names and confirm the changes by clicking “Continue (Enter)” button. Click “Save” button on the Overview screen and save your changes into a new or existing Customizing Transport Request.

TIP

Consider creating a custom Maintenance View for table T005T in ABAP Dictionary (SE11) if you have to provide translations for a dozen of countries – it will save you a lot of time and typing.

Translation of Units of Measurement (UoMs)


If you develop a multilingual, global Adobe Form you should make sure that all supported units of measurement are translated.

To translate units of measurement run transaction CUNI and open menu Goto->Translation->Units of measurement (F7). Enter the target language on the popup screen. Fill in the translations for all units of measure and confirm the changes by clicking “Save (Ctrl+S)” button. The system will ask you for a Customizing Transport Request.

TIP

Translations of Units of measurement are stored in table T006A (Assign Internal to Language-Dependent Unit). Unfortunately there’s no standard Maintenance View for the table. Translation in transaction CUNI is rather cumbersome as you have to enter one unit at a time (copy&paste is not possible). For mass units translation consider creating a custom Maintenance View in ABAP Dictionary (SE11).

Open transaction SE11, enter view name (e.g. Z_T006A) and click “Create”. Choose “Maintenance view” in the popup. Enter table T006A in tab “Table/Join Conditions”, next go to tab “View Fields” and select all fields of the table. Activate the View, next open menu “Utilities(M)->Table Maintenance Generator” to create a new Maintenance View. Go to SM30 and enter view name to maintain the translations.

Transporting Translations Between Systems


If you save a translation and the system doesn’t ask you for a Transport Request, this means that you have to create a Transport Request yourself to be able to move the translations to other systems. The procedure is quite simple.

Run transaction SLXT (SE63 Translation Transport). Select the correct language in field Target Language, select Workbench Request as a Transport Type (Transport of Copies are deleted when they reach the next target system) and provide a Description for the transport.

In section Time Period enter a date into Processing Date field (this is the date when translations were created). In section Filter fill in your user name into Object Processor field (or the name of a user who created the translation for you) . Click “Execute Program (F8)” to create a Transport Request with the translations.

Open transaction SE10 (Transport Organizer) and check if the Transport Request has been created and contains all required objects.

Handling Amounts and Quantities Fields


Your global Adobe Form should be ready to handle amounts in various currencies and quantities with different units of measurement.

For many programmers, what I’m going to write might seem obvious, as quantities and amounts storage principles in SAP systems are well-documented and taught on very first ABAP lessons, but I still encounter code converting amounts, quantities or tax percentages from internal SAP-representation to external format (usually for amounts in HUF/Hungarian forint or JPY/Japanese yen).

Just for the people who missed that lesson šŸ˜‰

  1. Always use the right Data Elements for amount/quantity fields when you define a data structure in ABAP Data Dictionary (amounts should be assigned a Data Element based on CURR Data Type,  quantities should have a Data Element based on QUAN as a Data Type). Do not use Data Elements based on a generic DEC Data Type (Decimal) or NUM (numeric) as SAP system doesn’t format such fields automatically.
  2.  Specify the correct Reference Table and Reference Field for each amount/quantity field
  3. Make sure you populate Reference Table and Reference Fields with the correct units/currencies at runtime (never leave it empty!)

If you follow those 3 simple rules you can forget about quantities and amounts conversion between the internal and external format – the system will do it for you.

TIP

For percentage fields set unit to ‘3’.

Common problems


Output doesn’t reflect the recent changes made to a translation

This is probably an outdated cache issue. Form templates are buffered in Adobe Document Services. This cache is activated by default. It is updated only if the template has changed in the original language. In the development system you can disable cache permanently by setting field CACHING to ‘-‘ in table FPCONNECT for your ADS destination (ADS by default). In the productive environment call report FP_PDF_TEST_26 (Delete Template Cache).

See the following OSS Notes for more information:

1007116 – Form output in wrong language
2258036 – Output of translated form is not currentā€‹

NOTE

Be careful when calling report FP_PDF_TEST_26 – sometimes it makes ADS server hang. In such case ADS restart is required.

Inconsistent xliff:rid issue

Sometimes, for an unknown reason, literal ID in the layout (attribute xliff:rid) and the ID of the same literal in the XLIFF file (attribute id of element trans-unit) are not synchronized properly. In such case the literal won’t be translated in the output. To resolve the issue run transaction SFP, enter the name of the Form and open it in Change mode. Open Layout editor/Adobe LiveCycle Designer and switch to XML Source View. Locate the Field with incorrect xliff:rid attribute in the XML editor and delete the attribute. Save the Layout – a new xliff:rid will be generated for the Field. Leave Adobe LiveCycle Designer and Activate the Form. Go to Translation Editor, locate the literal in the Target language window and provide the translation for it.

Translation editor upload issue

When you upload a translated XLIFF file to Translation Editor you might face a problem of redundant empty lines in the output (there’s an additional new line character after each literal). To workaround this issue upload the XLIFF file into Target Language window, change any of the literals by adding some random character to it. Save the translation. Go back to Translation Editor, let it format the translation for the Target Language. Remove the character that you inserted and save the translation again.

Translation of text literals inside scripts

Sometimes you need to use literals in a script to produce the desired output value.

Let’s consider the following simple FormCalc script filling company details in the footer.

var sep = " Ā· "
var nbsp = "u00a0"
var company = Ref($record.FOOTER.COMPANY_INFO)
//Company details
$ = concat("Company details:", nbsp, company.ADDRESS_ONE_LINE)
if(HasValue(company.TEL_NUMBER)) then
  $ = concat($, sep, "Tel:", nbsp, Replace(company.TEL_NUMBER, " ", nbsp) )
endif
if(HasValue(company.VAT_ID)) then
  $ = concat($, sep, "VAT ID:", nbsp, Replace(company.VAT_ID, " ", nbsp) )
endif

The above script is not well-suited for a multi-language form as it contains literals that won’t get translated (“Company details:”, “Tel.”, “VAT ID:”). To make it translation-friendly you should replace all literals with Form Variables.

Open the Form in Adobe LiveCycle Designer (SFP). Go to menu Edit->Form Properties…and select Variables from the list. Add a new variable for each literal used in the script (here I added 3 variables which names start with Txt*) and enter Value (text) in the original language for each variable. Confirm the changes with “OK” button.

Next replace each literal in the script with the corresponding Variable. The changed script should look like this:

var sep = " Ā· "
var nbsp = "\u00a0"
var company = Ref($record.FOOTER.COMPANY_INFO)

//Company details
$ = concat(TxtCompanyDetails, nbsp, company.ADDRESS_ONE_LINE)
if(HasValue(company.TEL_NUMBER)) then
  $ = concat($, sep, TxtTel, nbsp, Replace(company.TEL_NUMBER, " ", nbsp) )
endif
if(HasValue(company.VAT_ID)) then
  $ = concat($, sep, TxtVatID, nbsp, Replace(company.VAT_ID, " ", nbsp) )
endif

Save the Layout and exit Adobe LiveCycle Designer. Activate the Form and open menu Goto->Translation to display Translation Editor. Provide the translation for the Form Variables as for any other literal (see the translation procedure).

Still cannot solve your issue?

Our experts are always ready to help.
Get in touch and ask for a consulting offer.