본문 바로가기

ABAP 프로그래밍 개념/Modulazation Technique

2-1. Modularization Techniques - Program Structure : Processing Blocks

일반적으로, Processing Block은 넓게 Event Block, Dialog Module, Procedure로 분류됩니다. 이 Processing Block 각각에 알아보도록 합시다.


Declaration Area


각 ABAP Program은 전역 선언 영역과 여러 처리 블록으로 구성됩니다. 전역 선언 영역에서 정의된 Objects들은 ABAP Program에서 접근가능(Accessible & Visibile) 합니다. 몇몇의 Processing Block에서. 데이터 선언은 지역적(해당 Processing 안에서만 접근 & 가시성)입니다.

*프로그램의 전역선언
DATA : f1 TYPE c VALUE 'A',
       f2 TYPE c VALUE 'B'.
       
END-OF-SELECTION.

PERFORM output. "서브루틴 호출"

*&--------------------------------------------------------------*
*& Form OUTPUT
*&--------------------------------------------------------------*
FORM output.
*로컬 선언은 해당 Form 안에서만 가시성을 가짐

DATA f3 TYPE c VALUE 'C'.

WRITE f1.
WRITE f2.
WRITE f3.

ENDFORM.

위 예시를 보면, f1, f2는 프로그램의 전역 선언 영역(Global Declaration Area)에서 선언되어 있습니다. 프로그램은 OUPUT이라는 이름의 서브루틴을 포함하고 있고, 해당 서브루틴 안에는 f2이라는 Data Object를 선언했습니다. Data Object f3이 OUTPUT이라는 서브루틴 안에서 선언되었기 때문에, f3는 서브루틴에 지역적입니다. 다른말로 하면 , Data Object f3는 OUTPUT이라는 서브루틴 안에 지역적으로 가시성이 있고, 서브루틴 안에서만 ABAP 구문을 통해 접근 가능합니다.

프로그램의 다른 Processing Block 에서 Data Object f3에 대해서는 접근할 수 없습니다. 그러나, 전역 Data Object인 f2와 f3에 대해서는 프로그램의 어떠한 Processing Block에서도 접근 할 수 있습니다.


 Using Processign Blocks


Processing Block은 ABAP 구문을 포함하고 있는 "나눌 수 없는 단위(Indivisible Unit)" 입니다. 예를 들어, 위 코드에서 END-OF-SELECTION은 Event Block라는 Processing Block의 한 종류이고 PERFORM이라는 ABAP 구문을 포함하고 있습니다. FORM OUTPUT ~ ENDFORM 은 서브루틴으로, WRITE라는 구문을 포함하고 있는 Processing Block의 한 종류 입니다.

Processing Block은 Nested 될 수 없습니다, 그래서 하나의 Processing Block에 다른 Processing Block을 포함시킬 수 없습니다. 예를들어, FORM~ENDFORM 사이에 END-OF-SELECTION을 포함할 수 없습니다. 그러나 Processing Block에서 다른 Processing Block을 호출할 수는 있습니다.


Calling Processing Blocks


Processing Block은 ABAP 런타임 환경에서 외부적으로 호출되거나, 프로그램 내부에서 구체적인 구문을 통해 호출됩니다. 예를 들어, END-OF-SELECTION은 프로그램이 실행될 때 ABAP 런타임 환경에서 호출되고, FORM OUTPUT은 Procedure로서 코드에서 PERFORM문을 통해 호출됩니다.

 


Sequence of Processing Blcok


프로그램 코드를 다양한 Processing Block으로 나눠도, 프로그램 코드는 프로그램에서 정의된 Processing Block의 순서에 맞게 실행되지 않습니다. 특정 Processing Block이 호출된 상황은 ABAP 런타임 환경에 의한 것이거나 특정 Processing Block은 구문에 의해 실행되기 때문입니다.

그러므로, 프로그램에서 관리되는 Processing Block의 순서는 그것들이 실제 실행되는 순서와는 관련이 없습니다. Processing Block이 호출된 뒤에는, Processing Block 안에 있는 코드가 순차적으로 실행됩니다. 

예를 들어, 위에 코드 예시를 보면, 코드에서 진행된 Processing Blocks의 순서는 연관이 없습니다. 아래 코드 예시는 같은 코드이지만 FORM~ENDFORM의 위치를 재조정한 것입니다. 아래 구문도 결과는 같습니다.

*프로그램의 전역선언
DATA : f1 TYPE c VALUE 'A',
       f2 TYPE c VALUE 'B'.
       
*&--------------------------------------------------------------*
*& Form OUTPUT
*&--------------------------------------------------------------*
FORM output.
*로컬 선언은 해당 Form 안에서만 가시성을 가짐

DATA f3 TYPE c VALUE 'C'.

WRITE f1.
WRITE f2.
WRITE f3.

ENDFORM.  

END-OF-SELECTION.

PERFORM output. "서브루틴 호출"

Ending Processing Blocks


Processing Block은 실행된 Processing Block의 마지막 구문이 실행되고나면 끝납니다. 그러나, 해당 Processing Block은 프로그래밍적으로 CHECK, EXIT, RETURN과 같은 특정 구문을 사용하고나면 종료시킬 수 있습니다. 예를 들어, 특정 조건을 확인하고 나서, 만약 조건에 적합하지 않아 Processing Block의 남은 구문들을 실행시키고 싶지 않을 때, CHECK, EXIT, RETURN 구문을 사용하여 Processing Block을 종료하여 남아있는 구문을 진행시키지 않을 수 있습니다.

CHECK와 EXIT 구문은 만약 반복문(LOOP AT, DO ,WHILE) 에서 사용된다면, Prossessing Block에서 사용된것과 다르게 행동됩니다. 반복문 안에서 CHECK과 EXIT 구문이 사용된다면, Processing Block을 종료하는 것이 아닌, 반복문에만 영향을 미칩니다. \

예를들어, CHECK 구문은 현재의 진행하고 있는 반복문을 종료시키고 다음 반복을 처리합니다.

그러나, EXIT 구문은 CHECK와 달리, 완전하게 해당 반복문 자체를 종료시킵니다. EXIT과 CHECK 구문은 루프문 둘 다 P반복문 뒤에 Processing Block에서 남아있는 코드를 실행할 것입니다. 

RETURN 구문은 루프 내부에서 사용되거나 외부에서나 사용되거나 상관없이, Processing Block을 종료시킵나다. Processing Block이 어떻게 종료되든 상관없이, 제어는 종료될 때마다 Processing Block의 호출자에게 반환됩니다.

아래 예시는, 서브루틴 안에서 EXIT 구문의 사용을 보여줍니다. Write f3라는 구문은 EXIT 구문 뒤에서 실행되도록 짜여져 있는데, 이 구문은 EXIT 구문 후에 Processing Block이 종료되기 때문에 실행되지 않을 것입니다.

DATA : f1 TYPE c VALUE 'A',
       f2 TYPE c VALUE 'B'.
       
END-OF-SELECTION.
PERFORM output.

*&--------------------------------------------------------------*
*& Form OUTPUT
*&--------------------------------------------------------------*
FORM output.
DATA f3 TYPE c VALUE 'C'.

 WRITE f1.
 WRITE f2.
  EXIT.
 WRITE f3.
ENDFORM.

아래 예시는 DO 반복문 안에서 사용되는 EXIT 구문의 사용 예시입니다. 첫번째 반복문 뒤에, EXIT 구문을 만나면 반복문은 종료될 것이지만 시스템은 서브루틴 안에 있는 남아있는 구문을 실행할 것입니다. 그러므로 WRITE f3 구문이 실행될 것입니다.

DATA : f1 TYPE c VALUE 'A',
       f2 TYPE c VALUE 'B'.
       
END-OF-SELECTION.

PERFORM output. 
*&--------------------------------------------------------------*
*& Form OUTPUT
*&--------------------------------------------------------------*
FORM output.
DATA f3 TYPE c VALUE 'C'.

DO 3 TIMES.
 WRITE f1.
 WRITE f2.
  EXIT.
ENDDO.
 WRITE f3.
 
ENDFORM.

 

아래 구문은 CHECK 구문을 통해, Processing Block을 그만두는 예시입니다. 예를 들어, CHECK 구문을 사용하여 Data Object f2와 f3의 값이 매치가 되는지 확인하였습니다.

조건이 만족된다면, Processing Block의 남아있는 코드가 실행될 것입니다. 그렇지 않다면, Processing Block의 남아있는 코드를 실행시키지 않고 Processing Block을 멈출 것입니다. 예시를 보면, WRITE f3는 실행되지 않을 것인데,f2와 f3가 같은 값을 가지고 있기 때문입니다.

DATA : f1 TYPE c VALUE 'A',
       f2 TYPE c VALUE 'B'.
       
END-OF-SELECTION.

PERFORM output.

*&--------------------------------------------------------------*
*& Form OUTPUT
*&--------------------------------------------------------------*
FORM output.
DATA f3 TYPE c VALUE 'B'.

WRITE f1.
WRITE f2.

CHECK f2 <> f3.

WRITE f3.
ENDFORM.

다음 예시는, DO 반복문 안에서 CHECK 구문을 사용하여 Data Object f1과 f2의 값이 같은지를 확인하였습니다.

시스템이 CHECK 구문을 만났을 때, CHECK 조건이 만족되어야지만, CHECK 구문 이후의 구문들을 실행할 것입니다. 조건이 만족되지 않는다면, 시스템은 현재 반복문의 남은 코드를 실행하지 않고 다음 반복문으로 갈 것입니다.

반복문이 완료된 다음엔, 시스템은 Processing Block 안에 남아있는 코드를 실행할 것입니다. 그러므로 예시에서, WRITE f1 구문이 세번 실행될 것이고, f2 구문은 절대 실행되지 않을 것이고 f3 구문은 한번만 실행될 것입니다.

DATA : f1 TYPE c VALUE 'A',
       f2 TYPE c VALUE 'B'.
       
END-OF-SELECTION.

PERFORM output. 
*&--------------------------------------------------------------*
*& Form OUTPUT
*&--------------------------------------------------------------*
FORM output.

DATA f3 TYPE c VALUE 'B'.

DO 3 TIMES.
WRITE f1.
CHECK f1 = f2.
WRITE f2.
ENDDO.
WRITE f3.

ENDFORM.

 

아래 예시는, RETURN 구문을 DO 반복문 안에서 사용한 예시입니다. RETURN 구문은 Processing Block을 반복문 내,외와 상관없이 종료시키기 때문에 WRITE f1 구문은 한번만 실행되고, WRITE f2, WRITE f3 구문은 절대 실행되지 않습니다.

DATA : f1 TYPE c VALUE 'A',
       f2 TYPE c VALUE 'B'.

END-OF-SELECTION.
PERFORM output.
*&--------------------------------------------------------------*
*& Form OUTPUT
*&--------------------------------------------------------------*
FORM output.

DATA f3 TYPE c VALUE 'B'.
DO 3 TIMES.
 WRITE f1.
RETURN.
 WRITE f2.
ENDDO.
 WRITE f3.
ENDFORM.

Statements


모든 ABAP 구문은 전역 데이터 선언부를 제외하고 Processing Block에 속합니다. 만약 전역 데이터 선언부와 Processing Block 사이에 쓴 어떠한 구문들은 모두 자동적으로 START-OF-SELECTION Processing Block에 할당됩니다. START-OF-SELECTION은 Processing Block으로서 Executable 프로그램에서 디폴드로 작동되는 Proecessing Block으로 역할을 합니다.

아래 예시는, 다양한 Processing Block을 사용한 코드입니다. 대금청구 문서 넘버에 대한 아이템(품목) 데이터를 보여주고 있습니다.

TYPES: BEGIN OF ty_vbrp,
	   vbeln TYPE vbeln_vf, "Document Number"
	   posnr TYPE posnr, "Item Number"
	   fkimg TYPE fkimg, "Quantity"
	   vrkme TYPE vrkme, "UoM"
	   netwr TYPE netwr, "Net Value"
	   matnr TYPE matnr, "Material Number"
	   arktx TYPE arktx, "Description"
	   mwsbp TYPE mwsbp, "Tax Amount"
	   END OF ty_vbrp.
       
DATA : it_vbrp TYPE STANDARD TABLE OF ty_vbrp,
	   wa_vbrp LIKE LINE OF it_vbrp,
	   v_vbeln TYPE vbeln_vf.

PARAMETERS p_vbeln TYPE vbeln_vf.

INITIALIZATION. "Event Block"
AUTHORITY-CHECK OBJECT 'V_VBRK_FKA'
			ID 'FKART' FIELD 'F2'
			ID 'ACTVT' FIELD '03'.
            
IF sy-subrc <> 0.
	MESSAGE '권한 체크 실패' TYPE 'E'.
ENDIF.

AT SELECTION-SCREEN. "Event Block"

SELECT SINGLE vbeln FROM vbrk
	     INTO v_vbeln
        WHERE vbeln EQ p_vbeln.
        
IF sy-subrc IS NOT INITIAL.
	MESSAGE '유효하지 않은 번호입니다' TYPE 'E'.
ENDIF.

START-OF-SELECTION. "Event Block"

PERFORM get_data. "Calls procedure"
PERFORM show_output. "Calls procedure"

*&--------------------------------------------------------------*
*& Form GET_DATA
*&--------------------------------------------------------------*
FORM get_data .
SELECT vbeln
	   posnr
	   fkimg
	   vrkme
	   netwr
	   matnr
	   arktx
	   mwsbp
FROM vbrp
INTO TABLE it_vbrp
WHERE vbeln EQ p_vbeln.

ENDFORM. " GET_DATA"

*&--------------------------------------------------------------*
*& Form show-output
*&--------------------------------------------------------------*

FORM show_output . 
  FORMAT COLOR COL_HEADING.
  WRITE : / 'Item',
	10 'Description',
	33 'Billed Qty',
	48 'UoM',
	57 'Netvalue',
	70 'Material',
	80 'Taxamount'.
  FORMAT COLOR OFF.
  
LOOP AT it_vbrp INTO wa_vbrp.
  WRITE :/ wa_vbrp-posnr,
	10 wa_vbrp-arktx,
	33 wa_vbrp-fkimg LEFT-JUSTIFIED,
	48 wa_vbrp-vrkme,
	57 wa_vbrp-netwr LEFT-JUSTIFIED,
	70 wa_vbrp-matnr,
	80 wa_vbrp-mwsbp LEFT-JUSTIFIED.
ENDLOOP.

ENDFORM.

위 코드의 로부터의 레포트 결과를 보면, 사용자는 Selection Screen에 대금청구 문서를 입력하고, 해당 대금 청구문서에 적합한 품목 데이터들이 VBRP에서 조회될 것입니다.

이 코드에서, 예시로 다섯 가지의 Processing Block을 사용하고 있는데, 세 개는 Event Block(INITIALIZATION, AT SELECTION-SCREEN, START-OF-SELECTION) 이고 두 개는 Procedure( FORM get_data & FORM get_output)입니다.

Event Block은 우리에게 코드가 실행횔 순서를 통제할 수 있게 해줍니다. 예를 들어, 권한 체크와 관련된 코드는 INITIALIZATION이라는 Event Block에서 유지되어야는데, 대안으로 LOAD-OF-PROGRAM이라는 Event Block을 사용할 수 있습니다. 왜냐하면 INITIALIZATION이라는 Event는 늘 프로그램이 Initialized 될 때(초기값화 될 때) 발생되기 때문에, 사용자가 보고서를 실행할 때 요구하는 권한을 가지고 있는지 아닌지 해당 Event Block에서 확인 및 보증 할 수 있습니다.

유사하게, AT SELECTION-SCREEN이라는 Event는 유저가 Selection Screen에서 Execute 버튼을 클릭할 때에 진행됩니다. 이 Event Block에서 사용자가 입력한 값의 유효성을 검사하는 코드를 진행함으로써 프로그램 실행이 유효한 문서 번호 없이 계속되지 않도록 할 수 있습니다.

또한, 프로그램에서 두개의 Procedure를 통해 출력로직과 선택로직을 분리하였습니다. 이 Subroutine들은 START-OF-SELECTION이라는 Event Block에서 PERFORM 구문에 의해 호출됩니다.


Types of Processing Blocks


앞서 말했다 싶이, Processing Block은 Event Block, Dialog Module, Procedure로 분류됩니다. 이러한 Processing Block 가운데서 그것들을 차이가 나게 하는 요인들은 프로그램에서 어떻게 도입되는지어떻게 호출되는지 입니다. Processing Block의 유형은 또한 로컬 데이터를 유지할 수 있는지 여부와 Parameter Interface(매개 변수 인터페이스)에 대한 지원을 설정합니다.

바로 위 코드 예시를 보면 Procedures들은 ENDFORM이라는 고유의 END 구문을 통해 종료되는 것과 달리,
Event Block은 이벤트 키워드와 함께 도입되고 다음 Processing Block의 시작, 프로그램의 끝 또는 모듈화 단위의 첫 번째 정의에 의해 내부적으로 끝납니다.

추가적으로, Event Block들은 프로그램이 시작되면서 ABAP Runtime 환경에 의해 호출됩니다. 반대로, Subroutine과 같은 Procedures들은 START-OF-SELECTION 아래에서 특정 호출을 위한 PERFORM과 같은 구문에 의해 호출됩니다.

Event Block은 다른 Processing Block이랑 다르게 행동합니다. Event Block은 항상 ABAP 런타임 환경에 의해 호출되고, 호출은 Event에 의해서 유발됩니다. 예를 들어, Selection Screen에서나 List에서의 사용자의 행동은 호출되는 Event Block에 대응하는 특정 Event를 일으킵니다.

Selction Screen이 전송되기 전에 프로그램이 메모리에 로드될 때 이벤트가 트리거됩니다. 프로그램에서 해당 Event에 대응하는 Event Block을 정의하여 반응하게 하거나 만약 프로그램이 Event에 반응하기 원치않으면 Event Block을 무시하면됩니다. 이것은 Subroutine Call과는 종류가 다릅니다. 

Event Block과 Dialog Module은 Local Declaration Area(지역 선언 영역)을 가지고 있지 않습니다. 이 Blocks안에서 선언한 모든 데이터들은 자동으로 프로그램의 Global Declaration Area로 추가되어 전역 변수처럼 사용됩니다. 그러나, Procedure(Method, Subroutine, Function Module)에서 선언된 데이터들은 Local Data Declaration이라고 불리우고 선언된 Procedure에서만 가시성을 가지며 사용됩니다.

Processing Block은 프로그램에서 어떠한 순서로도 개발될 수 있습니다. 아래 코드는 바로 위에 제시한 코드와 같은 토드지만, Processing Block의 순서에만 차이를 가지고 있습니다.

TYPES: BEGIN OF ty_vbrp,
	   vbeln TYPE vbeln_vf, "Document Number"
	   posnr TYPE posnr, "Item Number"
	   fkimg TYPE fkimg, "Quantity"
	   vrkme TYPE vrkme, "UoM"
	   netwr TYPE netwr, "Net Value"
	   matnr TYPE matnr, "Material Number"
	   arktx TYPE arktx, "Description"
	   mwsbp TYPE mwsbp, "Tax Amount"
	   END OF ty_vbrp.
       
DATA : it_vbrp TYPE STANDARD TABLE OF ty_vbrp,
	   wa_vbrp LIKE LINE OF it_vbrp,
	   v_vbeln TYPE vbeln_vf.

PARAMETERS p_vbeln TYPE vbeln_vf.

AT SELECTION-SCREEN. "Event Block"

SELECT SINGLE vbeln FROM vbrk
	     INTO v_vbeln
        WHERE vbeln EQ p_vbeln.
        
IF sy-subrc IS NOT INITIAL.
	MESSAGE '유효하지 않은 번호입니다' TYPE 'E'.
ENDIF.

START-OF-SELECTION. "Event Block"

PERFORM get_data. "Calls procedure"
PERFORM show_output. "Calls procedure"

INITIALIZATION. "Event Block"
AUTHORITY-CHECK OBJECT 'V_VBRK_FKA'
			ID 'FKART' FIELD 'F2'
			ID 'ACTVT' FIELD '03'.
            
IF sy-subrc <> 0.
	MESSAGE '권한 체크 실패' TYPE 'E'.
ENDIF.


*&--------------------------------------------------------------*
*& Form GET_DATA
*&--------------------------------------------------------------*
FORM get_data .
SELECT vbeln
	   posnr
	   fkimg
	   vrkme
	   netwr
	   matnr
	   arktx
	   mwsbp
FROM vbrp
INTO TABLE it_vbrp
WHERE vbeln EQ p_vbeln.

ENDFORM. " GET_DATA"

*&--------------------------------------------------------------*
*& Form show-output
*&--------------------------------------------------------------*

FORM show_output . 
  FORMAT COLOR COL_HEADING.
  WRITE : / 'Item',
	10 'Description',
	33 'Billed Qty',
	48 'UoM',
	57 'Netvalue',
	70 'Material',
	80 'Taxamount'.
  FORMAT COLOR OFF.
  
LOOP AT it_vbrp INTO wa_vbrp.
  WRITE :/ wa_vbrp-posnr,
	10 wa_vbrp-arktx,
	33 wa_vbrp-fkimg LEFT-JUSTIFIED,
	48 wa_vbrp-vrkme,
	57 wa_vbrp-netwr LEFT-JUSTIFIED,
	70 wa_vbrp-matnr,
	80 wa_vbrp-mwsbp LEFT-JUSTIFIED.
ENDLOOP.

ENDFORM.

이 두 코드의 결과는 같은 Event Block의 순서는 다르지만, 같은 결과를 보여줍니다.

반응형