Category Archives: SAP BI IP

RSDMD_DEL_BACKGROUND and Transactional Infocubes

Program RSDMD_DEL_BACKGROUND is used to delete MD in BW. This program can be included in a PC to regularly clean up the “unused” master data entries of a characteristic. By unused we mean those entries whose SID is not referenced in any InfoProvider.

If you schedule such deletions on a characteristic that is used in a Transactional Infocube you might experience errors when there is an open (tellow) request in the Transactional Infocube.

Note “Note 1258548 – Master data cannot be deleted” expalis this.

One solution to this is probably to switch to load mode before running the deletion.


BI IP – Locking

928044 – BI lock server

LiveCache was an option until before BW 7.30. SAP has removed the option since 7.3 (1531412 – liveCache as BW lock server)

Message RSPLS 091 “Overloading of lock server for InfoProvider “ occurs when executing planning sequences via process chains. Note 928044 explains that you need to set the parametes “Lock Attemps” and “Wait Time in Seconds” on RSPLSE + enter ok_code EXPERT.

This error might be related to the following program error: 1911227 – Planning sequences in process chains and BW lock server

When “Lock Attempts” and “Wait Time in Seconds” have not been manually set, some default value is used. Note 994239 – BI lock server: Message RSPLS091 seems to indicate that the default wait time is 1 (or 3 seconds as of BW700?).

Check table RSPLS_LOCK_METHS, Fields ABAP_WAIT and ENQSER_REQ. (Only 1 record in table).


Delete all locks to Planning Cube via BEx Workbook


In our planning application we give the central controller the possibility of deleting all locks to the Planning Infocube to prepare for some central functions (as central settlement of all WBSs, or central version copy).

Here is how we proceed.

1) Create a Custom Planning Function type. This planning function type does nothing to the data it receives, but instead removes all locks on the desired Infoprovider. See below the code for the EXECUTE Method and the Settings for the PF Type. Note that the Planning Function has 1 parameter which is the name of the Infoprovider to be unlocked.

2) Create a Planning Function on any Aggregation Level not related to the Planning Cube that you wish to unlock. (Otherwise, the unlock Function might fail due to  locking conflicts with the locks it aims to clear!!).  Assign a BEx Variable of type Char, Single Value, Mandatory initial not allowed, on 0INFOPROV to the input parameter.

3) Create a filter in such a way that it will always return at least 1 record (otherwise the Planning Functions EXECUTE method will not be called).

4) Create a Planning Sequence on the Aggregation Level above, using the filter and the planning function.

5) Call the Planning Sequence from a BEx Command Button in the BEx Workbook. The button should contain the following command sequence.
PLANNING_SEQUENCE_NAME 1 <name of the Planning Sequence>
VAR_1_NAME    1  <name of variable on 0INFOPROV>
VAR_1_VALUE   1  <name of Infoprovider to unlock>

Settings for the planning function in RSPLF1

Properties Tab
- Without blocks
- Hide Column of Chars. To Be Changed
Parameter Tab
Parameter = INFOPROV / Description = INFOPROV
Parameter Type = Elementary
InfoObject = 0INFOPROV
Variables Allowed => Checked.

Code for the EXECUTE method of the planning function

method if_rsplfa_srvtype_imp_exec~execute.

*               DECLARATIONS

        l_r_param type ref to if_rsplfa_param_elem,
        l_infoprov type rsinfoprov.

        l_msgv type symsgv,
        log_handle type balloghndl,
        t_log_handle type bal_t_logh,
        log type bal_s_log,
        log_msg type bal_s_msg.

*               LOGIC
  "Log some infos

        <s_data_charsel> type rsplf_s_charsel.

  log-extnumber = 'Infrabel IP Logging'.
  log-object  = 'ZIIP'.
  log-subobject = 'ZIIP'.
  log-aldate = sy-datum.
  log-altime = sy-uzeit.
  log-aluser    = sy-uname.
  log-alprog    = sy-repid.
  call function 'BAL_LOG_CREATE'
      i_s_log      = log
      e_log_handle = log_handle
      others       = 1.

  " Get number of periods to be closed via parameter 'PERIODS' type FISCPER3
  l_r_param = i_r_param_set->get_param_elem( 'INFOPROV' ).
  l_r_param->get_value( importing e_value = l_infoprov ).

  concatenate 'Remove all user locks to: ' l_infoprov into l_msgv.
  log_msg-msgty     = 'I'.
  log_msg-msgid     = 'ZIIP'.
  log_msg-msgno     = '000'.
  log_msg-msgv1     = l_msgv.  " set to Planning Function
  log_msg-msgv2     = ''.  " set to value of filter
  log_msg-msgv3     = ''.  " set to planning sequence if any
  log_msg-msgv4     = ''.  " planning function step

  call function 'BAL_LOG_MSG_ADD'
      i_log_handle     = log_handle
      i_s_msg          = log_msg
      log_not_found    = 1
      msg_inconsistent = 2
      log_is_full      = 3
      others           = 4.

  append log_handle to t_log_handle.
  call function 'BAL_DB_SAVE'
      i_t_log_handle = t_log_handle.

  data: t_enq    type standard table of seqg3,
        t_enq_f  type standard table of seqg3,
        w_eng    type seqg3,
        v_result type sy-subrc,
        v_cube   type char30.

  refresh: t_enq_f,

  move l_infoprov to v_cube.

  call function 'ENQUEUE_READ'
      gclient                     = sy-mandt
      gname                       = 'RSPLS_S_LOCK'
*   GARG                        = ' '
      guname                      = ''
*   LOCAL                       = ' '
*   FAST                        = ' '
*   NUMBER                      =
*   SUBRC                       =
      enq                         = t_enq
*   SYSTEM_FAILURE              = 2
*   OTHERS                      = 3
  if sy-subrc = 0
     and t_enq[] is not initial.

    if v_cube ne space.
      loop at t_enq into w_eng.
        if w_eng-garg cs v_cube.
          append w_eng to t_enq_f.
      t_enq_f[] = t_enq[].

    if not t_enq_f[] is initial.
      call function 'ENQUE_DELETE'
          check_upd_requests    = 0
          suppress_syslog_entry = ' '
          subrc                 = v_result
          enq                   = t_enq_f.


BEx Workbook – Popup to pass values to Planning Function


Below are the information I gathered regarding techniques to allow some kind of dynamic selection of values to be passed to Planning Functions.

1) See note 1121654 – Note 1121654 – Problems transferring variables to planning func/sequence

2) Extract from a SDN Discussion:
Iin BEx workbook there is no Possibility to call an automatic pop up for variables in planning functions. The functions in BEx Workbook take the entries from cells like described in the notes. If you want to give the user more usability with pop-ups then you have to program VBA coding which writes the entry in the VBA pop up in the cell from which the planning function take the entry and then call the planning function from VBA code
1.) You have your button for the planing function and the command range for the variables. Let’s assume the variable value is in Cell D4. The name of the planning function is BUTTON_34 (you see that in the properties window of the BEX Button. You can implment the command range in the button in an extra sheet and then hide it.

2.) On the sheet with your query or cockpit (from where you want to run the planning function) you implement a second button – but not from the BEx menubar, from the VBA forms. Then you assign a VBA macro to this button.
3.) in this button you have to:
 a.) call a Msgbox for prompt asking for the value of the period
 b.) assign the value entered from the user to CELL D4 in the hidden sheet
 c.) run the planning funtion button in the hidden Sheet

A sample coding could look something like this:

Public sub Call_Funtion()

Dim Useranswer as string

Useranswer = InputBox("Please enter the period in the format MM/YYYY", "Period")

Table1.Range(D4).Value = Useranswer


Application.Run "'" & ThisWorkbook.Name & "'!TABLE1.BUTTON_34_Click

end sub

This should do fine. If you are more experienced in VBA you can design a form with more input fields. It would look more comofortable for the user. But to explain this how to do it would be done in a different board.

See original post:
If you do not have a single value variable but an interval the command range must look like this:

VAR_NAME_3                       1               MY_VAR_SO_TO
VAR_VALUE_LOW_EXT_3     1               04.2003 (Your Start value)
VAR_SIGN_3                         1               I
VAR_OPERATOR_3               1               BT
VAR_VALUE_HIGH_EXT_3     1               06.2003 (Your End value)

In the VBA code you then have to call 2 Propmts for input – one for start, one for end or you design a form if you are experienced. Then you assign the entered values to the ranges and call the buttoon via

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
      i_tsx_seldr = i_tsx_seldr
      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.


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).


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.

SAP BI IP – Data Slices

Data Slices and Performance =>

Char Derivation and Perf =

BPS Planning Function Exit Article ->

How to use BPS and Business Intelligence Integrated Planning in Parallel – Data Slices and Characteristic Relations (NW7.0) –

Custom IP Planning Function Types

Read c_th_data record

you can still use read table with key. The trick is to copy the values from the block characteristics I_S_BLOCK_LINE into a structure your ls_data and change and adapt the structure according to your needs. Then you can use  the read table into ls_data2 from ls_data. This way it will work.  < add example>

You can find an example e.g. in CL_RSPLFC_DISTR_KEY method IF_RSPLFA_SRVTYPE_IMP_EXEC~EXECUTE. Add the end of the code p_r_distribution->distribute is called. In this method you can find an example:

READ TABLE c_th_data ASSIGNING <s_data2> FROM <s_distr_data>.

So you are using the hashed key and fill the values you are looking for into  <s_distr_data>.

Reference data

Messages in Planning Function Type methods
See note 1815440 – Planning funtion relevant information messages are suppressed in BW 7.3x and not suppressed in BW 7.0x

See SCN forum post on the subject

Just create a Message and use the method i_r_msg->add_msg( ) to return it.

E,A,X messages are always displayed on the Web or BEx Analyzer. Other messages are suppressed by default as of BW 7.3 , unless you flag them as problem class “Very High”. This works as of SP7 or via Note 1653610.

To flag a message as “Very High” pass ‘1’ as parameter in the add_msg method

Error message:

MESSAGE E001(rsplf) WITH l_msg INTO l_msg.
i_r_msg->add_msg( ).  " No need to mention problem class

Warning or info message

MESSAGE W001(rsplf) WITH l_msg INTO l_msg.
i_r_msg->add_msg( '1'  ).  " Mention '1' as problem class
MESSAGE I001(rsplf) WITH l_msg INTO l_msg.
i_r_msg->add_msg( '1'  ).  " Mention '1' as problem class

Passing parameters

Elementary Types:

Example: Passing a 0VERSION value via a BEx variable.

1) In RSPLF1 / Parameter: create a parameter: parameter = VERSION, description = Version, parameter type = Elementary
Structure Parameters = leave empty, Parameter is Tabluar = unchecked, InfoObject = 0VERSION, Copy InfoObject Text = unchecked
Internal Default Val = leave empty, Variables allowed = checked

2) Create a PF using the planning function type. Assign a version value or a variable

3) In the code of the Planning Function Type class  ( in execute method for example)

l_r_version type ref to if_rsplfa_param_elem,
l_version type /bi0/oiversion.

" Get version from parameter elementary "VERSION"
l_r_version = i_r_param_set->get_param_elem( 'VERSION' ).
l_r_version->get_value( importing e_value = l_version ).


  1. Use i_r_infoprov object. Get the list of objects with  methods get_infoprov , get_t_charnm and get_t_keyfnm of i_r_infoprov_desc.  See CL_INM_FUNC_TYPE_CALC_PRODCOST->INIT_EXECUTION as example.
  2. Use i_r_msg. Returns  error messages in object i_r_msg.  See CL_INM_FUNC_TYPE_CALC_PRODCOST->INIT_EXECUTION as example.
  3. Use i_r_srv object. Provides info on the calling planning function via methods below. Check CL_INM_FUNC_TYPE_DEL_LCKD_VERS as example.
  • i_r_srv->get_name()
  • i_r_srv->GET_TEXT()
  • i_r_srv->GET_SRVTYPENM()
  • i_r_srv->GET_INFOPROV()
  • i_r_srv->GET_TAB_CHAR_USAGE()
  • i_r_srv->GET_PARAM_SET_RULES()
  • i_r_srv->GET_ADMIN_INFO()
  • lt_param_set_rules = i_r_srv->get_param_set_rules( ).
    lr_param_set = ls_param_set_rule-r_param_set.
    lt_param_keyfigures = lr_param_set->get_tab_param_struc( ‘KEYFIGURES’ ).
    lr_param_target_data_sel = lr_param_set->get_param_data_sel(‘CHA_VALUES’).

Use i_r_infoprov.

METHOD if_rsplfa_srvtype_imp_exec~init_execution.
mv_execute_pf = abap_true.
mv_infoprovider = i_r_infoprov_desc->get_infoprov( ).
mt_charnm = i_r_infoprov_desc->get_t_charnm( ).
mt_keyfnm = i_r_infoprov_desc->get_t_keyfnm( ).

* Make sure all necessary Characteristics are provided by the InfoProvider:
is_cha_included( iv_cha = '0MATERIAL' ir_msg = i_r_msg ).
is_cha_included( iv_cha = '0INM_PQUNIT' ir_msg = i_r_msg ).
is_cha_included( iv_cha = '0UNIT' ir_msg = i_r_msg ).

* Make sure all necessary Keyfigures are provided by the InfoProvider:
is_kyf_included( iv_kyf = '0AMOUNTFX' ir_msg = i_r_msg ).
is_kyf_included( iv_kyf = '0AMOUNTVR' ir_msg = i_r_msg ).
is_kyf_included( iv_kyf = '0INM_PDQTY' ir_msg = i_r_msg ).
is_kyf_included( iv_kyf = '0INM_PDCOST' ir_msg = i_r_msg ).
is_kyf_included( iv_kyf = '0INM_LOTSIZ' ir_msg = i_r_msg ).


Use i_r_msg.

data: lv_dummy type char100.
WITH iv_cha mv_infoprovider
INTO lv_dummy.
ir_msg->add_msg( ).