Validate Application Interface Framework (AIF) Value Mappings by Domain

In a customer project we defined quite some AIF Value Mappings and noticed that Users can insert any Data into the Value Mapping Table. We wanted to limit the possible entries to the fixed Vales or Values in the Value Table of the Domain of the Data Element used in the Value Mapping Definition.

Let´s say we have

“BUKRS” and Internal Field “XFELD”:

Value%20Mapping%20Definition

Value Mapping Definition

The Domains we use have a Value Table (BUKRS) and Fixed Values (XFELD):

Value%20table

Value table

Fixed%20Values

Fixed Values

Our Objective: Validate all Entries based on Value Table (Key Field with same Domain as Key) and Fixed Values (Or Value Ranges)

Solution: Implement BaDI “/AIF/VMAP” in SE19Create%20BaDI%20Implementation

Create BaDI Implementation

In Implementation for /AIF/IF_VMAP_MAIN~BEFORE_SAVE we can validate the maintained Values.

The maintained Values are persisted in the Global Table “‘(/AIF/VALUE_MAPPING)LT_TABLE->*’ “. We assign it to a Field Symbol:

DATA: lt_dbfields TYPE dfies_tab, lt_allowed_content TYPE cim_t_string, lv_maintained_value_str TYPE string. FIELD-SYMBOLS: <lt_maintained_values> TYPE ANY TABLE, <lt_columns> TYPE ANY TABLE. ASSIGN ('(/AIF/VALUE_MAPPING)LT_TABLE->*') TO <lt_maintained_values>.

The used Data Elements can be retrieved from the vmap manager instance:

DATA(lt_columns) = vmap_manager->get_column_types( ).

Then we loop thorugh the column, get their type, domain, Fixed Valued Indicator and Value Table and, if there is a Value Table, get the allowed Values from there

IF <lt_columns> IS ASSIGNED. LOOP AT <lt_columns> ASSIGNING FIELD-SYMBOL(<ls_column>). "Get Names of Column Types ASSIGN COMPONENT 'NAME' OF STRUCTURE <ls_column> TO FIELD-SYMBOL(<lv_column_name>). IF <lv_column_name> IS ASSIGNED. CASE <lv_column_name>. "Only these columns are relevant WHEN 'EXT_VALUE' OR 'INT_VALUE' OR 'EXT_VALUE1' OR 'EXT_VALUE2' OR 'EXT_VALUE3' OR 'EXT_VALUE4' OR 'EXT_VALUE5'. ASSIGN COMPONENT 'TYPE' OF STRUCTURE <ls_column> TO FIELD-SYMBOL(<lv_column_type>). IF <lv_column_type> IS ASSIGNED "These Data Elements are used if no Data Element is provided in /AIF/CUST AND <lv_column_type> <> '/AIF/VMAP_EXTVAL' AND <lv_column_type> <> '/AIF/VMAP_INTVAL'. SELECT domname "Get Domain for Data Element FROM dd04l INTO @DATA(lv_domain_name) UP TO 1 ROWS WHERE rollname = @<lv_column_type>. ENDSELECT. IF lv_domain_name IS NOT INITIAL. SELECT valexi, entitytab "Get Fixed Valued Indicator and Value Table FROM dd01l INTO @DATA(ls_domain_data) UP TO 1 ROWS WHERE domname = @lv_domain_name. ENDSELECT. IF sy-subrc IS NOT INITIAL. CLEAR ls_domain_data. ENDIF. ENDIF. IF ls_domain_data IS NOT INITIAL. IF ls_domain_data-entitytab IS NOT INITIAL. "Get DB Table Data CALL FUNCTION 'DDIF_FIELDINFO_GET' EXPORTING tabname = ls_domain_data-entitytab TABLES dfies_tab = lt_dbfields. "Get the Field with the same Domain LOOP AT lt_dbfields ASSIGNING FIELD-SYMBOL(<ls_dbfield>) WHERE domname = lv_domain_name AND keyflag = abap_true. DATA(lv_fieldname) = <ls_dbfield>-fieldname. ENDLOOP. IF sy-subrc IS NOT INITIAL. CLEAR lv_fieldname. ENDIF. "Select IF lv_fieldname IS NOT INITIAL. SELECT (lv_fieldname) FROM (ls_domain_data-entitytab) INTO TABLE @lt_allowed_content. ENDIF. ENDIF

Then we loop through the maintained Values and check if the data corresponds to the allowed data in the value table. If the domain is defined as domain with fixed values (indicator “valexi”), we check this with a Function Module FM_DOMAINVALUE_CHECK

LOOP AT <lt_maintained_values> ASSIGNING FIELD-SYMBOL(<ls_maintained_values>). ASSIGN COMPONENT <lv_column_name> OF STRUCTURE <ls_maintained_values> TO FIELD-SYMBOL(<lv_maintained_value>). IF <lv_maintained_value> IS ASSIGNED. lv_maintained_value_str = <lv_maintained_value>. ENDIF. IF lv_maintained_value_str <> '*' AND lv_maintained_value_str IS NOT INITIAL. "Values "*" and "" are always allowed. IF ls_domain_data-valexi IS NOT INITIAL. "Check against Fix Values / Intervals CALL FUNCTION 'FM_DOMAINVALUE_CHECK' EXPORTING i_domname = lv_domain_name i_domvalue = CONV val_single( lv_maintained_value_str ) EXCEPTIONS input_error = 1 value_not_allowed = 2 OTHERS = 3. IF sy-subrc <> 0. MESSAGE e003(xxxxx) WITH <lv_maintained_value> lv_domain_name. ENDIF. ELSEIF ls_domain_data-entitytab IS NOT INITIAL. "Check against DB Table we derived before LOOP AT lt_allowed_content ASSIGNING FIELD-SYMBOL(<lv_data>) WHERE table_line = <lv_maintained_value>. ENDLOOP. IF sy-subrc IS NOT INITIAL. MESSAGE e002(xxxxx) WITH <lv_maintained_value> lv_fieldname lv_domain_name ls_domain_data-entitytab . ENDIF. ENDIF. ENDIF. CLEAR lv_maintained_value_str. ENDLOOP. ENDIF. ENDIF. ENDCASE. ENDIF. CLEAR lv_domain_name. CLEAR lv_fieldname. CLEAR ls_domain_data. ENDLOOP. ENDIF. ENDIF. ENDIF.

The Message Class used has to be maintained of course.

Let´s Test in /AIF/VMAP:

With correct Values

With BUKRS = “XXXX” (not existent on T001):

With XFELD = “F” (Only “X” and “” are allowed)

Conclusion: This way we can validate Values maintained in AIF Value Mappings. But be careful: some Domains have huge Value Tables defined (e.g. FDNAME, Table DD03L with 15.351.250 entries), this can have quite a big impact on the runtime.