Update Descriptions of G/L Accounts by Language with a Recording

Jimbo's picture

Sleepy goatG/L Accounts are as mysterious to programmers as ABAP is to plumbers. They are used for some dark, esoteric purposes that only accountants can understand.

The requirement to update the description of G/L Accounts in only one language lead to the discovery that SAP automatically maintains the description in all the languages running in SAP at the time a G/L Account is created. The descriptions are stored in the SKAT table as a short (TXT20) and long (TXT50) text field.

The FS01 transaction allows for the descriptions (both TXT20 and TXT50) to be changed, but it only changes the description in the language of the user account logged into SAP in the language of the Chart of Accounts to which the G/L Account is linked in the T004 table. All of the other languages are left untouched and cannot be changed using the FS01 transaction.

This transaction asks for the Company Code to edit details specific to the G/L Account at the Company Code level. The descriptions are not maintained with the Company Code data in SKB1, but instead are maintained in SKAT, so changes to the description do not affect the SKB1 data which is helpful to know when making the recordings.

FST2 allows direct access to descriptions in all of the languages that the G/L Account has been described except for the language of the user account logged into SAP except for the language of the Chart of Accounts to which the G/L Account is associated. The descriptions in the user's Chart of Accounts language are ironically grayed out and cannot be touched with this transaction.

Because the FST2 transaction is so rarely used, it is unlikely that access has been granted to anybody in the production system. Before the go-live weekend, be sure to find out if any roles or users have access to this transaction.

Creating an LSMW object based on recordings is the easy part and populating the correct field is almost as easy. Start by creating a recording using the FS01 transaction using any G/L Account and Company Code combination and use it to touch the fields TXT20 and TXT50 (change the values slightly); it doesn't matter which company code is used as the descriptions are not related to a company code.

Default All the the field names and ensure that the SAKNR, BUKRS, TXT20 and TXT50 fields are available. These will be used when creating the batch a little later.

Next, create a recording using the FST2 transaction and be sure to touch every one of the first 11 short and long descriptions. If the recording doesn't catch these, then be sure to add them using Edit→Add Screen Field (Extended) like in the image below and be sure that *SKAT-SPRAS(11) is included as well; that will be used to add the language instead of editing it when the G/L Account has no descriptions in the language from the source file.

Next, add the recordings to the object attributes of the LSMW object. The image below shows how to use multiple recordings in an LSMW object.

Add the relationships between the source data and the recordings. Both need to have this association so that they can be used to create batches.

A few variables are declared to be used while creating the batch. They go in the Global Data Definitions and Declarations area.

parameters: p_break as checkbox.
data: lSKB1 like SKB1, lT002 like T002, lSKAT like SKAT,
      lT004 like T004, lSKA1 like SKA1,
      it_SKAT type standard table of SKAT initial size 0,
      nCurrent type i, nIndex type i.

Now the ABAP code can be knit in to determine which recording should be used based on the language of the user running the LSMW object. If the language of the description to be changed is not the same language being used by the user logged into SAP Chart of Accounts then the FS01 recording is not used.

translate FS02S-SPRAS to UPPER CASE.
select single * from T002 into lT002 where LAISO eq FS02S-SPRAS.
if sy-subrc ne 0.
  write: / FS02S-SPRAS color col_negative, 'Not a language.'.
  skip_transaction.
else.
**** Following code remarked out thanks to Jens Brehmen ****
*  if lT002-SPRAS ne SY-LANGU.
*    exit. "Do not use FS01!!!
*  endif.
endif.

The code pulls the language-specific record from T002 in order to properly compare the incoming ISO language code from the source data to SAP's internal 1-character SPRAS code. The incoming code in this case is ISO "PL" for Polish or "L" in SAP's SPRAS fields as can be seen in this debugger screenshot.

Next, the code finds a single Company Code value to populate the BURKS field in the batch while calling the FS01 transaction. The descriptions are independent of the Company Code data, so it doesn't matter which Company Code value is used to populate the BUKRS field, but a BUKRS value is required in order to make the transaction work.

shift FS02S-SAKNR right deleting trailing space.
overlay FS02S-SAKNR with '0000000000'.
select single * from SKB1 into lSKB1 where SAKNR eq FS02S-SAKNR.
if sy-subrc ne 0.  "Doesn't exist in this system.
  write: / FS02S-SAKNR color col_negative, 'Does not exist.'.
  skip_transaction.
else.
  "**** Following code added thanks to Jens Brehmen ****
  select * from SKA1 into lSKA1 where SAKNR eq lSKB1-SAKNR.
    select * from T004 into lT004 where KTOPL eq lSKA1-KTOPL.
      if lT002-SPRAS ne lT004-DSPRA. "Language of CoA
        exit. "Do not use FS01!!!
      endif.
    endselect.
  endselect.
  FS02D-SAKNR = lSKB1-SAKNR.
  FS02D-BUKRS = lSKB1-BUKRS.
  " We are only changing the description centrally, so it doesn't
  " matter which company code we choose.
endif.

If the language is different from the language of the user logged into SAP then the FST2 transaction is called by the batch. Here the language is checked again to ensure that the FST2 transaction is not called when the languages of the source data and SAP user Chart of Accounts match.

* The language is coming into the LSMW object as the ISO code
* and not the internal SPRAS, so converting . . .
translate FS02S-SPRAS to UPPER CASE.
select single * from T002 into lT002 where LAISO eq FS02S-SPRAS.
if sy-subrc ne 0.
  write: / FS02S-SPRAS color col_negative, 'Not a language.'.
  skip_transaction.
else.
**** Following code remarked out thanks to Jens Brehmen ****
*  if lT002-SPRAS eq SY-LANGU.
*    exit. "Do not use FST2!!!
*  endif.

The READ_HAUPTBUCH_TEXTE function is called to predict where on the screen the FST2 transaction will put the descriptions in each language. Based on which line the language will be, the screen fields are populated with the descriptions.

GL MemeIf there are no descriptions for the G/L Account in the language from the source data then the nIndex variable is 0 at the end of the loop. In this case, the 11th row is populated and the SPRAS is included in order to add a new record with the desired language.

Note: The system in which this LSMW object was created has only eight active languages. If there were more than ten languages active in the system then the recording would have included a few page-down keys to get to an empty page and a little more logic for predicting the location of the desired language in the list.

* The screen for editing the descriptions in different languages
* simply throws them up in the order that they occur in the database
* without sorting them.  The function below is used to standardize
* so that if it ever does start sorting then this LSMW object will
* still work correctly.
  shift FS02S-SAKNR right deleting trailing space.
  overlay FS02S-SAKNR with '0000000000'.
  CALL FUNCTION 'READ_HAUPTBUCH_TEXTE'
    EXPORTING
      kontenplan      = FS02S-KTOPL
      sachkonto       = FS02S-SAKNR
    TABLES
      texttab         = it_skat
    EXCEPTIONS
      konto_not_found = 1
      text_not_found  = 2.
  if sy-subrc ne 0.  "Doesn't exist in this system.
    write: / FS02S-SAKNR color col_negative, 'Does not exist.'.
    skip_transaction.
  else.
    "**** Following code added thanks to Jens Brehmen ****
    select * from SKA1 into lSKA1 where SAKNR eq FS02S-SAKNR.
      select * from T004 into lT004 where KTOPL eq lSKA1-KTOPL.
        if lT002-SPRAS eq lT004-DSPRA. "Language of CoA
          exit. "Do not use FST2!!!
        endif.
      endselect.
    endselect.

    FST2D-SAKNR = FS02S-SAKNR.
    FST2D-KTOPL = FS02S-KTOPL.
    nIndex = 0. nCurrent = 1. "Start nCurrent at line 1.
    loop at it_SKAT into lSKAT.
      if lSKAT-SPRAS eq lT002-SPRAS.
        nIndex = nCurrent.
      endif.
      add 1 to nCurrent.
    endloop.
    case nIndex.
     when 1. FST2D-TXT20_01 = FS02S-TXT20. FST2D-TXT50_01 = FS02S-TXT50.
     when 2. FST2D-TXT20_02 = FS02S-TXT20. FST2D-TXT50_02 = FS02S-TXT50.
     when 3. FST2D-TXT20_03 = FS02S-TXT20. FST2D-TXT50_03 = FS02S-TXT50.
     when 4. FST2D-TXT20_04 = FS02S-TXT20. FST2D-TXT50_04 = FS02S-TXT50.
     when 5. FST2D-TXT20_05 = FS02S-TXT20. FST2D-TXT50_05 = FS02S-TXT50.
     when 6. FST2D-TXT20_06 = FS02S-TXT20. FST2D-TXT50_06 = FS02S-TXT50.
     when 7. FST2D-TXT20_07 = FS02S-TXT20. FST2D-TXT50_07 = FS02S-TXT50.
     when 8. FST2D-TXT20_08 = FS02S-TXT20. FST2D-TXT50_08 = FS02S-TXT50.
     when 9. FST2D-TXT20_09 = FS02S-TXT20. FST2D-TXT50_09 = FS02S-TXT50.
    when 10. FST2D-TXT20_10 = FS02S-TXT20. FST2D-TXT50_10 = FS02S-TXT50.
     when others. "Hasn't been loaded for this language.
       FST2D-SPRAS_11 = FS02S-SPRAS. "Create new record.
       FST2D-TXT20_11 = FS02S-TXT20.
       FST2D-TXT50_11 = FS02S-TXT50.
    endcase.
  endif.
endif.

Update:

This LSMW object ended up never being used as the FST2 transaction is assigned to no role in the client's production system and they refused to grant it even to a FireFighter account. One of the FireFighter accounts had access to transaction FSP0, so rather than develop a complete new LSMW object to update descriptions for fewer than 200 G/L Accounts in just one language, it was decided to manually update the G/L Accounts by copy-pasting them from Excel.

Better to fail at originalityAnother Update:

An internet citizen has read this article and sent in some very insightful feedback. It is included below in its entirety to remind humble programmers like the one that wrote this article that one can learn something new every day.

Keep up the great work, Mr Brehman.

Hi,
I've just read your article "Update Descriptions of G/L Accounts by Language with a Recording" and it's by far the best I've seen about this topic. I think most people resign to direct updates on SKAT to achieve this goal.
But there is one error in it. You write: "except for the language of the user account logged into SAP. The descriptions in the user's language are ironically grayed out and cannot be touched with this transaction."
That's not completely correct. The language which is grayed out both in FST2 and in the according tab of FSP0 / FS00 is the maintenance language of the chart of accounts, T004-DSPRA. It is independent of the logon language.
Best regards,
Jens Brehmen

Dilbert Accounting

Programming Language: 
ABAP