ABAP New Syntax 정리

버전별 신규 문법 요약

ABAP은 7.40 SP02부터 대대적인 문법 현대화가 이루어졌습니다. 아래는 주요 버전별로 도입된 핵심 문법입니다.

버전도입 문법
7.40 SP02인라인 선언 DATA(...), FIELD-SYMBOL(...)
7.40 SP05VALUE #(), CORRESPONDING #(), String Template |{ }|
7.40 SP08CONV #(), COND #(), SWITCH #(), REDUCE #(), 테이블 표현식 itab[ ]
7.50FOR 표현식, FILTER, GROUP BY, MESH
7.52+Virtual Sort, 확장된 REDUCE, ENUM 타입

인라인 선언 (Inline Declaration)

DATA( ) — 변수 인라인 선언

Classic모든 버전
변수를 먼저 선언한 뒤 사용
New7.40 SP02+
사용 시점에 바로 선언
1" ── Classic ──
2DATA: lv_name TYPE string.
3lv_name = '홍길동'.
4
5DATA: ls_mara TYPE mara.
6SELECT SINGLE * FROM mara INTO ls_mara WHERE matnr = '000000001000000001'.
7
8DATA: lt_mara TYPE TABLE OF mara.
9SELECT * FROM mara INTO TABLE lt_mara UP TO 10 ROWS.
10
11" ── New (7.40 SP02+) ──
12DATA(lv_name2) = '홍길동'.  " 타입 자동 추론
13
14SELECT SINGLE * FROM mara INTO @DATA(ls_mara2)
15  WHERE matnr = '000000001000000001'.
16
17SELECT * FROM mara INTO TABLE @DATA(lt_mara2) UP TO 10 ROWS.

FIELD-SYMBOL( ) — Field Symbol 인라인 선언

1" ── Classic ──
2FIELD-SYMBOLS: <ls_mara> TYPE mara.
3LOOP AT lt_mara ASSIGNING <ls_mara>.
4  WRITE: / <ls_mara>-matnr.
5ENDLOOP.
6
7" ── New (7.40 SP02+) ──
8LOOP AT lt_mara ASSIGNING FIELD-SYMBOL(<ls_mara2>).
9  WRITE: / <ls_mara2>-matnr.
10ENDLOOP.
11
12" READ TABLE에서도 사용 가능
13READ TABLE lt_mara ASSIGNING FIELD-SYMBOL(<ls_found>)
14  WITH KEY matnr = '000000001000000001'.

VALUE # — 값 생성자 표현식

구조체나 내부 테이블에 값을 간결하게 할당합니다.

Classic
필드별 개별 할당 + APPEND 반복
New7.40 SP05+
한 줄로 구조체/테이블 생성

구조체 값 할당

1TYPES: BEGIN OF ty_item,
2         id   TYPE i,
3         name TYPE string,
4         qty  TYPE i,
5       END OF ty_item.
6
7" ── Classic ──
8DATA: ls_item TYPE ty_item.
9ls_item-id   = 1.
10ls_item-name = 'A4 용지'.
11ls_item-qty  = 100.
12
13" ── New (7.40 SP05+) ──
14DATA(ls_item2) = VALUE ty_item( id = 1 name = 'A4 용지' qty = 100 ).

내부 테이블 초기화

1" ── Classic ──
2DATA: lt_items TYPE TABLE OF ty_item,
3      ls_wa    TYPE ty_item.
4
5ls_wa-id = 1. ls_wa-name = 'A4 용지'. ls_wa-qty = 100.
6APPEND ls_wa TO lt_items.
7ls_wa-id = 2. ls_wa-name = '볼펜'.   ls_wa-qty = 50.
8APPEND ls_wa TO lt_items.
9ls_wa-id = 3. ls_wa-name = '노트'.   ls_wa-qty = 30.
10APPEND ls_wa TO lt_items.
11
12" ── New (7.40 SP05+) ──
13DATA(lt_items2) = VALUE ty_items(
14  ( id = 1 name = 'A4 용지' qty = 100 )
15  ( id = 2 name = '볼펜'    qty = 50  )
16  ( id = 3 name = '노트'    qty = 30  )
17).

기존 테이블에 행 추가 (BASE)

1" 기존 데이터를 유지하면서 추가
2lt_items2 = VALUE #( BASE lt_items2
3  ( id = 4 name = '지우개' qty = 20 )
4).

CONV # — 타입 변환

Classic
임시 변수를 선언하여 타입 변환
New7.40 SP08+
인라인으로 즉시 변환
1" ── Classic ──
2DATA: lv_str TYPE string,
3      lv_num TYPE i VALUE 42.
4lv_str = lv_num. " 암묵적 변환
5
6" FM 호출 시 타입 불일치 문제
7DATA: lv_matnr_str TYPE string VALUE '000000001000000001'.
8DATA: lv_matnr TYPE matnr.
9lv_matnr = lv_matnr_str. " 임시 변수 필요
10
11CALL FUNCTION 'Z_GET_MATERIAL_INFO'
12  EXPORTING iv_matnr = lv_matnr.
13
14" ── New (7.40 SP08+) ──
15CALL FUNCTION 'Z_GET_MATERIAL_INFO'
16  EXPORTING iv_matnr = CONV matnr( lv_matnr_str ).  " 즉시 변환

COND # / SWITCH # — 조건 표현식

COND # — IF 스타일 조건식

1DATA: lv_score TYPE i VALUE 85.
2
3" ── Classic ──
4DATA: lv_grade TYPE string.
5IF lv_score >= 90.
6  lv_grade = 'A'.
7ELSEIF lv_score >= 80.
8  lv_grade = 'B'.
9ELSEIF lv_score >= 70.
10  lv_grade = 'C'.
11ELSE.
12  lv_grade = 'F'.
13ENDIF.
14
15" ── New (7.40 SP08+) ──
16DATA(lv_grade2) = COND string(
17  WHEN lv_score >= 90 THEN 'A'
18  WHEN lv_score >= 80 THEN 'B'
19  WHEN lv_score >= 70 THEN 'C'
20  ELSE 'F'
21).
22" 결과: 'B'

SWITCH # — CASE 스타일 조건식

1DATA: lv_mtart TYPE mtart VALUE 'FERT'.
2
3" ── Classic ──
4DATA: lv_desc TYPE string.
5CASE lv_mtart.
6  WHEN 'ROH'.  lv_desc = '원자재'.
7  WHEN 'HALB'. lv_desc = '반제품'.
8  WHEN 'FERT'. lv_desc = '완제품'.
9  WHEN OTHERS. lv_desc = '기타'.
10ENDCASE.
11
12" ── New (7.40 SP08+) ──
13DATA(lv_desc2) = SWITCH string( lv_mtart
14  WHEN 'ROH'  THEN '원자재'
15  WHEN 'HALB' THEN '반제품'
16  WHEN 'FERT' THEN '완제품'
17  ELSE '기타'
18).
19" 결과: '완제품'

String Template — 문자열 템플릿

Classic
CONCATENATE로 문자열 결합
New7.40 SP05+
|{ }| 템플릿으로 간결하게
1DATA: lv_name TYPE string VALUE '홍길동',
2      lv_age  TYPE i VALUE 30.
3
4" ── Classic ──
5DATA: lv_msg TYPE string.
6CONCATENATE '이름:' lv_name ', 나이:' lv_age '세' INTO lv_msg SEPARATED BY space.
7
8" ── New (7.40 SP05+) ──
9DATA(lv_msg2) = |이름: { lv_name }, 나이: { lv_age }|.
10
11" 포맷 옵션
12WRITE: / |날짜: { sy-datum DATE = USER }|.
13WRITE: / |시간: { sy-uzeit TIME = USER }|.
14WRITE: / |정렬: { lv_name WIDTH = 20 ALIGN = LEFT PAD = '.' }|.
15" 결과: 정렬: 홍길동................
16
17" COND/SWITCH와 조합
18DATA: lv_flag TYPE abap_bool VALUE abap_true.
19WRITE: / |상태: { COND #( WHEN lv_flag = abap_true THEN '활성' ELSE '비활성' ) }|.

테이블 표현식 (Table Expression)

인덱스나 키로 내부 테이블의 특정 행에 직접 접근합니다.

1TYPES: BEGIN OF ty_emp,
2         id   TYPE i,
3         name TYPE string,
4       END OF ty_emp.
5
6DATA(lt_emp) = VALUE ty_emp_tab(
7  ( id = 1 name = '홍길동' )
8  ( id = 2 name = '성춘향' )
9  ( id = 3 name = '이몽룡' )
10).
11
12" ── Classic ──
13DATA: ls_emp TYPE ty_emp.
14READ TABLE lt_emp INTO ls_emp INDEX 2.
15WRITE: / ls_emp-name.  " 성춘향
16
17READ TABLE lt_emp INTO ls_emp WITH KEY id = 3.
18WRITE: / ls_emp-name.  " 이몽룡
19
20" ── New (7.40 SP08+) ──
21WRITE: / lt_emp[ 2 ]-name.        " 인덱스 접근 → 성춘향
22WRITE: / lt_emp[ id = 3 ]-name.   " 키 접근 → 이몽룡
23
24" 존재 여부 확인 (7.40 SP08+)
25IF line_exists( lt_emp[ id = 99 ] ).
26  WRITE: / '존재'.
27ELSE.
28  WRITE: / '없음'.
29ENDIF.
30
31" 행 수 확인 (7.40 SP08+)
32WRITE: / |{ lines( lt_emp ) }|.

주의: 테이블 표현식에서 해당 행이 없으면 CX_SY_ITAB_LINE_NOT_FOUND 예외가 발생합니다. line_exists( )로 먼저 확인하거나, TRY-CATCH로 감싸는 것이 안전합니다.

CORRESPONDING # — 구조체/테이블 매핑

서로 다른 구조체 간 동일 필드명을 자동으로 매핑합니다.

1TYPES: BEGIN OF ty_source,
2         matnr TYPE matnr,
3         maktx TYPE maktx,
4         mtart TYPE mtart,
5         extra TYPE string,  " 대상에 없는 필드
6       END OF ty_source.
7
8TYPES: BEGIN OF ty_target,
9         matnr TYPE matnr,
10         maktx TYPE maktx,
11         mtart TYPE mtart,
12         status TYPE c LENGTH 1,  " 소스에 없는 필드
13       END OF ty_target.
14
15DATA(ls_src) = VALUE ty_source(
16  matnr = '000000001000000001' maktx = 'A4 용지' mtart = 'ROH' extra = '기타'
17).
18
19" ── Classic ──
20DATA: ls_tgt TYPE ty_target.
21MOVE-CORRESPONDING ls_src TO ls_tgt.
22
23" ── New (7.40 SP05+) ──
24DATA(ls_tgt2) = CORRESPONDING ty_target( ls_src ).
25" matnr, maktx, mtart는 복사됨 / extra는 무시 / status는 초기값
26
27" MAPPING으로 필드명이 다른 경우 매핑
28" EXCEPT로 특정 필드 제외
29DATA(ls_tgt3) = CORRESPONDING ty_target( ls_src
30  MAPPING status = mtart     " mtart → status로 매핑
31  EXCEPT  maktx              " maktx 제외
32).

REDUCE # — 집계 표현식

내부 테이블의 값을 순회하며 집계합니다.

1TYPES: BEGIN OF ty_order,
2         item  TYPE string,
3         qty   TYPE i,
4         price TYPE p LENGTH 8 DECIMALS 2,
5       END OF ty_order.
6
7DATA(lt_orders) = VALUE ty_order_tab(
8  ( item = 'A4 용지'      qty = 100 price = '25000.00' )
9  ( item = '토너'          qty = 10  price = '85000.00' )
10  ( item = '사무용 의자'   qty = 5   price = '320000.00' )
11).
12
13" ── Classic ──
14DATA: lv_total TYPE p LENGTH 10 DECIMALS 2.
15LOOP AT lt_orders INTO DATA(ls_ord).
16  lv_total = lv_total + ( ls_ord-qty * ls_ord-price ).
17ENDLOOP.
18
19" ── New (7.40 SP08+) ──
20DATA(lv_total2) = REDUCE p LENGTH 10 DECIMALS 2(
21  INIT sum = CONV p LENGTH 10 DECIMALS 2( 0 )
22  FOR wa IN lt_orders
23  NEXT sum = sum + ( wa-qty * wa-price )
24).
25
26WRITE: / |총 금액: { lv_total2 }|.  " 5,950,000.00

FOR 표현식 — 테이블 가공

내부 테이블을 순회하며 새로운 테이블을 생성합니다.

1" ── Classic: 조건에 맞는 행만 복사 ──
2DATA: lt_expensive TYPE TABLE OF ty_order.
3LOOP AT lt_orders INTO ls_ord WHERE price > 50000.
4  APPEND ls_ord TO lt_expensive.
5ENDLOOP.
6
7" ── New (7.50+) ──
8DATA(lt_expensive2) = VALUE ty_order_tab(
9  FOR wa IN lt_orders WHERE ( price > 50000 )
10  ( wa )
11).
12
13" 필드 변환하면서 새 테이블 생성
14TYPES: BEGIN OF ty_summary,
15         item  TYPE string,
16         total TYPE p LENGTH 10 DECIMALS 2,
17       END OF ty_summary.
18
19DATA(lt_summary) = VALUE ty_summary_tab(
20  FOR wa IN lt_orders
21  ( item  = wa-item
22    total = wa-qty * wa-price )
23).

FILTER — 테이블 필터링

SORTED 또는 HASHED 테이블에서 조건에 맞는 행을 빠르게 추출합니다.

1TYPES: BEGIN OF ty_emp,
2         dept TYPE string,
3         name TYPE string,
4       END OF ty_emp.
5
6" SORTED TABLE 필요
7DATA(lt_emp) = VALUE ty_emp_sorted_tab(
8  ( dept = '개발팀' name = '홍길동' )
9  ( dept = '개발팀' name = '이몽룡' )
10  ( dept = '기획팀' name = '성춘향' )
11  ( dept = '인사팀' name = '심청이' )
12).
13
14" ── New (7.50+) ──
15DATA(lt_dev) = FILTER #( lt_emp WHERE dept = '개발팀' ).
16" 결과: 홍길동, 이몽룡만 포함

New SELECT 구문

7.40 SP05부터 SELECT 구문에 @ 이스케이프와 인라인 선언을 사용합니다.

1" ── Classic ──
2DATA: lt_result TYPE TABLE OF mara.
3SELECT * FROM mara
4  INTO TABLE lt_result
5  WHERE mtart = 'FERT'.
6
7" ── New (7.40 SP05+) ──
8SELECT * FROM mara
9  INTO TABLE @DATA(lt_result2)
10  WHERE mtart = 'FERT'.
11
12" 호스트 변수에 @ 붙이기
13DATA: lv_mtart TYPE mtart VALUE 'FERT'.
14SELECT matnr, mtart, matkl
15  FROM mara
16  INTO TABLE @DATA(lt_result3)
17  WHERE mtart = @lv_mtart.
18
19" 컬럼 구분자가 쉼표(,)로 변경됨에 주의
20" Classic: SELECT matnr mtart FROM mara
21" New:     SELECT matnr, mtart FROM mara

신규 문법 한눈에 비교

버전기능ClassicNew Syntax
7.40
SP02
변수 선언DATA: lv TYPE i. lv = 1.DATA(lv) = 1.
FS 선언FIELD-SYMBOLS: <fs>.ASSIGNING FIELD-SYMBOL(<fs>)
7.40
SP05
구조체 생성필드별 개별 할당VALUE ty( f1 = v1 )
테이블 생성APPEND 반복VALUE ty( ( ... ) ( ... ) )
문자열 결합CONCATENATE|{ var }|
구조체 매핑MOVE-CORRESPONDINGCORRESPONDING #( )
SELECTINTO TABLE ltINTO TABLE @DATA(lt)
7.40
SP08
타입 변환임시 변수 선언CONV type( val )
조건식 (IF)IF-ELSE 블록COND #( WHEN ... )
조건식 (CASE)CASE 블록SWITCH #( WHEN ... )
테이블 읽기READ TABLE ... INDEXitab[ idx ]
존재 확인READ + SY-SUBRCline_exists( itab[ ] )
집계LOOP + 누적REDUCE #( ... )
7.50테이블 가공LOOP + APPENDFOR wa IN itab ( wa )
필터링LOOP + WHEREFILTER #( itab WHERE ... )

팁: 시스템의 ABAP 버전은 SE38시스템상태에서 확인하거나, sy-saprl 시스템 변수로 확인할 수 있습니다.

Disclaimer — 이 포스트는 AI(Claude)를 활용하여 작성된 초안을 바탕으로 검수 및 보완하여 작성되었습니다. 내용 중 오류나 오타가 있다면 댓글로 알려주시면 감사하겠습니다.