SAP Abap Dinamik ALV

sap

Merhaba bu yazımızda SAP Abap Dinamik ALV konusunu ele alacağız. Mümkün olduğunca basit ve sade bir örnek üzerinden ilerleyeceğiz. Eğer bu örneğin mantığını kavrarsanız iş hayatında karşınıza çıkacak bir çok yerde sıkıntı yaşamadan sorunları çözebilirsiniz.

Senaryo

Örneğimizde dinamik alv için veriyi bir excel dosyasından okuyacağız. Malzeme, üretim yeri, ve depo yeri bazında tarihe göre satırları kümüle toplayacağız. Her farklı tarih ayrı bir kolon olarak gösterilecektir. Bu senaryoda tarih kolonu çekilen veriye göre değişiklik gösterecektir.

Excelden Veriyi Okuma

İlk olarak excelden verimizi okuyalım. Excel veri yapısı aşağıdaki gibi olacaktır. Siz de excel dosyanızı bu formatta düzenleyebilirsiniz.

MalzemeÜretim YeriDepo YeriTarihMiktar
1231000101001.01.20205
1231000101005.01.20207
4561000101005.01.20208
4561000101002.01.20201
4561000101003.01.20202

Selection screen de dosya yolumuzu seçeceğimiz bir parametre tanımlıyoruz. Dosya seçim popup ının gelmesi için AT SELECTION-SCREEN ON VALUE-REQUEST FOR da search help bağlamamız gerekiyor.


SELECTION-SCREEN BEGIN OF BLOCK b1.
PARAMETERS : p_file LIKE rlgrap-filename OBLIGATORY
  DEFAULT 'C:\Users\mozkan\Desktop\teknopati.xlsx'.
SELECTION-SCREEN END OF BLOCK b1.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
  CALL FUNCTION 'F4_FILENAME'
    EXPORTING
      program_name  = syst-cprog
      dynpro_number = syst-dynnr
      field_name    = ' '
    IMPORTING
      file_name     = p_file.

Dosya yolumuzu aldıktan sonra excelden verimizi aşağıdaki gibi okuyabiliriz.

METHOD get_data.
    DATA: it_raw       TYPE truxs_t_text_data.

    TRANSLATE p_file TO UPPER CASE.

    CALL FUNCTION 'TEXT_CONVERT_XLS_TO_SAP'
      EXPORTING
        i_field_seperator    = 'X'
        i_line_header        = 'X'
        i_tab_raw_data       = it_raw
        i_filename           = p_file
      TABLES
        i_tab_converted_data = gt_mard
      EXCEPTIONS
        conversion_failed    = 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.
  ENDMETHOD.

Fieldcat Oluşturma

Şimdi dinamik internal table oluşturacağız. Bunun için cl_alv_table_create=>create_dynamic_table methodunu kullanacağız. Dinamik tablo oluşturmak için önce istediğimiz yapıda bir fieldcat oluşturmalıyız. Malzeme, üretim yeri, depo yeri ve toplam kolonları sabit olacağı için el ile doldurabiliriz. Tarih alanını ise çektiğimiz verilerdeki tüm farklı tarihleri alıyoruz. Bir döngü ile fieldcat e ekliyoruz.


METHOD create_dyn_fcat.
    DATA: lv_counter TYPE i.
    gt_fcat_date[] = CORRESPONDING #( gt_mard ).
    SORT gt_fcat_date BY ersda.
    DELETE ADJACENT DUPLICATES FROM gt_fcat_date.

    CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
      EXPORTING
        i_structure_name       = 'ZMOS_TEKNOPATI'
      CHANGING
        ct_fieldcat            = gt_fcat
      EXCEPTIONS
        inconsistent_interface = 1
        program_error          = 2
        OTHERS                 = 3.

    DELETE gt_fcat WHERE fieldname EQ 'ERSDA' OR fieldname EQ 'LABST'.

    DESCRIBE TABLE gt_fcat LINES lv_counter.

    LOOP AT gt_fcat_date REFERENCE INTO DATA(lr_fcat_date).
      ADD 1 TO lv_counter.
      APPEND INITIAL LINE TO gt_fcat REFERENCE INTO DATA(lr_fcat).
      lr_fcat->col_pos = lv_counter.
      lr_fcat->fieldname = lr_fcat_date->ersda.
      lr_fcat->outputlen = 13.
      lr_fcat->ref_table = 'MARD'.
      lr_fcat->ref_field = 'LABST'.
    ENDLOOP.

    ADD 1 TO lv_counter.
    APPEND INITIAL LINE TO gt_fcat REFERENCE INTO lr_fcat.
    lr_fcat->col_pos = lv_counter.
    lr_fcat->fieldname = 'TOPLAM'.
    lr_fcat->outputlen = 13.
    lr_fcat->ref_table = 'MARD'.
    lr_fcat->ref_field = 'LABST'.
ENDMETHOD.

Burada ZMOS_TEKNOPATI tablosundan alıyoruz. Tablo yapısını aşağıdaki resimde görebilirsiniz.

1 tablo yapısı

Dinamik Tablo Oluşturma

Şimdi dinamik alv mizi aşağıdaki gibi oluşturalım. Bunun için gerekli data tanımlamalarını da yapmalısınız.



//Gerekli Tanımlamalar
DATA: gr_alv TYPE REF TO data.
FIELD-SYMBOLS:    TYPE STANDARD TABLE,
                  TYPE any,
                   TYPE any,
               TYPE any.

METHOD create_dyn_table.
    cl_alv_table_create=>create_dynamic_table(
      EXPORTING
        it_fieldcatalog = gt_fcat
      IMPORTING
        ep_table = gr_alv ).
    ASSIGN gr_alv->* TO .
ENDMETHOD.

Dinamik Tabloyu Doldurma

Şimdi oluşturduğumuz dinamik tabloyu dolduracağız. Burada önemli nokta dinamik olan tarih kolonlarını ASSIGN COMPONENT ile okuyarak doldurmak. Her satırda farklı stunlara denk gelecek veriler olabilir.


METHOD fill_dyn_table.
    DATA: lt_tmp_data TYPE TABLE OF zmos_teknopati.

    DATA: lv_matnr TYPE mard-matnr,
          lv_werks TYPE mard-werks,
          lv_lgort TYPE mard-lgort.

    DATA: lv_fieldname TYPE lvc_fname.

    LOOP AT gt_mard REFERENCE INTO DATA(lr_mard).
      COLLECT lr_mard->* INTO lt_tmp_data.
    ENDLOOP.

    LOOP AT lt_tmp_data REFERENCE INTO DATA(lr_tmp_data).
      IF lv_matnr NE lr_tmp_data->matnr OR lv_lgort NE lr_tmp_data->lgort
                                        OR lv_werks NE lr_tmp_data->werks.
        APPEND INITIAL LINE TO  ASSIGNING .
      ENDIF.

      ASSIGN COMPONENT 'TOPLAM' OF STRUCTURE  TO .
      ASSIGN COMPONENT 'MATNR' OF STRUCTURE  TO .
      IF  IS ASSIGNED.
         = lr_tmp_data->matnr.
        lv_matnr = lr_tmp_data->matnr.
      ENDIF.
      ASSIGN COMPONENT 'WERKS' OF STRUCTURE  TO .
      IF  IS ASSIGNED.
         = lr_tmp_data->werks.
        lv_werks = lr_tmp_data->werks.
      ENDIF.
      ASSIGN COMPONENT 'LGORT' OF STRUCTURE  TO .
      IF  IS ASSIGNED.
         = lr_tmp_data->lgort.
        lv_lgort = lr_tmp_data->lgort.
      ENDIF.

      lv_fieldname = lr_tmp_data->ersda.
      ASSIGN COMPONENT lv_fieldname OF STRUCTURE  TO .
      IF  IS ASSIGNED.
         = lr_tmp_data->labst.
        ADD  TO .
      ENDIF.
    ENDLOOP.
  ENDMETHOD.

Verileri Ekranda Gösterme

Dinamik tablomuzu da doldurduktan sonra ekranda Alv olarak gösterebiliriz. Ben burada dinamik yapıyalarda kullanımı kolay olduğu için cl_salv_table sınıfını kullandım. Siz isterseniz grid alv veya reuse alv de kullanabilirsiniz.


METHOD print_alv.
    DATA: lx_msg TYPE REF TO cx_salv_msg.
    TRY.
        cl_salv_table=>factory(
          IMPORTING
            r_salv_table = go_alv
          CHANGING
            t_table      =  ).
      CATCH cx_salv_msg INTO lx_msg.
    ENDTRY.

    alv_settings( ).
    go_alv->display( ).
ENDMETHOD.
dinamik

ABAP KODLARI

ZMOP_DENEME3


*&---------------------------------------------------------------------*
*& Report ZMOP_DENEME3
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ZMOP_DENEME3.

INCLUDE ZMOI_DENEME3_DEF.
INCLUDE ZMOI_DENEME3_CLS.

START-OF-SELECTION.
  lr_teknopati = new lcl_teknopati( ).
  lr_teknopati->run( ).

ZMOI_DENEME3_DEF


*&---------------------------------------------------------------------*
*& Include          ZMOI_DENEME3_DEF
*&---------------------------------------------------------------------*

CLASS lcl_teknopati DEFINITION DEFERRED.

DATA: lr_teknopati TYPE REF TO lcl_teknopati.

FIELD-SYMBOLS:    TYPE STANDARD TABLE,
                  TYPE any,
                   TYPE any,
               TYPE any.

SELECTION-SCREEN BEGIN OF BLOCK b1.
PARAMETERS : p_file LIKE rlgrap-filename OBLIGATORY
  DEFAULT 'C:\Users\mozkan\Desktop\teknopati.xlsx'.
SELECTION-SCREEN END OF BLOCK b1.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.

  CALL FUNCTION 'F4_FILENAME'
    EXPORTING
      program_name  = syst-cprog
      dynpro_number = syst-dynnr
      field_name    = ' '
    IMPORTING
      file_name     = p_file.

ZMOI_DENEME3_CLS


*&---------------------------------------------------------------------*
*& Include          ZMOI_DENEME3_CLS
*&---------------------------------------------------------------------*

CLASS lcl_teknopati DEFINITION.
  PUBLIC SECTION.
    TYPES: BEGIN OF ty_fcat_date,
             ersda TYPE mard-ersda,
           END OF ty_fcat_date.

    DATA: gt_mard      TYPE TABLE OF zmos_teknopati,
          gt_fcat_date TYPE TABLE OF ty_fcat_date,
          gt_fcat      TYPE lvc_t_fcat.

    DATA: gr_alv TYPE REF TO data.

    DATA: go_alv TYPE REF TO cl_salv_table.

    METHODS: run,
      get_data,
      create_dyn_fcat,
      create_dyn_table,
      fill_dyn_table,
      print_alv,
      alv_settings.
ENDCLASS.
CLASS lcl_teknopati IMPLEMENTATION.
  METHOD run.
    get_data( ).
    create_dyn_fcat( ).
    create_dyn_table( ).
    fill_dyn_table( ).
    print_alv( ).
  ENDMETHOD.
  METHOD get_data.
    DATA: it_raw       TYPE truxs_t_text_data.

    TRANSLATE p_file TO UPPER CASE.

    CALL FUNCTION 'TEXT_CONVERT_XLS_TO_SAP'
      EXPORTING
        i_field_seperator    = 'X'
        i_line_header        = 'X'
        i_tab_raw_data       = it_raw
        i_filename           = p_file
      TABLES
        i_tab_converted_data = gt_mard
      EXCEPTIONS
        conversion_failed    = 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.
  ENDMETHOD.
  METHOD create_dyn_fcat.
    DATA: lv_counter TYPE i.
    gt_fcat_date[] = CORRESPONDING #( gt_mard ).
    SORT gt_fcat_date BY ersda.
    DELETE ADJACENT DUPLICATES FROM gt_fcat_date.

    CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
      EXPORTING
        i_structure_name       = 'ZMOS_TEKNOPATI'
      CHANGING
        ct_fieldcat            = gt_fcat
      EXCEPTIONS
        inconsistent_interface = 1
        program_error          = 2
        OTHERS                 = 3.

    DELETE gt_fcat WHERE fieldname EQ 'ERSDA' OR fieldname EQ 'LABST'.

    DESCRIBE TABLE gt_fcat LINES lv_counter.

    LOOP AT gt_fcat_date REFERENCE INTO DATA(lr_fcat_date).
      ADD 1 TO lv_counter.
      APPEND INITIAL LINE TO gt_fcat REFERENCE INTO DATA(lr_fcat).
      lr_fcat->col_pos = lv_counter.
      lr_fcat->fieldname = lr_fcat_date->ersda.
      lr_fcat->outputlen = 13.
      lr_fcat->ref_table = 'MARD'.
      lr_fcat->ref_field = 'LABST'.
    ENDLOOP.

    ADD 1 TO lv_counter.
    APPEND INITIAL LINE TO gt_fcat REFERENCE INTO lr_fcat.
    lr_fcat->col_pos = lv_counter.
    lr_fcat->fieldname = 'TOPLAM'.
    lr_fcat->outputlen = 13.
    lr_fcat->ref_table = 'MARD'.
    lr_fcat->ref_field = 'LABST'.
  ENDMETHOD.
  METHOD create_dyn_table.
    cl_alv_table_create=>create_dynamic_table(
      EXPORTING
        it_fieldcatalog = gt_fcat
      IMPORTING
        ep_table = gr_alv ).
    ASSIGN gr_alv->* TO .
  ENDMETHOD.
  METHOD fill_dyn_table.
    DATA: lt_tmp_data TYPE TABLE OF zmos_teknopati.

    DATA: lv_matnr TYPE mard-matnr,
          lv_werks TYPE mard-werks,
          lv_lgort TYPE mard-lgort.

    DATA: lv_fieldname TYPE lvc_fname.

    LOOP AT gt_mard REFERENCE INTO DATA(lr_mard).
      COLLECT lr_mard->* INTO lt_tmp_data.
    ENDLOOP.

    LOOP AT lt_tmp_data REFERENCE INTO DATA(lr_tmp_data).
      IF lv_matnr NE lr_tmp_data->matnr OR lv_lgort NE lr_tmp_data->lgort
                                        OR lv_werks NE lr_tmp_data->werks.
        APPEND INITIAL LINE TO  ASSIGNING .
      ENDIF.

      ASSIGN COMPONENT 'TOPLAM' OF STRUCTURE  TO .
      ASSIGN COMPONENT 'MATNR' OF STRUCTURE  TO .
      IF  IS ASSIGNED.
         = lr_tmp_data->matnr.
        lv_matnr = lr_tmp_data->matnr.
      ENDIF.
      ASSIGN COMPONENT 'WERKS' OF STRUCTURE  TO .
      IF  IS ASSIGNED.
         = lr_tmp_data->werks.
        lv_werks = lr_tmp_data->werks.
      ENDIF.
      ASSIGN COMPONENT 'LGORT' OF STRUCTURE  TO .
      IF  IS ASSIGNED.
         = lr_tmp_data->lgort.
        lv_lgort = lr_tmp_data->lgort.
      ENDIF.

      lv_fieldname = lr_tmp_data->ersda.
      ASSIGN COMPONENT lv_fieldname OF STRUCTURE  TO .
      IF  IS ASSIGNED.
         = lr_tmp_data->labst.
        ADD  TO .
      ENDIF.
    ENDLOOP.
  ENDMETHOD.
  METHOD print_alv.
    DATA: lx_msg TYPE REF TO cx_salv_msg.
    TRY.
        cl_salv_table=>factory(
          IMPORTING
            r_salv_table = go_alv
          CHANGING
            t_table      =  ).
      CATCH cx_salv_msg INTO lx_msg.
    ENDTRY.

    alv_settings( ).
    go_alv->display( ).
  ENDMETHOD.
  METHOD alv_settings.
    DATA: lo_cols      TYPE REF TO cl_salv_columns.
    DATA: lr_fname     TYPE RANGE OF lvc_fname.
    DATA: lr_display   TYPE REF TO cl_salv_display_settings.

    lr_fname =  VALUE #( option = 'EQ' sign = 'I' ( low = 'MATNR' )
                                                  ( low = 'WERKS' )
                                                  ( low = 'LGORT' ) ).
    lo_cols = go_alv->get_columns( ).
    lo_cols->set_optimize( 'X' ).
    
    lr_display = go_alv->get_display_settings( ).
    lr_display->set_list_header( 'Teknopati Dinamik ALV' ).
    
    LOOP AT lo_cols->get( ) REFERENCE INTO DATA(lr_col).
      IF lr_col->columnname NOT IN lr_fname.
        lr_col->r_column->set_short_text( CONV #( lr_col->columnname ) ).
        lr_col->r_column->set_long_text( CONV #( lr_col->columnname ) ).
        lr_col->r_column->set_medium_text( CONV #( lr_col->columnname ) ).
      ENDIF.
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

Benzer diğer yazılarımıza buradan ulaşabilirsiniz. Bir sonraki yazımızda görüşmek dileğiyle.

E-bültene Abone Ol Merak etmeyin. Spam yapmayacağız.

Yazar

Merhaba, Kocaeli Üniversitesi Bilişim Sistemleri Mühendisliği Bölümü'nden 2019 yılında mezun oldum. Daha sonra Sap sektöründe çalışma hayatına başladım. Burada elimden geldiğince tecrübelerimi sizinle paylaşacağım.

İlgili Yazılar

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Hızlı yorum için giriş yapın.

Başka Yazı Yok

Kayıt Ol

Zaten üye misiniz? Giriş Yap

Giriş Yap

Henüz üyeliğiniz yok mu? Kayıt Ol