ABAP 기초 문법

조건문

IF / ELSEIF / ELSE / ENDIF

ABAP에서 가장 기본적인 조건 분기 구문입니다.

1DATA: lv_score TYPE i VALUE 85.
2
3IF lv_score >= 90.
4  WRITE: / '등급: A'.
5ELSEIF lv_score >= 80.
6  WRITE: / '등급: B'.
7ELSEIF lv_score >= 70.
8  WRITE: / '등급: C'.
9ELSE.
10  WRITE: / '등급: F'.
11ENDIF.
12" 결과: 등급: B

비교 연산자

ABAP은 기호와 키워드 두 가지 방식의 비교 연산자를 제공합니다.

키워드기호의미
EQ=같다
NE<>같지 않다
GT>크다
LT<작다
GE>=크거나 같다
LE<=작거나 같다
IS INITIAL-초기값인지 확인
IS NOT INITIAL-초기값이 아닌지 확인
BETWEEN ... AND ...-범위 내 확인
IN-Range 테이블 내 포함 여부
1DATA: lv_value TYPE i VALUE 50.
2
3" IS INITIAL 확인
4DATA: lv_empty TYPE string.
5IF lv_empty IS INITIAL.
6  WRITE: / 'lv_empty는 초기값입니다.'.
7ENDIF.
8
9" BETWEEN 사용
10IF lv_value BETWEEN 1 AND 100.
11  WRITE: / lv_value, '은(는) 1~100 사이입니다.'.
12ENDIF.
13
14" 논리 연산자: AND, OR, NOT
15DATA: lv_age TYPE i VALUE 25.
16IF lv_age >= 20 AND lv_age < 30.
17  WRITE: / '20대입니다.'.
18ENDIF.

CASE ~ WHEN

여러 값을 비교할 때 IF보다 가독성이 좋습니다.

1DATA: lv_mtart TYPE mtart VALUE 'FERT'.
2
3CASE lv_mtart.
4  WHEN 'ROH'.
5    WRITE: / '원자재 (Raw Material)'.
6  WHEN 'HALB'.
7    WRITE: / '반제품 (Semi-Finished)'.
8  WHEN 'FERT'.
9    WRITE: / '완제품 (Finished Product)'.
10  WHEN OTHERS.
11    WRITE: / '기타 자재유형:', lv_mtart.
12ENDCASE.
13" 결과: 완제품 (Finished Product)

반복문

DO ~ ENDDO

지정된 횟수만큼 반복합니다. SY-INDEX로 현재 반복 횟수를 확인할 수 있습니다.

1" 5번 반복
2DO 5 TIMES.
3  WRITE: / 'SY-INDEX:', sy-index.
4ENDDO.
5" 결과: 1, 2, 3, 4, 5
6
7" EXIT으로 중간 탈출
8DO 100 TIMES.
9  IF sy-index > 3.
10    EXIT.  " 루프 즉시 종료
11  ENDIF.
12  WRITE: / '반복:', sy-index.
13ENDDO.

WHILE ~ ENDWHILE

조건이 참인 동안 계속 반복합니다.

1DATA: lv_count TYPE i VALUE 1.
2
3WHILE lv_count <= 5.
4  WRITE: / '카운트:', lv_count.
5  lv_count = lv_count + 1.
6ENDWHILE.

LOOP AT ~ ENDLOOP

내부 테이블의 행을 순회합니다. ABAP에서 가장 많이 사용하는 반복문입니다.

1TYPES: BEGIN OF ty_item,
2         id   TYPE i,
3         name TYPE c LENGTH 20,
4       END OF ty_item.
5
6DATA: lt_items TYPE TABLE OF ty_item,
7      ls_item  TYPE ty_item.
8
9" 데이터 추가
10APPEND VALUE #( id = 1 name = '사과' ) TO lt_items.
11APPEND VALUE #( id = 2 name = '바나나' ) TO lt_items.
12APPEND VALUE #( id = 3 name = '딸기' ) TO lt_items.
13
14" INTO 방식: 행을 Work Area로 복사
15LOOP AT lt_items INTO ls_item.
16  WRITE: / 'SY-TABIX:', sy-tabix, ls_item-id, ls_item-name.
17ENDLOOP.
18
19" WHERE 조건 필터링
20LOOP AT lt_items INTO ls_item WHERE id >= 2.
21  WRITE: / '필터:', ls_item-name.
22ENDLOOP.
23" 결과: 바나나, 딸기

SY-TABIX vs SY-INDEX

시스템 변수용도사용 위치
SY-TABIX현재 처리 중인 내부 테이블 행 인덱스LOOP AT, READ TABLE
SY-INDEX현재 반복 횟수 카운터DO, WHILE

데이터 조회

SELECT SINGLE

하나의 행만 조회합니다. 결과가 있으면 SY-SUBRC = 0, 없으면 SY-SUBRC = 4입니다.

1DATA: ls_mara TYPE mara.
2
3SELECT SINGLE *
4  FROM mara
5  INTO ls_mara
6  WHERE matnr = '000000001000000001'.
7
8IF sy-subrc = 0.
9  WRITE: / '자재유형:', ls_mara-mtart.
10ELSE.
11  WRITE: / '자재를 찾을 수 없습니다.'.
12ENDIF.

SELECT ~ INTO TABLE

여러 행을 내부 테이블로 조회합니다.

1TYPES: BEGIN OF ty_material,
2         matnr TYPE matnr,
3         mtart TYPE mtart,
4         matkl TYPE matkl,
5       END OF ty_material.
6
7DATA: lt_materials TYPE TABLE OF ty_material.
8
9SELECT matnr mtart matkl
10  FROM mara
11  INTO TABLE lt_materials
12  WHERE mtart = 'FERT'
13    AND matkl = '001'.
14
15WRITE: / '조회 건수:', sy-dbcnt.

FOR ALL ENTRIES IN

내부 테이블의 값을 기준으로 대량 조회할 때 사용합니다.

주의: FOR ALL ENTRIES IN에 사용하는 내부 테이블이 비어있으면 WHERE 조건이 무시되어 전체 테이블을 조회합니다. 반드시 빈 테이블 체크를 해야 합니다!

1TYPES: BEGIN OF ty_text,
2         matnr TYPE matnr,
3         maktx TYPE maktx,
4       END OF ty_text.
5
6DATA: lt_texts TYPE TABLE OF ty_text.
7
8" ⚠️ 반드시 빈 테이블 체크!
9IF lt_materials IS NOT INITIAL.
10  SELECT matnr maktx
11    FROM makt
12    INTO TABLE lt_texts
13    FOR ALL ENTRIES IN lt_materials
14    WHERE matnr = lt_materials-matnr
15      AND spras = sy-langu.
16ENDIF.

JOIN (INNER / LEFT OUTER)

두 테이블을 결합하여 조회합니다.

1TYPES: BEGIN OF ty_mat_info,
2         matnr TYPE matnr,
3         mtart TYPE mtart,
4         maktx TYPE maktx,
5       END OF ty_mat_info.
6
7DATA: lt_mat_info TYPE TABLE OF ty_mat_info.
8
9" INNER JOIN: 양쪽 테이블에 모두 존재하는 데이터만
10SELECT a~matnr a~mtart b~maktx
11  FROM mara AS a
12  INNER JOIN makt AS b
13    ON a~matnr = b~matnr
14  INTO TABLE lt_mat_info
15  WHERE b~spras = sy-langu
16    AND a~mtart = 'FERT'.
17
18" LEFT OUTER JOIN: 왼쪽 테이블 기준, 오른쪽에 없으면 NULL
19SELECT a~matnr a~mtart b~maktx
20  FROM mara AS a
21  LEFT OUTER JOIN makt AS b
22    ON  a~matnr = b~matnr
23    AND b~spras = sy-langu
24  INTO TABLE lt_mat_info
25  WHERE a~mtart = 'FERT'.

서브루틴과 메서드

PERFORM / FORM

서브루틴은 코드를 재사용 가능한 블록으로 분리합니다. USING은 입력, CHANGING은 입출력 파라미터입니다.

1REPORT Z_SUBROUTINE_EXAMPLE.
2
3DATA: lv_result TYPE p LENGTH 8 DECIMALS 2.
4
5" 서브루틴 호출
6PERFORM calc_tax USING 1000000
7                 CHANGING lv_result.
8
9WRITE: / '세금:', lv_result. " 결과: 100,000.00
10
11" ──────────────────────────
12" 서브루틴 정의
13" ──────────────────────────
14FORM calc_tax USING    pv_amount TYPE p
15              CHANGING pv_tax    TYPE p.
16  " 10% 세금 계산
17  pv_tax = pv_amount * '0.1'.
18ENDFORM.

CLASS / METHOD 기초

현재 ABAP에서는 객체지향(OOP) 방식이 권장됩니다.

1REPORT Z_CLASS_EXAMPLE.
2
3" ==============================
4" 로컬 클래스 정의
5" ==============================
6CLASS lcl_calculator DEFINITION.
7  PUBLIC SECTION.
8    " 메서드 선언
9    METHODS: add
10      IMPORTING iv_a TYPE i
11                iv_b TYPE i
12      RETURNING VALUE(rv_result) TYPE i.
13
14    METHODS: multiply
15      IMPORTING iv_a TYPE i
16                iv_b TYPE i
17      EXPORTING ev_result TYPE i.
18ENDCLASS.
19
20CLASS lcl_calculator IMPLEMENTATION.
21  METHOD add.
22    rv_result = iv_a + iv_b.
23  ENDMETHOD.
24
25  METHOD multiply.
26    ev_result = iv_a * iv_b.
27  ENDMETHOD.
28ENDCLASS.
29
30" ==============================
31" 사용
32" ==============================
33DATA: lo_calc  TYPE REF TO lcl_calculator,
34      lv_sum   TYPE i,
35      lv_multi TYPE i.
36
37CREATE OBJECT lo_calc.
38
39" RETURNING 방식: 결과를 바로 받음
40lv_sum = lo_calc->add( iv_a = 10 iv_b = 20 ).
41WRITE: / '합계:', lv_sum.  " 결과: 30
42
43" EXPORTING 방식: 파라미터로 결과 받음
44lo_calc->multiply( EXPORTING iv_a = 5
45                             iv_b = 8
46                   IMPORTING ev_result = lv_multi ).
47WRITE: / '곱:', lv_multi.  " 결과: 40

문자열 처리

기본 문자열 함수

함수설명예시
CONCATENATE문자열 결합CONCATENATE a b INTO c SEPARATED BY ' '
SPLIT문자열 분리SPLIT str AT ',' INTO a b c
CONDENSE불필요한 공백 제거CONDENSE str NO-GAPS
TRANSLATE대소문자 변환TRANSLATE str TO UPPER CASE
STRLEN문자열 길이lv_len = strlen( str )
REPLACE문자열 치환REPLACE ALL OCCURRENCES OF 'a' IN str WITH 'b'
1DATA: lv_first  TYPE string VALUE 'Hello',
2      lv_second TYPE string VALUE 'ABAP',
3      lv_result TYPE string.
4
5" 문자열 결합
6CONCATENATE lv_first lv_second INTO lv_result SEPARATED BY ' '.
7WRITE: / lv_result.  " 결과: Hello ABAP
8
9" 문자열 분리
10DATA: lv_csv TYPE string VALUE 'A,B,C,D',
11      lv_a TYPE string, lv_b TYPE string,
12      lv_c TYPE string, lv_d TYPE string.
13
14SPLIT lv_csv AT ',' INTO lv_a lv_b lv_c lv_d.
15WRITE: / lv_a, lv_b, lv_c, lv_d. " 결과: A B C D
16
17" 대소문자 변환
18DATA: lv_text TYPE string VALUE 'hello world'.
19TRANSLATE lv_text TO UPPER CASE.
20WRITE: / lv_text. " 결과: HELLO WORLD
21
22" 치환
23DATA: lv_str TYPE string VALUE '2026-05-06'.
24REPLACE ALL OCCURRENCES OF '-' IN lv_str WITH '/'.
25WRITE: / lv_str. " 결과: 2026/05/06

String Template (7.40+)

ABAP 7.40부터 도입된 문자열 템플릿은 |{ }| 구문을 사용합니다.

1DATA: lv_name   TYPE string VALUE '홍길동',
2      lv_age    TYPE i VALUE 30,
3      lv_salary TYPE p LENGTH 8 DECIMALS 2 VALUE '5000000.00'.
4
5" 기본 사용
6DATA(lv_msg) = |이름: { lv_name }, 나이: { lv_age }|.
7WRITE: / lv_msg.
8" 결과: 이름: 홍길동, 나이: 30세
9
10" 포맷 옵션
11WRITE: / |날짜: { sy-datum DATE = USER }|.
12WRITE: / |금액: { lv_salary NUMBER = USER }|.
13WRITE: / |정렬: { lv_name WIDTH = 20 ALIGN = LEFT PAD = '.' }|.
14" 결과: 정렬: 홍길동................
15
16" 조건부 표현
17DATA: lv_flag TYPE abap_bool VALUE abap_true.
18WRITE: / |상태: { COND #( WHEN lv_flag = abap_true
19                           THEN '활성'
20                           ELSE '비활성' ) }|.
21" 결과: 상태: 활성

디버깅 기초

BREAK-POINT

코드에 중단점을 설정하면 해당 위치에서 프로그램 실행이 멈추고 디버거가 열립니다.

1DATA: lv_value TYPE i VALUE 100.
2
3lv_value = lv_value + 50.
4
5BREAK-POINT.  " 여기서 디버거 진입 → lv_value = 150 확인 가능
6
7lv_value = lv_value * 2.
8
9" 특정 사용자만 디버거 진입
10BREAK-POINT ID my_debug.  " SAAB에서 활성화 필요
11BREAK userid.             " 특정 사용자에게만 중단점 적용

주요 SY 시스템 변수

변수설명예시 값
SY-SUBRC직전 구문의 실행 결과 (0=성공)0, 4, 8
SY-TABIX내부 테이블 현재 행 인덱스1, 2, 3
SY-INDEXDO/WHILE 루프 카운터1, 2, 3
SY-DBCNTSELECT로 읽은 행 수15
SY-DATUM현재 날짜20260506
SY-UZEIT현재 시간143052
SY-UNAME로그인 사용자 IDSAPUSER
SY-TCODE현재 트랜잭션 코드SE38
SY-LANGU로그인 언어3 (한국어)
1WRITE: / '오늘 날짜:', sy-datum,
2       / '현재 시간:', sy-uzeit,
3       / '사용자:', sy-uname,
4       / '트랜잭션:', sy-tcode.

실무 예제: 자재 목록 조회 프로그램

MARA(자재 마스터)와 MAKT(자재 내역) 테이블을 JOIN하여 자재 목록을 조회하고 출력하는 전체 프로그램입니다.

1REPORT Z_MATERIAL_LIST.
2
3" ==============================
4" 1. 타입 정의
5" ==============================
6TYPES: BEGIN OF ty_material,
7         matnr TYPE matnr,   " 자재번호
8         mtart TYPE mtart,   " 자재유형
9         matkl TYPE matkl,   " 자재그룹
10         meins TYPE meins,   " 기본단위
11         maktx TYPE maktx,   " 자재내역
12       END OF ty_material.
13
14" ==============================
15" 2. TABLES 선언 (SELECT-OPTIONS 참조용)
16" ==============================
17TABLES: mara.
18
19" ==============================
20" 3. Selection Screen (조회 조건)
21" ==============================
22SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
23  SELECT-OPTIONS: so_matnr FOR mara-matnr,  " 자재번호 범위
24                  so_mtart FOR mara-mtart.   " 자재유형 범위
25  PARAMETERS: p_maxrow TYPE i DEFAULT 100.   " 최대 조회 건수
26SELECTION-SCREEN END OF BLOCK b1.
27
28" ==============================
29" 3. 데이터 선언
30" ==============================
31DATA: lt_materials TYPE TABLE OF ty_material,
32      ls_material  TYPE ty_material.
33
34DATA: lv_count TYPE i.
35
36" ==============================
37" 4. 데이터 조회 (START-OF-SELECTION)
38" ==============================
39START-OF-SELECTION.
40
41  SELECT a~matnr a~mtart a~matkl a~meins b~maktx
42    FROM mara AS a
43    INNER JOIN makt AS b
44      ON a~matnr = b~matnr
45    INTO TABLE lt_materials
46    UP TO p_maxrow ROWS
47    WHERE a~matnr IN so_matnr
48      AND a~mtart IN so_mtart
49      AND b~spras = sy-langu.
50
51  IF sy-subrc <> 0.
52    WRITE: / '조회된 데이터가 없습니다.'.
53    RETURN.
54  ENDIF.
55
56  " 건수 저장
57  lv_count = sy-dbcnt.
58
59" ==============================
60" 5. 데이터 출력
61" ==============================
62  WRITE: / '=== 자재 목록 ==='.
63  WRITE: / '총 조회 건수:', lv_count.
64  ULINE.
65  WRITE: / '자재번호',
66         22 '유형',
67         30 '그룹',
68         40 '단위',
69         46 '자재내역'.
70  ULINE.
71
72  LOOP AT lt_materials INTO ls_material.
73    " 자재유형에 따라 색상 구분
74    CASE ls_material-mtart.
75      WHEN 'FERT'.
76        FORMAT COLOR COL_POSITIVE.  " 녹색
77      WHEN 'ROH'.
78        FORMAT COLOR COL_NEGATIVE.  " 적색
79      WHEN OTHERS.
80        FORMAT COLOR COL_NORMAL.    " 기본색
81    ENDCASE.
82
83    WRITE: / ls_material-matnr,
84           22 ls_material-mtart,
85           30 ls_material-matkl,
86           40 ls_material-meins,
87           46 ls_material-maktx.
88  ENDLOOP.
89
90  FORMAT RESET.
91  ULINE.
92  WRITE: / '프로그램 종료. 사용자:', sy-uname, '실행시간:', sy-uzeit.
실행 결과 예시:
=== 자재 목록 === 총 조회 건수: 3 ───────────────────────────────────────── 자재번호 유형 그룹 단위 자재내역 ───────────────────────────────────────── 000000001000000001 FERT 001 EA 테스트 완제품 000000001000000002 ROH 002 KG 테스트 원자재 000000001000000003 HALB 001 EA 테스트 반제품 ───────────────────────────────────────── 프로그램 종료. 사용자: SAPUSER 실행시간: 143052

이 프로그램은 Selection Screen, JOIN SELECT, LOOP, IF/CASE, SY 변수, FORMAT 등 이번 포스트에서 다룬 핵심 문법을 모두 활용한 종합 예제입니다.

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