SAP 화면에서 사용자가 PC 의 파일을 직접 골라 ArchiveLink (TOA01) 에 저장해야 하는 시나리오가 있습니다. 외부 시스템(WEB · MES) 이 RFC 로 binary 를 넘기는 흐름과는 달리, SAP 사용자가 화면에서 직접 file dialog 를 열어 파일을 고르고 그 파일을 ArchiveLink 저장소로 보내는 단일 시점 업로드 패턴입니다.
이 흐름의 핵심은 PC 파일 → XSTRING → 1024 바이트 청크 테이블 의 두 단계 binary 변환. 표준 wrapper(CL_SECXML_HELPER) 로 PC 파일을 XSTRING 으로 받고, SCMS_XSTRING_TO_BINARY 로 ArchiveLink 가 요구하는 TBL1024 청크 형식으로 변환합니다. 그 다음 ARCHIV_CREATE_TABLE 한 번 호출로 TOA01 에 등록 완료.
이 글에서는 6단계 흐름 · XSTRING ↔ TBL1024 변환 · 확장자 자동 추출 · RAW 타입 호환 함정 · 외부 시스템 RFC 시나리오와의 차이까지 정리합니다. SAP 사용자가 화면에서 직접 ArchiveLink 에 첨부를 올려야 하는 케이스에 그대로 따라할 수 있게 단계별로 구성했습니다.
핵심 — 6단계 흐름
| 단계 | API | 변환 결과 |
|---|---|---|
| 1 | CL_SECXML_HELPER=>FILE_F4 |
PC 파일 경로 (filename STRING) |
| 2 | CL_SECXML_HELPER=>UPLOAD_FILE |
파일 내용 (bindata XSTRING) |
| 3 | SCMS_XSTRING_TO_BINARY |
청크 테이블 (SOLIX_TAB) + 정확한 길이 |
| 4 | CL_BCS_UTILITIES=>SPLIT_NAME |
파일명 + 확장자 분리 |
| 5 | SOLIX_TAB → TBL1024 변환 | ArchiveLink 호환 청크 |
| 6 | ARCHIV_CREATE_TABLE |
TOA01 등록 + Content Server 저장 |
전체 변환 사슬: PC 파일 → STRING (경로) → XSTRING (내용) → SOLIX_TAB (청크) → TBL1024 (ArchiveLink) → TOA01 (메타) + Content Server (실제 binary).
1단계 — PC 파일 선택 (FILE_F4)
CL_SECXML_HELPER 의 wrapper 메소드. 사용자에게 파일 선택 다이얼로그를 띄우고 풀 경로를 반환.
cl_secxml_helper=>file_f4(
EXPORTING
initial_directory = '' " 시작 경로 (빈 값 = 기본)
window_title = '첨부파일 선택'
IMPORTING
filename = DATA(lv_xfile) ).
" 사용자가 취소했는지 확인
IF lv_xfile IS INITIAL.
EXIT.
ENDIF.
내부적으로 표준 cl_gui_frontend_services=>file_open_dialog 호출. 더 정밀한 다이얼로그 옵션(필터·다중 선택) 이 필요하면 raw API 를 직접 사용.
2단계 — 파일 내용 → XSTRING (UPLOAD_FILE)
선택된 파일을 SAP 메모리로 읽어옵니다. XSTRING 단일 변수로 받아 후속 처리가 편리.
cl_secxml_helper=>upload_file(
EXPORTING
filename = lv_xfile
IMPORTING
bindata = DATA(lv_data_xstr) ).
DATA(lv_size) = xstrlen( lv_data_xstr ).
WRITE: / |업로드 크기: { lv_size } bytes|.
내부적으로 GUI_UPLOAD 함수가 BIN 모드로 파일을 읽어 BIN1024 테이블 → XSTRING 변환을 자동 처리.
3단계 — XSTRING → SOLIX 청크 테이블
ArchiveLink 가 받는 binary 형식은 1024 바이트 라인의 테이블. XSTRING 을 그 형식으로 분할.
DATA: lv_len TYPE i,
lt_tab TYPE solix_tab.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_data_xstr
* append_to_table = SPACE " 'X' = 기존 테이블에 추가
IMPORTING
output_length = lv_len " 정확한 바이트 수
TABLES
binary_tab = lt_tab.
SOLIX_TAB 의 한 라인은 SOLIX (LINE = RAW(255)) 가 아니라 실제로는 1024 바이트 청크에 가까운 구조입니다. OUTPUT_LENGTH 는 마지막 라인의 부분 사용량까지 정확하게 반영하므로 그대로 FLENGTH 파라미터에 전달.
대안 — CL_BCS_CONVERT=>XSTRING_TO_SOLIX 도 같은 동작을 합니다.
DATA(lt_solix) = cl_bcs_convert=>xstring_to_solix( iv_xstring = lv_data_xstr ).
함수 호출과 클래스 메소드 호출 중 코딩 스타일에 맞춰 선택. 결과는 동일.
4단계 — 파일명 + 확장자 분리
ARCHIV_CREATE_TABLE 의 DOC_TYPE 에 정확한 확장자(PDF · DOC · XLSX) 를 넣어야 합니다. CL_BCS_UTILITIES 의 표준 메소드로 자동 추출.
cl_bcs_utilities=>split_name(
EXPORTING
iv_name = lv_xfile
iv_delimiter = '.'
IMPORTING
ev_name = DATA(lv_filename)
ev_extension = DATA(lv_extension) ).
" 확장자를 대문자로 변환 (DOC_TYPE 은 대문자)
DATA(lv_type) = lv_extension.
TRANSLATE lv_type TO UPPER CASE.
확장자 검증 — TOADD 에 등록된 확장자만 허용되므로 사전 체크:
SELECT COUNT(*) FROM toadd
WHERE doc_type = lv_type.
IF sy-subrc <> 0.
MESSAGE |허용 안 된 확장자: { lv_type }| TYPE 'E'.
ENDIF.
5단계 — SOLIX_TAB → TBL1024 변환
ArchiveLink 가 요구하는 binary 청크 타입은 TBL1024. SOLIX_TAB 와는 RAW 타입이 다를 수 있어 명시적 변환 또는 호환 대입이 필요합니다.
DATA lt_bin_data TYPE TABLE OF tbl1024.
" SOLIX_TAB → TBL1024 직접 대입 (같은 구조라면 ABAP 이 호환 대입)
lt_bin_data = lt_tab.
핵심 함정 — RAW 타입 호환. 두 구조 모두 1024 바이트 RAW 라인이지만 SAP 릴리스에 따라 컴포넌트 이름이 다를 수 있습니다(LINE vs RLINE). 직접 대입이 실패하면 LOOP 변환:
DATA: ls_tbl1024 TYPE tbl1024.
LOOP AT lt_tab ASSIGNING FIELD-SYMBOL(<ls_solix>).
ls_tbl1024-line = <ls_solix>-line.
APPEND ls_tbl1024 TO lt_bin_data.
CLEAR ls_tbl1024.
ENDLOOP.
LOOP 변환은 어떤 환경에서도 안전. 직접 대입이 활성화되면 그 환경에서는 LOOP 를 생략해도 됩니다.
6단계 — ARCHIV_CREATE_TABLE 호출
준비된 청크 테이블 + 메타데이터를 ArchiveLink 표준 FM 에 전달.
CALL FUNCTION 'ARCHIV_CREATE_TABLE'
EXPORTING
ar_object = 'ZXXWEB' " IMG 정의 문서 유형
object_id = 'TEST-DOC-001' " 호출자 지정 키
sap_object = 'ZXXWEBGOS' " SAP 객체 매핑
flength = CONV sapb-length( lv_len ) " 정확한 바이트 수
doc_type = CONV toadd-doc_type( lv_type )
* document =
* mandt = sy-mandt
* vscan_profile = '/SCMS/KPRO_CREATE'
* filename = lv_filename
* descr = '사용자 첨부'
* IMPORTING
* outdoc = ls_outdoc
TABLES
* archivobject =
binarchivobject = lt_bin_data
EXCEPTIONS
error_archiv = 1
error_communicationtable = 2
error_connectiontable = 3
error_kernel = 4
error_parameter = 5
error_user_exit = 6
error_mandant = 7
blocked_by_policy = 8
OTHERS = 9.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ELSE.
MESSAGE '첨부파일이 등록되었습니다.' TYPE 'S'.
ENDIF.
핵심 파라미터:
AR_OBJECT— IMGOAD2에서 정의한 문서 유형OBJECT_ID— 회사 자체 키 (PO 번호 / 첨부 순번 / GUID)SAP_OBJECT—OAC3매핑FLENGTH— 정확한 파일 크기 (3단계의OUTPUT_LENGTH)DOC_TYPE— 4단계의 대문자 확장자BINARCHIVOBJECT— 5단계의 TBL1024 테이블
호출 직후 TOA01 에 한 행 + Content Server 에 실제 binary 가 저장됩니다.
외부 RFC 게이트웨이 시나리오와의 차이
같은 ArchiveLink 영역이지만 호출 컨텍스트가 다릅니다. 외부 시스템(WEB · MES) 이 RFC 로 binary 를 송신하는 패턴(ARCHIV_CREATE_TABLE 게이트웨이) 과 비교.
| 구분 | 사용자 직접 업로드 (이 글) | 외부 RFC 게이트웨이 |
|---|---|---|
| 호출 컨텍스트 | SAP GUI · 사용자 화면 | 외부 시스템(WEB · MES) · RFC |
| 파일 입력 | PC 파일 다이얼로그 (FILE_F4) | RFC IMPORTING 파라미터로 binary |
| 변환 사슬 | 파일 → XSTRING → SOLIX → TBL1024 | 외부에서 이미 청크 형태로 전송 |
| 확장자 / 메타 | 파일명에서 자동 추출 | 외부 시스템이 메타 함께 전달 |
| 호출 단위 | 사용자 한 명 / 한 번 | 자동화 / 다건 / 인터페이스 |
두 시나리오 모두 결국 ARCHIV_CREATE_TABLE 을 호출하고 TOA01 에 저장됩니다. 차이는 그 FM 에 도달하기까지의 binary 변환 사슬.
흔히 빠뜨리는 함정
RAW 타입 호환 (Notion 노트의 주의사항)
가장 큰 함정. SOLIX · TBL1024 · BIN1024 모두 1024 바이트 RAW 기반이지만 컴포넌트 명이 다를 수 있습니다. 첨부파일을 바이너리화 하는 RAW 의 TYPE 형태가 동일해야 ARCHIV_CREATE_TABLE 이 정상 처리. 대입이 실패하면 명시적 LOOP 변환으로 우회.
FLENGTH 누락
FLENGTH 를 비우거나 잘못된 값으로 넘기면 마지막 청크 라인의 사용량이 잘못 계산되어 파일이 손상됩니다. SCMS_XSTRING_TO_BINARY 의 OUTPUT_LENGTH 또는 xstrlen( lv_data_xstr ) 값을 그대로 사용.
DOC_TYPE 대소문자
TOADD 에 등록된 DOC_TYPE 은 대문자(PDF·XLSX). 파일명에서 추출한 소문자(pdf) 를 그대로 넘기면 매칭이 안 되어 거부됩니다. TRANSLATE ... TO UPPER CASE 필수.
OBJECT_ID 중복
같은 SAP_OBJECT × AR_OBJECT × OBJECT_ID 조합으로 두 번 호출하면 두 번째는 거부됩니다. 자동 채번 / GUID / PO + 순번 같이 항상 유일한 키를 보장.
" 중복 체크
SELECT SINGLE * FROM toa01
INTO @DATA(ls_dup)
WHERE sap_object = 'ZXXWEBGOS'
AND object_id = @lv_object_id
AND ar_object = 'ZXXWEB'.
IF sy-subrc = 0.
MESSAGE '동일한 OBJECT_ID 가 이미 존재합니다.' TYPE 'E'.
ENDIF.
사용자 취소 미처리
FILE_F4 직후 lv_xfile IS INITIAL 체크가 빠지면 UPLOAD_FILE 이 빈 경로로 호출되어 에러. 항상 다이얼로그 취소를 체크.
대용량 파일 메모리
XSTRING 으로 한 번에 메모리에 올리므로 100MB+ 대용량 파일은 SAP 서버 메모리 부담. 대용량 시나리오는 외부 RFC 청크 전송 패턴이 더 적합.
COMMIT WORK
ARCHIV_CREATE_TABLE 은 내부에서 update task 를 등록만 하고 실제 DB 반영은 호출자 LUW 의 COMMIT WORK 에서 처리됩니다. 화면 흐름 / 트랜잭션 종료 시점에 COMMIT WORK AND WAIT 가 호출되어야 TOA01 에 데이터가 남습니다.
바이러스 스캔 정책
VSCAN_PROFILE 기본값(/SCMS/KPRO_CREATE) 으로 백신 검사가 자동 동작. 사내 보안 정책에 따라 BLOCKED_BY_POLICY 예외 발생 가능 — 사용자에게 명확한 안내 메시지.
전체 코드 — 복사용 통합본
*&---------------------------------------------------------------------*
*& Report Z_XX_FILE_TO_TOA01
*&---------------------------------------------------------------------*
*& PC 파일을 사용자가 직접 선택해서 ArchiveLink (TOA01) 에 저장
*&---------------------------------------------------------------------*
REPORT z_xx_file_to_toa01.
PARAMETERS: p_obj TYPE saeobjid DEFAULT 'TEST-DOC-001',
p_arobj TYPE saeobjart DEFAULT 'ZXXWEB',
p_sapobj TYPE saeanwdid DEFAULT 'ZXXWEBGOS'.
START-OF-SELECTION.
DATA: lv_xfile TYPE string,
lv_data_xstr TYPE xstring,
lv_len TYPE i,
lt_solix TYPE solix_tab,
lt_bin_data TYPE TABLE OF tbl1024,
lv_filename TYPE string,
lv_extension TYPE string,
lv_type TYPE toadd-doc_type.
TRY.
" ★ 1) PC 파일 선택
cl_secxml_helper=>file_f4(
EXPORTING
initial_directory = ''
window_title = '첨부파일 선택'
IMPORTING
filename = lv_xfile ).
IF lv_xfile IS INITIAL.
WRITE: / '사용자가 취소했습니다.'.
RETURN.
ENDIF.
" ★ 2) PC → SAP (XSTRING)
cl_secxml_helper=>upload_file(
EXPORTING filename = lv_xfile
IMPORTING bindata = lv_data_xstr ).
CHECK lv_data_xstr IS NOT INITIAL.
" ★ 3) XSTRING → SOLIX 청크
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_data_xstr
IMPORTING
output_length = lv_len
TABLES
binary_tab = lt_solix.
" ★ 4) 파일명 + 확장자 분리
cl_bcs_utilities=>split_name(
EXPORTING
iv_name = lv_xfile
iv_delimiter = '.'
IMPORTING
ev_name = lv_filename
ev_extension = lv_extension ).
lv_type = lv_extension.
TRANSLATE lv_type TO UPPER CASE.
" 확장자 검증
SELECT COUNT(*) FROM toadd
WHERE doc_type = @lv_type.
IF sy-subrc <> 0.
MESSAGE |허용 안 된 확장자: { lv_type }| TYPE 'E'.
ENDIF.
" ★ OBJECT_ID 중복 체크
SELECT SINGLE * FROM toa01
INTO @DATA(ls_dup)
WHERE sap_object = @p_sapobj
AND object_id = @p_obj
AND ar_object = @p_arobj.
IF sy-subrc = 0.
MESSAGE '동일한 OBJECT_ID 가 이미 존재합니다.' TYPE 'E'.
ENDIF.
" ★ 5) SOLIX → TBL1024 변환
lt_bin_data = lt_solix. " 호환 대입 (불가능하면 LOOP 사용)
" ★ 6) ARCHIV_CREATE_TABLE 호출
CALL FUNCTION 'ARCHIV_CREATE_TABLE'
EXPORTING
ar_object = p_arobj
object_id = p_obj
sap_object = p_sapobj
flength = CONV sapb-length( lv_len )
doc_type = lv_type
TABLES
binarchivobject = lt_bin_data
EXCEPTIONS
error_archiv = 1
error_communicationtable = 2
error_connectiontable = 3
error_kernel = 4
error_parameter = 5
error_user_exit = 6
error_mandant = 7
blocked_by_policy = 8
OTHERS = 9.
IF sy-subrc <> 0.
ROLLBACK WORK.
MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ELSE.
COMMIT WORK AND WAIT.
MESSAGE |첨부파일 등록 완료: { lv_filename }.{ lv_extension }| TYPE 'S'.
ENDIF.
CATCH cx_root INTO DATA(lo_ex).
WRITE: / '에러:', lo_ex->get_text( ).
ENDTRY.
같이 보면 좋은 글:
- "ArchiveLink 첨부파일 업/다운로드 — ARCHIV_CREATE_TABLE · TOA01 · 외부 시스템 RFC 게이트웨이" — 외부 시스템 RFC 시나리오 짝꿍
- "CL_SECXML_HELPER 파일 업/다운로드 — FILE_F4 · UPLOAD_FILE · SAVE_FILE 3개 메소드" — XSTRING wrapper 의 더 자세한 사용
- "파일 업/다운로드 경로 자동 저장·복원 — file_open_dialog initial_directory + SPA/GPA 메모리 ID" — 사용자 경로 메모리 활용
- "CL_GOS_MANAGER 첨부파일 활용 — 자체 화면에 표준 GOS 서비스 끼우기" — SOFFCONT1 표준 첨부 메뉴
요약
| 단계 | API | 변환 |
|---|---|---|
| 1 | FILE_F4 |
PC → STRING (filename) |
| 2 | UPLOAD_FILE |
file → XSTRING |
| 3 | SCMS_XSTRING_TO_BINARY |
XSTRING → SOLIX_TAB + length |
| 4 | SPLIT_NAME |
파일명 + 확장자 분리 + 대문자 |
| 5 | SOLIX → TBL1024 | 호환 대입 / 명시 LOOP |
| 6 | ARCHIV_CREATE_TABLE |
TOA01 등록 + COMMIT WORK |
사용자가 SAP 화면에서 직접 PC 파일을 골라 ArchiveLink 에 저장하는 흐름은 PC → XSTRING → SOLIX → TBL1024 의 두 단계 binary 변환 만 정확히 처리하면 됩니다. CL_SECXML_HELPER 의 wrapper 로 파일 IO 를 간결하게, SCMS_XSTRING_TO_BINARY 로 청크 변환, SPLIT_NAME 으로 확장자 자동 추출 + 대문자 변환, 마지막에 ARCHIV_CREATE_TABLE 한 번 호출. RAW 타입 호환 / FLENGTH / DOC_TYPE 대문자 / OBJECT_ID 중복 / COMMIT 5가지 함정만 사전 차단하면 운영에서 안정적으로 동작합니다.
Disclaimer — 이 포스트는 실무 정리 노트를 바탕으로 AI 보조로 정리되었습니다. CL_SECXML_HELPER · SCMS_XSTRING_TO_BINARY · CL_BCS_UTILITIES · ARCHIV_CREATE_TABLE 메소드 시그니처는 SAP NetWeaver 표준(패키지 SAOP · SCMS · ECC 6.0 / S/4HANA on-premise) 기준이며, 사내 ArchiveLink Content Server 설정 · 백신 정책 · 권한 그룹 · 자체 BAdI 에 따라 일부 동작이 다를 수 있으니 운영 시스템 적용 전 개발·QA 환경에서 검증하시기 바랍니다. RAW 타입 호환 이슈는 SAP 릴리스 / 커널 패치에 따라 다를 수 있으므로 호환 대입이 실패하면 명시적 LOOP 변환으로 우회하시기 바랍니다.