ABAP ile treemapping

Bir tablomuz var, bu tablonun sonucunda şöyle bir çıktı almamız gerekiyor.
Ekran görüntüsü

Aşağıdaki ekran görüntüsünü ele alıp tablonun nasıl okunması gerektiğini anlatayım.

left-> önceki

right -> sonraki

up -> üstündeki

down->altındaki

left, right, up, down değerleri bir düğümün (node) diğer düğümlere göre konumunu gösterir. Soru işareti ile gösterilen ocaktan önce bir eleman olmadığı için o kökte başa gelmiş olunuyor.

Koddaki yorum satırlarıyla anlatılmaya çalışılmıştır.

*&---------------------------------------------------------------------*
*& Report ZCRM_TREE_MAPPING_2
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zcrm_tree_mapping_2.


TYPES : BEGIN OF tree,

          client  TYPE mandt,
          id_no   TYPE char10,
          name    TYPE char10,
          left_1  TYPE char10,
          right_1 TYPE char10,
          up_1    TYPE char10,
          down_1  TYPE char10,

        END OF tree .


TYPES : BEGIN OF kirilim_sayisi,

          id_no          TYPE char10,
          kirilim_sayisi TYPE char10,
          name           TYPE char10,
        END OF kirilim_sayisi.

TYPES :BEGIN OF print,

         index   TYPE char10,
         client  TYPE mandt,
         id_no   TYPE char10,
         name    TYPE char10,
         left_1  TYPE char10,
         right_1 TYPE char10,
         up_1    TYPE char10,
         down_1  TYPE char10,

       END OF print.


DATA : BEGIN OF tree_kirilim,

         kirilim_no TYPE char3,         " numara
         agac       TYPE TABLE OF tree, " tablo

       END OF tree_kirilim.



DATA : gt_agac      TYPE TABLE OF tree,
       gt_agac2     TYPE TABLE OF tree,
       gt_temp_agac TYPE TABLE OF tree,
       gs_agac      TYPE tree,
       gs_agac2     TYPE tree,
       gs_agac_root TYPE tree,

       gt_kirilim   LIKE TABLE OF tree_kirilim,
       gt_kirilim2  LIKE TABLE OF tree_kirilim,
       gs_kirilim   LIKE tree_kirilim,

       gt_print     TYPE TABLE OF print,
       gs_print     TYPE print,
       gs_print2    TYPE print,

       gt_yorumla   TYPE TABLE OF kirilim_sayisi,
       gs_yorumla   TYPE kirilim_sayisi.

DATA: lv_son_kontrol   TYPE boolean VALUE abap_false,
      lv_kirilim_sayac TYPE i VALUE 1.


"&  ________________________________________ Selection-Screen _________________________________________

SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.

PARAMETERS : p_rad1    RADIOBUTTON GROUP rb1,
             p_rad2    RADIOBUTTON GROUP rb1. " ters.

SELECTION-SCREEN END OF BLOCK b1.

SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-002.
PARAMETERS : p_yorum AS CHECKBOX .
SELECTION-SCREEN END OF BLOCK b2.
SELECT * FROM zcrm_t_tree_map INTO TABLE gt_agac.

"& _________________________________________ Selection-Screen  _________________________________________

" Biraz boşluk bırakmak istedim.
SKIP 2.

"& Elimizdeki tabloyu bi basalım ekrana...

*LOOP AT gt_agac INTO gs_agac.
*
*
*  WRITE :/
*       sy-vline, gs_agac-id_no,
*       sy-vline, gs_agac-name,
*       sy-vline, gs_agac-left_1,
*       sy-vline , gs_agac-right_1 ,
*       sy-vline , gs_agac-up_1,
*       sy-vline , gs_agac-down_1 , sy-vline.
*
*
*ENDLOOP.

SKIP 1.

" up ve left ' e göre bir sıralayalım.
SORT gt_agac ASCENDING BY up_1 left_1.
" ilk kırılımı bulmak istiyoruz. Sort'ladığımız için ilk kırılımı bulabildik.
READ TABLE gt_agac INTO gs_agac_root INDEX 1. "root bulduk
APPEND gs_agac_root TO gt_temp_agac.



"  ilk kırılımları bulan kod.
"& gt_kirilim içerisinde olmasını beklediğimiz sonuç şöyle olacak..
"
"  kilirim_no   tablo
"   1            3x9(internal tablo)->tree
"   ... diye devam ediyor.

LOOP AT gt_agac INTO gs_agac.

  IF gs_agac-left_1 EQ gs_agac_root-id_no.

    APPEND gs_agac TO gt_temp_agac.
    CLEAR gs_agac_root.
    gs_agac_root = gs_agac.

  ENDIF.

ENDLOOP.

gs_kirilim-agac = gt_temp_agac.
gs_kirilim-kirilim_no = lv_kirilim_sayac.
APPEND gs_kirilim TO gt_kirilim.
CLEAR: gs_kirilim , gs_agac, gt_temp_agac.


" bu perform,
"& gt_kirilim içerisinde olmasını beklediğimiz sonuç şöyle olacak..
"
"  kilirim_no   tablo
"   1            3x9(internal tablo)->tree
"   2            5x9(internal tablo)->tree
"   3            2x9(internal tablo)->tree
"   4            1x9(internal tablo)->tree
"   . gibi yapar...
PERFORM kirilim_belirleme.


" düz ve ya ters olmasına göre siralama yapar.
PERFORM siralama.

" & ağaç yapısını tutan tabloya kırılım numaralarını atamak için type'i print olan bir tablo oluşturduk,
" kirilim_no (index) ekledim.

PERFORM kirilim_atama.
" şöyle bir görünüm elde edeceğiz... gt_print.
"   index  client id_no  name  left_1    right_1  up_1   down_1
"     1     100    001   2015    0        005     0      002
"     2     100    002   Ocak    0        003     001    0
"     2     100    003   Şubat   002      0       001    0
"     1     100    005   2016    001      009     0      0



CLEAR : gs_agac , gs_print2.

DATA : lv_sayi  TYPE i, "toplam sayi sayısı..
       lv_sayac TYPE i VALUE 0.

DESCRIBE TABLE gt_print LINES lv_sayi .

READ TABLE gt_print INTO gs_print2 INDEX 1. " birinci elimde

PERFORM write USING gs_print2.

DATA: lv_krlm  TYPE i VALUE 1,
      lv_tmp   TYPE boolean VALUE abap_false,
      lv_yorum TYPE i VALUE 0.

DO.

  DATA: lv_max TYPE i.

  "kırılım sayılarını veren tablo
  IF lv_krlm EQ 1.

    lv_yorum = lv_yorum + 1.
    " eğer kırılım sayısı 1. de ise name yıldır..
    gs_yorumla-id_no          = lv_yorum.
    gs_yorumla-name           = gs_print2-name.
    gs_yorumla-kirilim_sayisi = lv_krlm.

    APPEND gs_yorumla TO gt_yorumla.

    lv_max = lv_krlm.

  ENDIF.

  IF ( lv_sayi ) = lv_sayac.

    CLEAR : gt_print, gs_print, gs_print2.
    EXIT.

  ENDIF.


  IF p_rad1 EQ abap_true.

    PERFORM duz.

  ELSEIF p_rad2 EQ abap_true.
 " eğer kırılımı ters istiyorsaaaaa.
    PERFORM ters.

  ENDIF.

ENDDO.

IF p_yorum EQ abap_true.
  NEW-LINE.
  PERFORM yorumla_print.
ENDIF.



FORM write USING is_print TYPE print.

  DATA: v_space(5) TYPE c VALUE '     '.

  DO is_print-index TIMES.

    WRITE: v_space.

  ENDDO.

  DATA(renk) = is_print-index.

  CASE renk.
    WHEN 1.
      WRITE : '-> ', is_print-name COLOR 1 NO-GAP  .
    WHEN 2.
      WRITE : '-> ', is_print-name COLOR 2 NO-GAP .
    WHEN 3.
      WRITE : '-> ', is_print-name COLOR 3 NO-GAP .
    WHEN 4.
      WRITE : '-> '  , is_print-name COLOR 4 NO-GAP .
    WHEN 5.
      WRITE : '-> '  , is_print-name COLOR 5 NO-GAP .
    WHEN 6.
      WRITE : '-> ' , is_print-name COLOR 6 NO-GAP .
    WHEN 7.
      WRITE : '-> ', is_print-name COLOR 7 NO-GAP .

    WHEN OTHERS.
      WRITE : '-> ' , is_print-name  .
  ENDCASE.


  NEW-LINE.

  lv_sayac = lv_sayac + 1.
ENDFORM.

FORM duz.



 " bir kırılımı var ve ilk kez yazılıyorsa. (lv_tmp = true.)

  IF gs_print2-down_1 NE '0' AND lv_tmp EQ abap_false.  "

    lv_krlm = lv_krlm + 1.

    IF lv_max <= lv_krlm.

      lv_max = lv_krlm.

      READ TABLE gt_yorumla INTO gs_yorumla WITH KEY id_no = lv_yorum.
      gs_yorumla-kirilim_sayisi = lv_max.

      MODIFY gt_yorumla FROM gs_yorumla TRANSPORTING kirilim_sayisi WHERE id_no = lv_yorum .

    ENDIF.

    READ TABLE gt_print INTO gs_print WITH KEY id_no = gs_print2-down_1.
    PERFORM write USING gs_print.


    CLEAR gs_print2.
    gs_print2 = gs_print.
    CLEAR: gs_print.

" kırılım yok ve eğer sağ tarafında bir eleman var ise.

  ELSEIF gs_print2-right_1 NE '0'.


    READ TABLE gt_print INTO gs_print WITH KEY id_no = gs_print2-right_1.


    IF lv_tmp EQ abap_true.

      READ TABLE gt_print INTO gs_print WITH KEY id_no = gs_print-right_1.

    ENDIF.

    PERFORM write USING gs_print.
    CLEAR gs_print2.
    gs_print2 = gs_print.
    CLEAR: gs_print.

    lv_tmp = abap_false.

 " eğer sağ tarafında
  ELSEIF gs_print2-right_1 EQ '0' AND gs_print2-down_1 EQ '0'.

    DATA(tmp) = lv_krlm - 1.
    DO tmp TIMES.

      READ TABLE gt_print INTO gs_print WITH KEY id_no = gs_print2-up_1. " yukarıdan gelen gs_print2.

      lv_krlm = lv_krlm - 1.
      IF gs_print-right_1 EQ '0'.

        READ TABLE gt_print INTO gs_print WITH KEY id_no = gs_print-right_1.
        lv_tmp = abap_true.

      ELSE .
        lv_tmp = abap_false.
        READ TABLE gt_print INTO gs_print WITH KEY id_no = gs_print-right_1.
        gs_print2 = gs_print.

        EXIT.
      ENDIF.


      IF gs_print-right_1 NE '0'.
        EXIT.
      ENDIF.

      gs_print2 = gs_print.

    ENDDO.

    IF lv_tmp NE abap_true.

      PERFORM write USING gs_print.

    ENDIF.

    CLEAR gs_print2.
    gs_print2 = gs_print.
    CLEAR: gs_print.

  ENDIF.

ENDFORM.

FORM ters.


  " gt_print2

  IF gs_print2-down_1 NE '0'. " kırılımı var mı ?

    lv_krlm = lv_krlm + 1.

    IF lv_max <= lv_krlm.

      lv_max = lv_krlm.

      READ TABLE gt_yorumla INTO gs_yorumla WITH KEY id_no = lv_yorum.
      gs_yorumla-kirilim_sayisi = lv_max.

      MODIFY gt_yorumla FROM gs_yorumla TRANSPORTING kirilim_sayisi WHERE id_no = lv_yorum .

    ENDIF.


    READ TABLE gt_print INTO gs_print WITH KEY id_no = gs_print2-down_1.

    "peki bu kırılım en sondaki mi ? sona doğru git
    PERFORM en_saga_git USING gs_print CHANGING gs_print.

    PERFORM write USING gs_print.
    CLEAR gs_print2.
    gs_print2 = gs_print.
    CLEAR: gs_print.

    lv_tmp = abap_false.

  ELSEIF gs_print2-left_1 NE '0'.

    READ TABLE gt_print INTO gs_print WITH KEY id_no = gs_print2-left_1.


    IF lv_tmp EQ abap_true.

      READ TABLE gt_print INTO gs_print WITH KEY id_no = gs_print-left_1.

    ENDIF.


    PERFORM write USING gs_print.

    CLEAR gs_print2.
    gs_print2 = gs_print.
    CLEAR: gs_print.

    "eğer solunda daha fazla gideceği yer yoksa, bir üst kırılıma çık.
  ELSEIF gs_print2-left_1 EQ '0' AND gs_print2-down_1 EQ '0'.  "


    DATA(tmp) = lv_krlm - 1.
    DO tmp TIMES.

      READ TABLE gt_print INTO gs_print WITH KEY id_no = gs_print2-up_1. " yukarıdan gelen gs_print2.
      lv_krlm = lv_krlm - 1.

      IF gs_print-left_1 EQ '0'.

        READ TABLE gt_print INTO gs_print WITH KEY id_no = gs_print-up_1.
        lv_tmp = abap_false.

      ELSE.

        lv_tmp = abap_true.
        READ TABLE gt_print INTO gs_print WITH KEY id_no = gs_print-left_1.
        gs_print2 = gs_print.

        EXIT.

      ENDIF.

      IF gs_print-left_1 EQ '0'.
        lv_tmp = abap_false.
        gs_print2 = gs_print.
      ELSE.
        READ TABLE gt_print INTO gs_print WITH KEY id_no = gs_print-left_1.
        gs_print2 = gs_print.
        lv_tmp = abap_true.
        EXIT.
      ENDIF.



    ENDDO.

    IF lv_tmp EQ abap_true.

      IF gs_print2-up_1 EQ '0'.
        lv_krlm = 1.
      ENDIF.

      PERFORM write USING gs_print.

    ENDIF.

  ENDIF.

ENDFORM.

FORM kirilim_atama.

  LOOP AT gt_kirilim2 INTO gs_kirilim.

    MOVE-CORRESPONDING gs_kirilim-agac TO gt_agac2.
    DATA(lv_tabix) =  sy-tabix.

    LOOP AT gt_agac2 INTO gs_agac.

      gs_print-index =  lv_tabix.
      gs_print-name = gs_agac-name.
      gs_print-client  =  gs_agac-client.
      gs_print-id_no   =   gs_agac-id_no.
      gs_print-down_1 = gs_agac-down_1.
      gs_print-left_1 = gs_agac-left_1 .
      gs_print-right_1 = gs_agac-right_1.
      gs_print-up_1 = gs_agac-up_1.

      APPEND gs_print TO gt_print.

    ENDLOOP.

  ENDLOOP.


ENDFORM.

FORM kirilim_belirleme.

  DO.

    READ TABLE gt_kirilim INTO gs_kirilim INDEX lv_kirilim_sayac.
    lv_kirilim_sayac  = lv_kirilim_sayac + 1.

    IF sy-subrc EQ 0 AND lv_son_kontrol = abap_false.

      gt_agac2 = gs_kirilim-agac.

      IF gt_agac2 IS NOT INITIAL.

        LOOP AT gt_agac2 INTO gs_agac.

          LOOP AT gt_agac INTO gs_agac2 WHERE up_1 EQ gs_agac-id_no.

            APPEND gs_agac2 TO gt_temp_agac.

          ENDLOOP.

        ENDLOOP.

        IF gt_temp_agac IS NOT INITIAL.

          lv_son_kontrol = abap_false.
          gs_kirilim-agac = gt_temp_agac.
          gs_kirilim-kirilim_no = lv_kirilim_sayac.


          APPEND gs_kirilim TO gt_kirilim.

        ELSE.

          lv_son_kontrol = abap_true.

        ENDIF.

        CLEAR : gt_temp_agac, gt_agac2.

      ENDIF.

    ELSE.

      EXIT.

    ENDIF.

  ENDDO.

  CLEAR : gs_kirilim, gs_agac, gt_agac2, lv_kirilim_sayac .


ENDFORM.

FORM siralama.

  LOOP AT gt_kirilim INTO gs_kirilim.

    MOVE-CORRESPONDING gs_kirilim-agac TO gt_agac2.

    IF p_rad1 EQ abap_true.

      SORT gt_agac2 ASCENDING BY up_1 left_1.
    ELSE.
      SORT gt_agac2 DESCENDING BY up_1 left_1.
    ENDIF.

    gs_kirilim-kirilim_no = sy-tabix.
    gs_kirilim-agac = gt_agac2.

    APPEND gs_kirilim TO gt_kirilim2.

  ENDLOOP.

  CLEAR: gs_kirilim, gt_agac2, gs_agac.

ENDFORM.

FORM en_saga_git USING is_print TYPE print
                  CHANGING es_print TYPE print.

  DATA : is_temp TYPE print.

  MOVE-CORRESPONDING is_print TO is_temp.

  DO.

    IF is_temp-right_1 NE '0'.

      READ TABLE gt_print INTO is_temp WITH KEY id_no = is_temp-right_1.

    ELSE. " en sağ ise...

      es_print = is_temp.
      EXIT.
    ENDIF.

  ENDDO.


ENDFORM.

FORM yorumla_print.

*  gt_yorumla

  CLEAR gs_yorumla.
  DATA: toplam TYPE i.
  DATA: sayi TYPE i.
  LOOP AT gt_yorumla INTO gs_yorumla.
    sayi = gs_yorumla-kirilim_sayisi.
    WRITE : / gs_yorumla-name(5) , ' -> ' , sayi, ' kırılımı vardır.' .
    toplam = toplam + gs_yorumla-kirilim_sayisi.
  ENDLOOP.

  WRITE:/ 'Toplam kırılım sayısı ', toplam.



ENDFORM.

Yorum bırakın

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.

WordPress.com'da bir web sitesi veya blog oluşturun

Yukarı ↑