ABAP 데이터 타입과 변수 선언
ABAP 데이터 타입 개요
ABAP(Advanced Business Application Programming)에서 데이터를 다루려면 먼저 타입(Type)과 변수(Data Object)의 개념을 이해해야 합니다. 타입은 데이터의 형태를 정의하고, 변수는 해당 타입에 맞는 실제 값을 저장하는 메모리 공간입니다.
ABAP의 데이터 타입은 크게 기본 타입(Elementary Type), 구조체(Structure), 내부 테이블(Internal Table)로 나뉩니다.
기본 타입 (Elementary Types)
ABAP에서 제공하는 기본 데이터 타입은 다음과 같습니다.
| 타입 | 설명 | 기본 길이 | 값 범위 / 예시 |
|---|
C | 문자(Character) | 1자리 | 'ABAP', 'Hello' |
N | 숫자 문자열(Numeric Text) | 1자리 | '001234' (숫자만 허용, 앞에 0 유지) |
I | 정수(Integer) | 4바이트 | -2,147,483,648 ~ 2,147,483,647 |
P | 패킹 십진수(Packed Decimal) | 8바이트 | 소수점 연산에 적합, DECIMALS 지정 |
D | 날짜(Date) | 8자리 | '20260506' (YYYYMMDD) |
T | 시간(Time) | 6자리 | '143052' (HHMMSS) |
STRING | 가변 길이 문자열 | 가변 | 길이 제한 없음 |
XSTRING | 가변 길이 바이트열 | 가변 | 바이너리 데이터 |
각 타입별 선언 예제
1REPORT Z_TYPE_EXAMPLE.
2
3
4DATA: lv_char TYPE c LENGTH 10 VALUE 'ABAP',
5 lv_numc TYPE n LENGTH 8 VALUE '00012345',
6 lv_string TYPE string VALUE 'Hello ABAP'.
7
8
9DATA: lv_int TYPE i VALUE 100,
10 lv_pack TYPE p LENGTH 8 DECIMALS 2 VALUE '1234.56'.
11
12
13DATA: lv_date TYPE d VALUE '20260506',
14 lv_time TYPE t VALUE '143000'.
15
16
17WRITE: / '문자(C):', lv_char,
18 / '숫자문자(N):', lv_numc,
19 / '문자열(STRING):', lv_string,
20 / '정수(I):', lv_int,
21 / '패킹(P):', lv_pack,
22 / '날짜(D):', lv_date,
23 / '시간(T):', lv_time.
실행 결과:
문자(C): ABAP
숫자문자(N): 00012345
문자열(STRING): Hello ABAP
정수(I): 100
패킹(P): 1,234.56
날짜(D): 20260506
시간(T): 143000
P 타입의 소수점 연산
P 타입은 금액, 수량 등 정밀한 소수점 연산이 필요할 때 사용합니다.
1DATA: lv_price TYPE p LENGTH 8 DECIMALS 2 VALUE '1500.00',
2 lv_quantity TYPE p LENGTH 8 DECIMALS 3 VALUE '2.500',
3 lv_total TYPE p LENGTH 8 DECIMALS 2.
4
5lv_total = lv_price * lv_quantity.
6
7WRITE: / '단가:', lv_price,
8 / '수량:', lv_quantity,
9 / '합계:', lv_total.
DATA 선언
DATA 키워드
DATA는 변수를 선언하는 가장 기본적인 키워드입니다.
1
2DATA lv_name TYPE string.
3
4
5DATA: lv_matnr TYPE c LENGTH 18,
6 lv_maktx TYPE c LENGTH 40,
7 lv_menge TYPE p LENGTH 13 DECIMALS 3.
8
9
10DATA: lv_bukrs TYPE bukrs,
11 lv_werks TYPE werks_d.
CONSTANTS
상수는 프로그램 실행 중 값이 변경되지 않는 데이터입니다.
1CONSTANTS: gc_max_rows TYPE i VALUE 1000,
2 gc_company TYPE bukrs VALUE '1000',
3 gc_status_a TYPE c LENGTH 1 VALUE 'A'.
4
5
TYPES
TYPES는 사용자 정의 타입을 만들 때 사용합니다. 메모리를 할당하지 않으며, 이후 DATA로 변수를 선언할 때 참조합니다.
1
2TYPES: ty_matnr TYPE c LENGTH 18,
3 ty_menge TYPE p LENGTH 13 DECIMALS 3.
4
5
6DATA: lv_matnr TYPE ty_matnr,
7 lv_menge TYPE ty_menge.
LIKE vs TYPE 비교
| 구분 | TYPE | LIKE |
|---|
| 참조 대상 | 타입(Type) 참조 | 기존 변수(Data Object) 참조 |
| 사용 예시 | DATA lv_a TYPE i | DATA lv_b LIKE lv_a |
| DDIC 참조 | DATA lv_c TYPE bukrs | DATA lv_d LIKE mara-matnr (필드 참조 가능) |
| 권장 여부 | 권장 | 레거시 코드에서 주로 사용 |
1DATA: lv_count TYPE i VALUE 10.
2DATA: lv_copy LIKE lv_count.
3
4
5DATA: lv_count2 TYPE i VALUE 20.
초기값과 CLEAR
각 데이터 타입은 선언 시 자동으로 초기값이 할당됩니다.
| 타입 | 초기값 |
|---|
C | 공백(Space) |
N | '0...0' (0으로 채움) |
I | 0 |
P | 0 |
D | '00000000' |
T | '000000' |
STRING | 빈 문자열('') |
CLEAR 구문을 사용하면 변수를 초기값으로 되돌릴 수 있습니다.
1DATA: lv_name TYPE string VALUE 'ABAP',
2 lv_num TYPE i VALUE 999.
3
4WRITE: / '초기화 전:', lv_name, lv_num.
5
6CLEAR: lv_name, lv_num.
7
8WRITE: / '초기화 후:', lv_name, lv_num.
9'', lv_num = 0
구조체 (Structure)
구조체는 서로 다른 타입의 필드를 하나로 묶은 복합 데이터 타입입니다. 데이터베이스 테이블의 한 행(Row)과 유사합니다.
BEGIN OF ~ END OF
1
2TYPES: BEGIN OF ty_material,
3 matnr TYPE matnr,
4 maktx TYPE maktx,
5 mtart TYPE mtart,
6 menge TYPE menge_d,
7 meins TYPE meins,
8 END OF ty_material.
9
10
11DATA: ls_material TYPE ty_material.
12
13
14ls_material-matnr = '000000001000000001'.
15ls_material-maktx = '테스트 자재'.
16ls_material-mtart = 'FERT'.
17ls_material-menge = '100.000'.
18ls_material-meins = 'EA'.
19
20WRITE: / '자재번호:', ls_material-matnr,
21 / '자재내역:', ls_material-maktx,
22 / '자재유형:', ls_material-mtart.
INCLUDE STRUCTURE
DDIC에 정의된 구조체를 포함하여 확장할 수 있습니다.
1
2TYPES: BEGIN OF ty_material_ext.
3 INCLUDE STRUCTURE mara.
4TYPES: maktx TYPE maktx,
5 status TYPE c LENGTH 1,
6 END OF ty_material_ext.
7
8DATA: ls_mat_ext TYPE ty_material_ext.
내부 테이블 (Internal Table)
내부 테이블은 구조체의 집합으로, 프로그램 실행 중 메모리에 여러 행의 데이터를 저장합니다. 데이터베이스 테이블과 달리 프로그램이 종료되면 사라집니다.
테이블 종류 비교
SSTANDARD TABLE
🔍 검색: 순차 (Linear)
📊 성능: O(n)
🔑 키 중복: 허용
📋 정렬: 미정렬
📌 접근: 인덱스 / 키
OSORTED TABLE
🔍 검색: 이진 (Binary)
📊 성능: O(log n)
🔑 키 중복: 선택 가능
📋 정렬: 자동 정렬
📌 접근: 인덱스 / 키
HHASHED TABLE
🔍 검색: 해시 (Hash)
📊 성능: O(1)
🔑 키 중복: 불허 (UNIQUE)
📋 정렬: 없음
📌 접근: 키만 가능
테이블 선언
1
2TYPES: BEGIN OF ty_employee,
3 empno TYPE n LENGTH 8,
4 name TYPE c LENGTH 40,
5 dept TYPE c LENGTH 20,
6 salary TYPE p LENGTH 8 DECIMALS 0,
7 END OF ty_employee.
8
9
10DATA: lt_emp_std TYPE STANDARD TABLE OF ty_employee
11 WITH DEFAULT KEY.
12
13
14DATA: lt_emp_sort TYPE SORTED TABLE OF ty_employee
15 WITH UNIQUE KEY empno.
16
17
18DATA: lt_emp_hash TYPE HASHED TABLE OF ty_employee
19 WITH UNIQUE KEY empno.
20
21
22DATA: lt_employees TYPE TABLE OF ty_employee.
23
24
25DATA: ls_employee TYPE ty_employee.
주요 조작 구문
APPEND: 테이블 끝에 행 추가
1
2ls_employee-empno = '00000001'.
3ls_employee-name = '홍길동'.
4ls_employee-dept = '개발팀'.
5ls_employee-salary = 5000000.
6APPEND ls_employee TO lt_employees.
7
8ls_employee-empno = '00000002'.
9ls_employee-name = '성춘향'.
10ls_employee-dept = '기획팀'.
11ls_employee-salary = 4800000.
12APPEND ls_employee TO lt_employees.
13
14
15APPEND VALUE #( empno = '00000003'
16 name = '이몽룡'
17 dept = '개발팀'
18 salary = 5200000 ) TO lt_employees.
READ TABLE: 특정 행 읽기
1
2READ TABLE lt_employees INTO ls_employee
3 WITH KEY empno = '00000002'.
4
5IF sy-subrc = 0.
6 WRITE: / '찾음:', ls_employee-name.
7ELSE.
8 WRITE: / '데이터 없음'.
9ENDIF.
10
11
12READ TABLE lt_employees INTO ls_employee INDEX 1.
13WRITE: / '첫 번째:', ls_employee-name.
MODIFY: 행 수정
1
2ls_employee-salary = 5500000.
3MODIFY lt_employees FROM ls_employee INDEX 2.
4
5
6ls_employee-dept = '경영지원팀'.
7MODIFY lt_employees FROM ls_employee
8 TRANSPORTING dept
9 WHERE empno = '00000002'.
DELETE: 행 삭제
1
2DELETE lt_employees INDEX 3.
3
4
5DELETE lt_employees WHERE dept = '기획팀'.
INSERT: 특정 위치에 삽입
1
2ls_employee-empno = '00000004'.
3ls_employee-name = '심청이'.
4ls_employee-dept = '인사팀'.
5ls_employee-salary = 4500000.
6INSERT ls_employee INTO lt_employees INDEX 1.
LOOP AT ~ WHERE
1
2LOOP AT lt_employees INTO ls_employee.
3 WRITE: / ls_employee-empno, ls_employee-name, ls_employee-dept.
4ENDLOOP.
5
6
7WRITE: / '── 개발팀만 조회 ──'.
8LOOP AT lt_employees INTO ls_employee WHERE dept = '개발팀'.
9 WRITE: / ls_employee-empno, ls_employee-name, ls_employee-salary.
10ENDLOOP.
11
12
13FIELD-SYMBOLS: <ls_emp> TYPE ty_employee.
14
15LOOP AT lt_employees ASSIGNING <ls_emp>.
16
17 <ls_emp>-salary = <ls_emp>-salary * '1.1'.
18ENDLOOP.
실무 예제: 구매오더 데이터 구조 설계
실제 SAP 업무에서 사용하는 구매오더(Purchase Order) 데이터를 구조체와 내부 테이블로 설계하고, 데이터를 추가/조회/집계하는 전체 예제입니다.
1REPORT Z_PO_DATA_EXAMPLE.
2
3
4
5
6TYPES: BEGIN OF ty_po_item,
7 ebeln TYPE c LENGTH 10,
8 ebelp TYPE n LENGTH 5,
9 matnr TYPE c LENGTH 18,
10 maktx TYPE c LENGTH 40,
11 menge TYPE p LENGTH 8 DECIMALS 3,
12 netpr TYPE p LENGTH 8 DECIMALS 2,
13 netwr TYPE p LENGTH 8 DECIMALS 2,
14 waers TYPE c LENGTH 5,
15 lifnr TYPE c LENGTH 10,
16 END OF ty_po_item.
17
18TYPES: ty_po_items TYPE STANDARD TABLE OF ty_po_item
19 WITH DEFAULT KEY.
20
21
22
23
24DATA: lt_po_items TYPE ty_po_items,
25 ls_po_item TYPE ty_po_item.
26
27DATA: lv_total_amount TYPE p LENGTH 10 DECIMALS 2,
28 lv_item_count TYPE i.
29
30
31
32
33ls_po_item-ebeln = '4500000001'.
34ls_po_item-ebelp = '00010'.
35ls_po_item-matnr = 'MAT-001'.
36ls_po_item-maktx = 'A4 복사용지'.
37ls_po_item-menge = '100.000'.
38ls_po_item-netpr = '25000.00'.
39ls_po_item-netwr = ls_po_item-menge * ls_po_item-netpr.
40ls_po_item-waers = 'KRW'.
41ls_po_item-lifnr = 'V-1001'.
42APPEND ls_po_item TO lt_po_items.
43
44CLEAR ls_po_item.
45
46ls_po_item-ebeln = '4500000001'.
47ls_po_item-ebelp = '00020'.
48ls_po_item-matnr = 'MAT-002'.
49ls_po_item-maktx = '토너 카트리지'.
50ls_po_item-menge = '10.000'.
51ls_po_item-netpr = '85000.00'.
52ls_po_item-netwr = ls_po_item-menge * ls_po_item-netpr.
53ls_po_item-waers = 'KRW'.
54ls_po_item-lifnr = 'V-1001'.
55APPEND ls_po_item TO lt_po_items.
56
57CLEAR ls_po_item.
58
59ls_po_item-ebeln = '4500000002'.
60ls_po_item-ebelp = '00010'.
61ls_po_item-matnr = 'MAT-003'.
62ls_po_item-maktx = '사무용 의자'.
63ls_po_item-menge = '5.000'.
64ls_po_item-netpr = '320000.00'.
65ls_po_item-netwr = ls_po_item-menge * ls_po_item-netpr.
66ls_po_item-waers = 'KRW'.
67ls_po_item-lifnr = 'V-2001'.
68APPEND ls_po_item TO lt_po_items.
69
70
71
72
73WRITE: / '====================================================='.
74WRITE: / '구매오더', 15 '항목', 22 '자재명', 45 '수량', 58 '단가', 75 '금액'.
75WRITE: / '====================================================='.
76
77LOOP AT lt_po_items INTO ls_po_item.
78 WRITE: / ls_po_item-ebeln,
79 15 ls_po_item-ebelp,
80 22 ls_po_item-maktx,
81 45 ls_po_item-menge,
82 58 ls_po_item-netpr,
83 75 ls_po_item-netwr.
84
85
86 lv_total_amount = lv_total_amount + ls_po_item-netwr.
87 lv_item_count = lv_item_count + 1.
88ENDLOOP.
89
90WRITE: / '====================================================='.
91WRITE: / '총 항목 수:', lv_item_count.
92WRITE: / '총 금액:', lv_total_amount, ls_po_item-waers.
93
94
95
96
97WRITE: / ''.
98WRITE: / '── 4500000001 구매오더 상세 ──'.
99
100LOOP AT lt_po_items INTO ls_po_item
101 WHERE ebeln = '4500000001'.
102 WRITE: / ls_po_item-ebelp, ls_po_item-maktx, ls_po_item-netwr.
103ENDLOOP.
실행 결과:
=====================================================
구매오더 항목 자재명 수량 단가 금액
=====================================================
4500000001 00010 A4 복사용지 100.000 25,000.00 2,500,000.00
4500000001 00020 토너 카트리지 10.000 85,000.00 850,000.00
4500000002 00010 사무용 의자 5.000 320,000.00 1,600,000.00
=====================================================
총 항목 수: 3
총 금액: 4,950,000.00 KRW
── 4500000001 구매오더 상세 ──
00010 A4 복사용지 2,500,000.00
00020 토너 카트리지 850,000.00
이 예제에서는 TYPES로 구매오더 구조체를 정의하고, DATA로 내부 테이블과 Work Area를 선언한 뒤, APPEND, LOOP, WHERE 등을 활용하여 실무에서 자주 접하는 구매 데이터 처리 패턴을 구현했습니다.
Disclaimer — 이 포스트는 AI(Claude)를 활용하여 작성된 초안을 바탕으로 검수 및 보완하여 작성되었습니다. 내용 중 오류나 오타가 있다면 댓글로 알려주시면 감사하겠습니다.