SAP ABAP 에서 한 프로그램이 다른 프로그램(SUBMIT) 을 호출한 후 그 결과 데이터를 받아와야 할 때가 자주 있습니다. 표준 리포트가 만든 ALV 데이터를 받아 재가공한다거나, 회사 자체 함수가 없어서 표준 리포트를 그대로 활용하고 싶을 때. 하지만 SUBMIT 은 호출 직후 호출자로 자동 복귀하면서 호출된 프로그램의 변수에 직접 접근할 수 없는 구조. 표준 함수 호출(CALL FUNCTION) 처럼 EXPORTING / IMPORTING 인자가 없습니다.
이 한계를 우회하는 표준 메커니즘이 ABAP 메모리(ABAP Memory) 를 활용한 데이터 전달. 호출된 프로그램이 결과를 EXPORT TO MEMORY ID 로 임시 메모리 영역에 저장하고, 호출자가 같은 키로 IMPORT FROM MEMORY ID 로 읽어오는 패턴. 한 LUW 안의 임시 저장소이므로 다른 사용자 / 다른 세션과 충돌하지 않습니다.
이 글에서는 ABAP 메모리의 동작 원리 · SUBMIT ... AND RETURN 흐름 · EXPORT / IMPORT 표준 구문 · 데이터 타입 일치 함정 · 메모리 정리(FREE MEMORY ID) · SAP 메모리(SPA/GPA) 와의 차이까지 정리합니다. 표준 리포트 결과를 자체 프로그램에서 재활용해야 하는 인터페이스 / 후처리 시나리오에 그대로 적용 가능합니다.
핵심 — ABAP Memory 흐름
| 단계 | 위치 | 동작 |
|---|---|---|
| 1 | 호출자 (caller) | SUBMIT ... AND RETURN 로 호출 |
| 2 | 호출된 프로그램 (callee) | 데이터 처리 후 EXPORT TO MEMORY ID 'KEY' |
| 3 | 호출된 프로그램 | LEAVE PROGRAM 또는 자동 종료 → 호출자로 복귀 |
| 4 | 호출자 | IMPORT FROM MEMORY ID 'KEY' 로 읽기 |
| 5 | 호출자 | FREE MEMORY ID 'KEY' 로 정리 |
이 5단계가 표준 흐름. 호출자와 호출된 프로그램 양쪽이 같은 메모리 ID 키로 통신하므로 키 문자열 일치 + 데이터 변수 정의 일치 두 가지만 맞추면 안전하게 데이터가 흘러갑니다.
1단계 — 호출된 프로그램 (callee) 에서 EXPORT
다른 프로그램에서 호출될 리포트가 결과를 메모리에 저장하는 코드.
REPORT z_xx_sub_program.
TYPES: BEGIN OF ty_result,
matnr TYPE matnr,
menge TYPE menge_d,
meins TYPE meins,
END OF ty_result.
DATA: lt_result TYPE TABLE OF ty_result.
START-OF-SELECTION.
" 1) 자체 로직으로 데이터 수집
SELECT matnr, menge, meins
FROM ekpo
INTO TABLE @lt_result
UP TO 100 ROWS.
" ★ 2) 결과를 ABAP 메모리에 저장
EXPORT lt_result FROM lt_result TO MEMORY ID 'ZSUBMIT_RESULT'.
" 3) (선택) 호출자로 자동 복귀하기 위해 LEAVE
" SUBMIT ... AND RETURN 으로 호출됐다면 자동 복귀
핵심 포인트:
EXPORT 변수 FROM 변수 TO MEMORY ID '키'구문- 한 번에 여러 변수 EXPORT 가능 —
EXPORT lt_a FROM lt_a lt_b FROM lt_b TO MEMORY ID '키' - 메모리 ID 키는 32자 이내 문자열 — Z 접두어 + 의미 있는 이름 권장
2단계 — 호출자 (caller) 에서 SUBMIT + IMPORT
호출자 측에서 SUBMIT 으로 위 리포트를 실행하고 결과를 받는 코드.
REPORT z_xx_caller_program.
TYPES: BEGIN OF ty_result,
matnr TYPE matnr,
menge TYPE menge_d,
meins TYPE meins,
END OF ty_result.
DATA: lt_result TYPE TABLE OF ty_result.
START-OF-SELECTION.
" ★ 1) SUBMIT 호출 — AND RETURN 으로 자동 복귀
SUBMIT z_xx_sub_program
AND RETURN
EXPORTING LIST TO MEMORY.
" ★ 2) ABAP 메모리에서 결과 읽기
IMPORT lt_result TO lt_result FROM MEMORY ID 'ZSUBMIT_RESULT'.
" 3) 결과 확인
WRITE: / |받아온 라인 수: { lines( lt_result ) }|.
LOOP AT lt_result INTO DATA(ls_row).
WRITE: / ls_row-matnr, ls_row-menge, ls_row-meins.
ENDLOOP.
" ★ 4) 메모리 정리
FREE MEMORY ID 'ZSUBMIT_RESULT'.
핵심 포인트:
SUBMIT ... AND RETURN— 호출 후 자동 복귀 (이게 없으면 호출자가 종료됨)IMPORT 변수 TO 변수 FROM MEMORY ID '키'구문- 메모리 키는 EXPORT 측과 정확히 일치
- 읽은 후
FREE MEMORY ID로 메모리 영역 정리
3단계 — 핵심 함정: 변수 정의 일치
가장 흔한 함정. 호출자의 변수 타입과 호출된 프로그램의 변수 타입이 정확히 일치해야 IMPORT 가 성공합니다.
" ★ 호출된 프로그램 (callee)
TYPES: BEGIN OF ty_result,
matnr TYPE matnr, " 18자
menge TYPE menge_d,
meins TYPE meins,
END OF ty_result.
DATA: lt_result TYPE TABLE OF ty_result.
" ★ 호출자 (caller) — 같은 TYPES 정의 필요
TYPES: BEGIN OF ty_result,
matnr TYPE matnr, " 같은 타입
menge TYPE menge_d,
meins TYPE meins,
END OF ty_result.
DATA: lt_result TYPE TABLE OF ty_result.
왜 중요한가 — ABAP 메모리는 변수의 raw binary 를 저장. 호출자가 다른 구조체로 IMPORT 하면 메모리는 같은 데이터를 다른 형식으로 해석해서 결과가 깨집니다.
권장 패턴 — 공통 타입을 Type Pool / 자체 Data Type 으로 만들어서 두 프로그램이 참조:
" 자체 type group ZRESULT
TYPE-POOL zresult.
TYPES: BEGIN OF zresult_ty_data,
matnr TYPE matnr,
menge TYPE menge_d,
meins TYPE meins,
END OF zresult_ty_data.
" 양쪽 프로그램에서 모두 동일하게 참조
TYPE-POOLS zresult.
DATA: lt_result TYPE TABLE OF zresult_ty_data.
또는 DDIC 구조체 / 테이블을 사용 — DB 테이블 / 데이터 엘리먼트를 공유하면 자동 일치.
4단계 — 다중 데이터 EXPORT / IMPORT
여러 변수를 동시에 메모리에 저장 / 읽기 가능.
" callee — 여러 데이터 한 번에 EXPORT
EXPORT lt_header FROM lt_header
lt_item FROM lt_item
lv_total_qty FROM lv_total_qty
TO MEMORY ID 'ZBATCH_RESULT'.
" caller — 같은 키로 한 번에 IMPORT
IMPORT lt_header TO lt_header
lt_item TO lt_item
lv_total_qty TO lv_total_qty
FROM MEMORY ID 'ZBATCH_RESULT'.
여러 변수를 묶어 한 키로 다루면 메모리 키 관리가 단순해집니다. 단 호출자 측이 EXPORT 한 변수명을 모두 알고 있어야 IMPORT 가능 — 인터페이스 문서 / 주석으로 명확히.
5단계 — Selection Screen 파라미터 전달 + 결과 받기
SUBMIT 으로 호출자가 호출된 프로그램의 Selection Screen 파라미터를 채울 수도 있습니다.
" 호출자
DATA: lr_matnr TYPE RANGE OF matnr,
lt_result TYPE TABLE OF ty_result.
" 자재 범위 채움
APPEND VALUE #( sign = 'I' option = 'BT'
low = 'MAT-0001' high = 'MAT-0099' ) TO lr_matnr.
" SUBMIT 시 Selection Option 파라미터 전달
SUBMIT z_xx_sub_program
WITH so_matnr IN lr_matnr " Selection Option 전달
WITH p_werks EQ '1000' " Parameter 전달
AND RETURN.
" 결과 메모리에서 읽기
IMPORT lt_result TO lt_result FROM MEMORY ID 'ZSUBMIT_RESULT'.
FREE MEMORY ID 'ZSUBMIT_RESULT'.
이 패턴이 표준 리포트(예: 표준 ALV 리포트) 를 자체 프로그램에서 재활용할 때 가장 흔히 쓰입니다. 표준 리포트는 EXPORT 코드가 있어야 결과 회수 가능하므로, 없다면 자체 wrapper 리포트 → 표준 리포트 결과를 EXPORT 하는 패턴.
6단계 — ABAP Memory vs SAP Memory (SPA/GPA) 차이
자주 헷갈리는 두 메모리 영역. 용도가 다릅니다.
| 항목 | ABAP Memory | SAP Memory (SPA/GPA) |
|---|---|---|
| 구문 | EXPORT / IMPORT MEMORY ID |
SET / GET PARAMETER ID |
| 저장 가능 데이터 | 변수 · 구조체 · ITAB · 복잡한 객체 | 단일 값 (최대 132자) |
| 지속 시간 | 현재 LUW (호출 체인 동안) | 사용자 세션 전체 (로그아웃까지) |
| SU01 사전 등록 | 불필요 | 선택 (Parameters 탭) |
| 적합 시나리오 | SUBMIT 결과 회수 / 큰 데이터 전달 | 화면 간 단일 값 자동 채움 (PO 번호 등) |
선택 — SUBMIT 결과를 받아오거나 큰 itab 을 전달하려면 ABAP Memory. 화면 간 단일 키 값(PO 번호 · 자재) 을 자동 채우려면 SPA/GPA.
흔히 빠뜨리는 함정
메모리 ID 키 불일치
EXPORT 측 키 'ZRESULT' 와 IMPORT 측 키 'ZRESULTS' (s 한 글자 차이) 가 다르면 IMPORT 가 빈 데이터를 반환. 에러 없이 조용히 실패하므로 디버깅이 어렵습니다. 키는 상수(CONSTANTS) 로 정의하고 양쪽에서 같은 상수를 참조.
변수 정의 불일치
호출자의 구조체와 호출된 프로그램의 구조체가 정확히 일치해야 합니다. 컬럼 하나 추가 / 타입 길이 변경만으로도 IMPORT 결과가 깨짐. 공통 TYPE-POOL 또는 DDIC 구조체 사용 권장.
AND RETURN 누락
SUBMIT 만 쓰면 호출 후 호출자가 종료됩니다. AND RETURN 이 있어야 호출자로 복귀해서 IMPORT 가 가능. 잊으면 IMPORT 라인이 실행조차 안 됩니다.
IMPORT 후 데이터 검증
IMPORT 가 실패해도 SY-SUBRC 가 0 이 아닌 값이 될 수 있지만, 빈 데이터는 정상 흐름 으로 처리됩니다. 받은 변수의 lines( ) 또는 IS INITIAL 체크로 데이터 존재 여부를 확인.
IMPORT lt_result TO lt_result FROM MEMORY ID 'ZRESULT'.
IF sy-subrc <> 0 OR lt_result IS INITIAL.
MESSAGE '결과를 받지 못했습니다.' TYPE 'I' DISPLAY LIKE 'E'.
RETURN.
ENDIF.
FREE MEMORY 누락
IMPORT 후 메모리에 데이터가 남아 있습니다. 다음 호출에서 의도 외 데이터가 섞일 수 있고, 세션 메모리도 누적되므로 사용 후 FREE MEMORY ID 정리 권장. 또는 전체 정리는 FREE MEMORY (모든 키).
표준 리포트 결과 회수 불가
EXPORT 코드가 없는 표준 리포트는 결과를 회수할 수 없습니다. 회피 패턴:
- List Memory 활용 —
SUBMIT ... EXPORTING LIST TO MEMORY+LIST_FROM_MEMORY+LIST_TO_ASCIFM - 자체 wrapper 만들기 — 표준 리포트 호출 후 결과 화면을 파싱
Memory 영역과 사용자 세션
ABAP Memory 는 현재 사용자 세션 + 현재 LUW 내에서만 유효. 다른 사용자는 같은 키로 IMPORT 해도 다른 데이터(또는 빈 데이터) 를 받습니다. 동시 사용자 충돌 걱정 없음.
다른 PRG 와 키 충돌
회사 자체 리포트 여러 개가 같은 메모리 키를 쓰면 의도 외 데이터를 받을 수 있습니다. 키 명명 규칙(Z + 프로그램명 + 의미) 로 충돌 방지. 예: 'ZRMM01_HEADER'·'ZRMM01_ITEM'.
전체 코드 — 복사용 통합본 (호출자 + 호출된 프로그램)
호출된 프로그램 (callee):
*&---------------------------------------------------------------------*
*& Report Z_XX_SUB_PROGRAM
*&---------------------------------------------------------------------*
*& SUBMIT 으로 호출되는 프로그램 — 결과를 ABAP 메모리에 저장
*&---------------------------------------------------------------------*
REPORT z_xx_sub_program.
TYPES: BEGIN OF ty_result,
matnr TYPE matnr,
werks TYPE werks_d,
menge TYPE menge_d,
meins TYPE meins,
END OF ty_result.
DATA: lt_result TYPE TABLE OF ty_result.
PARAMETERS: p_werks TYPE werks_d.
START-OF-SELECTION.
" 1) 자체 로직으로 데이터 수집
SELECT matnr, werks, menge, meins
FROM ekpo
INTO TABLE @lt_result
WHERE werks = @p_werks
UP TO 100 ROWS.
" ★ 2) 결과를 ABAP 메모리에 저장
EXPORT lt_result FROM lt_result TO MEMORY ID 'ZSUBMIT_RESULT'.
" (LEAVE PROGRAM 은 필요 시 — 호출자가 AND RETURN 사용하면 자동 복귀)
호출자 (caller):
*&---------------------------------------------------------------------*
*& Report Z_XX_CALLER_PROGRAM
*&---------------------------------------------------------------------*
*& SUBMIT 으로 다른 리포트 호출 + 결과 회수
*&---------------------------------------------------------------------*
REPORT z_xx_caller_program.
" ★ 호출된 프로그램과 동일한 타입 정의 (필수)
TYPES: BEGIN OF ty_result,
matnr TYPE matnr,
werks TYPE werks_d,
menge TYPE menge_d,
meins TYPE meins,
END OF ty_result.
CONSTANTS: c_memory_id TYPE c LENGTH 32 VALUE 'ZSUBMIT_RESULT'.
DATA: lt_result TYPE TABLE OF ty_result.
START-OF-SELECTION.
" ★ 1) SUBMIT 호출 — 파라미터 전달 + AND RETURN
SUBMIT z_xx_sub_program
WITH p_werks = '1000'
AND RETURN.
" ★ 2) ABAP 메모리에서 결과 IMPORT
IMPORT lt_result TO lt_result FROM MEMORY ID c_memory_id.
" 3) 결과 검증
IF sy-subrc <> 0 OR lt_result IS INITIAL.
MESSAGE '호출된 프로그램의 결과를 받지 못했습니다.' TYPE 'I' DISPLAY LIKE 'E'.
RETURN.
ENDIF.
WRITE: / |받은 라인 수: { lines( lt_result ) }|.
LOOP AT lt_result ASSIGNING FIELD-SYMBOL(<ls_row>).
WRITE: / <ls_row>-matnr, <ls_row>-werks, <ls_row>-menge, <ls_row>-meins.
ENDLOOP.
" ★ 4) 메모리 정리
FREE MEMORY ID c_memory_id.
같이 보면 좋은 글:
- "파일 업/다운로드 경로 자동 저장·복원 — file_open_dialog initial_directory + SPA/GPA 메모리 ID" — SAP Memory (SPA/GPA) 활용 패턴
- "BAPI · BDC 에러 메시지 확인 방법 — MESSAGE INTO · FORMAT_MESSAGE 빌드" — 호출 결과 메시지 처리
- "Search Help 매크로 활용 — F4IF_INT_TABLE_VALUE_REQUEST DEFINE 한 줄 호출" — 자주 반복되는 호출 패턴 매크로화
요약
| 단계 | 하는 일 | 핵심 포인트 |
|---|---|---|
| 1 | callee 에서 EXPORT | EXPORT 변수 FROM 변수 TO MEMORY ID '키' |
| 2 | caller 에서 SUBMIT | SUBMIT ... AND RETURN |
| 3 | caller 에서 IMPORT | IMPORT 변수 TO 변수 FROM MEMORY ID '키' |
| 4 | 결과 검증 | lines( ) 또는 IS INITIAL 체크 |
| 5 | 메모리 정리 | FREE MEMORY ID '키' |
ABAP 메모리는 SUBMIT 으로 호출된 다른 프로그램과 데이터를 주고받는 표준 표준 통신 채널. 호출자 / 호출된 프로그램 양쪽이 같은 메모리 키 + 같은 변수 정의를 공유하면 큰 ITAB / 구조체도 안전하게 전달됩니다. AND RETURN + 키 일치 + 변수 타입 일치 + 정리(FREE) 네 가지를 패턴으로 박아두면 표준 리포트 결과를 자체 프로그램에서 안정적으로 재활용할 수 있습니다.
Disclaimer — 이 포스트는 실무 정리 노트를 바탕으로 AI 보조로 정리되었습니다.
EXPORT / IMPORT MEMORY ID 구문 · SUBMIT ... AND RETURN 동작 · ABAP / SAP 메모리 영역 차이는 SAP NetWeaver 표준(ECC 6.0 / S/4HANA on-premise) 기준이며, 사내 표준 리포트 / 메모리 키 명명 정책 / 권한에 따라 일부 동작이 다를 수 있으니 운영 시스템 적용 전 개발·QA 환경에서 검증하시기 바랍니다. 표준 SAP 리포트가 EXPORT 코드를 제공하지 않는 경우 List Memory + 결과 파싱 또는 자체 wrapper 리포트로 우회하는 패턴도 함께 검토하시기 바랍니다.