SAP 프로그램에서 BAPI 호출 결과의 BAPIRET2 메시지를 사용자에게 보여주는 방법은 한 가지가 아닙니다. SAP 표준이 제공하는 함수 / 클래스만 해도 5종 이상이고, 화면 분위기 · 사용자 권한 · 호출 컨텍스트에 따라 더 적합한 것이 다릅니다. 한 줄짜리 간단한 표시부터 풀스크린 BAL 로그까지 폭이 넓어서, 시나리오마다 잘 맞는 도구를 고르는 게 핵심.
이 글에서는 BAPI 결과를 팝업 / ALV 로 표시하는 표준 5가지 방법 을 한곳에 모읍니다. CL_RMSL_MESSAGE · C14ALD_BAPIRET2_SHOW · C14Z_MESSAGES_SHOW_AS_POPUP · BAL_DSP_LOG_DISPLAY · REUSE_ALV_GRID_DISPLAY_LVC 각각의 호출 코드 · 화면 모양 · 적합 시나리오 · 함정까지 같이 정리합니다. 일괄 처리 화면이나 BAPI 후속 화면 만들 때 골라 쓰는 표준 도구 모음입니다.
핵심 — 5가지 방법 비교
| 방법 | 호출 방식 | 화면 형태 | 적합 시나리오 |
|---|---|---|---|
CL_RMSL_MESSAGE |
클래스 메소드 1줄 | 메시지 박스 POPUP | 간단 BAPIRET2 즉시 표시 |
C14ALD_BAPIRET2_SHOW |
FM 1줄 | 간단 ALV POPUP | BAPIRET2 그대로 ALV 표시 |
C14Z_MESSAGES_SHOW_AS_POPUP |
FM + 자체 구조체 | SAP 표준 메시지 POPUP | SAP 화면 톤 통일 필요 |
BAL_DSP_LOG_DISPLAY |
3개 FM 흐름 | 풀스크린 / 팝업 ALV | 대량 메시지 / 필터 / 통계 |
REUSE_ALV_GRID_DISPLAY_LVC |
Field Catalog 직접 만들기 | 자유 ALV | 메시지 + 비즈니스 키 컬럼 |
선택 기준 — 빠르게 한 번 이면 CL_RMSL_MESSAGE, 표준 ALV 분위기 면 C14ALD/C14Z, 메시지 누적 / 필터 / 통계 면 BAL, 자유 컬럼 + 자체 데이터 면 REUSE_ALV_GRID. 한 프로젝트에 두세 가지를 섞어 써도 무방.
방법 1 — CL_RMSL_MESSAGE=>DISPLAY (가장 가벼움)
표준 SAP 클래스(CL_RMSL_MESSAGE, Package RMSL). 한 줄 호출로 BAPIRET2 결과를 메시지 박스 형태로 띄움.
DATA(it_bapi_ret) = VALUE bapiret2_t(
( type = 'S'
id = '01'
number = '319' " 319 번 메시지로 해야 MESSAGE_V1 값이 그대로 출력
message_v1 = 'Test 성공 메시지' )
( type = 'E'
id = '01'
number = '319'
message_v1 = '에러 메시지 TEST2' ) ).
cl_rmsl_message=>display( it_bapi_ret ).
특징 — 별도 화면 / 컨테이너 / 설정 없이 한 줄로 표시. 사용자가 OK 누르면 즉시 닫힘. 메시지가 5~10건 이하의 간단 알림에 적합.
메시지 번호 319 의 의미 — 표준 메시지 클래스 01 의 319번은 &1&2&3&4 형태라 V1 ~ V4 값을 그대로 출력해줍니다. 임의 텍스트를 메시지로 띄울 때 유용한 트릭.
방법 2 — C14ALD_BAPIRET2_SHOW (BAPIRET2 ALV)
표준 FM (FG C14ALD · Package CBUI). BAPIRET2 테이블을 그대로 넘기면 ALV 표시.
DATA(it_bapi_ret) = VALUE bapiret2_t(
( type = 'S'
id = '01'
number = '319'
message_v1 = 'Test' )
( type = 'E'
id = '01'
number = '319'
message_v1 = 'TEST2' ) ).
CALL FUNCTION 'C14ALD_BAPIRET2_SHOW'
TABLES
i_bapiret2_tab = it_bapi_ret.
특징 — Field Catalog 직접 만들 필요 없이 BAPIRET2 표준 구조 그대로 ALV 화면에 표시. 메시지 타입 아이콘 자동 표시. CL_RMSL_MESSAGE 보다 좀 더 정돈된 UX.
방법 3 — C14Z_MESSAGES_SHOW_AS_POPUP (SAP 표준 메시지 톤)
같은 패키지 CBUI 의 다른 FM. BAPIRET2 와 약간 다른 자체 구조체를 입력으로 받음. SAP 표준 화면의 메시지 영역과 톤이 같아서 사용자 친숙도가 높습니다.
DATA: BEGIN OF lt_bapi_msg OCCURS 0,
msgid LIKE sy-msgid,
msgty LIKE sy-msgty,
msgno LIKE sy-msgno,
msgv1 LIKE sy-msgv1,
msgv2 LIKE sy-msgv2,
msgv3 LIKE sy-msgv3,
msgv4 LIKE sy-msgv4,
lineno LIKE mesg-zeile,
END OF lt_bapi_msg.
" BAPIRET2 → 자체 구조체 변환
LOOP AT pt_return ASSIGNING FIELD-SYMBOL(<ls_ret>).
lt_bapi_msg-msgid = <ls_ret>-id.
lt_bapi_msg-msgty = <ls_ret>-type.
lt_bapi_msg-msgno = <ls_ret>-number.
lt_bapi_msg-msgv1 = <ls_ret>-message.
lt_bapi_msg-lineno = sy-tabix.
APPEND lt_bapi_msg.
ENDLOOP.
IF lt_bapi_msg[] IS NOT INITIAL.
CALL FUNCTION 'C14Z_MESSAGES_SHOW_AS_POPUP'
TABLES
i_message_tab = lt_bapi_msg.
ENDIF.
특징 — BAPIRET2 를 자체 구조체로 한 번 변환하는 추가 단계가 있지만, 화면 톤이 SAP 표준 메시지 화면과 동일. 표준 트랜잭션과 자체 프로그램이 같이 운영되는 환경에서 사용자 혼란을 줄여줍니다.
방법 4 — BAL_DSP_LOG_DISPLAY (대량 + 필터 + 통계)
Business Application Log 의 표준 흐름. 메시지 누적 → 일괄 표시. 메시지 수가 많거나(50건+) 필터 / 통계 / Long Text 가 필요할 때 가장 강력.
DATA: lv_log_h TYPE balloghndl,
lt_log_h TYPE bal_t_logh,
ls_log TYPE bal_s_log,
ls_msg TYPE bal_s_msg,
ls_prof TYPE bal_s_prof.
" 1) 로그 핸들 생성
ls_log-extnumber = '메시지 테스트 중'.
ls_log-object = 'APPL_LOG'.
CALL FUNCTION 'BAL_LOG_CREATE'
EXPORTING
i_s_log = ls_log
IMPORTING
e_log_handle = lv_log_h.
" 2) 메시지 일괄 추가
DO 3 TIMES.
ls_msg-msgid = 'BL'.
ls_msg-msgno = '001'.
ls_msg-msgty = 'W'.
ls_msg-msgv1 = |라인 { sy-index } 에러 발생|.
ls_msg-probclass = '1'. " GRID 표시 시 강조 색상
CALL FUNCTION 'BAL_LOG_MSG_ADD'
EXPORTING
i_log_handle = lv_log_h
i_s_msg = ls_msg.
ENDDO.
" 3) 팝업 프로파일 받기
CALL FUNCTION 'BAL_DSP_PROFILE_POPUP_GET'
IMPORTING
e_s_display_profile = ls_prof.
ls_prof-use_grid = 'X'.
ls_prof-title = '메시지 테스트 중'.
ls_prof-disvariant-report = sy-repid.
ls_prof-cwidth_opt = 'X'.
APPEND lv_log_h TO lt_log_h.
" 4) ALV 팝업 표시
CALL FUNCTION 'BAL_DSP_LOG_DISPLAY'
EXPORTING
i_s_display_profile = ls_prof
i_t_log_handle = lt_log_h.
특징 — Long Text 자동 표시 / 메시지 타입별 통계 / 필터 / 검색 / 엑셀 내보내기까지 표준 ALV 의 모든 기능. PROBCLASS 로 메시지 중요도(1~4) 를 지정하면 GRID 모드에서 색상으로 표시됩니다.
방법 5 — REUSE_ALV_GRID_DISPLAY_LVC (자유 컬럼)
메시지 + 비즈니스 키(PO 번호 · 자재 · 거래처) 를 같이 보여줘야 할 때. Field Catalog 를 직접 만들어서 자유로운 컬럼 구성.
TYPES: BEGIN OF ty_msg,
seq TYPE i,
type TYPE bapiret2-type,
ebeln TYPE ekko-ebeln,
message TYPE string,
END OF ty_msg.
DATA: gt_message TYPE TABLE OF ty_msg,
gt_fcat TYPE lvc_t_fcat,
gs_fcat TYPE lvc_s_fcat.
" (gt_message 데이터 채움)
" Field Catalog 작성
gs_fcat-fieldname = 'SEQ'.
gs_fcat-scrtext_l = '순번'.
APPEND gs_fcat TO gt_fcat.
CLEAR gs_fcat.
gs_fcat-fieldname = 'TYPE'.
gs_fcat-scrtext_l = '메시지 유형'.
APPEND gs_fcat TO gt_fcat.
CLEAR gs_fcat.
gs_fcat-fieldname = 'EBELN'.
gs_fcat-scrtext_l = 'PO 번호'.
APPEND gs_fcat TO gt_fcat.
CLEAR gs_fcat.
gs_fcat-fieldname = 'MESSAGE'.
gs_fcat-scrtext_l = '메시지 내용'.
gs_fcat-outputlen = 60.
APPEND gs_fcat TO gt_fcat.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
it_fieldcat = gt_fcat
TABLES
t_outtab = gt_message.
특징 — 메시지 + 호출자가 알고 있는 비즈니스 키(PO · 자재 · 거래처) 를 같은 행에 묶어 사용자가 어떤 데이터가 실패했는지 즉시 파악 가능. 일괄 등록 / 검증 결과 화면에 가장 자주 쓰이는 패턴.
조합 패턴 — 메시지 빌드 → 표시
어떤 방법을 쓰든 BAPIRET2 의 MESSAGE 필드가 비어 있는 경우가 있으므로 호출 전 메시지 빌드는 항상 표준화하는 게 안전합니다.
LOOP AT lt_return ASSIGNING FIELD-SYMBOL(<ls_ret>).
IF <ls_ret>-message IS INITIAL.
MESSAGE ID <ls_ret>-id
TYPE <ls_ret>-type
NUMBER <ls_ret>-number
WITH <ls_ret>-message_v1
<ls_ret>-message_v2
<ls_ret>-message_v3
<ls_ret>-message_v4
INTO <ls_ret>-message.
ENDIF.
ENDLOOP.
" 이후 위 5가지 방법 중 적합한 것 호출
cl_rmsl_message=>display( lt_return ).
이 패턴이 BAPIRET2 의 MESSAGE 가 비어 있는 BAPI 의 결과도 일관되게 표시되게 해줍니다.
흔히 빠뜨리는 함정
메시지 번호 319 의 의미
CL_RMSL_MESSAGE=>display 예시에서 메시지 ID '01' + 번호 '319' 는 &1&2&3&4 자리표시 메시지. 임의 텍스트를 그대로 출력하는 표준 트릭. 직접 만든 메시지 클래스의 번호를 쓰면 그 메시지 텍스트가 표시됩니다.
BAPIRET2 MESSAGE 필드 신뢰 X
BAPI 마다 RETURN 의 MESSAGE 채움 정책이 다릅니다. 표시 직전에 MESSAGE ... INTO 로 빌드하는 패턴을 표준화.
C14ALD vs C14Z 차이
같은 CBUI 패키지의 비슷한 함수지만 입력 구조가 다릅니다. C14ALD 는 BAPIRET2 그대로, C14Z 는 자체 구조체. 사용 전 SE37 에서 시그니처 확인.
BAL probclass 색상
PROBCLASS 는 1(매우 높음) ~ 4(낮음) 의 메시지 중요도. GRID 모드에서만 색상으로 표시되므로 use_grid = 'X' 와 함께 설정해야 효과.
REUSE_ALV vs CL_SALV
REUSE_ALV 시리즈는 SAP 의 오래된 ALV API. 신규 개발에서는 CL_SALV_TABLE 권장. REUSE_ALV 는 기존 프로그램 유지보수 / Field Catalog 가 이미 만들어져 있는 케이스에서만.
CBUI 패키지 가용성
C14ALD_BAPIRET2_SHOW / C14Z_MESSAGES_SHOW_AS_POPUP 의 패키지 CBUI 는 일부 산업 솔루션 / Add-on 에서만 활성. 회사 시스템에 함수가 없으면 SE37 에서 검색 후 대체 함수로 분기.
Long Text 표시
BAL 만 메시지의 Long Text 자동 표시 지원. 다른 방법은 짧은 텍스트만 표시되므로 상세 설명이 필요한 메시지는 BAL 로 흐르는 게 사용자 친화적.
메시지 갯수가 매우 많을 때
10,000 건 이상의 메시지를 한 번에 표시하면 어떤 방법이든 화면 응답이 느려집니다. 사전 필터링(에러 / 워닝만) 또는 페이지 분할 전략을 함께 검토.
전체 코드 — 복사용 통합본 (BAPI + 메시지 빌드 + 표시 선택)
*&---------------------------------------------------------------------*
*& Report Z_XX_BAPI_POPUP_MESSAGE
*&---------------------------------------------------------------------*
*& BAPI 결과 메시지 표시 5가지 방법 데모
*&---------------------------------------------------------------------*
REPORT z_xx_bapi_popup_message.
PARAMETERS: p_meth TYPE c LENGTH 1 DEFAULT '1'. " 1~5
DATA: lt_return TYPE TABLE OF bapiret2.
START-OF-SELECTION.
" 샘플 데이터 (실제로는 BAPI / BDC 호출 결과)
APPEND VALUE #( type = 'S' id = '01' number = '319'
message_v1 = '정상 처리 완료' ) TO lt_return.
APPEND VALUE #( type = 'W' id = '01' number = '319'
message_v1 = '주의: 회계 기간 마감 임박' ) TO lt_return.
APPEND VALUE #( type = 'E' id = '01' number = '319'
message_v1 = '에러: 권한 부족' ) TO lt_return.
" ★ MESSAGE 필드 자동 빌드 (방어적)
LOOP AT lt_return ASSIGNING FIELD-SYMBOL(<ls_ret>).
IF <ls_ret>-message IS INITIAL.
MESSAGE ID <ls_ret>-id
TYPE <ls_ret>-type
NUMBER <ls_ret>-number
WITH <ls_ret>-message_v1
<ls_ret>-message_v2
<ls_ret>-message_v3
<ls_ret>-message_v4
INTO <ls_ret>-message.
ENDIF.
ENDLOOP.
" ★ 표시 방법 선택
CASE p_meth.
WHEN '1'. " CL_RMSL_MESSAGE (가장 가벼움)
cl_rmsl_message=>display( lt_return ).
WHEN '2'. " C14ALD_BAPIRET2_SHOW
CALL FUNCTION 'C14ALD_BAPIRET2_SHOW'
TABLES
i_bapiret2_tab = lt_return.
WHEN '3'. " C14Z_MESSAGES_SHOW_AS_POPUP (자체 구조체 변환)
DATA: BEGIN OF lt_msg OCCURS 0,
msgid LIKE sy-msgid,
msgty LIKE sy-msgty,
msgno LIKE sy-msgno,
msgv1 LIKE sy-msgv1,
msgv2 LIKE sy-msgv2,
msgv3 LIKE sy-msgv3,
msgv4 LIKE sy-msgv4,
lineno LIKE mesg-zeile,
END OF lt_msg.
LOOP AT lt_return INTO DATA(ls_ret).
lt_msg-msgid = ls_ret-id.
lt_msg-msgty = ls_ret-type.
lt_msg-msgno = ls_ret-number.
lt_msg-msgv1 = ls_ret-message.
lt_msg-lineno = sy-tabix.
APPEND lt_msg.
ENDLOOP.
CALL FUNCTION 'C14Z_MESSAGES_SHOW_AS_POPUP'
TABLES
i_message_tab = lt_msg.
WHEN '4'. " BAL_DSP_LOG_DISPLAY (대량 + 필터)
DATA: lv_log_h TYPE balloghndl,
lt_log_h TYPE bal_t_logh,
ls_log TYPE bal_s_log,
ls_bmsg TYPE bal_s_msg,
ls_prof TYPE bal_s_prof.
ls_log-extnumber = 'BAPI 처리 결과'.
ls_log-object = 'APPL_LOG'.
CALL FUNCTION 'BAL_LOG_CREATE'
EXPORTING
i_s_log = ls_log
IMPORTING
e_log_handle = lv_log_h.
LOOP AT lt_return INTO ls_ret.
ls_bmsg-msgid = ls_ret-id.
ls_bmsg-msgno = ls_ret-number.
ls_bmsg-msgty = ls_ret-type.
ls_bmsg-msgv1 = ls_ret-message_v1.
ls_bmsg-probclass = '1'.
CALL FUNCTION 'BAL_LOG_MSG_ADD'
EXPORTING
i_log_handle = lv_log_h
i_s_msg = ls_bmsg.
ENDLOOP.
CALL FUNCTION 'BAL_DSP_PROFILE_POPUP_GET'
IMPORTING
e_s_display_profile = ls_prof.
ls_prof-use_grid = 'X'.
ls_prof-title = 'BAPI 결과 메시지'.
ls_prof-disvariant-report = sy-repid.
ls_prof-cwidth_opt = 'X'.
APPEND lv_log_h TO lt_log_h.
CALL FUNCTION 'BAL_DSP_LOG_DISPLAY'
EXPORTING
i_s_display_profile = ls_prof
i_t_log_handle = lt_log_h.
WHEN '5'. " REUSE_ALV_GRID_DISPLAY_LVC (자유 컬럼)
TYPES: BEGIN OF ty_msg,
seq TYPE i,
type TYPE bapiret2-type,
message TYPE string,
END OF ty_msg.
DATA: gt_message TYPE TABLE OF ty_msg,
gt_fcat TYPE lvc_t_fcat,
gs_fcat TYPE lvc_s_fcat.
LOOP AT lt_return INTO ls_ret.
APPEND VALUE ty_msg(
seq = sy-tabix
type = ls_ret-type
message = ls_ret-message ) TO gt_message.
ENDLOOP.
gs_fcat-fieldname = 'SEQ'.
gs_fcat-scrtext_l = '순번'.
APPEND gs_fcat TO gt_fcat.
CLEAR gs_fcat.
gs_fcat-fieldname = 'TYPE'.
gs_fcat-scrtext_l = '유형'.
APPEND gs_fcat TO gt_fcat.
CLEAR gs_fcat.
gs_fcat-fieldname = 'MESSAGE'.
gs_fcat-scrtext_l = '메시지'.
gs_fcat-outputlen = 60.
APPEND gs_fcat TO gt_fcat.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
it_fieldcat = gt_fcat
TABLES
t_outtab = gt_message.
ENDCASE.
같이 보면 좋은 글:
- "ALV 형태 POPUP 메시지 표시 — BAL_DSP_LOG_DISPLAY · CL_SALV_TABLE set_screen_popup" — 같은 영역 두 가지 방법 비교
- "BAPI · BDC 에러 메시지 확인 방법 — MESSAGE INTO · FORMAT_MESSAGE 빌드" — 메시지 텍스트 빌드 패턴
- "BAdI 찾는 방법 5가지 — CL_EXITHANDLER 디버깅" — 메시지 발생 위치 추적
요약
| 방법 | 호출 | 적합 시나리오 |
|---|---|---|
| 1 | CL_RMSL_MESSAGE=>display |
한 줄, 즉시 표시, 메시지 박스 |
| 2 | C14ALD_BAPIRET2_SHOW |
BAPIRET2 → ALV POPUP |
| 3 | C14Z_MESSAGES_SHOW_AS_POPUP |
SAP 표준 화면 톤 |
| 4 | BAL_DSP_LOG_DISPLAY |
대량 메시지 / 필터 / Long Text |
| 5 | REUSE_ALV_GRID_DISPLAY_LVC |
자유 컬럼 + 비즈니스 키 |
BAPI 결과 메시지 표시는 시나리오에 맞춰 가장 가벼운 도구를 고르는 게 핵심. 5건 미만의 단순 알림은 CL_RMSL_MESSAGE, 표준 ALV 분위기는 C14ALD/C14Z, 대량 + 통계 + Long Text 가 필요하면 BAL, 메시지 + PO / 자재 같은 추가 컬럼이 필요하면 REUSE_ALV — 이렇게 매핑해두면 BAPI 후속 화면을 빠르게 만들 수 있습니다. 메시지 텍스트 빌드(MESSAGE ... INTO) 는 어떤 방법을 쓰든 호출 전 단계에서 표준화해두는 게 안전합니다.
Disclaimer — 이 포스트는 실무 정리 노트를 바탕으로 AI 보조로 정리되었습니다.
CL_RMSL_MESSAGE · C14ALD_BAPIRET2_SHOW · C14Z_MESSAGES_SHOW_AS_POPUP · BAL_DSP_LOG_DISPLAY 등 함수 / 클래스 시그니처는 SAP NetWeaver 표준(패키지 RMSL · CBUI · SZAL · ECC 6.0 / S/4HANA on-premise) 기준이며, 사내 산업 솔루션 / Add-on 활성화 여부에 따라 일부 함수가 없을 수 있으니 운영 시스템 적용 전 SE37 에서 사전 확인 후 사용 가능한 방법으로 분기하시기 바랍니다.