이번 포스팅에서는 Standard Table에 대해서만 다룰 예정이다. READ TABLE을 대체할 수 있는 신 문법, Table Expressions 에 대해 소개한다.
TYPES: BEGIN OF structure_type,
col1 TYPE type1,
col2 TYPE type2,
col3 TYPE type3,
END OF structure_type,
table_type TYPE STANDARD TABLE OF structure_type.
DATA: itab TYPE table_type.
" Old
READ TABLE itab INDEX 1 INTO DATA(wa).
" New
DATA(wa) = itab[ 1 ].
다만, 위처럼 사용하면 해당 index에 맞는 data가 존재하지 않을 때, ITAB_LINE_NOT_FOUND
Error가 발생한다. 이를 TRY-CATCH
를 이용해 해결해보면 방법은 아래와 같다.
TRY
DATA(wa) = itab[ 1 ].
CATCH cx_sy_itab_line_not_found.
ENDTRY.
하지만 매번 이렇게 사용하면 오히려 불편하다. 따라서 이런 상황에서는 아래처럼 VALUE
와 OPTIONAL
을 이용하여 감싸주어 해당 문제를 해결한다. 데이터가 존재한다는 확신이 없는 상황에서는 항상 써준다고 생각하면 좋을 것 같다.
DATA(wa) = VALUE #( itab[ 1 ] OPTIONAL ).
당연히 이렇게 특정 Field의 값만 가져오는 것도 가능하다.
DATA(val1) = VALUE #( itab[ 1 ]-col1 OPTIONAL ).
위와 마찬가지로, ITAB_LINE_NOT_FOUND
Error를 피하기 위해 VALUE
와 OPTIONAL
을 이용하여 감싸주는 것이 좋다.
" Old
READ TABLE itab WITH KEY col1 = 'VAL1' INTO DATA(wa).
" New
DATA(wa) = itab[ col1 = 'VAL1' ].
DATA(wa) = VALUE #( itab[ col1 = 'VAL1' ] OPTIONAL ).
조건을 여러가지 주고 싶은 경우엔 여러개를 써주면 된다.
" Old
READ TABLE itab WITH KEY col1 = 'VAL1'
col2 = 'VAL2' INTO DATA(wa).
" New
DATA(wa) = VALUE #( itab[ col1 = 'VAL1'
col2 = 'VAL2' ] OPTIONAL ).
일반적으로 Binary Search는 아래와 같이 진행한다.
SORT itab BY col1.
READ TABLE itab WITH KEY col1 = 'VAL1' BINARY SEARCH INTO DATA(wa).
안타깝게도 New Syntax에서는 이러한 형태의 Binary Search를 지원하지 않는다. 대신 Secondary Key를 사용해야한다. 아래 글을 보면 Secondary Key를 사용하는 것이 일반적으로 더 빠른 것 또한 알 수 있다.
SAP ABAP Technical Help: Performance READ TABLE with Secondary Table Key Vs Binary Search
이를 위해 Table을 다시 정의한다.
TYPES: table_type_secondary_key TYPE STANDARD TABLE OF structure_type
WITH NON-UNIQUE SORTED KEY key_1 COMPONENTS col1.
DATA: itab_secondary_key TYPE table_type_secondary_key.
이제 이를 이용해 Table을 읽을 수 있다. Secondary Key를 활용했기 때문에 추가적인 SORT 등을 수행 할 필요가 없다.
" Old
READ TABLE itab_secondary_key WITH TABLE KEY key_1 COMPONENTS col1 = 'VAL1' INTO DATA(wa).
" New
DATA(wa) = VALUE #( itab_secondary_key[ KEY key_1 col1 = 'VAL1' ] OPTIONAL ).
아래는 Table Expressions를 사용하는 예시들이다.
" Old
READ TABLE itab INDEX 1 ASSIGNING FIELD-SYMBOL(<fs>).
IF sy-subrc = 0.
...
ENDIF.
" New
ASSIGN itab[ 1 ] TO FIELD-SYMBOL(<fs>) ELSE UNASSIGN.
IF <fs> IS ASSIGN.
...
ENDIF.
" Old
READ TABLE itab WITH KEY col1 = 'VAL1' TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
...
ENDIF.
" New
IF line_exists( itab[ col1 = 'VAL1' ] ).
...
ENDIF.
"Old
READ TABLE itab WITH KEY col1 = 'VAL1' TRANSPORTING NO FIELDS
DATA(idx) = sy-tabix.
" New
DATA(idx) = line_index( itab[ col1 = 'VAL1' ] ).
데이터가 없는 경우는 0을 반환한다. 또한 Index가 존재할 수 없는 Hashed Table이나 Hashed Secondary Key를 사용한 경우에는 -1을 반환한다.
" Old
READ TABLE itab WITH KEY col1 = 'VAL1' ASSIGNING FIELD-SYMBOL(<fs>).
<fs>-col1 = 'VAL4'.
" New
itab[ col1 = 'VAL1' ]-col1 = 'VAL4'.
다만 앞서 설명했듯, 해당 구문은 ITAB_LINE_NOT_FOUND
가 발생할 수 있다. 이를 위해, 데이터가 존재하지 않을 수 있는 경우에는 아래처럼 사용한다. 다른 간단한 방법이 있는지는 잘 모르겠다.
" Old
READ TABLE itab WITH KEY col1 = 'VAL1' ASSIGNING FIELD-SYMBOL(<fs>).
IF sy-subrc = 0.
<fs>-col1 = 'VAL4'.
ENDIF.
" New
DATA(idx) = line_index( itab[ col1 = 'VAL1' ] ).
IF idx > 0.
itab[ idx ]-col1 = 'VAL4'.
ENDIF.
물론 아래처럼 직접적으로 TRY-CATCH
를 사용할 수도 있겠지만, SAP에서 권장하는 방법인지는 잘 모르겠다.
TRY.
itab[ col1 = 'VAL1' ]-col1 = 'VAL4'.
CATCH cx_sy_itab_line_not_found.
ENTRY.
Table안에 또 Table이 있고, 또 있고,,, 이런식으로 Nested 구조의 Table을 간단하게 접근할 수 있다. 대표적으로 ALV의 경우 lvc_t_scol
과 같은 table을 요구하는 경우가 많다. 이런 경우 Table Expressions가 굉장히 유용하게 활용될 수 있는데, 예시를 위해 아래 Type을 다시 지정한다.
TYPES: BEGIN OF nested_structure_type,
col4 TYPE type4,
inner_table TYPE table_type,
END OF nested_structure_type,
nested_table_type TYPE STANDARD TABLE OF nested_structure_type.
DATA: nested_itab TYPE nested_table_type.
이제 해당 table을 가지고 Table Expressions를 적용해보자. 편의를 위해 sy-subrc
, ITAB_LINE_NOT_FOUND
등을 체크하는 로직은 생략했다.
" Old
READ TABLE nested_itab WITH KEY col4 = 'VAL4' ASSIGNING FIELD-SYMBOL(<fs>).
READ TABLE <fs>-inner_table WITH KEY col1 = 'VAL1' ASSIGNING FIELD-SYMBOL(<fs_inner>).
<fs_inner>-col2 = 'VAL2'.
" New
nested_itab[ col4 = 'VAL4' ]-inner_table[ col1 = 'VAL1' ]-col2 = 'VAL2'.
감사합니다.
잘봤습니다 ^^