Don’t get lost in translation
Prompted by Colm’s question Writing ABAP for Translating – Best Practice and some of the answers to it, I put together this. It’s based in part on my own answer to the thread, elaborated and extended where necessary. This is not about the process of translation specifically, but the good coding practice that can be applied to make sure translation is possible.
As SAP is geared towards multiple language support most objects cope with this without additional considerations. A Data Element for example can be translated to another language at a point in the future regardless of whether that was your intention when the object was created. But there are some things that we can do during development to make the process of translation trouble free.
In programs, ALV reports and screens develop them to inherit text from the Data Element as much as possible as this reduces the volume of text to be translated and ensures consistency. And if you’re lucky the standard ones will already be translated.
Use Text Symbols for language specific text in programs and set the Maximum length to 10% to 15% longer than the English version (the default is the defined length). But keep in mind where the text will ultimately be displayed when setting the max length. If there are only 10 characters available on the screen for a text then the max needs to be 10 for every language.
(Edit: In my current 7.40 system the Maximum length no longer defaults to the same length as the entered text, instead the following algorithm is applied. If the entered text is less than 20 characters the Maximum length is set to the text length +10, if it’s greater than 20 characters the Maximum length is double the text length. While this easily avoids the problem of there not being enough space for the translated version of the text I think it’s still necessary for the developer to consider the available space on the screen for the text and set the Maximum length accordingly.)
If Text Symbols are used extensively in a program it can be useful to add a meaningful prefix to Text Symbol numbers, for example S for selection screen text, H for column headers.
However, don’t use text symbols for anything other than text. For example if your program uses a function code ‘SAVE’ store this as a literal or a constant, if it’s stored as a Text Symbol and gets translated things will stop working.
Always use numbered placeholders in messages (SE91) as the word order in the translated text may be different to English. For example, “Document &1 is locked by user &2”. If this were translated into Yoda-ese it would be, “Locked by user &2, document &1 is”. (Sorry about that, I really did try to find a genuine example, but I’m not much of a linguist).
If you’ve defined your own config tables containing a value and a description these need to be defined as two linked tables, one with the value and one a language dependent description. For example the relationship between T003 and T003T, or see this blog Getting the basics right – Creating the perfect config table (Part 3, Text tables)
In terms of transports, transaction SLXT (or program RS_LXE_RECORD_TORDER up to Netweaver 7.0) is useful if you plan to transport the languages separate from the development.
The Target Language field (despite being display only) can be changed using the search help, and the transport attributes should be set based on the conventions of your own transport landscape. An existing transport can be used by unchecking Create New Request and checking Grant
Non-SLXT Requests. The remaining selection criteria can be used to focus the extract on the required date, objects, packages etc.
As this tool only adds the language elements to the transport the timing of this is critical, if the translation transport is released before the original objects the language import will only be successful for those objects already transported.
However, if I have an object locked in a transport all translations for it will get moved when the transport is released, irrespective of the developer’s logon language. If the development and translation happen at the same time an additional language transport is unnecessary.
As well as the above report it also possible to manually add the translation of an object to a transport. The program ID to specify is LANG and once this is entered there will be a pop-up prompting for the required language key. The object type will be the same as the original object.
+1 for Yoda-ese example 🙂
Well written! Nice, short and clear. A good Blog!
I avoid text-symbolös as much as i can, except for parameters and select-options. Havinf the litarels in the text makes code much more easier to read, avoids you tpo double click on the text-001 symbol to see whats being "printed".
Double clicking on the literal will add a (nnn) to the literal make it a translatable text symbol.
There are two traps doing this:
(1) Always the text behind the literal is printed which can be over written:
Write:/ 'You are excellent'(001).
might be displayed as "You idiot"
(2) Stringliterals cant be treated this way 🙁
String literals can't be treated that way?
parameters p_file type string.
cl_gui_frontend_services=>directory_browse(
exporting
window_title = |{ 'Select a folder, captain!'(001) }|
initial_folder = p_file
changing
selected_folder = p_file ).
The method requires a string input, and this dynamically typecasts a text-symbol to a string. Is that what you meant?
A literal enclosed in ' is not a string literal, but a charachter literal. String literals are enclosed in back quotes `
`This is a string`
cant be turned into a text symbol by double clicking on it not by adding (001) manually. At least not in the version we have (702)
'This is not a string'
can be converted.
Your 'Select a folder...' is not a string literal.
It's a character literal enclosed in a string template...so it functions like a string literal to the compiler and the program, but it can still be treated like a character literal by the IDE (double clicking and so on). The method I listed above required a string as a parameter, and I turned a text symbol into a string in the same line. That's all I was trying to say.
But thats nothing special. Assigning a character literal to a string variable always works with type casting. Called once, the type casting does not harm, but in a loop....
At least the sentence "a string literal cant have a text-symbol like (001)" is still valid.
Good... Thanks for sharing...
Pardon my ADD, but what graphics editor did you use to make that sweet cutout of the screen painter dialog? That's really slick.
Hi Eric,
It was done with Snagit from TechSmith, version 11, really useful tool for both screen capture and editing.
Regards,
Nick
Hi Nick,
excerpt:
"Use Text Symbols for language specific text in programs and set the Maximum length to 10% to 15% longer than the English version."
I would recommend to extend the Maximum length by 50%. It depends on the target languages, but if e.g. Russian is involved, the words are significantly longer !
Best regards,
Nils
Hi Nils,
Thanks for the input, you make a very good point.
The problem stems from the fact that the system will automatically set the max length to the same as the length of the text when entered in the original language, which is not good for any translation requirement.
My only concern with increasing the max length beyond 10% or 15% is the risk of overrunning the available space on the actual output. For a target language which does have significantly longer words than the orginal language I would be more inclined to set the max length to the maximum available in the output rather than applying a large increment to the original language length.
Regards,
Nick