hello

sap vc is a powerfull tool. i like it, to design the vc the way that the logic is stored in decision tables, for instance a list of allowed options for a characteristic. so the end user just has to maintain the table when new master data is created, and does not have to create new dependencies.

there is a command call ‘table’ which allows access to variant tables. ( i think you already know)

sometimes there is a disadvantage that you have to create severall dependencies in order to pass the right selection criterias

my target was to create just one global dependency to cover all, which simplifies the maintenance of the configurator

i designed a generic variant function which reads data from the current configuration and with the possibility to use a cached access to variant table data.

dependency:

000010 Function Z_PRE_COND_00
000020 (GLOBAL_TABLENAME = ‘MYVARIANTTABLE’,
000030 OBJECT_CAWN_ATINN = mdata $self.CAWN_ATINN,
000040 OBJECT_CAWN_ATWRT = mdata $self.CAWN_ATWRT )
______ ________________________________________________________________________

the two characteristics CAWN_ATINN and CAWN_ATWRT are Object Characteristic with a link to the Table CAWN

this is used to find the name of the currently selected characteristic-value

Variant Table /NCU62

Variant Function /NCU66:

Example: Table POWER

Characteristics

PRODUCT

POWER

you see a list of allowed POWER values for the PRODUCT

so the global dependency/function validates, if only allowed POWER values for the selected PRODUCT are entered

we can use the same characteristic POWER for all PRODUCTS, but with different allowed values

>> search for entries with same characteristics/values as current configuration!

FUNCTION z_pre_cond_00.

*”———————————————————————-

*”*”Lokale Schnittstelle:

*”  IMPORTING

*”     REFERENCE(GLOBALS) TYPE  CUOV_00

*”  TABLES

*”      QUERY STRUCTURE  CUOV_01

*”      MATCH STRUCTURE  CUOV_01

*”  EXCEPTIONS

*”      FAIL

*”      INTERNAL_ERROR

*”———————————————————————-

  DATA it_imp_values  TYPE STANDARD TABLE OF  api_val_i.

  DATA its_imp_values TYPE SORTED TABLE OF  api_val_i       “MDW01

                      WITH UNIQUE KEY atnam atwtb atinn. “must be unique!

  FIELD-SYMBOLS <imp_values> TYPE api_val_i.

  DATA wa_imp_values TYPE api_val_i.

  DATA it_imp_char  TYPE STANDARD TABLE OF api_char.

  DATA its_imp_char TYPE SORTED TABLE OF api_char           “MDW01

                    WITH UNIQUE KEY atnam.  “must be unique!

  FIELD-SYMBOLS <fs_char> TYPE api_char.

  DATA wa_imp_char TYPE api_char.

  FIELD-SYMBOLS <fs_values> TYPE api_value.

  DATA wf_atinn LIKE cabn-atinn.

  DATA wf_atwrt LIKE cuov_01-atwrt.

  DATA it_char TYPE TABLE OF api_char.

  FIELD-SYMBOLS <fs_chk_char> TYPE api_char.

  TYPE-POOLS: cullt.

  DATA: wf_tablename TYPE  tablstruct-var_tab.

  DATA: it_vc_table TYPE TABLE OF  vtentries.

  DATA: it_vc_tab_char TYPE TABLE OF vtchars.

  DATA: self_instance            TYPE cullt_instance_nr VALUE 1.

  DATA: parent_instance          TYPE cullt_instance_nr VALUE 2.

  DATA: instance                 TYPE cullt_instance.

  DATA: wa_properties            TYPE LINE OF cullt_properties.

  DATA: characteristics          LIKE STANDARD TABLE OF bapicuch01.

  DATA: characteristics_value    LIKE STANDARD TABLE OF bapicuvl01.

  DATA: wa_characteristics_value LIKE bapicuvl01.

  DATA: wf_instance              LIKE capiparms-instance.

  DATA it_exp_values_error TYPE STANDARD TABLE OF api_val_i.

  DATA wa_exp_values_error TYPE api_val_i.

  DATA wa_exp_values TYPE api_value. 

  DATA it_exp_values  TYPE STANDARD TABLE OF api_value.

  DATA its_exp_values TYPE SORTED TABLE OF api_value        “MDW01

                      WITH NON-UNIQUE KEY atnam atwrt.

  DATA: ls_cabn TYPE cabn,

        ls_cawn TYPE cawn.

*  data: wf_atinn like cawn-atinn.

  DATA: wf_atnam LIKE cabn-atnam.

  DATA: wa_char LIKE LINE OF it_char.

  DATA: wf_atflv LIKE cawn-atflv.

  DATA: wf_tabix TYPE  vtentries-vtlineno.

  DATA: wf_found.

  DATA: wf_row_fields_match.

*..initialize table with export parameters………………………..*

  REFRESH match.

*..get value of input characteristic

  CALL FUNCTION ‘CUOV_GET_FUNCTION_ARGUMENT’

    EXPORTING

      argument      = ‘GLOBAL_TABLENAME’

    IMPORTING

      sym_val       = wf_atwrt

    TABLES

      query         = query

    EXCEPTIONS

      arg_not_found = 01.

  IF sy-subrc <> 0.

    RAISE internal_error.

  ENDIF.

  wf_tablename = wf_atwrt.

*..get value of input characteristic salesorganisation

  CALL FUNCTION ‘CUOV_GET_FUNCTION_ARGUMENT’

    EXPORTING

      argument      = ‘OBJECT_CAWN_ATINN’

    IMPORTING

      num_val       = wf_atflv

    TABLES

      query         = query

    EXCEPTIONS

      arg_not_found = 01.

  wf_atinn = wf_atflv.

*..get value of input characteristic salesorganisation

  CALL FUNCTION ‘CUOV_GET_FUNCTION_ARGUMENT’

    EXPORTING

      argument      = ‘OBJECT_CAWN_ATWRT’

    IMPORTING

      sym_val       = wf_atwrt

    TABLES

      query         = query

    EXCEPTIONS

      arg_not_found = 01.

  IF sy-subrc <> 0.

    RAISE internal_error.

  ENDIF.

* read current configuration values

  CLEAR it_char.

  CALL FUNCTION ‘CEI0_DDB_HAS_CHARACTERISTICS’

    TABLES

      exp_characteristics      = it_char

    EXCEPTIONS

      not_found                = 1

      no_characteristic_in_ddb = 2

      OTHERS                   = 3.

  READ TABLE it_char INTO wa_char WITH KEY atinn = wf_atinn. ” binary search.

  IF sy-subrc = ‘0’.

    wf_atnam = wa_char-atnam.

  ENDIF.

  IF NOT it_char[] IS INITIAL.

*  it_imp_char = its_imp_char. “sorted-> standard table

*  select values

    CALL FUNCTION ‘CEI0_DDB_HAS_VALUES’

      EXPORTING

        assigned_values      = ‘X’

        allowed_values       = ‘ ‘

        valid_values         = ‘ ‘

        inconsistent_values  = ‘ ‘

        first_assigned_value = ‘ ‘

        default_values       = ‘ ‘

        incl_author          = ‘X’

      TABLES

        imp_characteristics  = it_imp_char

        exp_values           = it_exp_values

      EXCEPTIONS

        not_found            = 1

        OTHERS               = 2.

    SORT it_exp_values BY atnam atwrt.

  ELSE.

* if CEI0_DDB_HAS_CHARACTERISTICS gives no values, use other function: (depends on vc-transaction/low-level configurator)

**  example  values from cs11

* this is not needed for input-screen related dependencies, but useful if you are working with procedures

    CALL FUNCTION ‘CULL_GET_INSTANCE’

      EXPORTING

        instance_nr      = parent_instance

      IMPORTING

        instance         = instance

      EXCEPTIONS

        unknown_instance = 1

        OTHERS           = 2.

    REFRESH it_exp_values.

    LOOP AT instance-properties INTO wa_properties.

      CLEAR wa_exp_values-atnam.

      wa_exp_values-atinn = wa_properties-characteristic.

      READ TABLE gt_cabn INTO ls_cabn WITH TABLE KEY atinn = wa_exp_values-atinn.

      IF sy-subrc <> ‘0’.

        SELECT SINGLE *

               FROM cabn

               INTO ls_cabn

              WHERE atinn = wa_exp_values-atinn.

        INSERT ls_cabn INTO TABLE gt_cabn.

      ENDIF.

      wa_exp_values-atnam = ls_cabn-atnam.

*wa_exp_values-ATBEZ = wa_properties-characteristic

      wa_exp_values-atwrt = wa_properties-value-atwrt.

*      if wa_properties-value-atwrt is initial

*      and wa_properties-value-atflv <> 0.

      IF ls_cabn-atfor <> ‘CHAR’.

* nicht immer usr01 sondern via set country…

        IF usr01-bname <> ‘ ‘.

          usr01-bname = sy-uname.

          DATA: w_zahl TYPE p DECIMALS 1, w_string(10).

          WRITE: w_zahl TO w_string.

          IF w_string CA ‘,’.

            usr01-dcpfm = ‘ ‘.

          ELSE.

            usr01-dcpfm = ‘X’.

          ENDIF.

        ENDIF.

        MOVE-CORRESPONDING ls_cabn TO ls_cawn.

        ls_cawn-atawe = ls_cabn-msehi. CLEAR ls_cabn-msehi.

        ls_cawn-spras = sy-langu.

        MOVE-CORRESPONDING wa_properties-value TO ls_cawn.

        CALL FUNCTION ‘CTCV_PREPARE_VALUES_TO_DISPLAY’

          EXPORTING

            align                  = ‘NO’

            decimalpoint           = usr01-dcpfm

            shift                  = ‘L’

            single                 = ‘NO’

            string_without_operand = ‘NO’

            string_without_unit    = ‘NO’

            structure_cabn         = ls_cabn

            structure_cawn         = ls_cawn

          IMPORTING

            string                 = wa_exp_values-atwrt.

      ENDIF.

*wa_exp_values-ATWTB = wa_properties-

      wa_exp_values-ataut = wa_properties-author.

      APPEND wa_exp_values TO it_exp_values.

    ENDLOOP.

  ENDIF.

* get vc table

  CALL METHOD zcl_ml_vc_table_cache=>get_table_content

    EXPORTING

      tablename      = wf_tablename

    IMPORTING

      it_vc_tab_char = it_vc_tab_char[]

      it_vc_table    = it_vc_table[].

  IF NOT it_vc_tab_char IS INITIAL.

* search dynamic table-entry:

    SORT it_exp_values BY atnam atwrt .

    SORT it_vc_table BY vtlineno vtcharact vtvalue.

    FIELD-SYMBOLS: <wa_vc_value> LIKE LINE OF it_vc_table.

    FIELD-SYMBOLS: <wa_vc_char> LIKE LINE OF it_vc_tab_char.

    wf_found  = ‘ ‘.

    DO.

      UNPACK sy-index TO wf_tabix .

      READ TABLE it_vc_table TRANSPORTING NO FIELDS

   WITH KEY vtlineno = wf_tabix.

      IF sy-subrc <> ‘0’. EXIT. ENDIF.

      wf_row_fields_match = ‘X’.

      LOOP AT it_vc_tab_char ASSIGNING <wa_vc_char>. “table structure

        READ TABLE it_exp_values INTO wa_exp_values

        WITH KEY atnam = <wa_vc_char>-charact BINARY SEARCH.

* Loop/multiple characteristics?

        IF sy-subrc <> ‘0’. CLEAR wa_exp_values. ENDIF.

        IF <wa_vc_char>-charact = wf_atnam.

          wa_exp_values-atwrt = wf_atwrt.

          DATA: wf_atzhl LIKE cawn-atzhl.

          SELECT SINGLE atzhl FROM cawnt INTO wf_atzhl

            WHERE atinn = wf_atinn AND atwtb = wf_atwrt

            AND spras = sy-langu.

          IF sy-subrc = ‘0’.

            SELECT SINGLE atwrt FROM cawn INTO wa_exp_values-atwrt

              WHERE atinn = wf_atinn

              AND atzhl = wf_atzhl.

          ENDIF.

          CLEAR sy-subrc.

        ENDIF.

* If sy-subrc = ‘0’.

* or vc_table-index = 1?

* empty value?

        READ TABLE it_vc_table TRANSPORTING NO FIELDS

         WITH KEY vtlineno = wf_tabix

                                           vtcharact = <wa_vc_char>-charact

                                           vtvalue = wa_exp_values-atwrt

                                           BINARY SEARCH.

        IF sy-subrc <> 0.

          CLEAR wf_row_fields_match.

          EXIT. “next line

        ENDIF.

      ENDLOOP.

      IF wf_row_fields_match = ‘X’. wf_found = ‘X’. EXIT. ENDIF.

    ENDDO.

    IF wf_found = ‘ ‘.

      RAISE fail. “no entry found, let the selection condition fail

    ENDIF.

*..add result to the table of output characteristics for procedures:

*.. pseudo output

*  CALL FUNCTION ‘CUOV_SET_FUNCTION_ARGUMENT’

*    EXPORTING

*      argument                = ‘OUT_CHAR’

*      vtype                   = ‘CHAR’

*      sym_val                 = value

*    TABLES

*      match                   = match

*    EXCEPTIONS

*      existing_value_replaced = 01.

* set a numeric output value

*data: wf_atflv like match-atflv.

*CALL FUNCTION ‘CONVERSION_EXIT_FLOAT_INPUT’

*  EXPORTING

*    INPUT         =  wa_exp_values-atwrt

* IMPORTING

*   OUTPUT        = wf_atflv.

*  CALL FUNCTION ‘CUOV_SET_FUNCTION_ARGUMENT’

*    EXPORTINg

*      argument                = query-varnam

*      vtype                   = ‘NUM’

**      sym_val                 =  wa_exp_values-atwrt

*      num_val = wf_atflv

*    TABLES

*      match                   = match

*    EXCEPTIONS

*      existing_value_replaced = 01.

  ELSE.

    RAISE fail. “table not found

  ENDIF.

ENDFUNCTION.

Class ZCL_ML_VC_TABLE_CACHE class to read and cache  variant tables

class ZCL_ML_VC_TABLE_CACHE definition

  public

  final

  create public .

*”* public components of class ZCL_ML_VC_TABLE_CACHE

*”* do not include other source files here!!!

public section.

  data:

    begin of table_list,

    table_name type tabname,

    tableobj type ref to ZCL_ML_VC_TABLE_CACHE,

    end of table_list .

  dataTABLE_STRUCTURE type ZML_VTCHARS . “table type of vtchars

  data TABLE_CONTENT type ZML_VTENTRIES .  “table type of vtentries

  class-data:

    TABLE_NAMES like table of table_list .

  data TABLE_NAME type TABLENAME .

  methods CONSTRUCTOR

    importing

      !TABLENAME type APITABL optional .

  class-methods GET_TABLE_CONTENT

    importing

      value(TABLENAME) type APITABL optional

    exporting

      !IT_VC_TAB_CHAR type ZML_VTCHARS “table type of VTCHARS

      !IT_VC_TABLE type ZML_VTENTRIES . “table type of VTENTRIES

Importing-Parameter

  TABLENAME TYPE APITABL  OPTIONAL  (Tabellenname)

method CONSTRUCTOR.

*  data: wf_tablename type CAPIPARMS-VAR_TAB.

   if tablename <> ‘ ‘.

*    wf_tablename = tablename.

   CALL FUNCTION ‘CARD_TABLE_READ_STRUCTURE’

     EXPORTING

       VAR_TAB                    = tablename

*   CHANGE_NO                  =

*   DATE                       =

*   LANGUAGE                   =

* IMPORTING

*   BASIC_DATA                 =

*   RETURN                     =

    TABLES

*   DESCRIPTIONS               =

     CHARACTERISTICS            = me->table_structure[]

*   VALUE_ASSIGNMENT_ALT       =

   EXCEPTIONS

     ERROR                      = 1

     OTHERS                     = 2

            .

  if sy-subrc = ‘0’.

* Lesen der Tabelleneinträge

    CALL FUNCTION ‘CARD_TABLE_READ_ENTRIES’

      EXPORTING

        VAR_TABLE             = tablename

*   CHANGE_NO             =

*   DATE                  =

      TABLES

        VAR_TAB_ENTRIES       = me->table_content[]

     EXCEPTIONS

       ERROR                 = 1

       OTHERS                = 2

              .

    IF SY-SUBRC <> 0.

* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

    ENDIF.

endif.

data: line like line of ZCL_ML_VC_TABLE_CACHE=>table_names.

line-table_name = tablename.

line-tableobj = me.

append line to ZCL_ML_VC_TABLE_CACHE=>table_names.

endif.

endmethod.

GET_TABLE_CONTENT

Beschreibung:

Statische Methode

Importing-Parameter

VALUE(TABLENAME) TYPE APITABL  OPTIONAL  (Tabellenname)

Exporting-Parameter

IT_VC_TAB_CHAR TYPE ZML_VTCHARS  (tabellentyp vtchars)

IT_VC_TABLE TYPE ZML_VTENTRIES  (tabellentyp vtentries)

method GET_TABLE_CONTENT.

  data: line like line of ZCL_ML_VC_TABLE_CACHE=>table_names.

  data:

    begin of table_list,

    table_name type tabname,

    tableobj type ref to ZCL_ML_VC_TABLE_CACHE,

    end of table_list .

  data: lo_table_cache type ref to ZCL_ML_VC_TABLE_CACHE.

  field-symbols: <line> type any.

  read table ZCL_ML_VC_TABLE_CACHE=>table_names into line

  with key table_name = tablename.

  if sy-subrc <> ‘0’.

     create object lo_table_cache

       EXPORTING

         tablename = tablename.

   else.

     lo_table_cache = line-tableobj.

   endif.

   it_vc_tab_char[] = lo_table_cache->table_structure[].

   it_vc_table[] = lo_table_cache->table_content[].

endmethod.

you can use it in preconditions/selection conditions and/or procedures.

of course you can also access a data dictionary table and create a table maintenance dialog, then you don’t need the access routines/class to variant tables at all

maybe you have similar requirements/ideas and this is of use for you.

To report this post you need to login first.

2 Comments

You must be Logged on to comment or reply to a post.

  1. Rishikesh Shenoy

    Hi Jorg,

    Excellent ! This is a very useful approach. I have one question though.

    Should you create the characteristics with all the possible values or can we just create the characteristics without values and use them in the function ?

    best regards,

    Rishi

    (0) 
    1. Jörg Knaus Post author

      hi rishi

      sorry i just saw your comment now

      if you assign values to characteristics, the Default F4 Value Help will work for the user, if you don’t do you, you will have to implement a userexit to determine the allowed values when the user presses f4. i did this once for a Project using CMOD for  CCUCEI0H (EXIT_SAPLCEI0_022, INCLUDE ZXCEI0U14)

      (0) 

Leave a Reply