如何设计报表读取价格条件数据?

本文介绍如何利用Runtime Types服务(RTTS)解决动态定价条件大师记录的ALV Grid报告问题。通过应用Area筛选,用户交互选择条件类型和访问序列,最后在ALV Grid中展示定制化的数据。

ummary

This post narrates the use of Runtime Type services to generate Dynamic ALV Grid Report for Pricing Condition Master Records.

Author(s):  Vinod Kumar T

   
Company:     NIIT Technologies Limited
Created on:    29.10.2010
Author(s) Bio
Vinod Kumar is an ABAP consultant working with NIIT Technologies Limited. 

Scenario

Requirement is to generate an ALV Grid report show the Pricing condition master records.  Since the Pricing condition master data is stored on the dynamically created tables based on the access sequence,   no specific table can be used for extracting the details.  Condition tables are to be determined based on the input criteria mentioned by the user. 

Initial selection criteria for the user will be the Application Area (Eg: V - Sales and Distribution) and the condition type.  After executing the report, available access sequences are to be displayed so that the user can select the required access sequence.  After selecting the access sequence, user should be prompted with Dynamic selection screen with the primary key fields of the Condition Table.  Based on these input values, data should be displayed in an ALV Grid.

Solution

Step 1: Selection Screen

Initial Selection Screen will have the fields Application Area and Pricing Condition Type.

 

Step 2: Determine Condition table

Based on the Application Area and pricing condition type, determine the access sequence.  Function module SD_COND_T685_SELECT is used to get the access sequence.  Based on the Access sequence, Program should prompt the user to select the required Key combination for selecting the Records.  Function module RV_GET_CONDITION_TABLES is used to create the popup with Applicable Key combinations of the access sequence.  Condition table for the selected key combination will be available in the exporting structure field TABLE_T681-KOTAB of the function module. 

Step 3: Additional Selection Screen Based on Condition Table Key Fields

Once the Condition table is determined, program should prompt the user with an additional selection screen with the key fields defined for the condition table.  Key fields of the condition table is extracted using the class method CL_RECA_DDIC_TABLE=>GET_FIELD_LIST with parameter IF_SUPPRESS_KEY = ABAP_FALSE and IF_SUPPRESS_NONKEY = ABAP_TRUE.   List of key fields will be stored in the exporting structure ET_FIELD_LIST.  From this field list, delete the entries related to Application Area and Condition Type which are already in the initial Selection Screen.

Activate the additional Selection screen (FREE-SELECTION) using the function modules FREE_SELECTIONS_INIT and FREE_SELECTIONS_DIALOG.

 

Step 4: Extract Data from Pricing Master Table

Once the user completes the additional Selection screen, dynamic WHERE condition for the data selection will be available in the export structure WHERE_CLAUSES of function module FREE_SELECTIONS_DIALOG. Add the standard "WHERE" condition for application area and Condition type with the dynamic "WHERE" conditions.    Based on the "WHERE" conditions, extract the data from Condition table and KONP.  Move the contents of these tables to the internal table created using RTTS (Runtime Type Services).

Step 5: Display the report

Display the report in ALV Grid using Object Oriented ABAP classes (SALV).

 

Sample Code

Dynamic Report using RTTS and Free-Selection Screens

ZVK_DYN_REPORT

*&---------------------------------------------------------------------*

*& Report  ZVK_DYN_REPORT

*&---------------------------------------------------------------------*

*& Report to Display Pricing condition Master Records

*&---------------------------------------------------------------------*

 

REPORT  zvk_dyn_report.

 

** Text Elements

* p_kappl : Application Area

* p_kschl : Condition Type

**

 

TYPE-POOLS : rsds,abap.

TABLES : t685,dd02l,t681a.

 

** Type definition for KONP & KONH Table

TYPES : BEGIN OF ty_konp,

           knumh TYPE knumh,

           kbetr TYPE kbetr_kond,

           krech TYPE krech,

           loevm_ko TYPE loevm_ko,

        END OF ty_konp.

 

TYPES : BEGIN OF ty_konh,

           knumh TYPE knumh,

        END OF ty_konh.

 

DATA : lt_konp TYPE STANDARD TABLE OF ty_konp,

       lt_konh TYPE STANDARD TABLE OF ty_konh,

       ls_konp TYPE ty_konp,

       ls_konh TYPE ty_konh.

 

DATA : key_index TYPE sy-tabix,

       val_index TYPE sy-tabix.

 

** Definitions for Pricing tables determination **

DATA : ls_t685 TYPE t685,

       ls_t681 TYPE t681,

       ls_tmc1t TYPE tmc1t.

 

** Definition for ALV Grid **

DATA : gr_table TYPE REF TO cl_salv_table.

 

DATA : gr_columns TYPE REF TO cl_salv_columns_table,

       gr_column  TYPE REF TO cl_salv_column_table,

       lt_columns TYPE salv_t_column_ref,

       ls_columns TYPE salv_s_column_ref,

       lv_domname TYPE domname.

 

DATA : gr_functions TYPE REF TO cl_salv_functions_list.

 

DATA : gr_layout    TYPE REF TO cl_salv_layout,

       gr_layout_key TYPE salv_s_layout_key.

 

DATA : gr_content TYPE REF TO cl_salv_form_element.

 

** Defintions for Dynamic Structures **

DATA : lt_tab TYPE REF TO cl_abap_tabledescr,

       ls_row TYPE REF TO cl_abap_structdescr,

       ls_frow TYPE REF TO cl_abap_structdescr,

       lt_component TYPE cl_abap_structdescr=>component_table,

       ls_component TYPE cl_abap_structdescr=>component.

 

FIELD-SYMBOLS :  <gt_tab> TYPE STANDARD TABLE,

                 <gs_row> TYPE ANY,

                 <gd_fld> TYPE ANY.

 

DATA : gt_tab TYPE REF TO data,

       gs_row TYPE REF TO data.

 

DATA : p_table TYPE dd02l-tabname.

 

** Declarations for Free Selections

DATA : lt_tables TYPE STANDARD TABLE OF rsdstabs,

       ls_tables TYPE rsdstabs,

       lt_fields TYPE STANDARD TABLE OF rsdsfields,

       ls_fields TYPE rsdsfields,

       lt_fields_n TYPE STANDARD TABLE OF rsdsfields,

       ls_fields_n TYPE rsdsfields.

 

DATA : selection_id TYPE dynselid,

       fs_dyns      TYPE rsds_type,

       fs_num       TYPE sy-tfill,

       lv_kind      TYPE char01.

 

** Declarations for Table Properties **

DATA : lt_field_list TYPE ddfields,

       ls_field_list TYPE dfies.

 

** Declaration for Dynamic Where Clause **

DATA : lt_clause TYPE STANDARD TABLE OF rsds_where,

       ls_clause TYPE rsds_where.

 

DATA : lt_where TYPE STANDARD TABLE OF rsdswhere,

       lt_where_add TYPE STANDARD TABLE OF rsdswhere,

       ls_where TYPE rsdswhere.

 

DATA : lv_kappl  TYPE char04,

       lv_kschl  TYPE char6.

 

** Selection Screen

SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME.

PARAMETERS : p_kappl TYPE t681a-kappl.

PARAMETERS : p_kschl TYPE t685-kschl.

SELECTION-SCREEN END OF BLOCK b1.

 

 

START-OF-SELECTION.

  PERFORM get_table_det.

  PERFORM create_structures.

  PERFORM free_selections.

  PERFORM report_display.

 

*&---------------------------------------------------------------------*

*&      Form  get_table_det

*&---------------------------------------------------------------------*

* To Get Details of Pricing condition Tables

*----------------------------------------------------------------------*

FORM get_table_det.

  CLEAR : ls_t685, ls_t681, ls_tmc1t.

** Get Pricing condition Access Sequence Key

  CALL FUNCTION 'SD_COND_T685_SELECT'

    EXPORTING

      cts_kappl = p_kappl

      cts_kschl = p_kschl

      cts_kvewe = 'A'

    IMPORTING

      cts_t685  = ls_t685.

** Get condition table based on access sequence selection

 

  IF ls_t685-kozgf IS NOT INITIAL.

    CALL FUNCTION 'RV_GET_CONDITION_TABLES'

      EXPORTING

        access_sequence        = ls_t685-kozgf

        application            = p_kappl

        condition_type         = p_kschl

        condition_use          = 'A'

        get_text               = 'X'

        like_pf4               = ' '

      IMPORTING

        table_t681             = ls_t681

        table_tmc1t            = ls_tmc1t

      EXCEPTIONS

        invalid_condition_type = 1

        missing_parameter      = 2

        no_selection_done      = 3

        no_table_found         = 4

        table_not_valid        = 5

        OTHERS                 = 6.

 

    IF sy-subrc <> 0 OR ls_t681-kotab IS INITIAL.

      MESSAGE 'Error in Determining Condition Table..' TYPE 'I' DISPLAY LIKE 'E'.

      STOP.

    ELSE.

      MOVE ls_t681-kotab TO p_table.

    ENDIF.

 

  ENDIF.

 

ENDFORM.                    "get_table_det

 

*&---------------------------------------------------------------------*

*&      Form  create_structures

*&---------------------------------------------------------------------*

* To Create Dynamic Structures for Display

*----------------------------------------------------------------------*

FORM create_structures.

* define local data

  data: lo_typedescr  type ref to cl_abap_typedescr.

 

** Get Structure of the table

**  ls_row ?= cl_abap_typedescr=&gtdescribe_by_name( p_name = p_table ).

  ls_row ?= cl_abap_typedescr=>describe_by_name( p_name = p_table ).

 

** Get the components in the extracted structrue

** And add one more field for Pricing condition value

  IF ls_row IS NOT INITIAL.

    lt_component = ls_row->get_components( ).

    CLEAR ls_component.

    MOVE 'KBETR' TO ls_component-name.

    ls_component-type ?= cl_abap_datadescr=>describe_by_name( 'KBETR_KOND' ).

        lo_typedescr ?= cl_abap_datadescr=>describe_by_name( 'KBETR_KOND' ).

**        ls_component-type = lo_typedescr->type_kind.

    APPEND ls_component TO lt_component.

  ENDIF.

  DESCRIBE TABLE lt_component LINES val_index.

 

** Find the Index for the Key field KNUMH

  LOOP AT lt_component INTO ls_component.

    IF ls_component-name = 'KNUMH'.

      MOVE sy-tabix TO key_index.

    ENDIF.

  ENDLOOP.

** Create new line type with added field

  CLEAR : ls_frow.

  TRY.

      ls_frow = cl_abap_structdescr=>create( p_components = lt_component ).

    CATCH cx_sy_struct_creation .

  ENDTRY.

 

** Create the Internal Table structure

  IF ls_frow IS NOT INITIAL.

    CLEAR : lt_tab.

    TRY.

**        lt_tab = cl_abap_tabledescr=&gtcreate( p_line_type  = ls_frow ).

        lt_tab = cl_abap_tabledescr=>create( p_line_type  = ls_frow ).

      CATCH cx_sy_table_creation .

    ENDTRY.

  ENDIF.

 

  IF lt_tab IS NOT INITIAL.

    CREATE DATA gt_tab TYPE HANDLE lt_tab.

  ENDIF.

 

  IF ls_row IS NOT INITIAL.

    CREATE DATA gs_row TYPE HANDLE ls_row.

  ENDIF.

 

  ASSIGN gt_tab->* to <gt_tab>.

  ASSIGN gs_row->* to <gs_row>.

 

 

ENDFORM.                    "create_structures

 

*&---------------------------------------------------------------------*

*&      Form  free_selections

*&---------------------------------------------------------------------*

* To Display Free Selections & extraction of data

*----------------------------------------------------------------------*

FORM free_selections.

  REFRESH : lt_tables, lt_fields, lt_fields_n.

  CLEAR   : ls_tables, ls_fields, ls_fields_n.

  CLEAR   : selection_id.

  CLEAR   : fs_dyns, fs_num.

  REFRESH : lt_where, lt_where_add.

 

** Extract Primary Key fields

  REFRESH : lt_field_list.

  CLEAR : ls_field_list.

  CALL METHOD cl_reca_ddic_tabl=>get_field_list

    EXPORTING

      id_name            = p_table

      if_suppress_mandt  = abap_true

      if_suppress_key    = abap_false

      if_suppress_nonkey = abap_true

    IMPORTING

      et_field_list      = lt_field_list

    EXCEPTIONS

      not_found          = 1

      OTHERS             = 2.

 

  IF lt_field_list IS NOT INITIAL.

** Delete the Mandatory fields available in Selection screen so that

** these fields will not show in Free Selection

    DELETE lt_field_list WHERE fieldname EQ 'KAPPL'.

    IF sy-subrc EQ 0.

      CLEAR : ls_where.

      CONCATENATE '''' p_kappl '''' INTO lv_kappl.

      CONCATENATE '(' 'KAPPL EQ ' lv_kappl ')' INTO ls_where-line SEPARATED BY space.

      APPEND ls_where TO lt_where.

    ENDIF.

    DELETE lt_field_list WHERE fieldname EQ 'KSCHL'.

    IF sy-subrc EQ 0.

      IF lt_where[] IS NOT INITIAL.

        CLEAR : ls_where.

        MOVE 'AND' TO ls_where-line.

        APPEND ls_where TO lt_where.

      ENDIF.

      CONCATENATE '''' p_kschl '''' INTO lv_kschl.

      CONCATENATE '(' 'KSCHL EQ' lv_kschl ')' INTO ls_where-line SEPARATED BY space.

      APPEND ls_where TO lt_where.

    ENDIF.

 

    MOVE 'F' TO lv_kind.                "Activate only Key fields in Free Selection.

    LOOP AT lt_field_list INTO ls_field_list.

      CLEAR : ls_fields.

      MOVE p_table TO ls_fields-tablename.

      MOVE ls_field_list-fieldname TO ls_fields-fieldname.

      APPEND ls_fields TO lt_fields.

    ENDLOOP.

  ELSE.

    MOVE 'T' TO lv_kind.                "Activate all fields in Free- Selections

  ENDIF.

 

** Call Free-Selections Init **

 

  MOVE p_table TO ls_tables-prim_tab.

  APPEND ls_tables TO lt_tables.

 

  CALL FUNCTION 'FREE_SELECTIONS_INIT'

    EXPORTING

      kind                     = lv_kind

      expressions              = fs_dyns-texpr

    IMPORTING

      selection_id             = selection_id

      where_clauses            = fs_dyns-clauses

      expressions              = fs_dyns-texpr

      field_ranges             = fs_dyns-trange

      number_of_active_fields  = fs_num

    TABLES

      tables_tab               = lt_tables

      fields_tab               = lt_fields

      fields_not_selected      = lt_fields_n

    EXCEPTIONS

      fields_incomplete        = 1

      fields_no_join           = 2

      field_not_found          = 3

      no_tables                = 4

      table_not_found          = 5

      expression_not_supported = 6

      incorrect_expression     = 7

      illegal_kind             = 8

      area_not_found           = 9

      inconsistent_area        = 10

      kind_f_no_fields_left    = 11

      kind_f_no_fields         = 12

      too_many_fields          = 13

      dup_field                = 14

      field_no_type            = 15

      field_ill_type           = 16

      dup_event_field          = 17

      node_not_in_ldb          = 18

      area_no_field            = 19

      OTHERS                   = 20.

  IF sy-subrc EQ 0.

** Call Free Selection Dialog Screen **

    CALL FUNCTION 'FREE_SELECTIONS_DIALOG'

      EXPORTING

        selection_id            = selection_id

        title                   = 'Free Selection for Pricing Conditions'

        as_window               = ' '

        alv                     = 'X'

        tree_visible            = 'X'

      IMPORTING

        where_clauses           = fs_dyns-clauses

        expressions             = fs_dyns-texpr

        field_ranges            = fs_dyns-trange

        number_of_active_fields = fs_num

      TABLES

        fields_tab              = lt_fields

        fields_not_selected     = lt_fields_n

      EXCEPTIONS

        internal_error          = 1

        no_action               = 2

        selid_not_found         = 3

        illegal_status          = 4

        OTHERS                  = 5.

    IF sy-subrc <> 0.

      MESSAGE 'Invalid Selection' TYPE 'I' DISPLAY LIKE 'E'.

      STOP.

    ELSE.

** Create Dynamic Where Clause

 

      CLEAR : ls_clause, ls_where.

      READ TABLE fs_dyns-clauses INTO ls_clause INDEX 1.

      IF sy-subrc EQ 0.

        lt_where_add[] = ls_clause-where_tab.

      ENDIF.

 

      IF lt_where[] IS NOT INITIAL.

        IF lt_where_add[] IS NOT INITIAL.

          CLEAR : ls_where.

          MOVE 'AND' TO ls_where-line.

          APPEND ls_where TO lt_where.

        ENDIF.

      ENDIF.

      APPEND LINES OF lt_where_add TO lt_where.

 

** Select Records From dynamic Pricing condition table using Dynamic Where clause

      IF lt_where[] IS NOT INITIAL.

        SELECT * FROM (p_table)

        INTO CORRESPONDING FIELDS OF TABLE <gt_tab>

        where (lt_where).

 

** Update Pricing condition record number in LT_KONH Table

        IF sy-subrc EQ 0 AND  <gt_tab> is NOT INITIAL.

          LOOP AT  <gt_tab> assigning <gs_row>.

            ASSIGN component key_index of structure <gs_row> to <gd_fld>.

            IF sy-subrc EQ 0.

              CLEAR : ls_konh.

              MOVE <gd_fld> TO ls_konh-knumh.

              APPEND ls_konh TO lt_konh.

            ENDIF.

          ENDLOOP.

 

** Extract Pricing Condition Value from KONP

          IF lt_konh[] IS NOT INITIAL.

            REFRESH : lt_konp.

            SELECT knumh kbetr krech loevm_ko FROM konp

            INTO TABLE lt_konp

              FOR ALL ENTRIES IN lt_konh

              WHERE knumh = lt_konh-knumh.

 

            IF lt_konp[] IS NOT INITIAL.

              DELETE lt_konp WHERE loevm_ko EQ 'X'.

            ENDIF.

          ENDIF.

        ENDIF.

      ENDIF.

      IF <gt_tab> is NOT INITIAL.

        LOOP AT <gt_tab> assigning <gs_row>.

*          CLEAR .

          ASSIGN component key_index of structure <gs_row> to <gd_fld>.

          IF sy-subrc EQ 0.

            CLEAR : ls_konp.

            READ TABLE lt_konp INTO ls_konp WITH KEY knumh = <gd_fld>.

            IF sy-subrc EQ 0.

              IF ls_konp-krech EQ 'A'.         "Calculation type is % then divide by 10

                COMPUTE ls_konp-kbetr = ls_konp-kbetr / 10.

              ENDIF.

              ASSIGN component val_index of structure <gs_row> to <gd_fld>.

              MOVE ls_konp-kbetr to <gd_fld>.

            ENDIF.

          ENDIF.

        ENDLOOP.

      ENDIF.

    ENDIF.

  ENDIF.

ENDFORM.                    "free_selections

*&---------------------------------------------------------------------*

*&      Form  report_display

*&---------------------------------------------------------------------*

* For Displaying ALV Grid

*----------------------------------------------------------------------*

FORM report_display.

  CLEAR : gr_table.

  TRY.

      CALL METHOD cl_salv_table=>factory

        EXPORTING

          list_display = if_salv_c_bool_sap=>false

        IMPORTING

          r_salv_table = gr_table

        CHANGING

          t_table      = <gt_tab>.

    CATCH cx_salv_msg .

  ENDTRY.

 

  IF gr_table IS NOT INITIAL.

** Activate standard Functions of ALV **

    gr_functions = gr_table->get_functions( ).

    gr_functions->set_all( if_salv_c_bool_sap=>true ).

** Activate Standard Layout Options **

    MOVE sy-repid TO gr_layout_key-report.

    gr_layout = gr_table->get_layout( ).

    gr_layout->set_key( gr_layout_key ).

    gr_layout->set_save_restriction( if_salv_c_layout=>restrict_none ).

** Column Settings **

    gr_columns = gr_table->get_columns( ).

    IF gr_columns IS NOT INITIAL.

      PERFORM column_settings.

    ENDIF.

    gr_columns->set_optimize( if_salv_c_bool_sap=>true ).

** Top of List **

    PERFORM top_of_page CHANGING gr_content.

    gr_table->set_top_of_list( gr_content ).

    CALL METHOD gr_table->display.

  ENDIF.

ENDFORM.                    "report_display

 

*&---------------------------------------------------------------------*

*&      Form  column_settings

*&---------------------------------------------------------------------*

* For Column settings for ALV Grid

*----------------------------------------------------------------------*

FORM column_settings.

  REFRESH : lt_columns.

  CLEAR : ls_columns.

  lt_columns = gr_columns->get( ).

  IF lt_columns[] IS NOT INITIAL.

    LOOP AT lt_columns INTO ls_columns.

      TRY.

          gr_column ?= gr_columns->get_column( columnname = ls_columns-columnname ).

        CATCH cx_salv_not_found .

      ENDTRY.

      IF gr_column IS NOT INITIAL.

        lv_domname = gr_column->get_ddic_domain( ).

**      Hide Client and condition number columns in ALV Grid

        IF lv_domname EQ 'MANDT' OR lv_domname EQ 'KNUMB'.

          gr_column->set_technical( if_salv_c_bool_sap=>true ).

        ENDIF.

      ENDIF.

    ENDLOOP.

  ENDIF.

 

ENDFORM.                    "column_settings

 

*&---------------------------------------------------------------------*

*&      Form  top_of_page

*&---------------------------------------------------------------------*

* To setting Top of Page in ALV Grid

*----------------------------------------------------------------------*

*      --&gtLR_CONTENT text

*---------------------------------------------------------------------*

FORM top_of_page CHANGING lr_content TYPE REF TO cl_salv_form_element.

  DATA : lr_grid TYPE REF TO cl_salv_form_layout_grid,

         lr_text TYPE REF TO cl_salv_form_text,

         lr_label TYPE REF TO cl_salv_form_label,

         lr_head TYPE string,

         lr_row  TYPE string.

  MOVE 'Pricing Conditions Report' TO lr_head.

  CONCATENATE 'Condition Type : ' p_kschl INTO lr_row SEPARATED BY space.

  CREATE OBJECT lr_grid.

 

  lr_grid->create_header_information(

                        row     = 1

                        column  = 1

                        text    = lr_head

                        tooltip = lr_head ).

  lr_grid->add_row( ).

  lr_label = lr_grid->create_label(

                        row         = 2

                        column      = 1

                        text        = lr_row

                        tooltip     = lr_row ).

  CONCATENATE 'Table : ' ls_tmc1t-gstru

              '/ Key Combination : ' ls_tmc1t-gstxt INTO lr_row SEPARATED BY space.

  lr_grid->add_row( ).

  lr_label = lr_grid->create_label(

                        row         = 3

                        column      = 1

                        text        = lr_row

                        tooltip     = lr_row ).

  lr_content = lr_grid.

 

ENDFORM.                    "top_of_page

 

Source Link:https://wiki.scn.sap.com/wiki/display/ABAP/Dynamic+Report+for+Pricing+Conditions+Master+Data

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值