Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
0 Kudos

Introduction

After running a BW-system for several years, there will be many InfoProviders where you are not sure if they are really being used by BEx Queries. But every time you have to modify or would like to replace the InfoProvider, you will have to edit the Multiprovider in which the Infoprovider is included.

A good option would be to remove the (unused) Infoprovider from the Multiprovider (where it won’t be called at query runtime to read data).

It would take a lot of time to check every query (based on the Multiprovider in which the Infoprovider is included). Therefore, it would be better to check the BW metadata tables via an ABAP program.


Checking Multiprovider and their queries

In order to determine the usage of a part provider in a query, we will have to

  • get the mapped key figures of the Infoprovider within the Multiprovider
  • check if these keyfigures are used in BEx queries/key figures (and no other PartProvider is filtered there)
  • find out if the filter at 0INFOPROV (in restricted key figure) is set to the PartProvider (“Fitting IP-Sel.?”=Y)


Instructions for use:

  • You can use single values, intervals or ranges (e.g. T*) on the selection screen; cubes and DSOs can also be used simultaneously.

Selection-Screen: Example with three InfoProvider (to check for usage)

The result is split into the

  • Usage of every Infoprovider within a  Multiprovider
    • “Keyf.incl.?” (=Key figure included?): set to X if one key figure of the PartProvider is used in the shown query/structure/key figure (“Mapname”)
    • “IP-Sel.?”(=Infoprovider selection existing?): X will be shown in this column when the global BEx element (“Mapname”) includes a selection of “0INFOPROV”
    • “Fitting IP-Sel.?” (=Fitting 0INFOPROV Selection?): In addition to “IP-Sel.?”, this field will be marked if the 0INFOPROV selection includes the shown Part cube/Provider (e.g. 0INFOPROV=TCHC001)
  • When there are no queries or other global BEx elements based on the resp. Multiprovider, there will be no entries at the details (e.g. Multiprovider: TCGMZ001)
  • At the chapter “==> LIST OF RESULTS:”, the aggregation of the detailed results from before will be displayed. The PartProvider which are not used in the respective Multiprovider (Used?=N) can be  removed from the Multiprovider (from a technical perspective).


  • List of Providers without any Multiprovider inclusion
    • Are these Providers still relevant or can they be deleted? 

Results: Example with three InfoProvider (to check for usage)


Summary

With the two lists (“LIST OF RESULTS:” / “CUBES WITHOUT MULTIPROVIDER INCLUSION”) you know which Infoprovider is not used by BEX elements within the resp. Multiprovider or that this Infoprovider is not used by any Multiprovider at all.

Please note that the program is only fitting for InfoCubes/DSOs within a Multiprovider and that it is not used for aggregation levels, planning functions or Composite Providers.




CODING

*&---------------------------------------------------------------------*
*& Report  ZBI_BEX_PARTCUBES_UNUSED
*&---------------------------------------------------------------------*
*& Created by/on: C. Heinrich - (11.02.2016)
*& Targets:
*& A) check usage of Cubes/DSO, included in Multiprovider, in queries
*&    and global BEx-elements (e.g. restricted key-figures)
*& B) also show Provider, which are not included in any Multiprovider
*& Additions:
*&  -> beside (all types of) Cubes, also DSOs are supported
*&---------------------------------------------------------------------*
REPORT ZBI_BEX_PARTCUBES_UNUSED LINE-SIZE 160 NO STANDARD PAGE HEADING.

TABLES: RSDCUBET.

**** Variables, internal tables
DATA: BEGIN OF ls_mpro,  " List of MultiProvider
        INFOCUBE TYPE RSINFOPROV,
        PARTCUBE TYPE RSINFOPROV,
        USED(1) TYPE C,
       END OF ls_mpro,
       lt_mpro LIKE STANDARD TABLE OF ls_mpro.
DATA: BEGIN OF ls_keyf, " List of found key-figures
        INFOCUBE TYPE RSINFOPROV,
        PARTCUBE TYPE RSINFOPROV,
        IOBJNM  TYPE RSIOBJNM,
       END OF ls_keyf,
       lt_keyf LIKE HASHED TABLE OF ls_keyf
         WITH UNIQUE KEY INFOCUBE IOBJNM PARTCUBE.
DATA: BEGIN OF ls_compic, " List of queries/elements to MultiProvider
         COMPUID TYPE SYSUUID_25,
         MAPNAME TYPE RSZCOMPID,
         INFOCUBE TYPE RSINFOPROV,
         PARTCUBE TYPE RSINFOPROV,
         FLAG_KEYF(1) TYPE C,     " key-f. of part-cube included(=X)?
         FLAG_SEL_IC(1) TYPE C,   " selection at 0INFOPROV exists? (Y/N)
         FLAG_PARTCUBE(1) TYPE C, " selection at corret part-cube (=Y)?
       END OF ls_compic,
       lt_compic LIKE STANDARD TABLE OF ls_compic.
DATA: lv_used(1) TYPE c.
*** Field-symbols:
FIELD-SYMBOLS: <fs_mpro> LIKE ls_mpro,
                <fs_compic> LIKE ls_compic,
                <fs_keyf> LIKE ls_keyf.

**** A) Selection-screen
SELECTION-SCREEN: BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
   SELECT-OPTIONS: S_CUBE FOR RSDCUBET-INFOCUBE OBLIGATORY.
SELECTION-SCREEN: END OF BLOCK b1.


*** B) Checking usage of Partprovider(s):
START-OF-SELECTION.

    " --> getting list of Multiprovider, including the Cube(s):
    SELECT RSDCUBEMULTI~INFOCUBE RSDCUBEMULTI~PARTCUBE
      FROM RSDCUBEMULTI
      INTO CORRESPONDING FIELDS OF TABLE lt_mpro
      WHERE RSDCUBEMULTI~OBJVERS = 'A'
        AND RSDCUBEMULTI~PARTCUBE IN S_CUBE.

    SKIP 1. FORMAT INTENSIFIED ON.
    WRITE: / '==> CHECK PER MULTI-PROVIDER AND GLOBAL BEX-ELEMENT:'.
    FORMAT INTENSIFIED OFF.
    LOOP AT lt_mpro ASSIGNING <fs_mpro>.
      " Header: Multiprovider / Part-Cube
      WRITE: / 'Multiprovider: ', <fs_mpro>-INFOCUBE,
               50 'Partprov.: ', <fs_mpro>-PARTCUBE.
      " --> get key-figures of part-cube which are included at the Multiprovider(s):
      SELECT RSDICMULTIIOBJ~INFOCUBE RSDICMULTIIOBJ~IOBJNM
             RSDICMULTIIOBJ~PARTCUBE
        FROM RSDICMULTIIOBJ INNER JOIN RSDIOBJ
          ON RSDICMULTIIOBJ~PARTIOBJ = RSDIOBJ~IOBJNM
         AND RSDICMULTIIOBJ~OBJVERS = RSDIOBJ~OBJVERS
        INTO CORRESPONDING FIELDS OF TABLE lt_keyf
        WHERE RSDICMULTIIOBJ~INFOCUBE = <fs_mpro>-INFOCUBE
          AND RSDICMULTIIOBJ~PARTCUBE = <fs_mpro>-PARTCUBE
          AND RSDICMULTIIOBJ~OBJVERS = 'A'
          AND RSDIOBJ~IOBJTP = 'KYF'.

***   --> now get queries and other BEx-elements similar to restricted key-figures
***       and structures, containing the key-figure(s) of the Partprovider(s):
       SELECT COMPUID MAPNAME INFOCUBE
         FROM RSZCOMPIC INNER JOIN RSZELTDIR
           ON RSZCOMPIC~COMPUID = RSZELTDIR~ELTUID
          AND RSZCOMPIC~OBJVERS = RSZELTDIR~OBJVERS
         INTO CORRESPONDING FIELDS OF ls_compic
         WHERE RSZCOMPIC~INFOCUBE = <fs_mpro>-INFOCUBE
           AND RSZCOMPIC~OBJVERS = 'A'.
         ls_compic-PARTCUBE = <fs_mpro>-PARTCUBE.
         APPEND ls_compic TO lt_compic.
       ENDSELECT.

       " every BEx-component should be checked downwards (recursively),
       " if one of the relevant key-figures is used and the Infoprovider (0INFOPROV)-
       " selection could cover also the part-cube(s):
       WRITE: / 'MultiProvider', 25 'Part-Cube', 40 'Mapname',
                85 'Keyf.incl?', 100 'IP-Sel.?', 110 'Fitting IP-Sel.?'.
       WRITE: / '------------------------------------------------------------' &
                '-------------------------------------------------------------' &
                '-----'.

       lv_used = 'N'. " Start with "is used"=no
       " check every query/key-figure for usage
       LOOP AT lt_compic ASSIGNING <fs_compic>.

           PERFORM CHECK_BEX_ELEMENT_RECURSIVE USING <fs_compic>-COMPUID
                                               CHANGING <fs_compic>.
           IF <fs_compic>-FLAG_KEYF = 'X' AND ( <fs_compic>-FLAG_PARTCUBE = 'Y'
                                              OR <fs_compic>-FLAG_SEL_IC <> 'Y' ).
              lv_used = 'Y'. " is used=yes
           ENDIF.
           WRITE: / <fs_compic>-INFOCUBE,     25 <fs_compic>-PARTCUBE,
                 40 <fs_compic>-MAPNAME,      85 <fs_compic>-FLAG_KEYF,
                 100 <fs_compic>-FLAG_SEL_IC, 110 <fs_compic>-FLAG_PARTCUBE.
       ENDLOOP.
       <fs_mpro>-USED = lv_used.
       SKIP.
    ENDLOOP.


*** C) Log at end of run:
     SKIP 3.
     ULINE.
     " C1. List of partprovider(s) usage
     FORMAT INTENSIFIED ON. WRITE: / '==> LIST OF RESULTS: '. FORMAT INTENSIFIED OFF.
     WRITE: / 'Multiprovider', 30 'Infocube', 50 'Used?'.
     WRITE: / '---------------------------------------------------------'.
     LOOP AT lt_mpro ASSIGNING <fs_mpro>.
       WRITE: / <fs_mpro>-INFOCUBE, 30 <fs_mpro>-PARTCUBE,
               50 <fs_mpro>-USED.
     ENDLOOP.
     SKIP 3.
     " C2. List of not-anywhere used part-cubes
     WRITE: / '--------------------------------------------------------------------------------'.
     FORMAT INTENSIFIED ON. WRITE: / '==> CUBE´S WITHOUT MULTIPROVIDER-INCLUSION: '.
     FORMAT INTENSIFIED OFF.
     PERFORM MISSING_CUBES.






*************************************************************************************
* Form CHECK_BEX_ELEMENT_RECURSIVE
* Key-figure and selection to 0INFOPROV will be checked by every BEx-element down-
* wards (form in recursive mode)
*************************************************************************************
FORM CHECK_BEX_ELEMENT_RECURSIVE USING I_ELTUID TYPE SYSUUID_25
                                  CHANGING C_COMPIC LIKE LS_COMPIC.
      DATA: BEGIN OF ls_range,  " entry at RSZRANGE
              IOBJNM TYPE RSIOBJNM,
               SIGN TYPE RALDB_SIGN,
               OPT  TYPE RSZ_OPERATOR,
               LOW  TYPE RSCHAVL,
               HIGH TYPE RSCHAVL,
            END OF ls_range.
      DATA: lv_eltuid TYPE SYSUUID_25.

      " Selection of Partprovider (at 0INFOPROV) or relevant key-figure present?
      " e.g. RSZRANGE-IOBJNM = '1KYFNM' plus RSZRANGE-LOW = 'MyKeyfigure'
      " or   RSZRANGE-IOBJNM = '0INFOPROV' plus RSZANGE-LOW = 'MyCube'
      SELECT IOBJNM SIGN OPT LOW HIGH FROM RSZRANGE
        INTO CORRESPONDING FIELDS OF ls_range
        WHERE ELTUID = I_ELTUID
          AND OBJVERS = 'A'
          AND IOBJNM IN ('1KYFNM', '0INFOPROV').
        IF ls_range-IOBJNM = '1KYFNM'.
           READ TABLE lt_keyf ASSIGNING <fs_keyf>
             WITH KEY INFOCUBE = C_COMPIC-INFOCUBE
                      IOBJNM = ls_range-LOW
                      PARTCUBE = C_COMPIC-PARTCUBE.
           IF sy-subrc = 0. " Key-figure of Part-Provider used at query!
              C_COMPIC-FLAG_KEYF = 'X'.
           ENDIF.
        ELSEIF ls_range-IOBJNM = '0INFOPROV'. " Selection at Infoprovider exists
           C_COMPIC-FLAG_SEL_IC = 'Y'.
           IF ls_range-SIGN = 'I' AND ls_range-OPT = 'EQ'. " Single value
             IF ls_range-LOW = C_COMPIC-PARTCUBE. " Selection to fitting part-cube exists
                 C_COMPIC-FLAG_PARTCUBE = 'Y'.
             ENDIF.
           ELSEIF ls_range-SIGN = 'I' AND ls_range-OPT = 'BT'. " Interval
             IF ls_range-LOW <> ''
               AND C_COMPIC-PARTCUBE BETWEEN ls_range-LOW AND ls_range-HIGH.
                 C_COMPIC-FLAG_PARTCUBE = 'Y'.
             ENDIF.
           ENDIF.
        ENDIF.
      ENDSELECT.

     " further check sub-elements of current BEx-element:
     SELECT TELTUID FROM RSZELTXREF INTO lv_eltuid
       WHERE SELTUID = I_ELTUID
         AND OBJVERS = 'A'.

       PERFORM CHECK_BEX_ELEMENT_RECURSIVE USING lv_eltuid
                                           CHANGING C_COMPIC.
     ENDSELECT.

ENDFORM.

*************************************************************************************
* Form MISSING_CUBES
* Some part-cube(s) not found in any Multiprovider? To this case, there should also
* a list be generated and shown
*************************************************************************************
FORM MISSING_CUBES.
   DATA: BEGIN OF ls_cube,
           INFOCUBE TYPE RSINFOCUBE, " Cube-Name
           CUBETYPE TYPE RSCUBETYPE, " Cube-/DSO-type
           TXTLG TYPE RSTXTLG, " Infoprovider-Text
         END OF ls_cube,
         lt_cube LIKE STANDARD TABLE OF ls_cube.
   FIELD-SYMBOLS: <fs_cube> LIKE ls_cube.
   " first get all cube(s) to selection:
   SELECT RSDCUBE~INFOCUBE RSDCUBE~CUBETYPE RSDCUBET~TXTLG
     FROM RSDCUBE INNER JOIN RSDCUBET
       ON RSDCUBE~INFOCUBE = RSDCUBET~INFOCUBE
      AND RSDCUBE~OBJVERS = RSDCUBET~OBJVERS
     INTO CORRESPONDING FIELDS OF TABLE lt_cube
     WHERE RSDCUBE~INFOCUBE IN S_CUBE
       AND RSDCUBE~OBJVERS = 'A'
       AND RSDCUBE~CUBETYPE <> 'M' " MPro not relevant
       AND RSDCUBET~LANGU = sy-langu.

   " also, add DSO to the selection:
   SELECT RSDODSO~ODSOBJECT AS INFOCUBE RSDODSO~ODSOTYPE AS CUBETYPE
          RSDODSOT~TXTLG AS TXTLG
     FROM RSDODSO INNER JOIN RSDODSOT
       ON RSDODSO~ODSOBJECT = RSDODSOT~ODSOBJECT
      AND RSDODSO~OBJVERS = RSDODSOT~OBJVERS
     APPENDING CORRESPONDING FIELDS OF TABLE lt_cube
     WHERE RSDODSO~ODSOBJECT IN S_CUBE
       AND RSDODSO~OBJVERS = 'A'
       AND RSDODSOT~LANGU = sy-langu.

   " now check cube(s) at multiprovider assignments:
   LOOP AT LT_CUBE ASSIGNING <fs_cube>.
     READ TABLE lt_mpro TRANSPORTING NO FIELDS
       WITH KEY PARTCUBE = <fs_cube>-INFOCUBE.
     IF sy-subrc = 0. " Cube is included in one multi-provider, no entry necessary
        <fs_cube>-INFOCUBE = 'DELETE'.
     ELSE.
        CASE <fs_cube>-CUBETYPE.
          WHEN '' OR ' ' OR 'T' OR 'W'. "=DSO
            WRITE: / 'DSO  ', <fs_cube>-INFOCUBE, 18 '/', <fs_cube>-TXTLG, 80 ' not included in any Multiprovider!'.
          WHEN OTHERS.
            WRITE: / 'Cube ', <fs_cube>-INFOCUBE, 18 '/', <fs_cube>-TXTLG, 80 ' not included in any Multiprovider!'.
        ENDCASE.
     ENDIF.
   ENDLOOP.
   DELETE LT_CUBE WHERE INFOCUBE = 'DELETE'.


ENDFORM.

Labels in this area