ERP/SAP/R/3

FIELD-SYMBOL 설명과 사용예

파란실버라이트 2011. 7. 19. 09:32

필드심볼 이야기(http://erp.sarang.net)
작성자 : 한상열

1. 개요

필드심볼 모르면 생노가다!
알면 초간단!


2. 상황 발생

각 계정별로 원하는 기간(월별) 동안의 총 Recivable과
Payable 금액을 보여주는 레포트를 짜고 싶습니다.

테이블을 찾았더니 GLT0 이군요. 첨에는 테이블이 예쁘
게 생겼다고 생각했습니다. 야~ 이거 월별 금액이 각각
의 월필드에 들어가있으니 무지 좋구만~

허걱!

근데 어떻게 각 필드별로 합을 구하쥐?
사용자가 어떤 기간을 줄지 알고?


3. 해결책

멋있는 멍님의 글을 참고해봅시다.


-----------------------------------------------------------------------------------
이 테이블을 자세히 살펴보면...

...
...
HSL01
HSL02
HSL03
HSL04
HSL05
HSL06
HSL07
HSL08
HSL09
HSL10
HSL11
HSL12
HSL13
HSL14
HSL15
HSL16
...
...

이런식으로 필드가 존재합니다...

이 때, 위에서 나열한 필드의 뒤 두 자리가 월을 나타낸다고 했을 때,
현재월까지의 합을 구하는 레포트를 구현한다고 가정을 해봅시다...

만약 Field-Symbol을 사용하지 않을 경우...
지금이 10월이니깐 로직이 이렇게 되겠죠...

변수 = GLT0-HSL01 + GLT0-HSL02 + ......... + GLT0-HSL10. (헥헥~~)

그렇다면 11월일때는 어떡할 것인가 ???
5월일때는 ? 12월일때는 ???
이거 완전한 노가다 입니다...

이때, 우리의 Field-Symbol이 등장합니다... 짜잔~~~

가볍게 코딩을 합니다...


...
FIELD-SYMBOLS <FIELD>.

DATA : CN(2) TYPE N,
FNAME(10),
SUM LIKE GLT0-HSL01.
...
...

DO CN TIMES. "여기서 CN이라는 변수는 해당 월
CC = SY-INDEX.
CONCATENATE 'GLT0-HSL' CC INTO FNAME.
ASSIGN (FNAME) TO <FIELD>.
SUM = SUM + <FIELD>.
CLEAR : FNAME, <FIELD>.
ENDDO.
...
...



이렇게 하면 위에서 했던 노가다를 간단히 몇 줄의 문장으로 기술할 수 있는 것이죠...

<FIELD>라는 FIELD-SYMBOL에는 GTL0-HSL01의 값부터 시작해서...
GTL0-HSL10의 값까지 차례로 들어가면서 더해지게 되는 것이죠...

그리고 보너스로...

이런 구문도 존재한답니다...



...
...
DO.
...
ASSIGN COMPONENT SY-INDEX OF STRUCTURE CUSTOMER TO .
...
ENDDO.



이때, 가령 CUSTOMER라는 INERNAL TABLE이 다음과 같은 필드를 가지는
구조를 참조한다고 할 때...
(KUNNR, ANRED, NAME1, PFACH, STRAS, PSTLZ, ORT01, TELF1, TELFX)

DO... ENDDO... 문장 내에서 필드의 수만큼 LOOP을 돌게 되는거죠...

즉, 하나씩 디버깅을 해보면, 첫번째 루프를 돌때는, <FIELD>에 CUSTOMER-KUNNR의 값이...
그 다음 루프를 돌때는, <FIELD>에 CUSTOMER-ANRED의 값이...
세번째 루프를 돌때는, <FIELD>에 CUSTOMER-NAME1의 값이 들어갑니다...
-----------------------------------------------------------------------------------





4. 결론

노가다 많이 줄였습니다.

**************************************************************************

FIELD만 바뀌고 규칙적인 작업을 할때 각각을 프로그램 LOGIC으로 구성하려면
단순 CODING으로 쓸 데없이 LINE만 길어 질 수 있다.
이때 FIELD-SYMBOL을 사용하면 간단히 해결되면서 프로그램을 분석하기도 한결 수월해 진다.

우선 FIELD-SYMBOL 의 여러가지 변형을 살펴보면

1. ASSIGN f TO <fs>.
단순히 field f의 값을 <fs>가 가리키도록 한다.

2. ASSIGN (f) TO <fs>.
동적 field를 이용한것인데 field f안의 값을 또 field명으로 보고 그 field의 값
을 <fs>가 가리키도록 한다.

3. ASSIGN TABLE FIELD (f) TO <fs>.
2와 같은 경우이나 f 의 값이 table의 field명 일때 그 table field의 값을
<fs>가 가리키도록 한다.

4. ASSIGN LOCAL COPY OF MAIN TABLE FIELD (f) TO <fs>.
3와 같은 경우이나 tables로 선언된 main program의 table field값을
<fs>가 가리키는 것이 아니라 값만 복사 하여 사용하기 때문에 변경할 수 없다.

5. ASSIGN COMPONENT idx OF STRUCTURE rec TO <fs>.
structure의 구성요소 순서를 idx에서 읽어 그 순서에 위치한 구성요소의 값을
<fs>에 할당한다.

6. ASSIGN COMPONENT name OF STRUCTURE rec TO <fs>.
structure의 구성요소명(field명)을 name에서 읽어 그 구성요소의 값을
<fs>에 할당한다.

5번을 제외한 모든 경우는 field명을 사용하는 것이라서 field명에 규칙이 없으면
coding line 줄이는데 효과를 보지 못한다.
따라서 여기서는 field명에 규칙이 없더라도 coding line을 획기 적으로 줄일 수 있는
5번경우를 사용한 예제만 소개하겠다.

예제)

FIELD-SYMBOLS : <FS1>, <FS2>.
DATA:IDX1 LIKE SY-INDEX.

DATA: BEGIN OF ITAB1 OCCURS 0,
CCYYMM(8),
WERKS LIKE MARD-WERKS,
MATNR LIKE MARD-MATNR,
LABST LIKE MARD-LABST,
UMLME LIKE MARD-UMLME,
INSME LIKE MARD-INSME,
EINME LIKE MARD-EINME,
SPEME LIKE MARD-SPEME,
RETME LIKE MARD-RETME,
VMLAB LIKE MARD-VMLAB,
VMUML LIKE MARD-VMUML,
VMINS LIKE MARD-VMINS,
VMEIN LIKE MARD-VMEIN,
VMSPE LIKE MARD-VMSPE,
VMRET LIKE MARD-VMRET,
END OF ITAB1.

DATA: ITAB2 LIKE ITAB1 OCCURS 0 WITH HEADER LINE.


경우1) FIELD-SYMBOL 사용하지 않았을 경우

LOOP AT ITAB1.
READ TABLE ITAB2 WITH KEY CCYYMM = ITAB1-PERIOD
WERKS = ITAB1-WERKS
MATNR = ITAB1-MATNR
BINARY SEARCH.

IF SY-SUBRC <> 0.
WRITE : / 'Not found in ITAB2 : ',
ITAB1-CCYYMM,
ITAB1-WERKS,
ITAB1-MATNR.
ELSE.
IF ITAB1-LABST <> ITAB2-LABST.
WRITE : / SY-INDEX,
ITAB2-CCYYMM,
ITAB2-WERKS,
ITAB2-MATNR,
ITAB1-LABST,
ITAB2-LABST.
ENDIF.

IF ITAB1-UMLME <> ITAB2-UMLME.
WRITE : / SY-INDEX,
ITAB2-CCYYMM,
ITAB2-WERKS,
ITAB2-MATNR,
ITAB1-UMLME,
ITAB2-UMLME.
ENDIF.


.............. 12번 반복 ........


ENDIF.
ENDLOOP.

경우2) FIELD-SYMBOL 사용했을 경우

LOOP AT ITAB1.
READ TABLE ITAB2 WITH KEY CCYYMM = ITAB1-PERIOD
WERKS = ITAB1-WERKS
MATNR = ITAB1-MATNR
BINARY SEARCH.

IF SY-SUBRC <> 0.
WRITE : / 'Not found in ITAB2 : ',
ITAB1-CCYYMM,
ITAB1-WERKS,
ITAB1-MATNR.
ELSE.

IDX1 = 3.

DO 12 TIMES.
IDX1 = IDX1 + 1.
ASSIGN COMPONENT IDX1 OF STRUCTURE ITAB1 TO <FS1>.
ASSIGN COMPONENT IDX1 OF STRUCTURE ITAB2 TO <FS2>.

IF <FS1> <> <FS2>.
WRITE : / SY-INDEX,
ITAB2-CCYYMM,
ITAB2-WERKS,
ITAB2-MATNR,
<FS1>,
<FS2>.
ENDIF.
ENDDO.
ENDIF.
ENDLOOP.

필드심볼을 이용하면 보통사용하는 테이블의 모양을 간단하게 바꿀 수 있다.

<기존에 사용하는 테이블>

연월 수량 금액 단가
200501 120 3500 23400
200502 3000 2300 3600
200503 500 1000 530
200504 300 28 400

<원하는 테이블>

  200501 200502 200503 200504
수량 120 3000 500 300
단가 3500 2300 1000 28
금액 23400 3600 530 400

우리가 원하는것은 해당연월에 수량, 단가, 금액이다.

field symbol을 이용해서 직접 확인해보자.

REPORT ZPPRTESTYW .
DATA: BEGIN OF S,
A VALUE '1', B VALUE '2', C VALUE '3', D VALUE '4',
E VALUE '5', F VALUE '6', G VALUE '7', H VALUE '8',
END OF S.

DATA OFF TYPE I.

FIELD-SYMBOLS <FS>.

ASSIGN S-A TO <FS>.

DO 4 TIMES.
OFF = SY-INDEX - 1.
ASSIGN <FS>+OFF(1) TO <FS>.
WRITE <FS>.
ENDDO.

==> 결과 1,2,4,7

<field symbol을 이용하여 데이터 뿌리기>

fname에 필드명을 count 와 조합하여 만든후 bufs로 assign한다.

LOOP AT it_sum3.
MOVE it_sum3-buname TO it_result-zrsbu.

DO 4 TIMES.

in = it_sum3-lfmon.
cn = cn + 1.
CONCATENATE 'it_result-zrs' in cn INTO fname.
ASSIGN (fname) TO <bufs>.

CASE cn.
WHEN 1.
<bufs> = it_sum3-abssu.
WHEN 2.
<bufs> = it_sum3-sucor.
WHEN 3.
<bufs> = it_sum3-abspr / rd_int.
WHEN 4.
<bufs> = it_sum3-prcor.
ENDCASE.
CLEAR : fname.
ENDDO.
COLLECT it_result.
CLEAR : it_result,it_sum3, cn, in.
ENDLOOP.

[출처] FIELD-SYMBOL 사용예|작성자 미래