In this blog post, I propose a little program to detect all DDIC structures and tables with invalid Enhancement Categories. It’s largely inspired by the SAP program Z_CHECK_ENH_CAT provided in the note 2205573 – Checking enhancement category for data dictionary objects with SAP tool, but this SAP program is to analyze just one given DDIC structure or table at a time.

The reason why I created this program was that after adding few more possible values to a custom DDIC domain and activating it, the activation log reported few standard DDIC structures with syntax errors, especially the DDIC structure PSHLP_CUSTFLDS_NTWK_ST. A check on it:
DDIC%20Structure%20check%20error

DDIC Structure check error

A fix is proposed by the note 1834868 – PSHLP: Syntax error in Customer field structures of HLP which consists in adjusting the Enhancement Category via SE11 > menu option Extras > Enhancement Category.

This syntax error didn’t seem to be a problem in production, but maybe this structure was actually never used. I created a little test program to use that DDIC structure, the program could activate, only a warning was reported by the Extended Check (SLIN).

I don’t know why it wasn’t detected earlier, so maybe we had other DDIC tables and structures in the same situation. It’s why I decided to extend the SAP program to detect all of them.

I named this custom program Z_CHECK_ENH_CAT_ALL.

The selection screen takes as input a list of packages, so you can type Z* to analyze all DDIC tables and structures which contain custom objects:

Selection%20screen%20of%20Z_CHECK_ENH_CAT_ALL

Selection screen of Z_CHECK_ENH_CAT_ALL

The result shows all analyzed DDIC tables and structures.

Just search “FAIL” to directly go to the errors.

Result%20of%20Z_CHECK_ENH_CAT_ALL

Result of Z_CHECK_ENH_CAT_ALL

In the example above, you can see that the Enhancement Category of ZBAPI_TE_DPR_PHASE is inconsistent. It’s because it includes BAPI_TE_DPR_PHASE whose Category is Can be Enhanced (without restriction), so ZBAPI_TE_DPR_PHASE Category should also be Can be Enhanced (at the time of the run it was Extensible alpha and numeric).

 

I hope this will help.

 

Source code (compiled and used on 7.40 SP08):

*This program extends z_check_enh_cat of note 2205573, copyright SAP.
*https://launchpad.support.sap.com/#/notes/2205573
*2205573 - Checking enhancement category for data dictionary objects with SAP tool

REPORT z_check_enh_cat_all LINE-SIZE 500.

TABLES tdevc.
SELECT-OPTIONS: s_devcl FOR tdevc-devclass DEFAULT 'Z*' OPTION CP.

TYPES: ty_tables TYPE STANDARD TABLE OF tabname WITH DEFAULT KEY.

TYPES:
  BEGIN OF ty_include,
    precfield TYPE char30,
    fieldname TYPE char30,
    rollname  TYPE char30,
  END OF ty_include,

  BEGIN OF ty_message,
    precfield TYPE char200,
  END OF ty_message.

DATA: g_wa_message TYPE ty_message,
      gt_message   TYPE TABLE OF ty_message,
      gv_deep      TYPE n.

START-OF-SELECTION.
  PERFORM main.

FORM main.

* 1. FIND ALL TABLES AND STRUCTURES TO BE CHECKED

  " starting from data elements
  SELECT dd03l~tabname
    FROM       tadir
    INNER JOIN tdevc   ON tdevc~devclass = tadir~devclass
    INNER JOIN dd03l   ON dd03l~rollname  = tadir~obj_name
                      AND dd03l~as4local  = 'A'
                      AND dd03l~as4vers   = 0
    WHERE tadir~devclass IN @s_devcl
      AND tadir~pgmid  = 'R3TR'
      AND tadir~object = 'DTEL'
  UNION
  SELECT dd03l_2~tabname
    FROM       tadir
    INNER JOIN tdevc   ON tdevc~devclass = tadir~devclass
    INNER JOIN dd03l   ON dd03l~rollname  = tadir~obj_name
                      AND dd03l~as4local  = 'A'
                      AND dd03l~as4vers   = 0
    INNER JOIN dd03l   AS dd03l_2
                       ON dd03l_2~precfield = dd03l~tabname
                      AND dd03l_2~fieldname LIKE '.INCLU%'
                      AND dd03l_2~as4local  = 'A'
                      AND dd03l_2~as4vers   = 0
    WHERE tadir~devclass IN @s_devcl
      AND tadir~pgmid  = 'R3TR'
      AND tadir~object = 'DTEL'
  UNION
  SELECT dd03l_3~tabname
    FROM       tadir
    INNER JOIN tdevc   ON tdevc~devclass = tadir~devclass
    INNER JOIN dd03l   ON dd03l~rollname  = tadir~obj_name
                      AND dd03l~as4local  = 'A'
                      AND dd03l~as4vers   = 0
    INNER JOIN dd03l   AS dd03l_2
                       ON dd03l_2~precfield = dd03l~tabname
                      AND dd03l_2~fieldname LIKE '.INCLU%'
                      AND dd03l_2~as4local  = 'A'
                      AND dd03l_2~as4vers   = 0
    INNER JOIN dd03l   AS dd03l_3
                       ON dd03l_3~precfield = dd03l_2~tabname
                      AND dd03l_3~fieldname LIKE '.INCLU%'
                      AND dd03l_3~as4local  = 'A'
                      AND dd03l_3~as4vers   = 0
    WHERE tadir~devclass IN @s_devcl
      AND tadir~pgmid  = 'R3TR'
      AND tadir~object = 'DTEL'
  " starting from domains
  UNION
  SELECT dd03l~tabname
    FROM       tadir
    INNER JOIN tdevc   ON tdevc~devclass = tadir~devclass
    INNER JOIN dd03l   ON dd03l~domname   = tadir~obj_name
                      AND dd03l~as4local  = 'A'
                      AND dd03l~as4vers   = 0
    WHERE tadir~devclass IN @s_devcl
      AND tadir~pgmid  = 'R3TR'
      AND tadir~object = 'DOMA'
  UNION
  SELECT dd03l_2~tabname
    FROM       tadir
    INNER JOIN tdevc   ON tdevc~devclass = tadir~devclass
    INNER JOIN dd03l   ON dd03l~domname   = tadir~obj_name
                      AND dd03l~as4local  = 'A'
                      AND dd03l~as4vers   = 0
    INNER JOIN dd03l   AS dd03l_2
                       ON dd03l_2~precfield = dd03l~tabname
                      AND dd03l_2~fieldname LIKE '.INCLU%'
                      AND dd03l_2~as4local  = 'A'
                      AND dd03l_2~as4vers   = 0
    WHERE tadir~devclass IN @s_devcl
      AND tadir~pgmid  = 'R3TR'
      AND tadir~object = 'DOMA'
  UNION
  SELECT dd03l_3~tabname
    FROM       tadir
    INNER JOIN tdevc   ON tdevc~devclass = tadir~devclass
    INNER JOIN dd03l   ON dd03l~domname   = tadir~obj_name
                      AND dd03l~as4local  = 'A'
                      AND dd03l~as4vers   = 0
    INNER JOIN dd03l   AS dd03l_2
                       ON dd03l_2~precfield = dd03l~tabname
                      AND dd03l_2~fieldname LIKE '.INCLU%'
                      AND dd03l_2~as4local  = 'A'
                      AND dd03l_2~as4vers   = 0
    INNER JOIN dd03l   AS dd03l_3
                       ON dd03l_3~precfield = dd03l_2~tabname
                      AND dd03l_3~fieldname LIKE '.INCLU%'
                      AND dd03l_3~as4local  = 'A'
                      AND dd03l_3~as4vers   = 0
    WHERE tadir~devclass IN @s_devcl
      AND tadir~pgmid  = 'R3TR'
      AND tadir~object = 'DOMA'
  " starting from tables
  UNION
  SELECT dd03l~tabname
    FROM       tadir
    INNER JOIN tdevc   ON tdevc~devclass = tadir~devclass
    INNER JOIN dd03l   ON dd03l~precfield = tadir~obj_name
                      AND dd03l~fieldname LIKE '.INCLU%'
                      AND dd03l~as4local  = 'A'
                      AND dd03l~as4vers   = 0
    WHERE tadir~devclass IN @s_devcl
      AND tadir~pgmid  = 'R3TR'
      AND tadir~object = 'TABL'
  UNION
  SELECT dd03l_2~tabname
    FROM       tadir
    INNER JOIN tdevc   ON tdevc~devclass = tadir~devclass
    INNER JOIN dd03l   ON dd03l~precfield = tadir~obj_name
                      AND dd03l~fieldname LIKE '.INCLU%'
                      AND dd03l~as4local  = 'A'
                      AND dd03l~as4vers   = 0
    INNER JOIN dd03l   AS dd03l_2
                       ON dd03l_2~precfield = dd03l~tabname
                      AND dd03l_2~fieldname LIKE '.INCLU%'
                      AND dd03l_2~as4local  = 'A'
                      AND dd03l_2~as4vers   = 0
    WHERE tadir~devclass IN @s_devcl
      AND tadir~pgmid  = 'R3TR'
      AND tadir~object = 'TABL'

    INTO TABLE @DATA(tables).

* 2. ANALYZE ALL STRUCTURES AND TABLES

  LOOP AT tables ASSIGNING FIELD-SYMBOL(<table>).
    WRITE / <table>-tabname COLOR 5.
    PERFORM check_one_table USING <table>-tabname.
  ENDLOOP.

ENDFORM.

FORM check_one_table USING p_table TYPE tabname.

  SELECT COUNT(*) FROM dd02l WHERE tabname = p_table AND as4local = 'A'.

  IF sy-subrc = 4.
    WRITE 'Table not found!'.
  ELSE.

    gt_message = VALUE #( ).

    PERFORM check_enhancements USING p_table
                                     ''.
    IF NOT gt_message[] IS INITIAL.
      LOOP AT gt_message INTO g_wa_message.
        WRITE: 'FAIL', g_wa_message.
        NEW-LINE NO-SCROLLING.
      ENDLOOP.
      WRITE 'The check was completed successfully!'.
    ELSE.
      WRITE 'No errors found!'.
    ENDIF.
  ENDIF.

ENDFORM.

FORM check_enhancements USING p_main_obj    TYPE char30
                              p_prev_obj    TYPE char30.

  DATA: lv_sub_ex   TYPE n, "EXCLASS/ ENHANCEMENT CATEGORY
        lv_main_ex  TYPE n,
        wa_includes TYPE ty_include,
        ls_includes TYPE TABLE OF ty_include,
        lv_curr_obj TYPE char30.

  lv_curr_obj = p_main_obj.

  SELECT SINGLE exclass FROM dd02l
    INTO lv_main_ex "Get the main structure
    WHERE tabname = lv_curr_obj AND as4local = 'A'.

  SELECT precfield fieldname rollname FROM dd03l "Get the fields
    INTO CORRESPONDING FIELDS OF wa_includes
    WHERE tabname = lv_curr_obj AND precfield <> '' AND as4local = 'A'. "( rollname = '' or datatype = 'STRU' ) AND AS4LOCAL = 'A'.

    APPEND wa_includes TO ls_includes.
  ENDSELECT.

  LOOP AT ls_includes INTO wa_includes.
    IF wa_includes-precfield <> ''.
      SELECT SINGLE exclass FROM dd02l INTO lv_sub_ex
        WHERE tabname = wa_includes-precfield AND as4local = 'A'.

      IF sy-subrc = 0 AND lv_main_ex < lv_sub_ex AND lv_main_ex <> 0 . "Check if will write
        PERFORM format_message USING p_main_obj
                                     wa_includes-precfield
                                     lv_sub_ex.
      ENDIF.
      PERFORM check_enhancements USING wa_includes-precfield "p_main_obj
                                       lv_curr_obj.          "previous
    ELSEIF wa_includes-rollname <> '' .
      SELECT SINGLE exclass FROM dd02l INTO lv_sub_ex
       WHERE tabname = wa_includes-rollname AND as4local = 'A' .

      IF sy-subrc = 0 AND lv_main_ex < lv_sub_ex AND lv_main_ex <> 0. "Check if will write
        PERFORM format_message USING p_main_obj
                                     wa_includes-rollname
                                     lv_sub_ex.
      ENDIF.
      PERFORM check_enhancements USING wa_includes-fieldname "p_main_obj
                                       lv_curr_obj.          "previous
    ENDIF.
  ENDLOOP.

ENDFORM.

FORM format_message USING p_main_obj  TYPE tabname
                          p_sub_obj   TYPE tabname
                          p_obj_ex    TYPE n.

  DATA lw_message TYPE ty_message.

  CONCATENATE lw_message p_sub_obj INTO lw_message.
  CONCATENATE lw_message 'has a bigger enhancement category than' p_main_obj INTO lw_message SEPARATED BY space.
  CONCATENATE lw_message '.' INTO lw_message.
  CONCATENATE lw_message p_sub_obj 'is set to ' INTO lw_message SEPARATED BY space.

  IF p_obj_ex   = 1.
    CONCATENATE lw_message '(Cannot be enhanced)' INTO lw_message SEPARATED BY space.
  ELSEIF p_obj_ex   = 2.
    CONCATENATE lw_message '(Can be enhanced (character-type)' INTO lw_message SEPARATED BY space.
  ELSEIF p_obj_ex   = 3.
    CONCATENATE lw_message '(Can be enhanced (character-type or numeric))' INTO lw_message SEPARATED BY space.
  ELSEIF p_obj_ex   = 4.
    CONCATENATE lw_message '(Can Be Enhanced (DEEP))' INTO lw_message SEPARATED BY space.
  ENDIF.

  APPEND lw_message TO gt_message.
  CLEAR lw_message.

ENDFORM.

 

Sara Sampaio

Sara Sampaio

Author Since: March 10, 2022

0 0 votes
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x