1 1 1 1 1 Rating 0% (0 Votes)
When you will want to create a customization table for your program but you want to do it that way that you want to have many key fields and some of them can be empty which would mean that this is valid for all entries then you have to do some little coding to handle it as you just cannot check only if key fields are same as in your checked structure. There is a way to do it and the method described can be used in all programing languages. I will show you two ways - static and dynamic.
In static one I will hard code key field names in the code which makes that you have to rewrite the code each time you change the structure of your configuration table. 
Dynamic way when done once then doesn't have to be redesign as I will use cl_abap_elemdescr and cl_abap_structdescr to get key fields. 
 
Ok, firstly we need to create our configuration table in dictionary using SE11. As sample I will create table only with two key fields on a base whom I will check the configuration.
 
After we need to create some entries in out table. I assume that if key field is empty then it's valid for all entries checked. For example bellow you can find picture with some dummy configuration entries. First line has both key fields empty so this means that if no other configuration will be found for specific airline and/or plane type then I will use this line. So this is kind of default configuration. Using initial fields gives us the possibility to store defaults also for part of the key, like in second line where airline is empty but the plane type is filled. In this case if we will not find configuration for our airline and plane type 747-400 then I will use this line for configuration. Third line shows example where we've set first key but second one is empty. This means that this line is valid for all plane type in airline AA for which there is no direct configuration.
 
 
Now let's go to ABAP. In the example of the code which you'll find bellow you can find two forms select_configuration_static and select_configuration_dynamic. This two forms will give you same result but they are done in different way. In fact you could also make dynamic version more dynamic by adding table parameter with your customization table and it's name then you could store it as a FM or method in a class so you could reuse it without any rework. But to make it more understandable I keep it that way.
 

report  zab_select_configuration.

datagt_zconf type standard table of zconf.
datags_zconf_static  type zconf.
datags_zconf_dynamic type zconf.
datags_zconf_source  type zconf.
datagt_sflight type standard table of sflight.
field-symbols<sf> type sflight.


"select our configuration
select into corresponding fields of table gt_zconf
  
from zconf.

"select sample data to check
select up to 100 rows into corresponding fields of table gt_sflight
  
from sflight.


loop at gt_sflight assigning <sf>.
  " static version where you manually check key fields and at each change of
  " your configuration table structure you have to adjust it
  clear gs_zconf_static.
  perform select_configuration_static using <sf>-carrid
                                            <sf>
-planetype
                                   changing gs_zconf_static.

  " dynamic verision, once done never changed again
  cleargs_zconf_dynamicgs_zconf_source.
  move-corresponding <sf> to gs_zconf_source.
  perform select_configuration_dynamic using gs_zconf_source
                                    
changing gs_zconf_dynamic.
*--------------------------------------------------------------------*
* do your coding here with configuration in gs_zconf_static or
* gs_zconf_dynamic
*--------------------------------------------------------------------*
endloop.


*&---------------------------------------------------------------------*
*&      Form  select_configuration_static
*&---------------------------------------------------------------------*
form select_configuration_static using f_carrid    type s_carrid
                                       f_planetype 
type s_planetye
                              
changing f_zconf type zconf.

  field-symbols<conf> type zconf.
  dataf_current_score type i.
  dataf_best_score type i.

  "loop at our configuration table
  loop at gt_zconf assigning <conf>.
    clear f_current_score"clear previous score
    if f_carrid eq <conf>-carrid.
      "if the fields are same then we add 20 to score
      add 20 to f_current_score.
    elseif <conf>-carrid is initial.
      "if the configuration field is empty this means this is valid for all
      "we add 10
      add 10 to f_current_score.
    else.
      "if the fields are different and configuration is not valid for all
      "then we go to next line of configuration
      continue.
    endif.

    "same rules applies here but as this is second key then the score is lower
    if f_planetype eq <conf>-planetype.
      add to f_current_score.
    elseif <conf>-planetype is initial.
      add to f_current_score.
    else.
      continue.
    endif.

    "check if we have bigger score than before and if yes then we change
    "our configuration structure
    if f_current_score > f_best_score.
      f_best_score f_current_score.
      f_zconf <conf>.
    endif.
  endloop.

endform.                    "select_configuration_static

*&---------------------------------------------------------------------*
*&      Form  select_configuration_dynamic
*&---------------------------------------------------------------------*
form select_configuration_dynamic using f_sour_conf type zconf
                               
changing f_resu_conf type zconf.


  field-symbols<source> type any,
                 <config> type any,
                 <conf>   type zconf,
                 <dfies> type dfies.

  dataf_keys_number type i.
  dataf_score type i.
  dataf_current_score type i.
  dataf_best_score type i.
  datafo_conf_str type ref to cl_abap_structdescr.
  dataft_ddfields type ddfields.
  dataf_continue  type c.

  "we create structure object for our customization table
  fo_conf_str ?= cl_abap_elemdescr=>describe_by_name'ZCONF' ).

  "lets get fields for table
  fo_conf_str->get_ddic_field_list(
*    exporting
*      p_langu                  = SY-LANGU
*      p_including_substructres = ABAP_FALSE
    receiving
      p_field_list             
ft_ddfields
    
exceptions
      not_found                1
      no_ddic_type             2
      others                   3
         ).
  if sy-subrc eq 0.
*   Implement suitable error handling here
  endif.

  "check it there was no problem before
  check ft_ddfields[] is not initial.

  "get the number of key fields
  loop at ft_ddfields assigning <dfies> where keyflag eq 'X'.
    add to f_keys_number.
  endloop.

  "loop at our configuration table
  loop at gt_zconf assigning <conf>.
    clear f_current_score"clear score.

    "we will check key fields only
    do f_keys_number times.
      "assign key field of configuration
      assign component sy-index of structure <conf> to <config>.
      if sy-subrc ne 0exitendif.
      "assign key field of source
      assign component sy-index of structure f_sour_conf to <source>.
      if sy-subrc ne 0exitendif.

      "prepare score value
      f_score 1.
      do f_keys_number sy-index times.
        "we do power of 10, the lower key field position the higher score
        f_score 10 * f_score.
      enddo.

      if <config> eq <source>.
        "if the fields are same then we add 2 times score
        do times.
          add f_score to f_current_score.
        enddo.
      elseif <config> is initial.
        "if the configuration field is empty this means this is valid for all
        "so we add score
        add f_score to f_current_score.
      else.
        "there is no match and configuration is not empty
        "so we have to go to next line of configuration
        f_continue 'X'.
        exit.
      endif.

    enddo.

    "check if we have to continue or not
    if f_continue eq 'X'.
      clear f_continue.
      continue.
    endif.

    "check if we have bigger score than before and if yes then we change
    "our configuration structure
    if f_current_score > f_best_score.
      f_best_score f_current_score.
      f_resu_conf <conf>.
    endif.
  endloop.

endform.                    "select_configuration_dynamic

Enjoy!