SAP BOX

'26/10/13 UPDATE

ABAP / FIELD NOTES

CONCATENATE에 ' '를 넣었는데 왜 공백이 사라질까

작은따옴표 ' '는 길이 1인 c 필드이고, CONCATENATE와 &&는 고정 길이 피연산자의 뒤 공백을 무시합니다. 그래서 끼워 넣은 공백이 사라집니다. SEPARATED BY, 역따옴표, 문자열 템플릿으로 공백을 남기는 법과 RESPECTING BLANKS, 빈 필드, 짧은 대상 필드의 함정을 가상 예로 봅니다.

이름과 성 사이에 공백 하나를 넣으려고 CONCATENATE lv_first ' ' lv_last INTO lv_full.라고 썼는데, 결과가 ANNA BERG가 아니라 ANNABERG로 나옵니다. 오타처럼 보이지만 ABAP 규칙대로 동작한 결과입니다. 이 글을 읽고 나면 작은따옴표로 쓴 공백이 왜 사라지는지 설명하고, 공백을 남기는 세 가지 방법 가운데 하나를 고르고, 고친 뒤에도 남는 RESPECTING BLANKS, 빈 필드, 짧은 대상 필드의 함정을 미리 확인할 수 있습니다.

예시의 lv_first와 lv_last는 TYPE c LENGTH 10이고 값은 'ANNA'와 'BERG'입니다. 결과를 받는 lv_full은 string입니다. 이름과 프로그램은 모두 지어낸 것이고 코드는 실제 시스템에서 실행하지 않았습니다. 글에 적은 결과는 ABAP 키워드 문서의 CONCATENATE, 연결 연산자 &&, 문자 리터럴 페이지(7.58판, CONCATENATE는 7.50판도 대조)의 규칙을 적용해 따진 값이며, 문서 본문은 영어입니다.

' '는 공백 한 칸짜리 c 필드다

먼저 리터럴의 타입을 봅니다. 작은따옴표로 감싼 '...'는 텍스트 필드 리터럴이고, 타입은 감싼 글자 수만큼의 길이를 가진 c입니다. 그래서 ' '는 공백 한 칸이 든 길이 1의 c 필드와 같습니다. 문서는 빈 텍스트 필드 리터럴은 없다고도 적습니다. ''라고 써도 공백 한 칸이 든 ' '와 같은 뜻입니다.

다음은 CONCATENATE의 규칙입니다. 문자열 처리에서 고정 길이 피연산자, 곧 c처럼 길이가 정해진 데이터 객체의 뒤 공백은 기본적으로 무시됩니다. lv_first는 ANNA 뒤에 공백 6칸이 채워진 필드라 그 6칸이 빠지고, ' '는 한 칸이 통째로 뒤 공백이라 내용이 남지 않습니다. 세 피연산자에서 공백이 모두 빠지니 결과는 ANNABERG입니다. 대상 필드가 충분히 길므로 sy-subrc는 0이고, 오류도 경고도 없습니다.

SAP 노트

' '를 넣었는데 ANNABERG가 된다

가상 예: lv_first, lv_last는 TYPE c LENGTH 10, 값은 'ANNA'와 'BERG'

  1. 피연산자 세 개

    CONCATENATE lv_first ' ' lv_last INTO lv_full.

    • lv_first: ANNA + 공백 6칸
    • ' ': 길이 1인 c, 공백 1칸
    • lv_last: BERG + 공백 6칸
  2. 고정 길이의 뒤 공백은 무시

    c, n, d, t: trailing blanks ignored

    • ANNA 뒤 공백 6칸 → 무시
    • ' '는 전부 뒤 공백 → 빈 내용
    • BERG 뒤 공백 6칸 → 무시
  3. 결과

    sy-subrc = 0

    • lv_full = ANNABERG
    • &&로 써도 같다
    • lv_first && ' ' && lv_last

이름과 변수는 가상입니다. 결과는 ABAP 키워드 문서(7.58판, 7.50판)의 CONCATENATE·&& 규칙으로 따진 값이며 실행 결과가 아닙니다.

작은따옴표 ' '는 길이 1인 c 타입 리터럴이고, 그 한 칸은 뒤 공백입니다. CONCATENATE와 &&는 고정 길이 피연산자의 뒤 공백을 무시하므로 끼워 넣은 공백도 함께 사라집니다.

연결 연산자로 바꿔 lv_full = lv_first && ' ' && lv_last.라고 써도 마찬가지입니다. && 문서도 고정 길이의 문자형 피연산자는 뒤 공백을 무시한다고 적습니다. 문장을 바꾸는 것만으로는 해결되지 않고, 공백을 넣는 방식을 바꿔야 합니다.

공백을 남기는 세 가지 방법

첫째, 공백을 피연산자가 아니라 구분자로 넣습니다. CONCATENATE lv_first lv_last INTO lv_full SEPARATED BY space.는 ANNA BERG를 만듭니다. 문서는 SEPARATED BY의 구분자 sep가 고정 길이여도 뒤 공백을 지킨다고 적습니다. 같은 규칙이므로 SEPARATED BY ' '로 써도 결과는 같습니다. 피연산자 자리의 ' '와 구분자 자리의 ' '가 다르게 취급되는 셈입니다.

둘째, 역따옴표 리터럴을 씁니다. `...`는 텍스트 문자열 리터럴이고 타입이 string입니다. string의 뒤 공백은 항상 의미가 있으므로 lv_full = lv_first && ` ` && lv_last.는 공백을 남깁니다. 작은따옴표와 역따옴표 한 글자 차이로 결과가 갈립니다.

셋째, 문자열 템플릿을 씁니다. lv_full = |{ lv_first } { lv_last }|.에서 | | 안에 직접 적은 글자는 리터럴 텍스트이고, 템플릿 안의 공백은 언제나 의미가 있습니다. 중괄호 안의 c 값은 뒤 공백을 빼고 들어가므로 결과는 정확히 ANNA BERG입니다. 세 방법 중 무엇을 고를지는 팀의 코딩 규칙을 따르면 되지만, 새 코드라면 읽는 사람이 공백을 눈으로 확인하기 쉬운 템플릿이 무난합니다.

SAP 노트

공백을 남기는 세 가지 방법

같은 lv_first, lv_last로 ANNA BERG를 만든다

  • SEPARATED BY space

    CONCATENATE lv_first lv_last INTO lv_full SEPARATED BY space.

    • 구분자 sep의 뒤 공백은 지킨다
    • 피연산자 사이마다 한 번 넣음
    • ' '를 구분자로 써도 같다
  • 역따옴표 ` `

    lv_full = lv_first && ` ` && lv_last.

    • ` `는 string 타입 리터럴
    • string의 공백은 항상 유지
    • &&와 함께 쓰면 된다
  • 문자열 템플릿

    lv_full = |{ lv_first } { lv_last }|.

    • | | 안의 리터럴 공백은 그대로
    • { } 안의 c 값은 뒤 공백 무시
    • 결과 ANNA BERG

&&와 문자열 템플릿은 ABAP 7.0 EhP2부터 쓸 수 있습니다. 예시는 가상이며 실행하지 않았습니다.

공백을 피연산자로 넣지 말고 구분자로 넣거나, 뒤 공백이 의미를 갖는 string 타입으로 넣습니다. 문자열 템플릿에서는 | | 안에 적은 공백이 그대로 결과에 들어갑니다.

고친 뒤에도 남는 세 가지 함정

RESPECTING BLANKS를 붙이면 공백이 살아나긴 하지만, 원하는 결과와는 다릅니다. 이 추가 문법은 끼워 넣은 공백만이 아니라 모든 피연산자의 뒤 공백을 지킵니다. CONCATENATE lv_first ' ' lv_last INTO lv_full RESPECTING BLANKS.의 결과는 ANNA, 공백 7칸(필드를 채운 6칸과 끼워 넣은 1칸), BERG, 공백 6칸입니다. 이 문법은 필드 길이 그대로 이어 붙여야 하는 고정 폭 레코드를 만들 때처럼 공백이 실제 데이터인 경우에 씁니다.

SEPARATED BY는 연속한 피연산자 사이마다 구분자를 넣습니다. 그래서 lv_first가 비어 있으면, 규칙대로라면 결과가 앞에 공백이 붙은 ' BERG'가 됩니다. 성이나 이름이 빠질 수 있는 데이터라면 빈 값을 먼저 걸러 내거나 결과의 앞 공백을 처리해야 합니다.

대상 필드가 string이 아니라 고정 길이라면 길이도 확인합니다. 결과가 대상보다 짧으면 오른쪽을 공백으로 채우고, 길면 오른쪽에서 잘라 냅니다. lv_short TYPE c LENGTH 6에 ANNA BERG를 넣으면 ANNA B만 남고, 이때 sy-subrc가 4가 됩니다. 잘림은 런타임 오류가 아니므로 sy-subrc를 확인하지 않으면 모르고 지나갑니다. string 대상은 길이가 결과에 맞춰지므로 잘리지 않습니다.

SAP 노트

고친 뒤에도 남는 세 가지 함정

RESPECTING BLANKS, 빈 필드, 짧은 대상 필드

  • RESPECTING BLANKS

    CONCATENATE lv_first ' ' lv_last INTO lv_full RESPECTING BLANKS.

    • 모든 피연산자의 뒤 공백을 지킴
    • lv_first의 공백 6칸도 들어감
    • ANNA + 7칸 + BERG + 6칸
  • lv_first가 비어 있으면

    SEPARATED BY space

    • 구분자는 두 피연산자 사이에 들어감
    • 앞 피연산자가 비어도 넣는다
    • 결과 ' BERG', 앞에 공백
  • 대상 필드가 짧으면

    IF sy-subrc = 4.

    • lv_short TYPE c LENGTH 6
    • 오른쪽이 잘려 'ANNA B'
    • sy-subrc = 4로 알 수 있다

결과는 문서 규칙으로 따진 값이며 실행 결과가 아닙니다. 대상이 string이면 길이가 결과에 맞춰지고 잘리지 않습니다.

RESPECTING BLANKS는 끼워 넣은 공백만이 아니라 고정 길이 필드를 채운 공백까지 모두 살립니다. 빈 필드와 짧은 대상 필드도 따로 확인해야 합니다.

편집기에서 확인할 자리와 릴리스 차이

아래 편집기 예시는 위 내용을 한 화면에 모은 것입니다. ①은 선언, ②는 공백이 사라지는 쓰기, ③과 ④는 공백을 남기는 세 방법, ⑤는 RESPECTING BLANKS입니다. 기존 코드에서 ' '가 CONCATENATE나 &&의 피연산자 자리에 있으면 의도한 공백이 빠지고 있을 가능성이 큽니다.

SAP GUI ABAP 편집기 화면에 번호 다섯 개가 있다. 1은 lv_first와 lv_last를 TYPE c LENGTH 10으로, lv_full을 string으로 선언한 줄, 2는 CONCATENATE lv_first ' ' lv_last INTO lv_full의 결과가 ANNABERG라는 주석, 3은 SEPARATED BY space로 ANNA BERG가 되는 줄, 4는 lv_first && ` ` && lv_last와 |{ lv_first } { lv_last }|가 모두 ANNA BERG라는 줄, 5는 RESPECTING BLANKS를 붙이면 ANNA, 공백 7칸, BERG, 공백 6칸이 된다는 줄이다.
같은 두 필드로 공백이 사라지는 쓰기, 공백이 남는 세 가지 쓰기, RESPECTING BLANKS를 한 화면에 모은 예시. ZDEMO_CONCAT_BLANKS와 값은 가상이고 코드는 실행하지 않았으며, 주석의 결과는 문서의 규칙으로 따진 값이다.

CONCATENATE의 뒤 공백 규칙과 SEPARATED BY, RESPECTING BLANKS는 7.50판과 7.58판 문서에 같은 내용으로 있습니다. &&와 문자열 템플릿은 ABAP 7.0 EhP2에서 들어왔으므로, 그보다 오래된 시스템에서는 SEPARATED BY가 쓸 수 있는 방법입니다. 공백을 넣을 때는 피연산자 자리에 ' '를 두지 말고, 구분자로 넣거나 string으로 넣는다는 것 하나만 기억하면 됩니다.

끝 · END OF NOTE목록으로
COMMENTS BOX

이 기록에 대화를 더해 주세요.

궁금한 점, 다른 접근, 직접 해 본 결과를 나눠 주세요.

최신순

로그인 상태 확인 중…

댓글을 불러오는 중…