스크린의 생명주기는
PBO(Process Before Output)와
PAI(Process After Input)라는
두 가지 핵심 이벤트와 화면 흐름 제어 명령어로 구성된다.
PBO는 화면이 사용자에게 보이기 전에 데이터를 준비하고 화면 속성을 제어하는 단계이며,
PAI 는 사용자의 입력 값을 처리하고 비즈니스 로직을 실행하는 단계다.
💡 PBO 시점에 스크린 만들어지고 있다.
끝날시점 스크린으로 값이 넘어온다.
💡 PAI 시작시점에 스크린으로 값이 넘어온다. (작업을 해야하니까)
끝날시점에 스크린이 사라진다.

입력값을 주고 엔터를 친다. 그 후 화면은 이전의 화면과 같은 화면일까 ?
NO.
화면은 PAI를 거쳐 Next Screen으로 이동하고, PBO로 새로운 스크린이 만들어진다. Next Screen이 같은 화면 번호여서 똑같아 보이지만 다른 스크린이 새로 생성된 것이다.
생물의 생명주기란 어떤 대상이 탄생해서 성장하고, 유지되다가 결국 소멸하는 일련의 과정을 의미한다.
ABAP에서 스크린 생명주기는 생물의 생명주기랑 비슷하다. 스크린 어떻게 만들어지고 유지되고 결국 소멸하고 또 다시 탄생하는 그 과정의 총칭이다.
그리고 대표적인 단계가 PBO, PAI다.
이 단계는 화면이 사용자에게 보이기 직전에 실행되는 부분이다.
화면에 표시될 데이터를 준비하고, 입력 필드를 활성화하거나 비활성화하는 등 화면의 모습을 설정하는 역할을 한다.
PBO가 끝나면 비로소 화면이 사용자에게 나타나게 됩니다.
이 단계는 사용자가 화면에 무언가를 입력하거나 버튼을 클릭하는 등 액션을 취했을 때 실행되는 부분이다.
사용자가 입력한 값을 프로그램으로 가져와서 유효한지 검사하고, 필요한 비즈니스 로직(예: 데이터 조회, 저장)을 수행하며, 다음 화면으로 이동할지 결정하는 등의 작업을 한다.
PAI가 끝나면 다음 PBO가 실행되어 새로운 화면이 나타나거나, 현재 화면이 다시 표시될 수 있습니다.
그리고 다음 화면을 결정짓는 명령어는 SET SCREEN이다.

이미지에서 하이라이트 표시된 Next Dynpro가 바로 넥스트스크린을 정적으로 결정짓는 부분이다.
(참고. 아무것도 입력되지 않으면 0으로 인식한다)
넥스트 스크린은 엑션으로 pai가 실행되고 나고 현재화면이 사라진뒤 다음에 보여질 스크린을 결정짓는다.
스크린에서 지정하고 싶지 않고, 동적으로 지정하고 싶다면 SET SCREEN을 사용한다.
이 말은 즉 슨, 기본적으로
Next Dynpro에 의해 정의된 스크린 번호가 넥스트 스크린을 결정하고,
SET SCREEN명령어를 사용한다면, 이 명령어로 선언된 스크린 번호가 넥스트 스크린이 된다는 것이다.
MODULE user_command_0100 INPUT.
CASE ok_code.
WHEN 'EXIT'.
LEAVE PROGRAM.
WHEN 'CANC'.
SET SCREEN 0.
WHEN 'BACK'.
LEAVE TO SCREEN 0.
WHEN 'S200'.
SET SCREEN 0200."dynamic screen
MESSAGE i999(zmcb00) WITH gv_carrid.
LEAVE SCREEN."현재스크린 떠남
WHEN 'ENTER'.
WHEN OTHERS.
ENDCASE.
ENDMODULE.
현재 스크린은 100. Next Dynpro은 100이다. (가장 일반적인 경우)
예시1)
S200인 액션
100에서 pai를 탄다.
그리고 SET SCREEN에 의해서 next screen이 200으로 변한다.
현재화면 멈추고 메세지띄우고 (by type i)
leave screen으로 현재 스크린을 떠난다.
pbo로 넥스트스크린 200으로 이동(생성)한다.(기존스크린삭제됨)
예시2)
ENTER를 입력했다면
100에서 pai를 탄다.
pbo로 Next Dynpro인 100으로 이동(생성)한다.(기존스크린삭제됨)
이해가 될 것이다.
화면에 대한 명령어가 없다면 스크린의 기본 설정 Next Dynpro에 따라서
다음 스크린이 결정되고,
SET SCREEN이 있다면 그것에 해당하는 스크린이 다음 스크린이 된다.
SET SCREEN 0.
LEAVE SCREEN.
= LEAVE TO SCREEN 0.
이걸 왜 주의해야할까? SET SCREEN은 단순히 다음 스크린을 설정하는거지 현재 화면을 끝내(종료)는 것이 아니라는 것이다.
LEAVE SCREEN이 있어야 즉시, 현재 화면이 끝나고 다음 스크린으로 넘어가는것이다.
즉, 이 명령어가 있다면 뒤에 정의된 함수 및 로직은 무시된다.
왜냐? 현재 스크린이 제거되었는걸?
WHEN 'S200'.
SET SCREEN 0200."dynamic screen
MESSAGE i999(zmcb00) WITH gv_carrid.
여기서는 메세지는 보일까?
YES.
SET SCREEN은 다음스크린을 설정할 뿐,
현재 화면을 즉시 종료하지는 않는다.
자, 이제
넥스트 스크린으로 이동.
스크린 100 -> 스크린 200으로 이동하기에 대한
pbo/pai 간단한 설명을 끝냈다.
이번에는 뒤로가기다.
가장 흔히 쓰는 뒤로가기는 LEAVE TO SCREEN 0 명령어다.
WHEN 'BACK'.
LEAVE TO SCREEN 0.
앞서 말했듯
SET SCREEN 0, LEAVE TO SCREEN을 합친 형태다.
넥스트 스크린을 0으로 설정한다는건 어떤 의미일까?
0은 없는 화면이다. 그래서 0으로 이동할려고하면 프로그램이 종료되거나 기존에 남아있던 화면으로 돌아간다.
지금 현재 화면은 200으로
스크린은 100 -> 200으로 왔다.
그럼 기존 100은 남아있는건가..?
NO.
앞서 말했듯 기존 스크린은 삭제되고 넥스트 스크린(여기서는 set screen 설정에 의해)으로 200이 새로 생긴것이다.
100은 사라지고, 200만 남았다.
그래서 SET SCREEN은 다음 화면을 설정하고 현재 화면을 종료하여 메모리를 효율적으로 사용한다.
다시 돌아가서 그러면 200에서 뒤로가기
즉LEAVE TO SCREEN 0.을 사용한다면?
넥스트 스크린을 0으로 설정하고
현재 스크린을 제거한다.
그 결과 프로그램이 종료된다. 왜냐? 스크린 0은 없다.
그럼 어떻게 해야 다시 100으로 돌아갈 수 있는가?
앞서 말한 SET SCREEN을 다시 써주면 된다.
SET SCREEN 100으로 말이다.
한가지 더,
만약 아래처럼 아무것도 입력을 안한다면?
nextnpro를 통해 넥스트 스크린으로 이동할 것이다. 그리고 nextnpro은 일반적으로 자기자신이다.
WHEN 'BACK'.
이제 반복에 반복을 했으니 다음 Call Screen으로 넘어가자.
전공생이나 이 개발직 공부를 해봤다면
사실 이게 더 이해하기가 쉬울 것이다. CALL STACK이 익숙할테니.
앞선 스크린은
현재스크린을 삭제하고 넥스트 스크린을 생성하는 방식이었다.
콜스크린은
현재스크린을 삭제하지 않고, 잠시 홀딩시킨 상태에서
넥스트 스크린을 그 위에 쌓는다. (STACK과 같은 구조)
그래서 로직도, 코드도 조금 다르다.
MODULE user_command_0100 INPUT.
CASE ok_code.
...
WHEN 'BACK'.
LEAVE TO SCREEN 0.
...
WHEN 'C200'.
CALL SCREEN 0200.
WHEN OTHERS.
ENDCASE.
ENDMODULE.
MODULE user_command_0200 INPUT.
CASE sy-ucomm.
WHEN 'BACK'.
LEAVE TO SCREEN 100.
WHEN 'C100'.
CALL SCREEN 0100.
WHEN OTHERS.
ENDCASE.
ENDMODULE.
자 다시 해보자
초기 스크린은 100이다.
Fuction code C200 액션이 발생한다.
그럼 CALL SCREEN으로 200을 호출한다.
그리고 스크린 200의 pbo을 통해
200스크린이 보이고 생성된다. (스크린 100 위에 쌓인다. 스크린 100이 제거되지 않음).
스크린 200에서 뒤로 가기를 하면?
LEAVE TO SCREEN 100. 으로
현재 스크린으로 종료하고 스크린 100으로 이동(생성한다).
=> 여기서 주목할 점
뒤로가기할때
LEAVE TO SCREEN 100.을 하면
이전 스크린 100으로 돌아오는 것이 아니고
100이 새로 생성된다는 것이다.
200에서 뒤로가기하며 next screen 100으로 이동
200의 pai가 종료되면서 새로운 스크린(100)으로 이동
(200이 100으로 대체된다고 생각하면됨)
빈약하지만 플로우를 도식화하면 아래와 같다.
200 → 뒤로가기(next 100) → 100 → 뒤로가기 (next 스크린 0)→사라짐
-> 100 → 뒤로가기 (next 스크린 0)→사라짐
그래서 뒤로가기를 두번을 해야지 기존 스크린 100으로 돌아가야하는 상황이 생긴다. 불필요한 클릭을 한 번 더 해야하는것이다.
한번에 이전의 스크린 100으로 돌아갈려면?
MODULE user_command_0100 INPUT.
CASE ok_code.
...
WHEN 'BACK'.
LEAVE TO SCREEN 0.
...
WHEN 'C200'.
CALL SCREEN 0200.
WHEN OTHERS.
ENDCASE.
ENDMODULE.
MODULE user_command_0200 INPUT.
CASE sy-ucomm.
WHEN 'BACK'.
LEAVE TO SCREEN 0.
WHEN 'C100'.
CALL SCREEN 0100.
WHEN OTHERS.
ENDCASE.
ENDMODULE.
100→200→100 ⇒ back을 한 번하면 초기화면으로 이동.
바뀐 것은
user_command_0200의 BACK 부분이다.
100이 0으로 바뀌었다.
WHEN 'BACK'.
LEAVE TO SCREEN 0.
200에서 뒤로가기하며 스크린 삭제되고 next screen 0으로 이동한다..
pai가 끝나면서 새로운 스크린(0)으로 이동해야하는데 없다.
그러면 전에 있던 스크린 100으로 이동한다.
콜스크린에서는 이전 스크린으로 돌아오기 위해서는 넥스트스크린 설정을 0으로 해야한다.
MODULE user_command_0100 INPUT.
CASE ok_code.
WHEN 'CANC'.
SET SCREEN 0.
* LEAVE SCREEN.
WHEN 'BACK'.
LEAVE TO SCREEN 0.
WHEN 'C200'.
CALL SCREEN 0200.
CLEAR gv_carrname.
SELECT SINGLE carrname
FROM scarr
INTO gv_carrname
WHERE carrid = gv_carrid.
WHEN 'ENTER'.
WHEN OTHERS.
ENDCASE.
ENDMODULE.
100 → 200으로 콜스크린이 이동되면
그 밑에는 홀딩된다.
그리고 200에서 뒤로가기로 기존 100으로 돌아오면, select 구문 실행된다.
그래서 처음 100에서 200으로 콜스크린 이동시에는 gv_carrname 결과값이 보이지 않지만 (왜냐면 select 구문이 아직 실행안됨)
100으로 돌아온 후 콜스크린 이동시에, gv_carrname이 반영(적용)된다.
그래서 한발자국씩 늦게 보인다.
이 문제를 해결하는 법은 간단하다
select 구문을 먼저 실행시키고 콜 스크린을 하면 된다.

[CALL, SET, LEAVE]
100의 PAI에서 콜스크린으로 200이 불러와지고,
200에서 뒤로가기로 leave to screen 0로
200스크린이 삭제된다.
다시 100으로 돌아온다.
계속 100의 PAI구문 실행된다.
별다른 set screen 설정이 없기때문에
next screen으로 200이 생성된다. (nextnpro 200. 기존 100은 삭제됨)
여기서 뒤로가기를 하면
스크린은 200밖에 없으므로
leave to screen 0이 의해 현재 스크린 삭제되고, 초기화면으로 돌아간다.(프로그램 종료)
그래서 동작은
100 → 200
200에서 뒤로가기 ⇒ 200
200에서 뒤로가기 ⇒ 프로그램 종료.