Category Archives: SAP ABAP

Locate the PSA for a Data Source

Business scenario:
For a given BW master data object, I needed to identify deletions that take place in the source system. However for this particular object, the data source does not provide you with a deletion flag. Instead, the object is simply removed from the source tables.

psa

I therefore created a transformation in BW that flags as ‘deleted’ those master data records that do not appear any more in the PSA table of the daily FULL load.

The transformation i created is a loop-back transformation (the source and target of the transformation are the same object). In the source routine, the PSA table of the objects data source is checked.

To identify the PSA table dynamically I used the functions described in the Following SDN Article. (If you use SAPLINK, the report described in the article is available for download below.
You can download the code of the function here in Saplink format.
Download – PROG_ZBW_IDENTIFY_PSA.slnk – 5.2 kB – 300   downloads

See also SAP FM ZAIB2_PSA_TAB_AND_REQ_GET returns lots of info (PSA table, last request et al)

Some information on how to access PSA data:
When the system detects an incompatible change to the transfer structure, a new version of the PSA, meaning a new PSA table, is created. Data is written to the new table when the next request is updated.

The original table remains unchanged and is given a version. You can continue to use all of the PSA functions for each request that was written to the old table.
Data is read from a PSA table in the appropriate format.

1.  If the request was written to the PSA table before the transfer structure was changed, the system uses the format that the transfer structure had before the change.

2.  If the request was been written to the PSA table after the transfer structure was changed, the system uses the format that the transfer structure has after the changed

ABAP Unit Testing

If you want to start using ABAP Unit Testing, the links below will help you. They were useful to me when I started experimenting it.

 

ABAP unit tests enable writing and running white box tests during the development of complex BW transformation rules and routines. This How-To document shows you the tools you need to develop BW transformations according to a test-driven paradigm. Step by step, we describe a prototype implementation of an ABAP unit test for a selected BW transformation.

Update Master Data attribute via ABAP – Example program

*&———————————————————————*
*& Report  ZTST_RSDMD_WRITE_ATTRI
*&
*&———————————————————————*
*&
*&
*&———————————————————————*

REPORT  ZTST_RSDMD_WRITE_ATTRI.

PARAMETERS:
p_wbs type /bi0/oiwbs_elemt.

data:
lt_idocstate type RSARR_T_IDOCSTATE,
l_subrc type sy-subrc,
ls_pwbs_elemt type /bi0/pwbs_elemt,
lt_pwbs_elemt type table of /bi0/pwbs_elemt,
ls_attr type RSD_s_IOBJNM,
lt_attr type RSD_T_IOBJNM.

ls_attr-iobjnm = ‘ISTARTDAT’.
append ls_attr to lt_attr.

ls_pwbs_elemt-wbs_elemt = p_wbs.
ls_pwbs_elemt-/bic/istartdat = ‘19690301’.
append ls_pwbs_elemt to lt_pwbs_elemt.

CALL FUNCTION ‘RSDMD_WRITE_ATTRIBUTES_TEXTS’
EXPORTING
i_iobjnm                     = ‘0WBS_ELEMT’
i_tabclass                   = ‘M’
I_T_ATTR                     = lt_attr
*   I_S_MINFO                    =
*   I_REQUNR                     =
*   I_DATAPAKID                  =
*   I_MONITORING                 =
*   I_CREATE_STATISTICS          = RS_C_TRUE
IMPORTING
E_T_IDOCSTATE                = lt_idocstate
E_SUBRC                      = l_subrc
TABLES
i_t_table                    = lt_pwbs_elemt
EXCEPTIONS
ATTRIBUTE_NAME_ERROR         = 1
IOBJ_NOT_FOUND               = 2
GENERATE_PROGRAM_ERROR       = 3
OTHERS                       = 4.
.
IF sy-subrc <> 0.
* Implement suitable error handling here
exit.
ENDIF.

CALL FUNCTION ‘RSDMD_MD_ACTIVATE’
EXPORTING
i_chabasnm       = ‘0WBS_ELEMT’.

Integrate Planning – Characteristic Relationships – Exit

Char relationships template class = CL_RSPLS_CR_EXIT_BASE

Create method

The create method has to fill table e_th_chas with all admissible combinations for the given selection table i_tsx_seldr. Use the method seldr_to_range to convert i_tsx_seldr to a the format e_t_range which is similar to a standard ABAP range table.

CALL METHOD seldr_to_range
    EXPORTING
      i_tsx_seldr = i_tsx_seldr
    IMPORTING
      e_t_range   = lt_range.

The selection tables can be compared with the ‘where’ part of an SQL statement. So in general it is not ok to pick values from the selection table and to fill it to e_th_chas.

Infos:

1) characteristic relationships depend on the InfoCube, not on the aggregation level. This is the reason why per relation you have to choose the characteristics relevant for the relation. So you can (and should) use the minimal set of characteristics needed in the relation. The system automatically decides when a relation has to be called (based in the aggregation level used and the ‘list geometry in an input ready query).

2)

The create method will be called at run time whenever the system has to create the valid combinations (e.g. in some implementations of planning functions or in input ready queries when the setting ‘access mode for result values’ based on characteristic relationships is used). This does not affect invalid combinations, e.g. when these combinations exists on the DB.

When invalid combinations exist on DB then the system will read these combinations and will check these combinations (call the check method) and make the corresponding records not input ready. Usually one should delete invalid combinations with the corresponding planning function and then compress the cube with zero elemination.

Get size of database table via ABAP

Check program Check program RSTABLESIZE
or following code.

Update for BW74: FM ‘EM_GET_NUMBER_OF_ENTRIES’ import parameter has changed. see new code below.

Code up to BW 73

REPORT ZTEST_ILESH.

TABLES : DD02L.

SELECT-OPTIONS : S_TABLES FOR DD02L-TABNAME.

DATA : GT_TABROWS LIKE STANDARD TABLE OF DDCDIM,
       WA_TABROWS LIKE DDCDIM.

SELECT TABNAME
  FROM DD02L
  INTO CORRESPONDING FIELDS OF TABLE GT_TABROWS
  WHERE TABNAME IN S_TABLES.

CALL FUNCTION 'EM_GET_NUMBER_OF_ENTRIES'
  TABLES
    IT_TABLES = GT_TABROWS.

LOOP AT GT_TABROWS INTO WA_TABROWS.
  WRITE : / WA_TABROWS-TABNAME , WA_TABROWS-TABROWS.
ENDLOOP.

Code from BW74

Download – PROG_ZBC_CHECK_SYSTEM_TABLES_74.slnk] – 1.3 kB – 273   downloads

REPORT  ZBC_CHECK_SYSTEM_TABLES.

TABLES : DD02L.

SELECT-OPTIONS : S_TABLES FOR DD02L-TABNAME.

DATA : GT_TABROWS LIKE STANDARD TABLE OF DDCDIM,
       WA_TABROWS LIKE DDCDIM.

SELECT TABNAME
  FROM DD02L
  INTO CORRESPONDING FIELDS OF TABLE GT_TABROWS
  WHERE TABNAME IN S_TABLES.

CALL FUNCTION 'EM_GET_NUMBER_OF_ENTRIES'
  TABLES
    IT_TABLES = GT_TABROWS.

LOOP AT GT_TABROWS INTO WA_TABROWS.
  WRITE : / WA_TABROWS-TABNAME , WA_TABROWS-TABROWS.
ENDLOOP.

SAP Authorizations and Profiles handy reports

Report S_BCE_68001400 => Users by Complex Selection Criteria

Report S_BCE_68001415 => Authorizations by Complex Selection Criteria

Table AGR_PROF => Link between Generated profile and role.
List Users using a Composite roles => Table AGR_USERS => COL_FLAG <>’X’

Roles in Composite Role => Table AGR_AGRS

 

See also= http://wiki.sdn.sap.com/wiki/display/Security/Collection+of+SAP+Security+Tables

Pass BEx Variable values from a Query to other applications using EXPORT TO MEMORY

A simple way to communicate the values of the BEx variables for a BEx Query execution to some other application (another query, an ABAP program…), is to store these values in memory via the command EXPORT to MEMORY

here is a rough description of the development actions to perform to achieve this:

1) Create a user parameter ID in table TPARA => SM30, TPARA, maintain, enter on  empty field, create new… per query whose values you want to export.

2) Add code in ZXRSRU01 for  i_step = 3 for and i_s_rkb1d-compid = <name of the BEx query passing values>.

ex:

if i_step = 3.

case i_s_rkb1d-compid.

when <name of query>.

* <add here code to export parameters>

CALL FUNCTION ‘Z_EXPORT_ZXRSRU01_VALUES’
EXPORTING
i_t_var_range = i_t_var_range
i_parameter_id = ‘MYPARAMETER’.

* ________

endif.

3)  Create the following FM: Z_EXPORT_ZXRSRU01_VALUES. The function does the following:

– a) Generate a unique ID that will be used to identify the variables in the export memory.

– b) This UUID is stored in the user parameter created in step 1 (SET PARAMETER)

-c) Export to memory the whole table i_t_var_range

Example

“1st generate a UUID

DATA: system_uuid TYPE REF TO if_system_uuid,
uuid TYPE sysuuid_c32.

system_uuid = cl_uuid_factory=>create_system_uuid( ).

TRY.

GET  PARAMETER ID ‘ZIP_PS100_JUMP1’ FIELD uuid.
IF uuid IS NOT INITIAL.
DELETE FROM MEMORY ID uuid.
ENDIF.
uuid = system_uuid->create_uuid_c32( ).
” Export to memory
EXPORT p1 = i_t_var_range TO  MEMORY ID uuid.

” Set user related parameter ID to UUID
SET PARAMETER ID ‘ZIP_PS100_JUMP1’ FIELD uuid.

CATCH cx_uuid_error.
ENDTRY.

4) The receiving program should do the following:

DATA:
l_s_range TYPE rsr_s_rangesid,
l_t_var_range TYPE rrs0_t_var_range,
uuid TYPE sysuuid_c32.

FIELD-SYMBOLS:
<s_var_range> TYPE rrs0_s_var_range.

GET PARAMETER ID ‘MYPARAMETER’ FIELD uuid.

IF uuid IS NOT INITIAL.
IMPORT  p1 = l_t_var_range FROM  MEMORY ID uuid.
LOOP AT l_t_var_range ASSIGNING <s_var_range>.
l_s_range-sign = <s_var_range>-sign.
l_s_range-opt = <s_var_range>-opt.
l_s_range-low = <s_var_range>-low.
l_s_range-high = <s_var_range>-high.
APPEND l_s_range TO e_t_range.
ENDLOOP.

ENDIF.