이번 포스팅에서는 정적인 언어인 ABAP을 Dynamic 하게 변화시켜주는 Field Symbol에 대해 알아보겠습니다.
변수의 값은 메모리 공간을 가집니다. 변수를 선언하고 값을 넣으면 할당된 메모리 공간에 입력한 값이 들어가겠죠.
원하는 변수가 있는 메모리 공간에 접근하기 위해서는 주소를 할당하여 찾을 수 있도록 되어 있습니다.
Field Symbol은 이 변수의 값을 직접 가르키는 변수라 생각하시면 되겠습니다. C 언어의 Pointer가 워낙 유명하여 아시겠지만, 느낌상 비슷한 역할을 합니다.하지만 Pointer라기 보다는 변수의 낙네임, 분신? 에 더 가깝습니다.
변수가 선언 시에 고유한 이름과 메모리 공간을 가진다면, Field Symbol은 자신의 메모리 공간은 갖지않고 선언후 원하는 변수에 할당하여 사용하는 유동적 성격을 띕니다.
이것이 Dynamic 한 특징을 가지게 해줍니다.
1) 선언
1-1) 명시적인 선언(Fully Type)
Field symbol을 선언할 때 참조하는 오브젝을 지정하여 그 Type을 명시하는 방법입니다.
위처럼 어떤 형식을 참조하여 선언하면 사용시에도 같은 형식의 변수에 ASSIGN 하여 사용하여야 합니다.
1-2) 일반적인 선언(Generic Type)
선언 시에 명시적인 참조 없이 두리뭉실 선언해두고 나중에 ASSIGN 되는 변수의 값을 가르키는 방식입니다.
유동적인 선언이 되겠습니다.
위와 같이 선언하면 정해지지 않은 형식으로 ASSIGN 할 때 그 유형을 결정할 수 있습니다.
1-3) 두선언 방법의 차이점
선언 방법의 예를 보면,
명시적 선언의 경우 <FS1>-MATNR과 같이 필드를 명시한 코딩이 가능하지만
일반적인 방법의 경우 ASSIGN ('LT_MATNR-MATNR') TO <FS1>처럼 할당할 때 필드까지 지정해서 코딩해야 합니다.
두 선언 방법으로 크게 차이나는 부분은 없습니다. 하지만 코딩이 명시적이 않을 때 유지보수 측면에서 어려움이 가중될 수 있습니다. 특히 남의 프로그램을 분석해야 할 때 가독성은 떨어지게 되겠죠.
2) ASSIGN (할당)
Field Symbol의 선언 만으로는 어떤 일도 일어나지 않았다 말할 수 있습니다. 부모가 아이가 생기 전 이름은 이걸로 해야지 하고 미리 정해둔 것과 마찬가지입니다. 많이 사용하는 것부터 보겠습니다.
2-1) 동적 할당(Dynamic Specifications)
할당을 원하는 변수명 또는 테이블, 구조의 필드명 사용. 가장 즐겨 사용하는 방법으로 할당이 간편하고 유동적입니다.
모두가 MATNR 변수를 할당하는 예입니다.
( ) 안은 변수 자체가 아닌 명칭을 넣어 명칭과 동일한 변수를 찾아 할당합니다.
2-2) 정적 할당(Static Specification)
변수의 메모리 주소를 가공하여 데이터의 일부나 Structure 등의 연속 할당된 메모리 공간을 ASSIGN 할 수 있습니다.
2-2-1) 기본 구문
ASSIGN dobj [+off][(len)] To.
여기서 offset과 length는 CHAR +,( ) 연산자와 비슷한 기능을 합니다. [ ]는 필수가 아닌 옵션을 말합니다.
offset과 length를 지정하면 기본적으로는 CHAR Type의 변수(C, N, D, T)만 ASSIGN이 가능합니다.
예를 들어 봅시다.
lv_str2와 <fs1>은 모두 '234' 값을 가집니다.
디버깅으로 <fs1>과 <fs2>를 보면 아래와 같이 전자는 3자리, 후자는 9자리가 할당되어 있습니다.
'*' 구문은 그 피할당 변수의 크기를 가져와 그 크기를 넘지 않게 할당을 합니다. <fs2>는 1자리를 제외한 나머지 9자리가 할당됩니다.
2-2-2) 연속된 메모리 공간의 예.
Structure와 같은 연속된 메모리 공간에 할당된 Object의 예를 보면
i) ls_table-fld1을 <fs1>에 할당할 때 10자리가 할당되었습니다.
ii) <fs1>을 <fs2>에 할당할 때 5자리 띄고 10자리를 할당하려 하니 <fs1>의 자리수10자리를 넘어 할당되지 않았습니다.
iii) RANGE 옵션은 해당 Strcture가 메모리에 할당된 총공간만큼 할당이 가능하게 하는 옵션입니다.
여기서 Structure는 fld1+fld2+fld3의 메모리 크기를 말합니다.
iv) <fs1>을 <fs4>에 12자리 띄고 10자리를 할당합니다. 12자리를 띄면 <fs1>의 크기인 10자리를 넘어서게 됩니다.
그러나 오류는 나지 않고 할당이 됩니다. RANGE 옵션으로 할당 가능한 총자릿수를 Structure의 크기로 했기 때문입니다.
<fs1>, <fs2> , <fs3>, <fs4>의 값을 보면 <fs4>에 이상한 문자가 들어와 있습니다.
Structure가 할당된 메모리를 보면 아래와 같이 22Byte가 할당되어 있습니다. 디버깅 화면의 Hexadecimal 4자리가 2Byte 블록 이므로 총 22블록이 있다는 말입니다..
유니코드를 사용할 때 2byte가 Char 한 글자입니다. Interger형은 4Byte입니다. 이는 이전의 Data Type 포스팅에서 살펴보았습니다.
[ABAP] - [SAP ABAP 강좌 18] Data Type
즉 RANGE로 제한한 Structure의 크기는 22자리로 보면 됩니다. 메모리 상에는 이 데이터가 한 줄로 할당이 되어있다 생각하고 12(10)으로 잘라 할당해보면 Interger 변수 영역까지 넘어 갑니다.
CHAR형이 아닌 경우 조심해 사용해야겠습니다. 자주 사용할지는 모르겠지만.. 설명이 길어졌습니다.
동적 할당 중 INCREMENT 옵션을 쓴 경우도 정적 할당과 같은 로직으로 이해하시면 편하겠습니다.
ASSIGN ls_table-fld1 INCREMENT 1 TO <fs1> RANGE ls_table. => 'ABDCEFGHIJ'
3) CASTING (형 변환)
할당하면서 데이터형을 변환할 때 사용합니다.
3-1) 일반적인 구문
기본적인 구문은 아래와 같습니다. 단 피할당 변수와 Casting 되는 유형의 메모리 크기는 같아야 합니다.
ASSIGN에서 Structure가 메모리에 인접하여 할당되고 글자의 수가 아닌 2byte 단위의 공간이 1자리로 할당되는 것을 보았습니다. 이는 CASTING에서도 그대로 적용됩니다. 역으로 Structure로의 Casting도 가능합니다.
fld1, fld2, fld3에 할당된 자릿수만큼 값이 들어갑니다.
3-2) DECIMAL 옵션
금액이나 수량을 다룰 때 소수점의 위치를 변경해야 할 경우가 있습니다. 그럴 때 유용할 수 있겠네요.
소수점의 위치를 DECIMALS 뒤의 숫자로 지정 가능합니다. 단 지정된 변수의 크기를 넘지는 못합니다.
위의 결과를 디버깅으로 보면 아래와 같습니다.
4) 초기화와 상태 체크
Field Symbol의 경우 그 생성 시 상태는 SY-SUBRC로 체크되지 않습니다.
정상적인 생성의 유무를 체크하려면 IF <fs> IS ASSIGNED, IF <fs> IS NOT ASSIGNED 구문으로 체크합니다.
ASSIGN을 해제할 때는 UNASSIGN <fs>. 의 구문을 사용합니다.
5) 활용
-. Internal Table에 세로, 가로의 데이터 매핑.
엑셀 업로드 펑션의 필드별 세로 형식의 데이터를 Internal Table의 가로 필드에 매핑해줄 때
-. Internal Table LOOP문에서 년월 별로 금액을 가진 필드의 Total 값의 계산.
월별 필드를 Do 문으로 Field Symbol에 할당하여 합계를 내는 예.
-. Internal Table LOOP문 Work Area로 사용하여 Internal Table값 직접 변경.
Field Symbol은 피할당 변수의 메모리로 직접 접근이 가능하므로 Work Area를 이용한 Modify 구문 없이 직접적인 데이터의 변경이 가능합니다. 물론 속도도 빠릅니다.
포스팅에 예를 든 구문중 SAP ECC에서는 안 되는 것도 있겠네요. 감안해서 봐주세요.
이상으로 Field Symbol 포스팅을 마치겠습니다.
다음 포스팅은 동적 프로그래밍의 또 다른 방법중 Data Reference에 대해 다뤄 보겠습니다.
긴 글 읽어주셔서 감사합니다.
'ABAP' 카테고리의 다른 글
[SAP ABAP 강좌 24] Range 변수 (1) | 2021.07.28 |
---|---|
[SAP ABAP 강좌 23] Internal Table 활용4 - LOOP AT (0) | 2021.06.30 |
[SAP ABAP 강좌 22] Internal Table 활용3 - MODIFY, DELETE (0) | 2021.06.29 |
[SAP ABAP 강좌 21] Internal Table 활용2 - READ, LOOP (0) | 2021.06.28 |
[SAP ABAP 강좌 20] Internal Table 활용1 - APPEND,COLLECT (0) | 2021.06.25 |
최근댓글