메뉴 건너뛰기

SAP 한국 커뮤니티

효과적인 ABAP/4 프로그램 작성기법

열공아밥 2009.12.21 05:56 조회 수 : 8928 추천:1

제 1 장. SELECT 구문 최적화

1. SAP R/3 아키텍처 이해하기

● SAP R/3의 아키텍처를 이해하기 위하여 아래와 같이 VBAK 테이블에서
데이터를 1,000 건 SELECT하는 프로그램을 작성해보자.

● 읽어올 정보는 다음과 같다.
-. VBAK-VBELN (order number)
-. VBAK-AUART (order type)
-. VBAK-BNAME (name of orderer)
-. VBAK-KUNNR (sold to party)



■ 일반적으로 아래와 같은 방식으로 SELECT 문장을 작성할 것이다.

REPORT ZSAMPLE1.
TABLES: VBAK.

SELECT * FROM VBAK.
IF SY-DBCNT > 1000.
EXIT.
ENDIF.
WRITE:/ VBAK-VBELN ...
ENDSELECT.



■ 위의 구문은 VBAK 테이블의 모든 칼럼을 한 건씩 읽어 가면서, WRITE하는
구조로 되어 있으며, SY-DBCNT를 체크하여 1,000 건이 넘으면 EXIT하도록
되어 있다.








■ SAP R/3 시스템은 위의 그림과 같이 3-tier 구조로 되어 있다.
즉, 사용자가 시스템에 특정 데이터에 대한 요청을 하면, 어플리케이션 서버가
중간에서 사용자의 요청을 가공한 후, 데이터베이스 서버에 데이터에 대한 요청을
보내고, 데이터베이스 서버로부터 데이터를 받아, 다시 가공하여 사용자에게
보내는 방식으로 처리한다.

■ 따라서, 앞장의 코드와 같이 select * 하게 되면, 문제에서 제시한 4개의 필드외에
해당 레코드의 모든 필드를 가져오게 된다. 즉, VBAK 테이블의 한 레코드의 크기가
대략 575 바이트인데, 1,000 건을 가져와야 하므로, 총 575,000 바이트를 데이터
베이스 서버에서 어플리케이션 서버로 전송해야 하며, 한번 전송할때의 패킷 크기가
32,000 바이트인 경우(시스템에 따라 다를 수 있음), 총 20여회의 네트웍 트래픽이
발생하게 된다(575,000/32,000).



3. SELECT * 의 개선

● 이 슬라이드는 SELECT * 형태의 문장을 COLUMN Selection을 이용하여
개선하는 예를 보여준다.

SELECT * FROM VBAK ...
WRITE:/ VBAK-VBELN, VBAK-AUART, ...
ENDSELECT



SELECT VBELN AUART BNAME KUNNR
INTO (VBAK-VBELN, VBAK-AUART, ...) FROM VBAK ...
WRITE:/ VBAK-VBELN, VBAK-AUART, ...
ENDSELECT



■ 위와 같이 사용하려는 4개의 칼럼들만을 가져오도록 할 경우의 네트웍 트래픽은
다음과 같다.

■ 즉, 4개 칼럼의 크기의 합이 59 바이트이므로 1,000 건을 읽는다해도, 59,000 바이트
의 데이터만 데이터베이스 서버에서 어플리케이션 서버로 전송되면 된다. 패킷의
크기가 역시 32,000 바이트라면, 이 경우에는 총 2번의 네트웍 트래픽만 필요하게
되는 것이다.

■ BSEG, VBFA와 같은 SAP cluster table에 대하여는 column selection을
할수 없다(column selection을 하도록 코드를 작성해도 내부적으로는 전체 칼럼을
읽는다). 이러한 테이블을 column selection으로 읽고 싶은 경우에는, 시스템을
다운시키고, 테이블의 형태를 cluster table에서 transparent table로 바꾼다.



4. 데이터 건수 체크 요령

● 이 슬라이드는 SY-DBCNT를 이용한 데이터 건수 체크 문장을
UP TO n ROWS 구문을 이용하여 개선하는 예를 보여준다.

SELECT VBELN BNAME ... INTO (VBAK-VBELN, ...) FROM VBAK.
IF SY-DBCNT > 1000. EXIT. ENDIF.
WRITE:/ VBAK-VBELN, VBAK-AUART, ...
ENDSELECT.



SELECT VBELN BNAME ... INTO (VBAK-VBELN, ...)
FROM VBAK UP TO 1000 ROWS.
WRITE:/ VBAK-VBELN, VBAK-AUART, ...
ENDSELECT.



■ 위의 예에서 첫번째 문장은 데이터 1,000 을 건건이 데이터베이스 서버에서
어플리케이션 서버로 전송하는 반면, 두번째 문장은 데이터베이스 서버에서 1,000
건을 읽은 후에 일괄적으로 어플리케이션 서버로 전송하는 방식으로 동작한다.
따라서, 두번째 문장이 훨씬 좋은 성능을 나타낸다.

■ where 조건 없이 데이터 한 건 만을 가져오는 경우라면, 차이가 더욱 두드러진다.
즉, 아래의 문장들을 참조하라.

■ SELECT VBELN BNAME ... INTO(VBAK-VBELN, ...) FROM VBAK.
WRITE:/VBAK-VBELN, VBAK-AUART, ...
EXIT.
ENDSELECT.

■ SELECT VBELN BNAME ... INTO(VBAK-VBELN, ...) FROM VBAK UP TO 1 ROWS.
WRITE:/VBAK-VBELN, VBAK-AUART, ...
ENDSELECT.

■ 응답속도 비교
SELECT ... EXIT. ENDSELECT 150,000 ms
SELECT ... UP TO 1 ROWS 1,500 ms



5. CHECK 구문의 개선

● 이 슬라이드는 CHECK 문장에 들어가는 조건을 SELECT 문장에 포함하여
개선하는 방법을 보여준다.

PARAMETERS: PARAM1,
DATA: BEGIN OF SEARCH_STRING,
FIRST(9) VALUE '_________',
PARAM,
END OF SEARCH_STRING.
SELECT VBELN AUART ... INTO (VBAK-VBELN, ...) FROM VBAK.
CHECK VBAK-VBELN+9(1) = PARAM1.
WRITE:/ VBAK-VBELN, VBAK-AUART, ...
ENDSELECT.


SEARCH_STRING-PARAM = PARAM1.
SELECT VBELN BNAME ... INTO (VBAK-VBELN, ...) FROM VBAK.
WHERE VBELN LIKE SEARCH_STRING.
WRITE:/ VBAK-VBELN, VBAK-AUART, ...
ENDSELECT.

■ VBAK 테이블에서 57,000건을 가져오는 것을 테스트해 보았을 경우,
SELECT & CHECK → 27,958,000 ms
SELECT WITH WHERE condition → 3,065,000 ms

■ 가능하다면 어떠한 경우라도, check condition은 WHERE 절 안에 들어와야 하며,
이것은 SELECT SINGLE에도 적용된다.
SELECT SINGLE VBELN AUART ... INTO (VBAK-VBELN, ...) FROM VBAK
WHERE VBELN = '0090000090'
AND BNAME = 'Smith'.

위의 구문에서 VBAK 테이블의 키필드는 VBELN이지만, BNAME을 CHECK로 빼지 않고
WHERE 절에 포함시킴으로써, 데이터베이스 서버와 어플리케이션 서버간의
쓸데없는 네트웍 트래픽을 줄일수 있다.

■ 그러나, CHECK 조건이 매우 까다롭고 복잡할 경우에는 오히려 데이터베이스에서 일단
데이터를 받아오는 것이 빠를 수도 있다. 이것은 SQL trace를 이용하여 실제로 어떤
방법이 빠른지 조사해보고 결정하여야 한다.



6. ORDER BY 구문의 개선

● 이 슬라이드는 SELECT 구문에서 사용되는 ORDER BY 를 Internal sort를
이용하여 개선하는 방법을 보여준다.

SELECT VBELN BNAME ... INTO (VBAK-VBELN, ...) FROM VBAK.
WHERE BNAME IN BNAME_SO
ORDER BY BNAME DESCENDING.
ENDSELECT.



SELECT VBELN BNAME ... INTO TABLE IVBAK FROM VBAK.
WHERE BNAME IN BNAME_SO.
SORT IVBAK BY BNAME DESCENDING.



■ 대부분의 경우에 데이터베이스 서버보다는 ABAP/4 프로그램내에서 SORT를
수행하는 것이 좋다.

이유: 많은 양의 데이터를 데이터베이스 서버에서 SORT하는 것은 그 시스템을
사용중인 모든 USER에게 영향을 미친다. 하지만, ABAP/4 프로그램내에서
처리하게 되면 해당 어플리케이션 서버에만 영향을 미친다.

■ 하지만 SELECT 구문내에서 ORDER BY를 이용하여 정렬하고자 하는 필드에 인덱스가
적절하게 구성되어 있으면, 데이터베이스 서버에 해롭지 않다.



7. APPEND 구문의 개선

● 이 슬라이드는 APPEND 구문을 이용하여 Internal 테이블에 건건이
데이터를 추가하는 것을 INTO TABLE 을 사용하여 개선하는 것을 보여준다.

SELECT VBELN AUART ... INTO (IVBAK-VBELN, ...) FROM VBAK
WHERE BNAME IN BNAME_SO.
APPEND IVBAK.
* Do more stuff
ENDSELECT.



SELECT VBELN AUART ... INTO TABLE IVBAK FROM VBAK
WHERE BNAME IN BNAME_SO.
LOOP AT IVBAK.
* Do more stuff
ENDLOOP.



■ Internal table의 내용을 한꺼번에 전송하는 것이 더욱 효과적이다.

■ 데이터를 인터널 테이블로 한꺼번에 읽어 들이는 방법의 또다른 효과는
처리시간이 매우 짧다는 것이다.

■ SELECT loop내에서 많은 처리를 할수록 ORA0155 Snapshot too old
(rollback segment too small) 에러를 만날 확률이 높다.

■ 수행시간이 긴 SELECT 문장은 동일한 작업 대상 테이블에 대한 INSERT/UPDATE
문장과 I/O Contention을 일으킬 확률이 많으며, 이럴 경우, 데이터베이스가 반드시
read consistency를 보장한다고 단언하기 어렵다.



8. VIEW를 이용한 Nested SELECT 개선

● 이 슬라이드는 여러 개의 테이블에서 데이터를 가져올 때, VIEW를 이용하여
NESTED SELECT를 개선하는 방법을 보여준다.

SELECT VBELN AUART BNAME KUNNR INTO ... FROM VBAK
WHERE VBELN IN VBELN_SO.
...
SELECT POSNR MATNR KWMENG MEINS INTO ... FROM VBAP
WHERE VBELN = VBAK-VBELN.
WRITE:/ VBAK-VBELN, VBAP-POSNR ...
ENDSELECT.
...
ENDSELECT.


SELECT * FROM ZV_VBAK
WHERE VBELN IN VBELN_SO.
WRITE:/ ZV_VBAK-VBELN, ZV_VBAK-POSNR ...
ENDSELECT.



■ VBAK : 716 건, VBAP : 2779 건의 데이터를 대상으로 테스한 결과는 다음과 같다.

■ Nested Select : 3,892,184 microseconds(약 4초)
뷰의 사용 : 981,385 microseconds(약 1초)

■ Nested Select 대신에 뷰를 이용하여 두개의 테이블을 조인한 다음, 뷰에서
데이터를 읽어오는 것이 훨씬 수행속도가 빠르다.

■ 그러나, 데이터베이스 뷰는 버퍼를 경유하지 않고 바로 데이터베이스에서 데이터를
읽어 오기 때문에 두개의 테이블 중 하나가 버퍼링이 되고 있는 경우, 버퍼링의 장점을 살리지 못하여, 늦어지는 경우가 아주 가끔 발생할 수도 있다. 이런 경우는 SQL trace를 이용하여 실제로 수행시간을 측정하고 결과가 좋은 것을 사용하도록 한다.

■ Data dictionary의 database view는 항상 inner join이다.



9. SELECT for all entries를 이용한 Outer Join

● 이 슬라이드는 SELECT FOR ALL ENTRIES를 이용하여 ABAP/4에서
Outer Join을 구현한 예이다.

SELECT VBELN AUART ... INTO ... FROM VBAK WHERE ...
SELECT POSNR MATNR KWMENG MEINS INTO ... FROM VBAP
WHERE VBELN = VBAK-VBELN.
...
ENDSELECT.
ENDSELECT.


SELECT VBELN AUART ... INTO TABLE IVBAK FROM VBAK
WHERE VBELN IN VBELN_SO.
SELECT VBELN POSNR MATNR ... INTO TABLE IVBAP FROM VBAP
FOR ALL ENTRIES IN IVBAK
WHERE VBELN = IVBAK-VBELN.

LOOP AT VBAK.
READ TABLE IVBAP WITH KEY VBELN = IVBAK-VBELN BINARY SEARCH
TRANSPORTING NO FIELDS.
LOOP AT IVBAP FROM SY-TABIX.
...
ENDLOOP.
ENDLOOP.


■ Outer join을 할 경우에는 위의 코드처럼 FOR ALL ENTRIES IN 구문을 이용하여
SELECT한 후, Internal table에서 처리하도록 한다.



10. SQL 함수 사용하기

● 이 슬라이드는 SELECT 구문에서 LOOP을 돌면서 처리하는 형태의 합이나,
평균을 구하는 스타일을 SQL 함수를 이용하여 개선하는 예를 보여 준다.

DATA: BEGIN OF VBQTY OCCURS 0.
MATNR LIKE VBAP-MATNR,
KWMENG LIKE VBAP-KWMENG,
MEINS LIKE VBAP-MEINS.

SELECT MATNR KWMENG MEINS INTO VBQTY
FROM VBAP WHERE ...
COLLECT VBQTY.
ENDSELECT.


SELECT MATNR SUM( KWMENG ) MEINS INTO TABLE VBQTY
FROM VBAP WHERE ...
GROUP BY MATNR MEINS.



■ 10,000 건의 데이터를 처리하였을 경우, 아래와 같은 성능 차이가 나왔다.

■ SELECT + COLLECT : 2,370,000 ms
SELECT SUM .. INTO : 1,574,000 ms

■ GROUP BY 절은 Pool table이나, cluster table에는 사용될 수 없다
(BSEG, VBFA).



11. WHERE 절 없는 SELECT 구문은 피하라.

● 아래와 같이 WHERE 조건 없이 SELECT 구문을 사용하는 것은 매우 위험하다.

SELECT col1 col2 ... into ... FROM VBAK.
PERFORM CALCULATE_STUFF.
ENDSELECT.



■ 특히 다음과 같이 빠른 속도로 크기가 증가하는 테이블에는 절대로 사용하지 말라.
- BKPF, BSEG, COBK, COEP, LIPK, LIPS, MKPF, MSEG, VBAK, VBAP, VBPA, VBFA.

■ 테이블의 모든 데이터를 읽어 작업을 수행하려 한다면 다음과 같이 exec sql 구문을 이용한 native sql을 구사하여 application server를 bypass 하도록 한다. 그렇지 않으면 application server가 where 절에 mandt 조건을 붙여, full table scan이 되지 않고 인덱스를 이용하게 되어 최악의 결과를 초래한다.

exec sql.
select /*+ rule */
vbeln into :ivbak-vbeln
from vbak
where mandt||'' = :sy-mandt
endexec.



제 2 장. DML 구문 최적화

1. 효과적인 UPDATE 기법

● SELECT 와 ENDSELECT 사이에서 LOOP을 돌면서 UPDATE 하는 형태는
아래와 같이 WHERE 절을 이용하여 개선할 수 있다.

PARAMETERS : VKBUR_PA LIKE ZVBAK-VKBUR.
SELECT-OPTIONS : VBELN_SO FOR ZVBAK-VBELN.
SELECT * FROM ZVBAK WHERE VBELN IN VBELN_SO.
ZVBAK-VKBUR = VKBUR_PA.
UPDATE ZVBAK.
ENDSELECT.
IF SY-SUBRC = 0. COMMIT WORK. ELSE. ROLLBACK WORK. ENDIF.



UPDATE ZVBAK SET VKBUR = VKBUR_PA
WHERE VBELN IN VBELN_SO.
IF SY-SUBRC = 0. COMMIT WORK. ELSE. ROLLBACK WORK. ENDIF.



■ ZVBAK 1,000 건을 대상으로 테스트한 결과는 다음과 같다.

■ SELECT .. UPDATE : 1.8 초
UPDATE .. SET : 0.3 초

■ 위의 코딩에서 COMMIT WORK 또는 ROLLBACK WORK 구문은
논리적인 작업단위가 끝나면 반드시 기술해 주어야 한다는 것을 잊지 말자.
COMMIT WORK 이나 ROLLBACK WORK을 빠뜨리면, 데이터베이스 서버가
수정 정보를 계속 rollback segment에 가지고 있어야 하기 때문에 시스템에
overload로 계속 남아있게 된다.



2. 효과적인 INSERT 기법

● 데이터를 테이블에 Insert 하고자 할 경우, Loop을 돌면서 건건이
처리하는 것을 아래의 예처럼 한꺼번에 Insert하면 더욱 효과적임.

LOOP AT IT100.
MOVE IT100 TO Z100.
INSERT Z100.
ENDLOOP.



INSERT Z100 FROM TABLE IT100.



■ 아래의 결과는 Internal table의 건수별로 테스트 결과를 나타낸 것이다.

■ 1,000 건 입력시
- 한 건씩 Insert : 2.58 초
- 한꺼번에 Insert : 0.72 초
■ 5,000 건 입력시
- 한 건씩 Insert : 9.66 초
- 한꺼번에 Insert : 1.59 초
■ 10,000 건 입력시
- 한 건씩 Insert : 20.00 초
- 한꺼번에 Insert : 2.47 초



3. 효과적인 DELETE 기법

● SELECT 와 ENDSELECT 사이에서 LOOP을 돌면서 DELETE 하는 형태는
아래와 같이 WHERE 절을 이용하여 개선할 수 있다.

SELECT-OPTIONS : VBELN_SO FOR ZVBAK-VBELN.
SELECT * FROM ZVBAK WHERE VBELN IN VBELN_SO.
DELETE ZVBAK.
ENDSELECT.
IF SY-SUBRC = 0. COMMIT WORK. ELSE. ROLLBACK WORK. ENDIF.



DELETE FROM ZVBAK WHERE VBELN IN VBELN_SO.
IF SY-SUBRC = 0. COMMIT WORK. ELSE. ROLLBACK WORK. ENDIF.



■ ZVBAK 1,000 건을 대상으로 테스트한 결과는 다음과 같다.

■ SELECT .. DELETE : 3.0 초
DELETE FROM : 1.2 초

■ 첫번째 코딩은 거의 최악의 코딩이다. 첫번째 경우에 데이터베이스 서버는
대상 데이터를 찾아서 전부 어플리케이션 서버로 전송한다. 데이터를 받은
어플리케이션 서버는 아무일도 하지 않고, 받은 데이터를 다시 데이터베이스
서버로 전송하고, 데이터베이스 서버는 이 데이터를 삭제한다.

■ 그러나, 두번째 경우처럼 코딩하면, 데이터의 발췌 및 삭제작업이
데이터베이스 서버에서만 발생하게 되므로, 어플리케이션 서버와 데이터베이스
서버간에 데이터 전송 작업이 전혀 일어나지 않는다.



제 3 장. 효과적인 Internal Table Handling

1. Nested LOOP 처리

● NESTED LOOP은 BINARY SEARCH를 이용하여 아래와 같이 개선할 수 있다.

DATA: IVBAK LIKE VBAK OCCURS 0,
IVBAP LIKE VBAP OCCURS 0.
SORT: IVBAK BY VBELN, IVBAP BY VBELN.
LOOP AT IVBAK.
LOOP AT IVBAP WHERE VBELN = VBAK-VBELN.
WRITE:/ IVBAK-VBELN, IVBAP-VBPOS, ...
ENDLOOP.
ENDLOOP.


LOOP AT IVBAK.
READ TABLE IVBAP WITH KEY VBELN = IVBAK-VBELN
BINARY SEARCH TRANSPORTING NO FIELDS.
LOOP AT IVBAP FROM SY-TABIX.
IF IVBAP-VBELN <> IVBAK-VBELN. EXIT. ENDIF.
WRITE:/ IVBAK-VBELN, IVBAP-VBPOS, ...
ENDLOOP.
ENDLOOP.



■ IVBAK : 5,000 건, IVBAP : 20,000 건일 경우에 다음과 같은 결과가 나왔다.

■ Nested LOOP with WHERE condition : 5 분
LOOP/READ BINARY SEARCH/LOOP : 15 초.



2. 효과적인 LOOP 처리

● 특정 조건을 만족하는 데이터가 몇건인지를 알고 싶은 경우에는
다음과 같이 한다.

LOOP AT IVBAK TRANSPORTING NO FIELDS
WHERE BNAME = 'Smith'.
ADD 1 TO COUNTER.
ENDLOOP.


■ 만약 특정 조건을 만족시키는 데이터가 있는지만 알고 싶다면,
다음과 같은 코드를 이용하라.
■ LOOP AT IVBAK TRANSPORTING NO FIELDS
WHERE VBELN > '0300000100'.
EXIT.
ENDLOOP.
IF SY-SUBRC = 0.
* Condition is true
ENDIF.



3. Internal TABLE간 데이터 복사

● 동일한 구조를 가지는 두개의 Internal table간에 서로 데이터를
복사하고자 할 경우에는 아래와 같이 한다.

DATA: ITAB1 LIKE VBAK OCCURS 100 WITH HEADER LINE,
ITAB2 LIKE VBAK OCCURS 100 WITH HEADER LINE,

REFRESH ITAB2.
LOOP AT ITAB1.
MOVE ITAB1 TO ITAB2.
APPEND ITAB2.
ENDLOOP.



ITAB2[] = ITAB1[]



■ 위의 방법은 동일한 구조를 가지는 INTERNAL TABLE간에만 적용된다는 점에
주의하라.



4. Internal TABLE의 데이터 APPEND

● 동일한 구조를 가지는 두개의 Internal table간에 서로 데이터를
APPEND 하고자 할 경우에는 아래와 같이 개선한다.

DATA: ITAB1 LIKE VBAK OCCURS 100 WITH HEADER LINE,
ITAB2 LIKE VBAK OCCURS 100 WITH HEADER LINE,

LOOP AT ITAB1.
MOVE ITAB1 TO ITAB2.
APPEND ITAB2.
ENDLOOP.


APPEND LINES OF ITAB1 TO ITAB2.



5. Internal Table의 데이터 삭제

● 여러건의 데이터를 Internal Table에서 삭제하고자 할 경우에는,
LOOP을 돌지 말고 아래와 같이 한다.

LOOP AT IVBAK WHERE BNAME = 'Smith'.
DELETE IVBAK.

ENDLOOP.


DELETE IVBAK WHERE BNAME = 'Smith'.



6. Internal Table의 중복 데이터 삭제

● Internal Table에서 중복 데이터를 삭제할 경우, 다음과 같은 문장을
사용하라.

DELETE ADJACENT DUPLICATES FROM ITAB
[COMPARING FIELD1 FIELD2 ... FIELDn].



■ 아래의 방법을 사용하기 위해서는 비교조건 필드를 기준으로 sort가 되어 있어야
한다. 비교조건이 없다면, 모든 필드로 SORT가 되어 있어야 한다.
번호 제목 글쓴이 날짜 조회 수
348 [Function]달력 팝업창을 뛰워보자 [14] file 양키 2010.10.07 7928
347 <img src=d.gif>[Function]Edit 팝업창을 뛰워보자[추천:e-abap] [19] file 양키 2010.09.28 6638
346 [Function]금액(숫자)를 영문철자로 바꿔보자 [3] file 양키 2010.09.28 6565
345 [Function]조직구조 팝업창을 뛰워보자 [5] file 양키 2010.09.28 7344
344 SELECT 문의 종류 및 CONCATENATE의 사용 [24] file iceout 2010.08.21 11839
343 <img src=d.gif>Abap 리포트 소스 스캔프로그램 소개[추천:e-abap] [12] file 양키 2010.07.13 7428
342 <img src=b.gif>Windows 7 에서 SAP GUI ALV 반응느림 해결방법 공유 (GUI720 기준)[추천:e-abap][추천:유리선율][추천:보나] [17] 점점 2010.07.02 14825
341 [TIP] FILE_OPEN_DIALOG시 바탕화면을 기본경로로 설정하기 [16] file 고양이야옹 2010.06.29 6965
340 <img src=d.gif>찾고자하는 화면을 쉽게찾을수있는 방법[추천:e-abap] [7] file 양키 2010.06.19 5836
339 난수발생 함수. [3] 무풍지대 2010.06.17 7631
338 SAP 지뢰 찾기 [10] file 버미! 2010.06.10 6908
337 <img src=d.gif>구매오더 아카이브 방법[추천:e-abap] [14] file 양키 2009.08.14 5772
336 [TIP] (기초) SAP ABAB 예제찾기 SE83 [19] file 촌놈악마 2010.06.01 6115
335 [TIP] (기초) 화면에 Sap Key 값이 안보일때 해결방안 [3] file 촌놈악마 2010.06.01 4891
334 Buffer Bypass 방법 [4] sapjoy 2010.05.20 6659
333 특정프로그램 내에서 프린터로 직접 프린트하는 함수 [8] 미쓰조 2010.03.18 6492
332 Report 개발 시 Select-option에 search help 값이 자동으로 입력이 안될때 [6] file 곰님MAX 2010.02.13 9930
331 사용자 패스워드 변경 함수, 창 [11] sapjoy 2009.12.21 26634
330 로그 오프 시키는 함수, LOGOFF, 로그오프 [4] sapjoy 2009.12.21 5904
» 효과적인 ABAP/4 프로그램 작성기법 [24] 열공아밥 2009.12.21 8928