ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ABAP OPEN DATASET - itab 서버 파일 저장
    SAP 2026. 6. 5. 18:07

    abap_open_dataset.html
    0.02MB
    abap_open_dataset.docx
    0.02MB

     

    ABAP OPEN DATASET - itab 서버 파일 저장

    ABAP OPEN DATASET — itab 서버 파일 저장

    Application Server 파일 쓰기 · OPEN DATASET 문법 · 주의사항 · 실전 패턴

    1. OPEN DATASET 전체 문법

    1-1. 기본 구문 형식

    OPEN DATASET <filename>
      FOR { INPUT | OUTPUT | APPENDING | UPDATE }
      IN  { TEXT MODE | BINARY MODE }
      [ ENCODING { DEFAULT | UTF-8 | NON-UNICODE } ]
      [ WITH SMART LINEFEED ]
      [ MESSAGE <msg_var> ]
      [ FILTER <filter_cmd> ].

    1-2. 모드 옵션 상세

    모드 방향 파일 없을 때 파일 있을 때 주 용도
    FOR OUTPUT 쓰기 신규 생성 덮어씀 (기존 내용 삭제) 새 파일 생성
    FOR APPENDING 쓰기 신규 생성 파일 끝에 이어씀 로그 누적
    FOR INPUT 읽기 SY-SUBRC ≠ 0 (오류) 읽기 전용 열기 파일 읽기
    FOR UPDATE 읽기+쓰기 SY-SUBRC ≠ 0 (오류) 읽기·쓰기 병행 부분 수정

    1-3. 텍스트 vs 바이너리 모드

    구분TEXT MODEBINARY MODE
    줄바꿈 처리 TRANSFER 시 자동 줄바꿈(LF/CRLF) 추가 없음 — 있는 그대로 기록
    ENCODING 지정 필수 고려 (UTF-8 / DEFAULT) 없음 (바이트 그대로)
    주 용도 TXT, CSV, 로그 Excel(XLSX), PDF, ZIP

    1-4. ENCODING 옵션

    설명권장 상황
    ENCODING UTF-8 UTF-8로 저장 한글 포함, 다국어, 외부 연동
    ENCODING DEFAULT 시스템 Code Page 따름 ECC 레거시, 동일 시스템 내 재사용
    ENCODING NON-UNICODE Non-Unicode 시스템 호환 특수 레거시 환경

    💡 S/4HANA는 항상 Unicode 시스템이므로 ENCODING UTF-8을 기본으로 사용한다.
    한글 데이터가 있는 경우 ENCODING DEFAULT는 시스템 설정에 따라 깨질 수 있으니 UTF-8 명시 권장.

    2. itab → || 구분자로 서버 파일 저장

    2-1. 기본 패턴 (String Template 활용)

    TYPES: BEGIN OF ty_item,
             matnr TYPE matnr,
             maktx TYPE maktx,
             menge TYPE menge,
             meins TYPE meins,
             werks TYPE werks,
           END OF ty_item.
    
    DATA: lt_item   TYPE TABLE OF ty_item,
          lv_path   TYPE string VALUE '/tmp/output/item_export.txt',
          lv_msg    TYPE string.
    
    " ─── 헤더 포함 여부에 따라 선택 ───
    DATA(lv_header) = 'MATNR||MAKTX||MENGE||MEINS||WERKS'.
    
    OPEN DATASET lv_path
      FOR OUTPUT
      IN TEXT MODE
      ENCODING UTF-8
      MESSAGE lv_msg.
    
    IF sy-subrc <> 0.
      " 오류 처리
      MESSAGE lv_msg TYPE 'E'.
    ENDIF.
    
    " 헤더 라인 출력
    TRANSFER lv_header TO lv_path.
    
    " 데이터 라인 출력
    LOOP AT lt_item INTO DATA(ls_item).
      DATA(lv_line) = |{ ls_item-matnr }||{ ls_item-maktx }||{ ls_item-menge }||{ ls_item-meins }||{ ls_item-werks }|.
      TRANSFER lv_line TO lv_path.
    ENDLOOP.
    
    CLOSE DATASET lv_path.

    💡 String Template |{ ... }| 안에서 || 구분자를 직접 삽입할 수 있다.
    불필요한 CONCATENATE 없이 한 줄로 처리 가능하여 가독성이 좋다.

    2-2. 숫자/날짜 포맷 지정 예시

    " 숫자: 소수점 2자리 고정, 날짜: YYYY-MM-DD 형식
    DATA(lv_line) = |{ ls_item-matnr WIDTH = 18 }||{ ls_item-menge DECIMALS = 2 }||{ ls_item-erdat DATE = ISO }|.
    TRANSFER lv_line TO lv_path.
    String Template 포맷팅설명예시 결과
    WIDTH = n고정 너비 (우측 패딩)MATNR
    DECIMALS = n소수점 자리수 고정100.00
    DATE = ISO날짜를 YYYY-MM-DD2025-06-05
    DATE = USER사용자 포맷 날짜2025.06.05
    TIME = ISO시간을 HH:MM:SS14:30:00
    ALPHA = OUTLeading zero 제거000001 → 1
    ALPHA = INLeading zero 복원1 → 000001

    2-3. CONDENSE 처리 (앞뒤 공백 제거)

    LOOP AT lt_item INTO DATA(ls_item).
      DATA(lv_matnr) = CONV string( ls_item-matnr ).
      DATA(lv_maktx) = CONV string( ls_item-maktx ).
      CONDENSE lv_matnr NO-GAPS.
      CONDENSE lv_maktx.   " 앞뒤 공백만 제거 (중간 공백 유지)
    
      DATA(lv_line) = |{ lv_matnr }||{ lv_maktx }||{ ls_item-menge DECIMALS = 2 }|.
      TRANSFER lv_line TO lv_path.
    ENDLOOP.

    ⚠️ CHAR/NUMC 타입 필드는 자동으로 우측 공백이 붙는다.
    String Template 사용 시에도 CHAR 타입은 정의된 길이만큼 공백이 포함되므로,
    파일 파싱 시 문제가 되면 CONDENSE 또는 CONV string() 후 처리 권장.

    3. OPEN DATASET 주의사항

    3-1. SY-SUBRC 체크

    구문SY-SUBRC = 0SY-SUBRC ≠ 0
    OPEN DATASET FOR OUTPUT정상 열림경로 없음, 권한 없음
    OPEN DATASET FOR INPUT정상 열림파일 없음, 권한 없음
    TRANSFER정상 기록디스크 풀, I/O 오류
    CLOSE DATASET정상 닫힘이미 닫힘(무시 가능)
    OPEN DATASET lv_path FOR OUTPUT IN TEXT MODE ENCODING UTF-8 MESSAGE lv_msg.
    IF sy-subrc <> 0.
      WRITE: / 'OPEN DATASET 실패:', lv_msg.
      RETURN.
    ENDIF.
    
    LOOP AT lt_item INTO DATA(ls_item).
      TRANSFER lv_line TO lv_path.
      IF sy-subrc <> 0.
        WRITE: / 'TRANSFER 실패 - TABIX:', sy-tabix.
        EXIT.
      ENDIF.
    ENDLOOP.
    
    CLOSE DATASET lv_path.

    3-2. 반드시 CLOSE DATASET

    ⚠️ CLOSE DATASET을 누락하면 파일 핸들이 서버에 남아 다음 OPEN 시 오류 또는 데이터 손실이 발생할 수 있다.
    예외(EXCEPTION) 처리 후에도 반드시 CLOSE가 실행되도록 구조를 잡는다.

    " TRY-CATCH 패턴으로 CLOSE 보장
    TRY.
        OPEN DATASET lv_path FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
        LOOP AT lt_item INTO DATA(ls_item).
          TRANSFER lv_line TO lv_path.
        ENDLOOP.
      CATCH cx_root INTO DATA(lx_err).
        " 예외 발생 시에도 CLOSE 실행
        CLOSE DATASET lv_path.
        RAISE EXCEPTION lx_err.
    ENDTRY.
    
    CLOSE DATASET lv_path.

    3-3. 서버 경로 권한 (AL11 확인)

    💡 Application Server 파일 시스템 경로는 트랜잭션 AL11에서 확인한다.
    SAP 관리자가 허용한 디렉터리 외에는 OPEN DATASET이 권한 오류(SY-SUBRC <> 0)로 실패한다.

    체크 항목설명
    AL11 경로 확인 SAP 허용 디렉터리 목록 확인 (예: /usr/sap/<SID>/tmp)
    OS 파일 권한 <sid>adm 계정에 write 권한 필요
    권한 오브젝트 S_DATASET: 프로그램에 파일 접근 권한 부여 필요
    경로 구분자 유닉스 계열은 /, Windows는 \ — 서버 OS 확인

    3-4. 멀티 App Server 환경 주의

    ⚠️ SAP 시스템이 멀티 App Server(CI + App 서버 여러 대)인 경우,
    OPEN DATASET은 현재 work process가 실행되는 서버의 로컬 파일 시스템에 저장된다.
    따라서 특정 서버에 저장했어도 다음 실행 시 다른 서버에서 해당 파일을 못 찾을 수 있다.
    공유 파일 시스템(NFS/SFTP)을 사용하거나 SET SERVER로 서버를 고정해야 한다.

    3-5. 대용량 데이터 처리

    " ✅ 권장: LOOP 안에서 lv_line 재선언 대신 DATA 미리 선언
    DATA: lv_line TYPE string.
    
    OPEN DATASET lv_path FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
    LOOP AT lt_item INTO DATA(ls_item).
      lv_line = |{ ls_item-matnr }||{ ls_item-maktx }||{ ls_item-menge DECIMALS = 2 }|.
      TRANSFER lv_line TO lv_path.
    ENDLOOP.
    CLOSE DATASET lv_path.

    💡 LOOP 안에서 매번 DATA(lv_line)을 선언하면 첫 번째 반복 이후에는 선언이 아닌 재할당이 된다.
    성능보다 가독성 차원에서 LOOP 밖에 미리 선언하는 것을 권장.

    4. 그 외 체크해야 할 사항

    • 파일 경로 하드코딩 금지PARAMETERS 또는 커스텀 테이블(TVARVC 등)에서 경로를 읽어 유연하게 처리
    • 파일명에 타임스탬프 포함 — 동일 프로그램 재실행 시 덮어쓰기 방지: output_<sy-datum>_<sy-uzeit>.txt
    • 헤더 라인 포함 여부 결정 — 수신 시스템 파싱 방식에 따라 헤더 ON/OFF 파라미터화
    • 빈 itab 처리 — LOOP 전에 IF lt_item IS INITIAL. RETURN. ENDIF.로 빈 파일 생성 방지
    • TRANSFER 후 sy-subrc 체크 — 디스크 풀 등의 I/O 오류를 루프 내에서 감지
    • 인코딩 수신자 확인 — 수신 시스템이 UTF-8 / EUC-KR 어느 인코딩을 기대하는지 사전 확인
    • BOM(Byte Order Mark) — UTF-8 파일을 Windows Excel에서 열려면 BOM 필요 → FILTER 또는 별도 BOM 바이트 앞에 삽입 고려
    • DELETE DATASET로 기존 파일 삭제 후 재생성 — FOR OUTPUT은 덮어쓰지만, 이전 파일보다 작은 경우 잔여 바이트가 남을 수 있으므로 명시적으로 DELETE 후 생성 권장
    • Background Job 실행 시 권한 주의 — 다이얼로그와 백그라운드는 다른 OS 권한 컨텍스트로 실행될 수 있음
    • MESSAGE 파라미터 활용 — 오류 메시지를 변수로 받아 로그 테이블에 기록하면 운영 디버깅이 쉬움

    DELETE DATASET 패턴

    " 기존 파일 명시적 삭제 후 새로 생성
    DELETE DATASET lv_path.
    " sy-subrc 체크 불필요 (파일 없어도 0 반환)
    
    OPEN DATASET lv_path FOR OUTPUT IN TEXT MODE ENCODING UTF-8 MESSAGE lv_msg.
    IF sy-subrc <> 0.
      MESSAGE lv_msg TYPE 'E'.
    ENDIF.

    파일명 타임스탬프 패턴

    DATA(lv_path) = |/tmp/export/item_{ sy-datum }{ sy-uzeit }.txt|.
    " 결과 예: /tmp/export/item_202506051430.txt

    5. 전체 완성 코드 예제

    REPORT z_itab_to_file.
    
    TYPES: BEGIN OF ty_item,
             matnr TYPE matnr,
             maktx TYPE maktx,
             menge TYPE menge,
             meins TYPE meins,
             werks TYPE werks,
             erdat TYPE erdat,
           END OF ty_item.
    
    DATA: lt_item  TYPE TABLE OF ty_item,
          lv_path  TYPE string,
          lv_line  TYPE string,
          lv_msg   TYPE string.
    
    " 경로 설정 (타임스탬프 포함)
    lv_path = |/tmp/export/item_{ sy-datum }{ sy-uzeit }.txt|.
    
    " 테스트 데이터 추가
    APPEND VALUE ty_item( matnr = '000000000000001234'
                          maktx = '테스트 자재'
                          menge = '100.500'
                          meins = 'KG'
                          werks = '1000'
                          erdat = sy-datum ) TO lt_item.
    
    " 빈 itab 체크
    IF lt_item IS INITIAL.
      WRITE: / '출력 데이터 없음'.
      RETURN.
    ENDIF.
    
    " 기존 파일 삭제
    DELETE DATASET lv_path.
    
    " 파일 열기
    OPEN DATASET lv_path
      FOR OUTPUT
      IN TEXT MODE
      ENCODING UTF-8
      MESSAGE lv_msg.
    
    IF sy-subrc <> 0.
      WRITE: / '파일 열기 실패:', lv_msg.
      RETURN.
    ENDIF.
    
    " 헤더 출력
    TRANSFER 'MATNR||MAKTX||MENGE||MEINS||WERKS||ERDAT' TO lv_path.
    
    " 데이터 출력
    LOOP AT lt_item INTO DATA(ls_item).
      lv_line = |{ ls_item-matnr ALPHA = OUT }||{ ls_item-maktx }||{ ls_item-menge DECIMALS = 3 }||{ ls_item-meins }||{ ls_item-werks }||{ ls_item-erdat DATE = ISO }|.
      TRANSFER lv_line TO lv_path.
      IF sy-subrc <> 0.
        WRITE: / 'TRANSFER 오류 - ROW:', sy-tabix.
        EXIT.
      ENDIF.
    ENDLOOP.
    
    CLOSE DATASET lv_path.
    
    WRITE: / '파일 저장 완료:', lv_path.

    💡 ALPHA = OUT을 사용하면 0000000000000012341234로 Leading Zero를 제거하여 출력한다.
    수신 시스템에서 자재번호를 Leading Zero 없이 처리한다면 이 옵션을 활용.

    #ABAP #OPEN_DATASET #TRANSFER #itab_파일저장 #Application_Server #UTF-8 #String_Template #S4HANA
Designed by Tistory.