SAP ABAP 에서 음수를 화면이나 ALV·스마트폼·리스트에 출력해 보면, 마이너스 부호가 숫자 뒤에 붙어 1,000- 형태로 표시되는 경우가 흔합니다. 회계·재무 문서의 전통적인 표기 방식이지만, 일반 사용자에게는 어색하게 보여 "마이너스 부호를 앞으로 옮겨 달라" 는 요청이 자주 들어옵니다.
원인은 WRITE 문이나 ABAP 표준 변환 동작이 음수를 오른쪽 부호(trailing minus) 로 출력하기 때문입니다. ABAP 의 숫자형(P, I, NETWR 같은 통화/수량 도메인) 을 CHAR 으로 변환하면 시스템이 자동으로 trailing minus 를 붙입니다. 이를 leading minus(앞 부호) 로 바꾸는 방법은 두 갈래로 정리됩니다.
이 글은 ABAP 에서 음수의 마이너스 부호를 숫자 앞으로 옮기는 두 가지 표준 방법 — String Template 의 sign = 옵션과 표준 함수 CLOI_PUT_SIGN_IN_FRONT — 을 한 화면에 모아 정리한 실무 메모입니다. 각 sign 옵션 6종(leftplus·left·leftspace·right·rightplus·rightspace) 의 출력 차이까지 표로 보여드립니다.
핵심 — 두 가지 방법 한눈 비교
| 방법 | 사용 형태 | 언제 쓰나 |
|---|---|---|
String Template sign = |
|{ lv_value SIGN = LEFTPLUS }| |
ABAP 7.40+ 모던 문법 — 한 줄로 부호 위치·공백·+ 표시 모두 제어 |
FM CLOI_PUT_SIGN_IN_FRONT |
CALL FUNCTION ... CHANGING value = lv_text. |
레거시 코드·이미 WRITE TO 로 변환된 CHAR 변수가 있을 때 |
| WRITE 출력 | WRITE lv_value NO-SIGN. |
부호 자체를 출력하지 않을 때 (보조 옵션) |
핵심 한 줄: 새 코드는 String Template sign = , 레거시 또는 이미 CHAR 변환된 문자열은 CLOI_PUT_SIGN_IN_FRONT. 두 방법 모두 SAP 표준이며 시스템 버전 의존이 없습니다.
1단계 — 문제 확인: ABAP 기본은 trailing minus
문제 재현은 1줄짜리 변수로 충분합니다. 음수 한 개를 CHAR 변수로 변환해 출력해 봅니다.
DATA: lv_value TYPE p DECIMALS 2 VALUE '-1000',
lv_text(15).
WRITE lv_value TO lv_text.
CONDENSE lv_text.
WRITE: / '변경전', lv_text.

출력 결과는 1,000.00- 또는 1000.00- 처럼 부호가 뒤에 붙습니다. SAP 의 P 타입은 회계 표기 관례를 따르기 때문에 일반 사용자가 보기엔 어색합니다. 두 가지 방법으로 부호를 앞으로 옮깁니다.
2단계 — 모던 방법: String Template sign = 옵션 6종
ABAP 7.40 부터 도입된 String Template(| ... |) 의 sign = 옵션이 가장 깔끔합니다. 옵션 6종이 부호 위치·+ 표시·공백 처리를 각각 다르게 합니다.
DATA lv_value TYPE p DECIMALS 2 VALUE '-1000'.
WRITE: / '변경후', |{ lv_value SIGN = LEFTPLUS }|. " +/- 왼쪽, 공백 없음
WRITE: / '변경후', |{ lv_value SIGN = LEFT }|. " - 만 왼쪽 (기본값)
WRITE: / '변경후', |{ lv_value SIGN = LEFTSPACE }|. " +/- 왼쪽, 공백 있음
WRITE: / '변경후', |{ lv_value SIGN = RIGHT }|. " - 만 오른쪽
WRITE: / '변경후', |{ lv_value SIGN = RIGHTPLUS }|. " +/- 오른쪽, 공백 없음
WRITE: / '변경후', |{ lv_value SIGN = RIGHTSPACE }|. " +/- 오른쪽, 공백 있음
옵션별 출력 결과를 표로 정리합니다(예시값 양수 1000 / 음수 -1000).
| 옵션 | 양수 출력 | 음수 출력 | 특징 |
|---|---|---|---|
LEFTPLUS |
+1000.00 |
-1000.00 |
양수도 + 명시, 부호 왼쪽 붙임 |
LEFT (기본) |
1000.00 |
-1000.00 |
음수만 - 왼쪽 (일반적으로 가장 자연스러움) |
LEFTSPACE |
·1000.00 (앞 공백) |
-1000.00 |
양수는 공백 1칸 / 음수는 - / 컬럼 폭 맞추기 좋음 |
RIGHT |
1000.00 |
1000.00- |
기존 ABAP 기본 동작과 동일 (부호 뒤) |
RIGHTPLUS |
1000.00+ |
1000.00- |
양수도 + 명시, 부호 오른쪽 붙임 |
RIGHTSPACE |
1000.00· (뒤 공백) |
1000.00- |
양수는 뒤 공백 1칸 / 음수는 뒤 - / 컬럼 폭 맞추기 |
음수 부호를 "앞으로" 보내는 것이 목적이라면 일반적으로 LEFT 가 가장 자연스러운 표기입니다(양수: 1000.00, 음수: -1000.00). 보고서 양식상 양수도 부호를 명시해야 한다면 LEFTPLUS, 컬럼 폭 정렬이 중요하면 LEFTSPACE 를 선택합니다.
3단계 — 클래식 방법: CLOI_PUT_SIGN_IN_FRONT
이미 WRITE TO 또는 MOVE 로 CHAR 변수에 변환된 상태인데 거기서 trailing minus 를 leading minus 로만 바꾸고 싶을 때, 또는 7.40 이전 시스템의 레거시 코드에서는 표준 FM CLOI_PUT_SIGN_IN_FRONT 을 사용합니다.
DATA: lv_value TYPE p DECIMALS 2 VALUE '-1000',
lv_text(15).
WRITE lv_value TO lv_text.
CONDENSE lv_text.
" lv_text 시점: '1000.00-'
CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT'
CHANGING
value = lv_text.
" lv_text 결과: '-1000.00'
WRITE: / '변경후', lv_text.

함수의 동작은 단순합니다. CHANGING 파라미터 value(CLIKE) 의 마지막 자리가 - 이면 그 부호를 떼서 문자열 맨 앞으로 옮기고, 나머지 자리를 한 칸씩 오른쪽으로 시프트해 폭을 맞춥니다. 양수에는 영향을 주지 않습니다.
함수 그룹은 LOIK 의 일반 FM 으로 시스템 버전 의존 없이 모든 ECC / S/4HANA 환경에서 동작합니다. 다만 SAP BW(Business Warehouse) 환경에서는 제공되지 않습니다.
4단계 — 어느 방법을 언제 쓸까
상황별 권장은 단순합니다.
| 상황 | 권장 방법 |
|---|---|
| 신규 ABAP 7.40+ 코드 | |{ lv SIGN = LEFT }| |
| 레거시 코드(7.40 미만) 또는 이미 CHAR 변환된 변수 | CLOI_PUT_SIGN_IN_FRONT |
| ALV 컬럼 출력에서 부호 위치 강제 | ALV Fieldcat 으로 직접 처리 불가 → CHAR 컬럼으로 별도 가공 후 출력 |
| 부호를 아예 안 보이게 | WRITE lv NO-SIGN. |
성능 차이는 사실상 없습니다. CLOI_PUT_SIGN_IN_FRONT 는 내부적으로 문자열 마지막 한 자만 검사하므로 호출 비용이 무시할 수준이며, String Template 도 컴파일 시점에 최적화된 코드로 변환됩니다. 선택 기준은 가독성·일관성·시스템 버전입니다.
흔히 빠뜨리는 함정
CHAR 폭 부족
DATA: lv_value TYPE p DECIMALS 2 VALUE '-1000',
lv_text(10). " ❌ 너무 좁음
WRITE lv_value TO lv_text.
" 결과: 잘림 또는 부호 누락 가능
CHAR 변수 폭이 변환 후 길이(부호 + 천단위 콤마 + 소수점 + 자릿수) 보다 좁으면 잘리거나 시스템이 별표(*) 로 채웁니다. 통화 금액은 CHAR 20 정도로 넉넉히 잡는 것이 안전합니다.
CONDENSE 누락
WRITE lv_value TO lv_text. " 결과: ' 1000.00-' (앞쪽 공백)
" CONDENSE 안 함
CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT'
CHANGING value = lv_text.
" 함수가 마지막 - 만 보고 처리 / 앞 공백은 그대로
WRITE ... TO 결과는 보통 앞쪽에 공백이 채워진 상태입니다. CONDENSE 로 공백을 정리한 뒤 함수를 호출해야 결과가 깔끔합니다.
String Template 안에 P 타입 직접 못 넣는 경우
ABAP 버전에 따라 String Template 안에 통화/수량 도메인이 직접 들어가면 통화 단위·소수점 자릿수가 환경 설정에 따라 해석돼 의도와 다른 결과가 나올 수 있습니다. 명시적으로 DECIMALS = n, NUMBER = USER 같은 보조 옵션을 함께 지정합니다.
WRITE: / |{ lv_value SIGN = LEFT DECIMALS = 2 NUMBER = USER }|.
양수에는 + 안 붙음
기본 LEFT 와 RIGHT 옵션은 음수에만 - 부호를 붙입니다. 양수에도 + 를 명시해야 하면 LEFTPLUS 또는 RIGHTPLUS 를 사용합니다.
CLOI_PUT_SIGN_IN_FRONT 에 숫자형 직접 넘기기
CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT'
CHANGING value = lv_value. " ❌ P 타입 직접 → 타입 충돌
함수의 CHANGING 파라미터는 CLIKE(문자형) 입니다. 숫자형(P·I·F) 를 직접 넘기면 활성화 단계에서 오류가 납니다. 반드시 WRITE ... TO 또는 |{ ... }| 로 CHAR 변환 후 호출합니다.
전체 코드 — 복사용 통합본
위 두 방법과 sign 옵션 6종 비교를 한 프로그램으로 합친 예제. SE38 에 그대로 붙여 실행하면 변환 전후를 모두 확인할 수 있습니다.
REPORT zr_sign_demo.
DATA: lv_value TYPE p DECIMALS 2 VALUE '-1000',
lv_text(20).
* 1) 변환 전 — ABAP 기본 동작 (trailing minus)
WRITE lv_value TO lv_text.
CONDENSE lv_text.
WRITE: / '변경전 :', lv_text.
* 2) String Template SIGN 옵션 6종
WRITE: /.
WRITE: / 'LEFTPLUS :', |{ lv_value SIGN = LEFTPLUS }|.
WRITE: / 'LEFT (기본) :', |{ lv_value SIGN = LEFT }|.
WRITE: / 'LEFTSPACE :', |{ lv_value SIGN = LEFTSPACE }|.
WRITE: / 'RIGHT :', |{ lv_value SIGN = RIGHT }|.
WRITE: / 'RIGHTPLUS :', |{ lv_value SIGN = RIGHTPLUS }|.
WRITE: / 'RIGHTSPACE :', |{ lv_value SIGN = RIGHTSPACE }|.
* 3) 클래식: CLOI_PUT_SIGN_IN_FRONT
WRITE: /.
WRITE lv_value TO lv_text.
CONDENSE lv_text.
CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT'
CHANGING
value = lv_text.
WRITE: / 'CLOI 함수 변환후:', lv_text.
* 4) 부호 자체 제거 (보조)
WRITE: /.
WRITE: / '부호 제거 :', lv_value NO-SIGN.
실행 결과는 모든 옵션의 출력이 한 화면에 나열돼 양수·음수 케이스를 한눈에 비교할 수 있습니다.
요약
| 단계 | 방법 | 핵심 |
|---|---|---|
| 1 | 문제 확인 | ABAP 기본은 음수 trailing minus (1000.00-) |
| 2 | 모던 방법 | String Template |{ lv SIGN = LEFT }| — 한 줄 처리 |
| 3 | 클래식 방법 | FM CLOI_PUT_SIGN_IN_FRONT — CHAR 변수 CHANGING |
| 4 | 선택 기준 | 신규 코드 = String Template · 레거시/이미 CHAR = FM |
ABAP 에서 음수 부호를 앞으로 옮기는 표준 방법은 두 가지뿐입니다. ABAP 7.40 이상의 모던 코드라면 |{ lv SIGN = LEFT }| 한 줄로 끝나고, 레거시·CHAR 변환 이후 단계에서는 CLOI_PUT_SIGN_IN_FRONT 한 번 호출이면 됩니다. sign 옵션 6종은 부호 위치·+ 표시·공백 정렬 요구에 따라 골라 쓰면 보고서·ALV·스마트폼 어디서나 깔끔한 표기가 가능합니다.
Disclaimer — 이 포스트는 실무 정리 노트를 바탕으로 AI 보조로 정리되었습니다.
String Template 의 SIGN = 옵션은 ABAP 7.40 이상에서 제공되는 표준 문법이며 옵션 6종(LEFTPLUS·LEFT·LEFTSPACE·RIGHT·RIGHTPLUS·RIGHTSPACE) 의 동작은 SAP Help Portal 의 abapcompute_string_format_options 문서에 명시돼 있습니다. CLOI_PUT_SIGN_IN_FRONT 는 함수 그룹 LOIK 의 일반 FM 으로 ECC / S/4HANA on-premise / Steampunk(ABAP Cloud) 환경에서 모두 동작하지만, SAP BW 에서는 제공되지 않습니다. 환경에 따라 통화·수량 도메인의 소수점 자릿수 해석이 사용자 프로필 설정(NUMBER = USER) 에 따라 달라질 수 있어, 정확한 자릿수가 필요한 보고서는 DECIMALS = n 을 명시하시기 바랍니다.