본문 바로가기
ALV · 화면 · 리포트

[SAP ABAP] BAPI 결과 POPUP MESSAGE 표시 5가지 — CL_RMSL · C14ALD_BAPIRET2_SHOW · C14Z · BAL · REUSE_ALV

by Song.sh 2026. 5. 26.

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 에서 사전 확인 후 사용 가능한 방법으로 분기하시기 바랍니다.