Introduction
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.
Example
Let´s say we have
“BUKRS” and Internal Field “XFELD”:
Value Mapping Definition
The Domains we use have a Value Table (BUKRS) and Fixed Values (XFELD):
Value table
Fixed Values
Our Objective: Validate all Entries based on Value Table (Key Field with same Domain as Key) and Fixed Values (Or Value Ranges)
Implementation Steps
Solution: Implement BaDI “/AIF/VMAP” in SE19
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)
No comments:
Post a Comment