ABAP log

March 1, 2007

Reading other program’s data using field symbols in ABAP.

Filed under: ABAP, SAP — abaplog @ 7:30 pm

One of the first questions we ask when we are going to implement a new logic in an SAP user exit is: what kind of data is available as input and what can I modify as output? Though limited, most of the time the parameters of user exit functions let us do what we want. But sometimes we get stuck because some field is not provided. The field can be either some global field of the calling program or a global field in a function group that is used by calling program. (You should remember that in latter case, the data is still sitting in the memory until we exit the main program or transaction, and can be used by any subsequent calls).

There is a simple trick that allows you read and modify the global data of any module loaded by a running program. It is using the ABAP’s dynamic assignment feature of field-symbols. The best way is to show it with an example.

The user exit ZXCO1U06 is running when we save a production order in the transaction CO02. In this user exit you can do some additional checks, modify data, probably issue some messages and so on. Unfortunately, only header data of the order is provided as its parameter. Reading the database is not an option because any updated data (new operations, new status flags) is not yet written to the database. If you want to read, say, order operations or their status, you either call the same functions that are called by CO02 (as the same global data is used), or access the data directly. If we want to check the status of the order and ist operations, we could read the global data (internal tables) of the function group BSVA, that is used to manage the status in CO02. The table that contains the status flags is called JEST_BUF and we can get the table content in out user exit in the following way:

* See declarations in LBSVATOP
* This type should match the one used in SAP program!
types: begin of t_jest.
            include structure jest_upd.
types:
            mod,
            inact_old like jest-inact,
          end of t_jest.

data:
  lf_text(40)   type c,
  lt_jest       type standard table of t_jest.

field-symbols:
  <ls_jest_buf>      type any table.

lf_text = '(SAPLBSVA)JEST_BUF[]'.
assign (lf_text) to <ls_jest_buf>.
check sy-subrc = 0.
lt_jest[] = <ls_jest_buf>.  "now everything is in lt_jest !

If we want to do some changes of the global data, we could do a “reversed” assignment to the field-symbol:

<ls_jest_buf> = lt_jest[].

Finding the needed program and variable names is not a straightforward task, but can be done with debugger. The best motivation is that there is rarely some alternative solution (that is less ugly than using dynamic ABAP assignments).

Important note: Using user exits is a kind of advanced task because you can easily screw up the SAP program’s internal data. But this trick gives you even more chances of doing that, so everything should be done with a special care.

5 Comments »

  1. I already used these tricks to get the required data from the “old” transactions.

    I am now however stuck in transaction ME22N, It uses classes (objects) and I am still trying to find a way to access an existing object in memory without knowing its address.
    All I know is that if I look in the debugger the variable my_model contains that following value {O:687*\CLASS=CL_PO_HEADER_HANDLE_MM}.

    With the cl_po_header_handle_mm I should be able to retrieve the object from memory where it is called CL_PO_HEADER_HANDLE_MM========CP.
    Of course I should check the PO order number to make sure I got the right object.

    The problem is I can’t seem to get this done in the old fashion way like used above. Or I am just making a mistake. It would be nice if we could loop over the shared memory area to see what data is stored like the sap memory viewer. (Just the names not the entire memory space)

    Help would be appreciated. If I am posting this at the wrong place then I am sorry and try to get my answers elsewhere.

    Comment by Xavier Wallece — May 23, 2007 @ 10:17 am

  2. I’ve tried what you say but for a table control (trx BP -> create person: under indentification tab) and the assign fails. Here the code.

    TYPES: BEGIN OF i_tablecontrol_line.
    INCLUDE STRUCTURE DFKKBPTAXNUM.
    TYPES: END OF i_tablecontrol_line.

    DATA: l_tabla(36),
    i_tc type standard table of i_tablecontrol_line.

    FIELD-SYMBOLS
    TYPE ANY TABLE.

    l_tabla = ‘(SAPLBUPA_BUTX_DIALOG)DFKKBPTAXNUM[]’.
    ASSIGN (l_tabla) TO
    .
    i_tc[] =
    .

    Comment by Mikel — June 5, 2007 @ 8:58 am

  3. Mikel, I would try setting a breakpoint and then entering exactly the same string in fields value display: (SAPLBUPA_BUTX_DIALOG)DFKKBPTAXNUM[]

    If there is any problem, the debugger will say that the field doesn’t exist. In this case, check the program you are trying to access. Is the field name correct, is it really a table?

    Comment by abaplog — June 11, 2007 @ 8:40 pm

  4. i tried this in a user exit in MIGO. It enables us to get the movement type (bwart) maintain in header level.
    The function group is MIGO.
    Header level structre is GODEFAULT_TV

    below is how i did it.
    data: st_godif_ty type GODEFAULT_TV,
    tb_godif_ty like standard table of st_godif_ty,
    tx_godif_ty(30) type c.

    FIELD-SYMBOLS TYPE ANY.
    tx_godif_ty = ‘(SAPLMIGO)GODEFAULT_TV’.
    assign (tx_godif_ty) to .
    check sy-subrc = 0.
    st_godif_ty = .
    data: tbwart type mseg-bwart.
    tbwart = st_godif_ty-bwart.

    This helps a lot thanks so much…..

    gajaba
    colombo

    Comment by gajaba — November 1, 2007 @ 2:55 pm

  5. Works like a charm! Thanks for this very helpful and great tip. Saves me lots of re-programming.
    I’m using it to extract the equipment data from the program SAPLIPW1

    Comment by Christian — April 17, 2009 @ 12:41 pm


RSS feed for comments on this post. TrackBack URI

Leave a comment

Create a free website or blog at WordPress.com.