본문 바로가기
ABAP 문법 & 기법

[SAP ABAP] 프로그레스 바 표시하는 법 — SAPGUI_PROGRESS_INDICATOR / cl_akb_progress_indicator

by Song.sh 2026. 5. 14.

ABAP 리포트 프로그램이 대량 데이터를 처리할 때 사용자가 가장 답답해 하는 게 "이거 도대체 얼마나 더 걸리는 거지?" 입니다. 화면이 멈춰 보이면 사용자는 프로그램이 죽은 줄 알고 강제 종료하기 십상이죠. 이 상황을 해결하는 가장 단순한 UX 개선이 프로그레스 바(진행률 표시) 입니다.

 

SAP는 두 가지 표준 방식을 제공합니다. 오래된 펑션 모듈 SAPGUI_PROGRESS_INDICATOR 와 현대적 클래스 cl_akb_progress_indicator. 둘 다 SAP GUI 좌측 하단에 진행 상태를 노란색 바와 메시지로 표시해 줍니다.

 

이 글은 펑션 방식·클래스 방식 + 성능 최적화 트릭(같은 % 일 때 호출 생략) 을 정리한 메모입니다.


핵심 원리

두 방식의 동작 차이를 정리합니다.

방식 호출 형태 언제 쓰는가
펑션 방식 CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR' 레거시 코드와 통합 / FORM 으로 래핑해 재사용
클래스 방식 cl_akb_progress_indicator=>get_instance( ) 신규 개발 / 깔끔한 OOP 패턴 선호

둘 다 SAP GUI 좌측 하단 상태바에 노란 진행 바와 텍스트를 띄워줍니다. 사용자 입장에서는 동일한 경험이지만, 코드 측면에서는 클래스 방식이 더 간결합니다.

핵심 성능 포인트는 공통입니다 — 퍼센트가 바뀔 때만 호출 해야 한다는 점. 매 LOOP 마다 호출하면 화면 갱신 오버헤드 때문에 처리 속도가 크게 떨어집니다.


1단계 — 대상 데이터 조회 + 라인 수 확보

진행률 계산에는 현재 위치(sy-tabix) 와 전체 라인 수 두 값이 필요합니다. LOOP 시작 전에 전체 라인 수를 미리 잡아두는 게 중요.

DATA: mara_lines TYPE i,    " 전체 라인 수
      gd_percent TYPE i.    " 직전 표시된 퍼센트 (중복 호출 방지용)

START-OF-SELECTION.

  SELECT *
    INTO TABLE @DATA(gt_data)
    FROM mara.

  " 전체 라인 수 확보
  DESCRIBE TABLE gt_data LINES mara_lines.

  CLEAR gd_percent.

  LOOP AT gt_data INTO DATA(gs_data).

    PERFORM progress_bar USING 'reading internal table data...'
                                sy-tabix
                                mara_lines.

    " 실제 처리 로직 ...
  ENDLOOP.

핵심 포인트:

  • DESCRIBE TABLE ... LINES 로 전체 라인 수 조회 (sy-dbcnt 도 가능)
  • gd_percent — 직전 호출 시 퍼센트 저장. 다음 LOOP 에서 같은 % 면 호출 생략하는 가드 변수
  • 매 LOOP 마다 progress_bar FORM 에 현재 위치·전체 라인 수 전달

2단계 — 펑션 방식 FORM 작성

재사용 가능한 progress_bar FORM 을 만듭니다. 안에서 SAPGUI_PROGRESS_INDICATOR 펑션을 호출하는 구조.

FORM progress_bar USING p_value     " 표시할 메시지
                        p_tabix     " 현재 위치
                        p_nlines.   " 전체 라인 수

  DATA: w_percentage    TYPE p,
        w_percent_char(3).

  " 1) 퍼센트 계산
  w_percentage    = ( p_tabix / p_nlines ) * 100.
  w_percent_char  = w_percentage.

  " 2) 앞 공백 제거 (왼쪽 정렬용)
  SHIFT w_percent_char LEFT DELETING LEADING ' '.

  " 3) 표시 메시지 조립 — "메시지 76 %"
  DATA(w_text2) = |{ p_value } { w_percent_char } %|.

  " ★ 핵심: 퍼센트가 바뀌었을 때만 호출 (성능 최적화)
  IF w_percentage GT gd_percent OR p_tabix EQ 1.

    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        percentage = w_percentage
        text       = w_text2.

    gd_percent = w_percentage.

  ENDIF.

ENDFORM.

핵심 포인트:

  • w_percentage TYPE p — Packed 타입으로 소수점 없는 정수 % 계산
  • SHIFT LEFT DELETING LEADING — 숫자 변환 시 생기는 앞 공백 제거 (" 76" → "76")
  • IF w_percentage GT gd_percent — 핵심 성능 트릭. 직전 % 보다 클 때만 호출 → 같은 % 일 때 펑션 호출 절약
  • OR p_tabix EQ 1 — 첫 라인일 때는 무조건 한 번 표시해서 사용자에게 "시작됐다" 신호

3단계 — 성능 최적화의 중요성

100만 건 LOOP 에서 진행 바를 매번 호출하면 어떤 일이 일어날까요?

호출 빈도 결과
매 LOOP 마다 호출 (1,000,000회) 화면 갱신 오버헤드로 처리 시간 급증 — 진행 바가 오히려 발목 잡음
% 변경 시에만 호출 (최대 100회) 화면 갱신 부담 거의 없음. 진짜 처리 속도 그대로 유지

100% 까지 가는 동안 진행 바 갱신은 최대 100번 이면 충분합니다(1%, 2%, … 100%). 매 LOOP 가 아니라 퍼센트가 정수 단위로 바뀔 때만 호출하도록 가드를 두는 게 핵심 트릭. 위 FORM 의 IF w_percentage GT gd_percent 가 정확히 그 역할입니다.


4단계 — 클래스 방식 대안

신규 개발이면 좀 더 깔끔한 클래스 방식을 권장합니다. 별도 FORM 정의 없이도 인스턴스만 만들면 끝.

CONSTANTS: co_max TYPE i VALUE 1000000.

START-OF-SELECTION.

  " 1) 싱글톤 인스턴스 획득
  DATA(o_progress) = cl_akb_progress_indicator=>get_instance( ).

  DO co_max TIMES.

    " 2) 매 LOOP 호출해도 내부적으로 % 단위 최적화됨
    o_progress->display(
      force_display = abap_false      " false = 변경 시에만 실제 표시
      total         = co_max          " 전체 건수
      processed     = sy-index        " 현재 위치
      message       = 'test progress' ).

  ENDDO.

 

핵심 포인트:

  • get_instance( ) — 싱글톤 패턴. 매번 새 객체 생성하지 않음
  • force_display = abap_false클래스 내부에서 알아서 % 단위 최적화 처리. 펑션 방식처럼 직전 % 비교 가드를 따로 만들 필요 없음
  • total · processed 가 전체/현재 위치. % 는 클래스가 자동 계산

펑션 방식보다 코드가 짧고, % 비교 가드 로직이 클래스 내부로 캡슐화 되어 있어 실수할 여지가 적습니다.


흔히 빠뜨리는 함정

매 LOOP 마다 호출 (성능 가드 누락)

가장 흔한 함정. 펑션 방식에서 IF w_percentage GT gd_percent 가드 없이 매번 CALL FUNCTION 하면 100만 건 처리에 30분 걸릴 게 2~3시간으로 늘어남. 반드시 가드 또는 클래스 방식의 force_display = abap_false 사용.

0으로 나누기

p_nlines 가 0인 상태로 p_tabix / p_nlines 계산하면 즉시 덤프(COMPUTE_BCD_OVERFLOW). 빈 테이블 LOOP 는 안 들어가지만, 호출 전에 라인 수 0 체크 권장.

전체 라인 수 안 채움

DESCRIBE TABLE ... LINES 호출을 빼먹고 0으로 두면 진행 바가 항상 0%로 표시되거나 위 0 나누기 발생. SELECT 직후 반드시 라인 수 확보.

첫 라인 표시 누락

IF w_percentage GT gd_percent 조건만 두면 처음 1% 가 되기 전까지는 화면에 아무것도 안 뜨다가 갑자기 1%부터 나타남. OR p_tabix EQ 1 추가해서 첫 라인에 무조건 한 번 표시.

백그라운드 잡에서 호출 — 의미 없음

진행 바는 SAP GUI(클라이언트) 가 있을 때만 시각적으로 표시. SM37 배치 잡에서는 호출해도 화면에 아무것도 안 뜸. 배치는 SM50 워크프로세스 또는 잡 로그로 진행 상태 확인.

텍스트 길이 제한

SAPGUI_PROGRESS_INDICATORtext 파라미터는 70자 제한. 메시지가 길면 잘림. 자재명·고객명 같은 긴 텍스트는 줄여서 표시.

% 가 100을 넘는 경우

sy-tabix 보정 없이 LOOP 가 끝나도 100% 미만으로 끝나거나 반대로 100을 초과하는 케이스 발생 가능. 마지막에 percentage = 100 명시 호출로 마무리 권장.


전체 코드 — 복사용 통합본

위 단계를 펑션 방식과 클래스 방식 두 가지로 SE38 즉시 실행 가능한 통합본입니다.

펑션 방식 (FORM 래핑)

REPORT zexample_progress_bar_form.

DATA: mara_lines TYPE i,
      gd_percent TYPE i.

START-OF-SELECTION.

* 1) 대상 데이터 조회 + 라인 수 확보 ----------------------------------
  SELECT *
    INTO TABLE @DATA(gt_data)
    FROM mara.

  DESCRIBE TABLE gt_data LINES mara_lines.

  IF mara_lines = 0.
    MESSAGE '처리할 데이터가 없습니다.' TYPE 'S' DISPLAY LIKE 'E'.
    RETURN.
  ENDIF.

  CLEAR gd_percent.

* 2) LOOP 안에서 progress_bar FORM 호출 ------------------------------
  LOOP AT gt_data INTO DATA(gs_data).

    PERFORM progress_bar USING 'reading internal table data...'
                                sy-tabix
                                mara_lines.

    " 실제 처리 로직 ...

  ENDLOOP.

* 3) 마지막 100% 명시 마무리 -----------------------------------------
  CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
    EXPORTING
      percentage = 100
      text       = 'completed'.

*&---------------------------------------------------------------------*
*&      Form  PROGRESS_BAR
*&---------------------------------------------------------------------*
FORM progress_bar USING p_value      " 표시 메시지
                        p_tabix      " 현재 위치
                        p_nlines.    " 전체 라인 수

  DATA: w_percentage    TYPE p,
        w_percent_char(3).

  " 퍼센트 계산
  w_percentage    = ( p_tabix / p_nlines ) * 100.
  w_percent_char  = w_percentage.
  SHIFT w_percent_char LEFT DELETING LEADING ' '.

  DATA(w_text2) = |{ p_value } { w_percent_char } %|.

  " ★ 핵심: 퍼센트 변경 시에만 호출 (성능 최적화)
  IF w_percentage GT gd_percent OR p_tabix EQ 1.

    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        percentage = w_percentage
        text       = w_text2.

    gd_percent = w_percentage.

  ENDIF.

ENDFORM.

클래스 방식 (더 간결)

REPORT zexample_progress_bar_class.

CONSTANTS: co_max TYPE i VALUE 1000000.

START-OF-SELECTION.

* 1) 싱글톤 인스턴스 획득 --------------------------------------------
  DATA(o_progress) = cl_akb_progress_indicator=>get_instance( ).

* 2) LOOP 안에서 display 호출 ----------------------------------------
  DO co_max TIMES.

    " ★ 핵심: force_display = abap_false 면 클래스가 % 단위 최적화
    o_progress->display(
      force_display = abap_false
      total         = co_max
      processed     = sy-index
      message       = 'test progress' ).

    " 실제 처리 로직 ...

  ENDDO.

* ※ 클래스 방식은 별도 가드 변수·FORM 정의 불필요
*   - get_instance( ) 한 번
*   - display( total, processed ) 호출만으로 끝
*   - 신규 개발에 우선 권장

요약

단계 처리 핵심
1 전체 라인 수 확보 DESCRIBE TABLE ... LINES
2 펑션 방식 — SAPGUI_PROGRESS_INDICATOR FORM 래핑 + 가드 변수 + percentage/text
3 성능 최적화 가드 IF w_percentage GT gd_percent OR p_tabix EQ 1
4 클래스 방식 — cl_akb_progress_indicator get_instance( ) + display( total, processed )
5 마무리 마지막에 percentage = 100 + 'completed' 명시 호출

프로그레스 바 자체는 한 줄짜리 펑션 호출이지만, 퍼센트 변경 시에만 호출 이라는 작은 가드 하나가 성능에 큰 영향을 줍니다. 펑션 방식은 FORM 래핑으로 재사용하고, 신규 개발은 cl_akb_progress_indicator 로 가는 게 깔끔합니다. 사용자에게 "이 프로그램이 살아 있다"는 신호 하나를 주는 것만으로 강제 종료 클레임이 크게 줄어듭니다.


Disclaimer — 이 포스트는 실무 정리 노트를 바탕으로 AI 보조로 정리되었습니다. SAPGUI_PROGRESS_INDICATOR 펑션과 cl_akb_progress_indicator 클래스는 SAP GUI 클라이언트 환경에서만 시각적으로 표시되며, 배치 잡(SM37) 에서는 동작하지 않습니다. SAP 버전·GUI 버전에 따라 클래스 가용성이 다를 수 있으므로 운영 환경 적용 전 개발 시스템에서 확인하시기 바랍니다.