We all have heard about dynamic conditions in WHERE clauses (Dynamic where clause - ABAP Development - SCN Wiki), dynamic READ statements (Dynamic WHERE in READ TABLE | SCN), dynamic internal tables/ structures/ ALV (Tutorial abap - Code for Dynamic Alv grid - Code Gallery - SCN Wiki), in short dynamic programming (Dynamic Programming - Application Development on AS ABAP - SAP Library)...
But, when I searched about dynamic conditions in IF statement, I couldn't find many hits. Some of the hits said, it was not possible, some said to use ranges, and some others said it required dynamic subroutine generation etc.
I have used EVAL_FORMULA function module before (Program to evaluate formula in a string - ABAP Development - SCN Wiki). But, I haven't had much success with TEXT operations, using this function module.
So, I am here to discuss a method to achieve dynamic IF conditions in ABAP.
Interfaces used:
IF_FOBU_CONNECTOR
IF_FOEV_CONNECTOR
Classes used:
CL_FOBU_FORMULA - Formula Builder
CL_FOEV_FORMULA - Formula Evaluator
This same method can be used to evaluate dynamic formulae, just by changing the return type of the method. Since, I have used return type as BOOLEAN, I expect a TRUE or FALSE value to be returned by the method.
Global Class ZCL_EVALUATE_DYNAMIC_CONDITION:
1 class zcl_evaluate_dynamic_condition definition
2 public
3 final
4 createpublic .
5
6 publicsection.
7
8 interfaces if_fobu_connector .
9 interfaces if_foev_connector .
10
11 types:begin of ty_field_values .
12 types name type string.
13 types data typerefto data.
14 types type type string.
15 typesend of ty_field_values .
16 types:tyt_field_values typestandardtable
17 of ty_field_values withnon-uniquekey table_line .
18
19 class-methods factory
20 returning
21 value(rv_evaluator) typerefto zcl_evaluate_dynamic_condition .
22 methods calculate
23 importing
24 value(it_dictionary) type tyt_field_values
25 value(iv_formula) type string
26 returning
27 value(rv_value) type boolean .
28 protectedsection.
29 privatesection.
30
31 data dictionary type tyt_field_values .
32 endclass.
33
34 class zcl_evaluate_dynamic_condition implementation.
35
36 methodcalculate.
37 data: lr_env typerefto if_foev_connector,
38 lr_fenv typerefto if_fobu_connector,
39 lr_formula typerefto cl_fobu_formula,
40 lr_runtime typerefto cl_foev_formula.
41
42 dictionary = it_dictionary.
43 lr_env ?= me.
44 lr_fenv ?= me.
45 cl_fobu_formula=>create(
46 exporting
47 im_tech_names = abap_true
48 im_environment = lr_fenv
49 im_desired_type ='BOOLEAN' "<<<<<
"Change this return type to use for other purposes
50 io_fobu_storage =cl_fobu_storage=>get_instance()
51 importing
52 ex_formula = lr_formula ).
53 lr_formula->parse( iv_formula ).
54 lr_runtime =cl_foev_formula=>load_from_fobu(
55 im_formula = lr_formula
56 im_environment = lr_env ).
57 data(lv_resuld) =lr_runtime->evaluate().
58 assign lv_resuld->* to field-symbol(<res>).
59 rv_value =<res>.
60 endmethod.
61
62 methodfactory.
63 createobject rv_evaluator.
64 endmethod.
65
66 methodif_fobu_connector~check.
67 endmethod.
68
69 methodif_fobu_connector~get.
70 endmethod.
71
72 methodif_fobu_connector~get_all_operands.
73 endmethod.
74
75 methodif_fobu_connector~parse_op_get.
76 readtable dictionary into data(meaning)
77 withkey name = ch_tech_name.
78 if sy-subrc eq 0.
79 ex_type = meaning-type.
80 ex_token = cl_fobu_formula=>c_token_appl_1.
81 endif.
82 endmethod.
83
84 methodif_fobu_connector~pushbuttons_get.
85 endmethod.
86
87 methodif_fobu_connector~pushbutton_op_get.
88 endmethod.
89
90 methodif_foev_connector~evaluate.
91 readtable dictionary into data(meaning)
92 withkey name = im_fieldname.
93 if sy-subrc eq 0.
94 assign meaning-data->* to field-symbol(<fld>).
95 createdata re_result like<fld>.
96 assign re_result->* to field-symbol(<res>).
97 <res> =<fld>.
98 else.
99 raiseexceptiontype cx_foev_formula_invalid
100 exporting
101 textid =|{ im_fieldname } field was not found in dictionary|.
102 endif.
103 endmethod.
104 endclass.
Explanation:
- IF_FOBU_CONNECTOR~PARSE_OP_GET helps in specifying the field types and token type, based on DICTIONARY entries.
- IF_FOEV_CONNECTOR~EVALUATE helps in converting the fieldnames into values, based on the DICTIONARY entries.
- LT_FIELDVALUES holds the values of all possible fields that may be used in the formula. Here, since I already know what are the fields used in my formula, I am passing only these values. This is stored in the DICTIONARY, so that the above methods may use it.
- In the code below, I am passing a constant formula to the method, but purpose of this method is to analyze any dynamic text formula.
Example usage:
1 class zcl_evaluate_dynamic_condition
2 definitionload.
3 try.
4 data:lt_fieldvalues
5 type zcl_evaluate_dynamic_condition=>tyt_field_values.
6 lt_fieldvalues =value#(( name ='PLAAB'
7 type ='MDPS-PLAAB'
8 data =ref#( gs_mdps-plaab ))
9 ( name ='DELKZ'
10 type ='MDPS-DELKZ'
11 data =ref#( gs_mdps-delkz ))
12 ( name ='LIFNR'
13 type ='MDPS-LIFNR'
14 data =ref#( gs_mdps-lifnr ))
15 ( name ='PLUMI'
16 type ='MDPS-PLUMI'
17 data =ref#( gs_mdps-plumi ))).
18
19 ifzcl_evaluate_dynamic_condition=>factory()->calculate(
20 iv_formula =|PLAAB = '02' AND DELKZ = 'BB'
AND LIFNR <> '' AND PLUMI = '-'|
21 it_fieldvalues = lt_fieldvalues )= abap_true.
22 continue.
23 endif.
24 catch cx_root.
25 endtry.