Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
Sandra_Rossi
Active Contributor
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 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 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 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.

 
2 Comments