CRM and CX Blogs by Members
Find insights on SAP customer relationship management and customer experience products in blog posts from community members. Post your own perspective today!
Showing results for 
Search instead for 
Did you mean: 
Former Member

Hello SCN,

So the other day I had the following requirement (I work on a SAP CRM 7.0 system): I wrote a new program in which I needed some data processing which was already coded in the subroutine of another – already existing – program. Since it concerned a pretty large piece of code, I decided not to simply copy-paste the logic but to call the subroutine from within my program like this:

PERFORM subroutine IN PROGRAM main_program CHANGING t_result.

Since the program in which I was calling the subroutine has a selection screen, and some of these parameters are used in the subroutine, I had to add an importing (USING) parameter to the subroutine which contained the values for these parameters. These values are partially supplied by the user in the selection screen of my program, and others are calculated in my program flow. So the above statement was corrected as follows:

PERFORM subroutine IN PROGRAM main_program

USING     t_selscr_parameters

CHANGING  t_result.

Now comes the tricky part :smile: . The table T_SELSCR_PARAMETERS is a table with structure RSPARAMS (so basically the standard type for any selection screen, with components SELNAME, KIND, SIGN, OPTION, LOW and HIGH). Containing records with the exact names (SELNAME) of the corresponding selection screen parameter, and – of course – the value to be transferred to the selection screen parameter (e.g. SIGN=’I’, OPTION = ‘EQ’, LOW = ‘xxx’).

So I added some logic to the subroutine which we are calling: a loop over SELSCR_PARAMETERS to transfer the value of each table line into the corresponding parameter from our main program’s selection screen.

For a regular parameter, I knew I could work with a field symbol of type ‘any’, and simply assign the name of the parameter (LS_RSPARAM-SELNAME) to this field symbol – let’s name him <FS_ANY>. If the assignment works (which it should, because I named the parameter records in the SELSCR_PARAMETERS table exactly the same as the parameters in the selection screen), you can transfer the value in the selection screen parameter by using the following statement:


But.. next to the ‘regular’ parameters, there were also some ranges (SELECT-OPTIONS) which needed to be transferred into the selection screen. Ranges are in fact separate internal tables with header line

So you could use the same statement as for a regular parameter

ASSIGN ls_rsparam-selname TO <fs_any>.

But it would not be useful, since you need to append a structure of type RSPARAMS to your range (assigned to <FS_ANY>) and you can't do that - because <FS_ANY> is not an internal table.

So, you might think, I simply create a new field-symbol <fs_anytab> TYPE ANY TABLE :smile: . That way I can assign ls_rsparam-selname to <fs_anytab>, and append to that field-symbol.

True, syntactically this logic would not cause any problems, and your program would activate without errors. But once you step over the statement, you will get the following shortdump:

So below you can find how I solved this issue. I searched for answers in the forum discussions here on SCN, but couldn't find it immediately. Perhaps it is out there somewhere (especially since this concept is widely used in R/3, not so much in CRM though) but I blogged about this nonetheless, hoping to save a fellow colleague some valuable time :wink: ;

DATA:            ref(50)         TYPE c,

                 dref            TYPE REF TO data.


                <fs_any>         TYPE any,

                <fs_any_1>       TYPE any,

                <fs_anytab>      TYPE ANY TABLE.

LOOP AT i_selscr_parameters INTO ls_rsparam.

  CASE ls_rsparam-kind.

    WHEN 'P'.

*     This is a regular parameter

      ASSIGN (ls_rsparam-selname) TO <fs_any>.

      IF <fs_any> IS ASSIGNED.

        <fs_any> = ls_rsparam-low.

        UNASSIGN <fs_any>.


    WHEN 'S'.

*     This is a range. Now ranges are in fact tables with header line,

*     and a row structure SIGN OPTION LOW HIGH.

      CONCATENATE: '(' sy-repid ')' ls_rsparam-selname '[]' INTO ref.


      ASSIGN (ref) TO <fs_anytab>.

*     So now we have the table (MAINPROGRAM)S_RANGE[] assigned to a

*     field-symbol of type ANY TABLE without dumping 😉

      IF <fs_anytab> IS ASSIGNED.

*       We still need a structure which has the same line type as <fs_anytab>

        CREATE DATA dref LIKE LINE OF <fs_anytab>.

*       And now <fs_any> has our line type, we can start transferring the

*       values to the different components of the structure

        ASSIGN dref->* TO <fs_any>.

        IF <fs_any> IS ASSIGNED.

          ASSIGN COMPONENT 'SIGN' OF STRUCTURE <fs_any> TO <fs_any_1>.

          IF <fs_any_1> IS ASSIGNED.

            <fs_any_1> = ls_rsparam-sign.

            UNASSIGN <fs_any_1>.


          ASSIGN COMPONENT 'OPTION' OF STRUCTURE <fs_any> TO <fs_any_1>.

          IF <fs_any_1> IS ASSIGNED.

            <fs_any_1> = ls_rsparam-option.

            UNASSIGN <fs_any_1>.


          ASSIGN COMPONENT 'LOW' OF STRUCTURE <fs_any> TO <fs_any_1>.

          IF <fs_any_1> IS ASSIGNED.

            <fs_any_1> = ls_rsparam-low.

            UNASSIGN <fs_any_1>.


          ASSIGN COMPONENT 'HIGH' OF STRUCTURE <fs_any> TO <fs_any_1>.

          IF <fs_any_1> IS ASSIGNED.

            <fs_any_1> = ls_rsparam-high.

            UNASSIGN <fs_any_1>.






NOTE: The point of this blog is to elaborate on accessing internal table variables dynamically across programs, I certainly do not claim this was the best or most performant solution to my original requirement :wink: . Any comments on this blog however are highly appreciated!