ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Internal Table] Internal table
    SAP/Abap 2022. 1. 19. 19:28

    [Internal table : 명령어]

    1) 인터널테이블 값 할당

    일반 변수와 마찬가지로 MOVE구문을 사용한 값 할당이 가능하다.
    # Header line이 없는 인터널 테이블
    [MOVE | MOVE-CORRESPONDING] itab1 TO itab2.                 ==            itab2 = itab1

    # Header line이 있는 인터널 테이블
    [MOVE | MOVE-CORRESPONDING] itab1[] TO itab2[].            ==            itab2[] = itab1[]
    • Header line이 있는 인터널테이블 할당시 header line값만 복사된다.
      • [] 키워드를 사용해야 table의 body값이 복사된다.
    REPORT ZA05_15.
    
    TYPES : BEGIN OF t_line,
      col1 TYPE i,
      col2 TYPE i,
    END OF t_line.
    
    DATA : gt_itab1 TYPE STANDARD TABLE OF t_line WITH HEADER LINE,
           gt_itab2 TYPE STANDARD TABLE OF t_line,
           gs_wa    LIKE LINE OF gt_itab2.
    
    DO 5 TIMES.
      gt_itab1-col1 = sy-index.
      gt_itab1-col2 = sy-index.
      INSERT TABLE gt_itab1.
    ENDDO.
    
    *MOVE gt_itab1[] TO gt_itab2.
    gt_itab2 = gt_itab1[].
    
    LOOP AT gt_itab2 INTO gs_wa.
      WRITE : / gs_wa-col1, gs_wa-col2.
    ENDLOOP.

     

    2) 인터널테이블 초기화

    CLEAR / REFRESH / FREE 구문으로 인터널 테이블을 초기화 할 수 있다.
    • CLEAR: Header line이 있는 경우 header line만 삭제된다. 그 외에는 table body를 삭제한다.
    • REFRESH: Table body를 삭제한다.
    • FREE: 할당된 메모리공간을 반환한다.
    REPORT ZA05_16.
    
    DATA : BEGIN OF gs_line,
      col1 TYPE i,
      col2 TYPE c,
    END OF gs_line.
    
    * DATA : gt_itab LIKE STANDARD TABLE OF gs_line.
    DATA : gt_itab LIKE STANDARD TABLE OF gs_line WITH HEADER LINE.
    
    gs_line-col1 = 1.
    gs_line-col2 = 'A'.
    INSERT gs_line INTO TABLE gt_itab.
    
    gs_line-col1 = 2.
    gs_line-col2 = 'B'.
    INSERT gs_line INTO TABLE gt_itab.
    
    *REFRESH gt_itab.
    FREE    gt_itab.
    *CLEAR   gt_itab.
    
    IF gt_itab IS INITIAL.
      WRITE : / 'Header line has no data'.
      IF gt_itab[] IS INITIAL.
        WRITE : / 'Internal table has no data'.
        FREE gt_itab.
      ENDIF.
    ENDIF.

     

    3) 인터널테이블 정렬

    SORT구문을 통해 인터널테이블 데이터를 정렬할 수 있다.
    # 테이블의 key컬럼으로 정렬
    SORT itab [ASCENDING | DESCENDING]

    # 임의의 컬럼을 지정하여 정렬
    SORT itab [ASCENDING | DESCENDING]
               BY f1 [ASCENDING | DESCENDING] ... BY fn [ASCENDING | DESCENDING]
    • Standard table, Hashed table의 데이터를 정렬할 수 있고, Sorted table에서는 사용이 불가능하다.
      • Sorted table은 이미 정렬된 데이터를 table로 갖고있으므로 SORT구문 사용시 syntax error가 발생한다.
    • Stable sort: SORT구문이 실행될때마다 바뀌는 sort sequence를 유지해주는 구문
    SORT itab ... STABLE
      • Key컬럼값이 같은경우 key컬럼 외의 데이터는 SORT될때마다 sequence가 바뀔 수 있는데 이와같은 문제를 stable sort로 해결할 수 있다.
    REPORT ZA05_17.
    
    DATA : BEGIN OF gs_line,
      col1 TYPE c,
      col2 TYPE i,
    END OF gs_line.
    
    DATA : gt_itab LIKE STANDARD TABLE OF gs_line WITH NON-UNIQUE KEY col1.
    
    gs_line-col1 = 'B'.  gs_line-col2 = 3.  APPEND gs_line TO gt_itab.
    gs_line-col1 = 'C'.  gs_line-col2 = 4.  APPEND gs_line TO gt_itab.
    gs_line-col1 = 'A'.  gs_line-col2 = 2.  APPEND gs_line TO gt_itab.
    gs_line-col1 = 'A'.  gs_line-col2 = 1.  APPEND gs_line TO gt_itab.
    
    WRITE : / '========ORIGINAL========'.
    PERFORM write_data.
    
    WRITE : / '========SORT========'.
    SORT gt_itab.
    PERFORM write_data.
    
    WRITE : / '========SORT(+COL1, +COL2)========'.
    SORT gt_itab BY col1 col2.
    PERFORM write_data.
    
    WRITE : / '========SORT(-COL1, +COL2)========'.
    SORT gt_itab ASCENDING BY col1 DESCENDING col2 ASCENDING.
    PERFORM write_data.
    
    
    FORM write_data.
      LOOP AT gt_itab INTO gs_line.
        WRITE : / gs_line-col1, gs_line-col2.
      ENDLOOP.
    ENDFORM.

     

    4) 인터널테이블의 속성 조회

    DESCRIBE TABLE itab [LINES gv_line] [OCCURS gv_init] [KIND gv_kind]
    • [LINES gv_line]: 해당 인터널 테이블의 현재 line수를 gv_line변수에 반환
    • [OCCURS gv_init]: 해당 인터널 테이블의 초기 line수를 gv_init변수에 반환
    • [KIND gv_kind]: 해당 인터널 테이블의 종류를 gv_kind에 반환 (T: Standard, S: Sorted, H: Hashed)
    REPORT ZA05_18.
    
    DATA : BEGIN OF gs_line,
      col1 TYPE c,
      col2 TYPE i,
    END OF gs_line.
    
    DATA : gt_itab LIKE STANDARD TABLE OF gs_line INITIAL SIZE 10.
    DATA : gv_line TYPE i.
    
    DO 20 TIMES.
      gs_line-col1 = sy-index.
      gs_line-col2 = sy-index * 2.
      INSERT gs_line INTO TABLE gt_itab.
    ENDDO.
    
    DESCRIBE TABLE gt_itab LINES gv_line.
    WRITE : / 'Internal table line: ', gv_line.

     

     

     

    [Internal table: 데이터 삽입]

    1) INSERT 구문

    • Table key를 이용한 line단위 데이터 삽입
      • 데이터 삽입 성공시 [sy-subrc = 0]
      • 데이터 삽입 실패(key값 중복)시 [sy-subrc = 4]
    INSERT line INTO TABLE itab.
    • Table key를 이용한 여러 line 데이터 삽입
      • itab1: source table   /   itab2: target table 
      • FROM ~ TO 구문을 통해 source table의 일부만 target table에 삽입할 수 있다.
    INSERT lines OF itab1 [FROM n1] [TO n2] INTO TABLE itab2.
    REPORT ZA05_19.
    
    DATA : BEGIN OF gs_line,
      col1 TYPE c,
      col2 TYPE i,
    END OF gs_line.
    
    DATA : gt_itab1 LIKE STANDARD TABLE OF gs_line WITH NON-UNIQUE KEY col1.
    DATA : gt_itab2 LIKE SORTED TABLE OF gs_line WITH NON-UNIQUE KEY col1.
    
    gs_line-col1 = 'B'.
    gs_line-col2 = 1.
    INSERT gs_line INTO TABLE gt_itab1.
    
    gs_line-col1 = 'A'.
    gs_line-col2 = 2.
    INSERT gs_line INTO TABLE gt_itab1.
    
    gs_line-col1 = 'C'.
    gs_line-col2 = 3.
    INSERT gs_line INTO TABLE gt_itab1.
    
    INSERT LINES OF gt_itab1 INTO TABLE gt_itab2.
    *INSERT LINES OF gt_itab1 FROM 1 TO 2 INTO TABLE gt_itab2.
    
    LOOP AT gt_itab2 INTO gs_line.
      WRITE : / gs_line-col1, gs_line-col2.
    ENDLOOP.

     

    • Index를 이용한 line단위 데이터 삽입
      • idx: target 인덱스
    INSERT line INTO itab [INDEX idx].
    • Index를 이용한 여러 line 데이터 삽입
    INSERT lines OF itab1 INTO itab2 [INDEX idx].

     

    • 인터널테이블의 타입에 따른 INSERT구문 효과
    Standard Table 인터널테이블 마지막 위치에 삽입   => APPEND구문과 같은 효과
    Sorted Table 인터널테이블의 정렬 순서에 따라 삽입
    Hashed Table 인터널테이블의 key컬럼의 hash값 순서에 따라 삽입
    REPORT ZA05_20.
    
    DATA : BEGIN OF gs_line,
      col1 TYPE c,
      col2 TYPE n,
    END OF gs_line.
    
    DATA : gt_itab LIKE STANDARD TABLE OF gs_line WITH NON-UNIQUE KEY col1.
    *DATA : gt_itab LIKE SORTED TABLE OF gs_line WITH UNIQUE KEY col1.
    *DATA : gt_itab LIKE HASHED TABLE OF gs_line WITH UNIQUE KEY col1.
    
    gs_line-col1 = 'B'.
    gs_line-col2 = 1.
    INSERT gs_line INTO TABLE gt_itab.
    
    gs_line-col1 = 'A'.
    gs_line-col2 = 2.
    INSERT gs_line INTO TABLE gt_itab.
    
    gs_line-col1 = 'A'.
    gs_line-col2 = 3.
    INSERT gs_line INTO TABLE gt_itab.
    
    gs_line-col1 = 'C'.
    gs_line-col2 = 4.
    INSERT gs_line INTO TABLE gt_itab.
    
    LOOP AT gt_itab INTO gs_line.
      WRITE : / gs_line-col1, gs_line-col2.
    ENDLOOP.

     

     

    2) APPEND 구문

    INSERT구문은 key와 index로 데이터를 삽입할 수 있는 반면, APPEND구문은 index만 이용할 수 있다.
    따라서 APPEND구문은 Hashed table에는 사용이 불가능하다.
    • line단위 데이터 삽입
      • APPEND 성공 시 시스템변수 sy-tabix에 추가된 데이터의 index를 저장한다.
    APPEND line TO itab.
    • 여러 라인 데이터 삽입
      • FROM ~ TO 구문을 통해 source table의 일부만 target table에 삽입할 수 있다.
    APPEND lines OF itab1 [FROM n1] [TO n2] TO itab2.
    REPORT ZA05_21.
    
    DATA : BEGIN OF gs_line,
      col1 TYPE c,
      col2 TYPE n,
    END OF gs_line.
    
    DATA gt_itab LIKE STANDARD TABLE OF gs_line WITH NON-UNIQUE KEY col1.
    *DATA gt_itab LIKE SORTED TABLE OF gs_line WITH UNIQUE KEY col1.
    *DATA gt_itab LIKE HASHED TABLE OF gs_line WITH UNIQUE KEY col1.
    
    gs_line-col1 = 'B'.
    gs_line-col2 = 1.
    APPEND gs_line TO gt_itab.
    
    gs_line-col1 = 'A'.
    gs_line-col2 = 2.
    APPEND gs_line TO gt_itab.
    
    gs_line-col1 = 'A'.
    gs_line-col2 = 3.
    APPEND gs_line TO gt_itab.
    
    gs_line-col1 = 'C'.
    gs_line-col2 = 4.
    APPEND gs_line TO gt_itab.
    
    BREAK-POINT.
    • 인터널테이블의 타입에 따른 APPEND구문 효과
    Standard Table 인터널테이블 마지막 위치에 삽입   => SORTED BY옵션을 통해 정렬상태로 삽입이 가능하다.
    Sorted Table 인터널테이블이 정렬된 상태를 유지하도록 로직을 구성해야 한다.
    Hashed Table APPEND 구문 사용 불가능
    • SORTED BY 구문을 통해 인터널테이블의 line수 유지하기
      • 인터널테이블의 line수 유지를 위해서는 INITIAL SIZE를 통해 크기를 지정해야한다.
      • 해당 구문 사용시 인터널테이블의 INITIAL SIZE를 유지하며 데이터를 삽입할 수 있다.
    APPEND wa TO itab SORTED BY f.
    REPORT ZA05_22.
    
    DATA : BEGIN OF gs_line,
      col1 TYPE c,
      col2 TYPE i,
    END OF gs_line.
    
    DATA : gt_itab LIKE TABLE OF gs_line INITIAL SIZE 2.
    
    gs_line-col1 = 'C'.
    gs_line-col2 = 1.
    APPEND gs_line TO gt_itab SORTED BY col1.
    
    gs_line-col1 = 'A'.
    gs_line-col2 = 2.
    APPEND gs_line TO gt_itab SORTED BY col1.
    
    gs_line-col1 = 'B'.
    gs_line-col2 = 3.
    APPEND gs_line TO gt_itab SORTED BY col1.
    
    LOOP AT gt_itab INTO gs_line.
      WRITE : / gs_line-col1, gs_line-col2.
    ENDLOOP.

     

     

    3) COLLECT 구문

    COLLECT 구문을 통해 인터널테이블의 Numeric 타입(Type f, i, p) 컬럼을 집계할 수 있다.
    • 인터널테이블의 key컬럼을 제외한 컬럼들은 모두 Numeric 타입(Type f, i, p)이어야 한다.
    • 데이터 삽입시, 같은 key값이 존재하면 집계기능을 수행하고, 존재하지 않는다면 삽입기능을 수행한다.
    • Open SQL의 GROUP BY구문과 비슷한 역할을 수행한다.
    REPORT ZA05_23.
    
    DATA : BEGIN OF gs_line,
      col1(3)  TYPE c,
      col2(2)  TYPE n,
      col3     TYPE i,
    END OF gs_line.
    
    DATA : gt_itab LIKE STANDARD TABLE OF gs_Line
                      WITH NON-UNIQUE KEY col1 col2.
    
    gs_line-col1 = 'AA'.    gs_line-col2 = '17'.    gs_line-col3 = 660.
    COLLECT gs_line INTO gt_itab.
    
    gs_line-col1 = 'AL'.    gs_line-col2 = '34'.    gs_line-col3 = 220.
    COLLECT gs_line INTO gt_itab.
    
    gs_line-col1 = 'AA'.    gs_line-col2 = '17'.    gs_line-col3 = 280.
    COLLECT gs_line INTO gt_itab.
    
    LOOP AT gt_itab INTO gs_line.
      WRITE : / gs_line-col1, gs_line-col2, gs_line-col3.
    ENDLOOP.

    REPORT ZA05_24.
    
    DATA : BEGIN OF gs_line,
      carrid      TYPE sflight-carrid,
      connid      TYPE sflight-connid,
      paymentsum  TYPE sflight-paymentsum,
    END OF gs_line.
    
    DATA : gt_itab LIKE TABLE OF gs_line
                    WITH NON-UNIQUE KEY carrid connid
                    WITH HEADER LINE.
    DATA : gt_sum  LIKE TABLE OF gs_line
                    WITH NON-UNIQUE KEY carrid connid
                    WITH HEADER LINE.
    
    SELECT carrid connid paymentsum
      INTO CORRESPONDING FIELDS OF TABLE gt_itab
      FROM sflight.
    
    LOOP AT gt_itab.
      COLLECT gt_itab INTO gt_sum.
    ENDLOOP.
    
    LOOP AT gt_sum.
      WRITE : / gt_sum-carrid, gt_sum-connid, gt_sum-paymentsum.
    ENDLOOP.

     

     

    [Internal table: 데이터 변경]

    MODIFY 구문을 통해 key컬럼 값, index 조건을 기준으로 인터널테이블 데이터를 변경할 수 있다.

    1) Table key를 이용한 line단위 데이터 변경

    • 인터널테이블이 NON-UNIQUE KEY이고, 중복 key값이 존재한다면 가장 상위 line의 데이터를 변경한다.
    • TRANSPORTING구문을 사용하여 전체 컬럼 중 일부 컬럼 값만 변경할 수 있다.
    MODIFY TABLE itab FROM wa [TRANSPORTING f1 f2 ...].
    REPORT ZA05_25.
    
    DATA : BEGIN OF gs_line,
      col1(2)   TYPE c,
      col2      TYPE i,
      col3      TYPE sy-datum,
    END OF gs_line.
    
    DATA : gt_itab LIKE STANDARD TABLE OF gs_line WITH NON-UNIQUE KEY col1 col2.
    
    gs_line-col1 = 'AA'.
    gs_line-col2 = 50.
    INSERT gs_line INTO TABLE gt_itab.
    
    gs_line-col1 = 'AA'.
    gs_line-col2 = 26.
    INSERT gs_line INTO TABLE gt_itab.
    
    gs_line-col1 = 'AA'.
    gs_line-col2 = 50.
    gs_line-col3 = '20201029'.
    
    MODIFY TABLE gt_itab FROM gs_line.
    
    LOOP AT gt_itab INTO gs_line.
      WRITE : / gs_line-col1, gs_line-col2, gs_line-col3.
    ENDLOOP.

     

    2) WHERE 조건을 이용한 여러 line단위 데이터 변경

    MODIFY itab FROM wa TRANSPORTING f1 f2 ... WHERE cond.
    REPORT ZA05_26.
    
    DATA : BEGIN OF gs_line,
      carrid     TYPE sflight-carrid,
      carrname   TYPE scarr-carrname,
      fldate     TYPE sflight-fldate,
    END OF gs_line.
    
    DATA : gt_itab LIKE TABLE OF gs_line.
    
    SELECT carrid
      INTO CORRESPONDING FIELDS OF TABLE gt_itab
      FROM sflight.
    
    LOOP AT gt_itab INTO gs_line.
      AT NEW carrid.
        SELECT SINGLE carrname
          INTO gs_line-carrname
          FROM scarr
          WHERE carrid = gs_line-carrid.
          
        MODIFY gt_itab FROM gs_line TRANSPORTING carrname
          WHERE carrid = gs_line-carrid.
      ENDAT.
      WRITE : / gs_line-carrid, gs_line-carrname.
    ENDLOOP.

    # AT ~ 구문

    AT FIRST 인터널테이블의 첫번째 데이터가 처리될때 수행
    AT NEW f1 컬럼 f1에 새로운 값이 삽입될때 수행
    AT END OF f1 컬럼 f1의 값이 마지막일때 수행
    AT LAST 인터널테이블의 마지막 데이터가 처리될때 수행

     

    3) Index를 이용한 여러 line단위 데이터 변경

    MODIFY itab FROM wa [INDEX idx] [TRANSPORTING f1 f2 ...].

     

     

    [Internal table: 데이터 삭제]

    DELTE 구문을 통해 인터널테이블의 데이터를 삭제할 수 있다.

    1) Table key를 이용한 line단위 데이터 삭제

    • 인터널테이블이 NON-UNIQUE KEY이고, 중복 key값이 존재한다면 한건의 데이터만 삭제한다.
    DELETE TABLE itab [FROM wa]
    DELETE TABLE itab WITH TABLE KEY k1=f1 ... kn=fn.

     

    2) WHERE구문을 이용한 여러 line단위 데이터 삭제

    DELETE itab WHERE cond.

     

    3) Index를 이용한 데이터 삭제

    DELETE itab [INDEX idx].
    DELETE itab [FROM n1] [TO n2]

     

    4) ADJACENT DUPLICATE 구문을 이용한 중복라인 삭제

    • 해당 구문을 사용하기 위해서는 SORT구문을 통해 인터널테이블을 정렬해야 한다.
    • COMPARING구문 미사용시 테이블의 key값이 중복된 데이터를 삭제한다.
    DELETE ADJACENT DUPLICATES ENTRIES FROM itab [COMPARING f1 f2 ... | ALL FIELDS]
    REPORT ZA05_30.
    
    DATA : BEGIN OF gs_line,
      carrid    TYPE sflight-carrid,
      connid    TYPE sflight-connid,
    END OF gs_line.
    
    DATA : gt_itab LIKE TABLE OF gs_line WITH HEADER LINE.
    
    SELECT carrid connid
      INTO CORRESPONDING FIELDS OF TABLE gt_itab
      FROM sflight.
    
    DELETE ADJACENT DUPLICATES FROM gt_itab.
    
    LOOP AT gt_itab.
      WRITE : / gt_itab-carrid, gt_itab-connid.
    ENDLOOP.

     

     

     

    [Internal table: 데이터 조회]

    READ구문을 통해 인터널테이블의 데이터를 조회할 수 있다.
    조회한 데이터는 특정 Work area에 복사하거나, Header line에 복사할 수 있다.

    1) Table key 사용

    • 데이터 조회 성공: [sy-subrc = 0, sy-tabix = idx]
    • 데이터 조회 실패: [sy-subrc = 4]
    READ TABLE itab FROM wa INTO result.
    READ TABLE itab WITH TABLE KEY k1=f1 ... kn=fn INTO result.
    REPORT ZA05_31.
    
    DATA : BEGIN OF gs_line,
      carrid     TYPE scarr-carrid,
      carrname   TYPE scarr-carrname,
    END OF gs_line.
    
    DATA : gt_itab LIKE TABLE OF gs_line WITH NON-UNIQUE KEY carrid.
    
    SELECT carrid carrname
      INTO CORRESPONDING FIELDS OF TABLE gt_itab
      FROM scarr.
    
    gs_line-carrid = 'AA'.
    READ TABLE gt_itab FROM gs_line INTO gs_line.
    WRITE : / gs_line-carrid, gs_line-carrname.
    
    READ TABLE gt_itab WITH TABLE KEY carrid = 'AB' INTO gs_line.
    WRITE : / gs_line-carrid, gs_line-carrname.

     

    2) Work area 할당

    READ TABLE itab WITH KEY k1 ... INTO wa
                        [COMPARING f1 f2 ... | ALL FIELDS]
                        [TRANSPORTING f1 f2 ... | ALL FIELDS | NO FIELDS].
    •  COMPARING구문: READ 구문의 결과 데이터에 비교조건을 추가한다.
      • 즉, READ 결과가 반환되면 COMPARING구문 필드와 한번 더 비교하여 값을 반환한다. 
      • 비교조건 TRUE : [sy-subrc = 0]
      • 비교조건 FALSE: [sy-subrc = 2]
    • TRANSPORTING: READ 구문의 결과 데이터에 추출할 컬럼을 추가한다.
      • 즉, READ 결과가 반환되면 TRANSPORTING구문의 필드값만 반환한다.
    REPORT ZA05_32.
    
    DATA : BEGIN OF gs_line,
      col1 TYPE c,
      col2 TYPE i,
      col3 TYPE i,
    END OF gs_line.
    
    DATA : gt_itab LIKE SORTED TABLE OF gs_line WITH UNIQUE KEY col1.
    
    gs_line-col1 = 'A'. gs_line-col2 = 1. gs_line-col3 = 1.
    INSERT gs_line INTO TABLE gt_itab.
    
    gs_line-col1 = 'B'. gs_line-col2 = 2. gs_line-col3 = 2.
    INSERT gs_line INTO TABLE gt_itab.
    
    CLEAR gs_line.
    
    gs_line-col1 = 'A'.
    READ TABLE gt_itab FROM gs_line INTO gs_line
        COMPARING col2 TRANSPORTING col2.
    
    WRITE : / 'SY-SUBRC: ', sy-subrc.
    WRITE : / 'RESULT  : ', gs_line-col1, gs_line-col2, gs_line-col3.

     

    3) Index를 이용한 데이터 조회

    • 데이터 조회 성공: [sy-subrc = 0]
    • 데이터 조회 실패: [sy-subrc = 4]
    READ TABLE itab INDEX idx INTO result.

     

    4) Binary search로 데이터 조회

    • BINARY SEARCH구문의 대상 컬럼을 기준으로 정렬된 상태에서 사용이 가능하다.
    • READ구문 수행시 순차탐색이 아닌, 이진탐색을 이용하므로 조회 성능이 향상된다.
    READ TABLE itab WITH KEY k1=f1 ... kn=fn INTO result BINARY SEARCH.

     

    'SAP > Abap' 카테고리의 다른 글

    [ABAP Dictionary] Overview & Table  (0) 2022.01.29
    [Debugging] Debugger  (0) 2022.01.22
    [Internal Table] Internal table 개념  (0) 2022.01.19
    [Modularization] Function  (0) 2022.01.18
    [Modularization] Subroutine  (0) 2022.01.17
Designed by Tistory.