본문 바로가기
ABAP 문법 & 기법

[SAP ABAP] SWU_OBJECT_PUBLISH ALV GOS 아이콘 만드는 방법 — 표준 첨부 메뉴 한 줄 등록 (BUS2012 · OAC0)

by Song.sh 2026. 5. 22.

ALV 리포트 화면에서 사용자가 어떤 행을 선택했을 때, 그 행에 연결된 첨부파일 / 노트 / 비즈니스 문서를 바로 볼 수 있게 하려면 SAP 표준 GOS 서비스를 ALV 의 시스템 메뉴에 등록 해야 합니다. 자체 Dynpro 화면에 Custom Container 를 그리고 CL_GOS_MANAGER 를 직접 인스턴스화하는 방법도 있지만, ALV 리포트처럼 이미 화면 프레임이 정해진 출력 화면 에서는 더 가벼운 방법이 있습니다.

 

표준 Function Module SWU_OBJECT_PUBLISH 를 호출하면 현재 LUW 의 ALV 화면 메뉴에 GOS 아이콘이 자동으로 추가 됩니다. ALV 의 표준 툴바 / 시스템 메뉴 어디에서도 클릭 가능한 GOS 서비스 메뉴가 펼쳐지며, 첨부파일 추가 · 조회 · 송신 등의 기능이 표준 ME23N 과 동일하게 동작합니다.

 

이 글에서는 SWU_OBJECT_PUBLISH 의 시그니처·OAC0/OAC3 저장소와의 관계·ALV 더블클릭 이벤트와 연동 패턴·다건 객체 등록·CL_GOS_MANAGER 와의 차이점까지 한 번에 정리합니다. ALV 조회 리포트에 첨부 기능을 가볍게 끼워 넣고 싶을 때 가장 빠른 도구입니다.

핵심 — SWU_OBJECT_PUBLISH vs CL_GOS_MANAGER

항목 SWU_OBJECT_PUBLISH (FM) CL_GOS_MANAGER (Class)
호출 방식 Function Module 한 줄 클래스 인스턴스 생성
적합 시나리오 ALV 조회 리포트 · 표준 메뉴 등록 자체 Dynpro · Custom Container
컨테이너 필요 여부 불필요 (표준 메뉴 자동 등록) 필수 (CL_GUI_CUSTOM_CONTAINER)
다건 객체 등록 반복 호출 (각 행마다) SET_ID_OF_PUBLISHED_OBJECT 로 전환
코드 라인 수 5~10줄 20~30줄 (PBO/PAI 포함)

선택 기준: ALV 조회 위주 + 표준 메뉴에서 GOS 접근 이면 SWU_OBJECT_PUBLISH, 자체 Dynpro + 화면 영역에 GOS 아이콘 직접 배치 면 CL_GOS_MANAGER. 두 방식 모두 내부적으로 같은 GOS 백엔드(SRGBRBREL) 를 사용하므로 첨부 결과는 동일합니다.


1단계 — 시그니처 확인

구분 파라미터 의미
IMPORTING OBJTYPE BOR 객체 유형 (예: BUS2012) 또는 OAC0 저장소명
IMPORTING OBJKEY 객체 키 값 (PO 번호 · 자재문서 등)
IMPORTING CREATOR (Opt) 첨부 생성자 (기본 = 로그인 사용자)
IMPORTING METHOD (Opt) 기본 동작 메소드 (특수 시나리오만 사용)
IMPORTING MODE (Opt, 기본 'E') 'E' Edit / 'A' Display
TABLES CONTAINER (Opt) 컨텍스트 데이터 (워크플로우 연동 시)

리턴 — 함수 호출 자체로 GOS 등록이 끝납니다. 호출자가 별도 객체 / 메모리를 관리할 필요가 없습니다.


2단계 — OBJTYPE 결정 — BOR 객체 vs OAC0 저장소

표준 BOR 객체 사용 (가장 흔함):

" PO 4500000001 에 GOS 아이콘 등록
CALL FUNCTION 'SWU_OBJECT_PUBLISH'
  EXPORTING
    objtype = 'BUS2012'                " 표준 PO BOR 객체
    objkey  = '4500000001'
    mode    = 'A'                      " 조회 모드
  EXCEPTIONS
    objtype_not_found = 1.

OAC0 저장소 사용 (회사 자체 객체 + DMS 저장소):

T-Code: OAC0
 → 저장소 정의 (Content Repository)
 → 또는 Document type 매핑

T-Code: OAC3
 → Workflow Object Repository Browser
 → BOR 객체 ↔ 저장소 매핑

자체 Z 객체에 첨부를 붙이려면 BOR 객체를 신규 정의(SWO1) 하거나 OAC0/OAC3 으로 저장소를 등록한 후 그 이름을 OBJTYPE 에 전달합니다.

자주 쓰는 BOR 객체 매핑:

OBJTYPE 대상 OBJKEY 예시
BUS2012 구매오더 4500000001
BUS2081 송장 51000000012026
BUS2017 자재문서 MBLNR + MJAHR
BUS1001 · MARA 자재 마스터 MATNR

3단계 — ALV 더블 클릭 이벤트와 연동

ALV 의 표준 더블 클릭 이벤트(DOUBLE_CLICK) 에서 SWU_OBJECT_PUBLISH 를 호출하면 사용자가 더블 클릭한 행의 객체를 GOS 에 즉시 등록.

" ALV 더블 클릭 핸들러
METHOD on_double_click.

  DATA: ls_data TYPE ty_alv_data.

  " 1) 더블 클릭한 행의 데이터 가져오기
  READ TABLE gt_alv_data INTO ls_data INDEX e_row-index.
  CHECK sy-subrc = 0.

  " 2) GOS 등록 — 그 행의 PO 번호를 객체로
  CALL FUNCTION 'SWU_OBJECT_PUBLISH'
    EXPORTING
      objtype = 'BUS2012'
      objkey  = ls_data-ebeln
      mode    = 'A'                    " 조회 모드
    EXCEPTIONS
      objtype_not_found = 1.

ENDMETHOD.

호출 후 사용자가 ALV 상단 메뉴 → System → Services for Object 를 누르면 그 PO 에 연결된 첨부 / 노트 / 송신 메뉴가 나타납니다. 사용자가 행을 더블 클릭할 때마다 다른 PO 가 GOS 에 활성 으로 등록됩니다.


4단계 — INITIALIZATION 시점 등록 (단일 객체 시나리오)

리포트가 단일 객체(예: 특정 PO 한 건의 상세) 만 다루면 INITIALIZATION / START-OF-SELECTION 에서 한 번만 등록.

START-OF-SELECTION.

  " 단일 PO 의 GOS 메뉴 활성화
  CALL FUNCTION 'SWU_OBJECT_PUBLISH'
    EXPORTING
      objtype = 'BUS2012'
      objkey  = p_ebeln                " Selection screen 파라미터
      mode    = 'E'                    " 변경 가능
    EXCEPTIONS
      objtype_not_found = 1.

  " ALV 출력 ...

이 패턴에서는 ALV 전체에 하나의 객체가 항상 활성. 화면 시작부터 끝까지 GOS 메뉴를 통해 같은 PO 의 첨부 / 노트를 다룰 수 있습니다.


5단계 — 변경 모드 (편집) 활용

조회 ALV 는 MODE = 'A' 가 일반적이지만, 사용자가 ALV 에서 직접 첨부를 올리는 시나리오라면 'E' 로 전환.

CALL FUNCTION 'SWU_OBJECT_PUBLISH'
  EXPORTING
    objtype = 'BUS2012'
    objkey  = p_ebeln
    mode    = 'E'                      " 첨부 추가 / 삭제 가능
  EXCEPTIONS
    objtype_not_found = 1.

권한 그룹에 따라 동적 분기:

DATA lv_mode TYPE sgs_rwmod.

AUTHORITY-CHECK OBJECT 'Z_GOS_ATTACH'
  ID 'ACTVT' FIELD '02'.                " 02 = Change

IF sy-subrc = 0.
  lv_mode = 'E'.
ELSE.
  lv_mode = 'A'.
ENDIF.

CALL FUNCTION 'SWU_OBJECT_PUBLISH'
  EXPORTING
    objtype = 'BUS2012'
    objkey  = p_ebeln
    mode    = lv_mode
  EXCEPTIONS
    objtype_not_found = 1.

6단계 — 첨부 유무 표시 (ALV 컬럼 + 아이콘)

ALV 행마다 첨부 유무를 컬럼에 표시하려면 SRGBRBREL 을 한 번에 조회한 후 아이콘 컬럼을 채웁니다.

" 1) 모든 행의 첨부 유무 한 번에 조회 (대용량 권장)
SELECT instid_a
  INTO TABLE @DATA(lt_atta_keys)
  FROM srgbrbrel
 FOR ALL ENTRIES IN @gt_alv_data
 WHERE instid_a = @gt_alv_data-ebeln
   AND typeid_a = 'BUS2012'
   AND catid_a  = 'BO'
   AND reltype  = 'ATTA'.

" 2) ALV 데이터에 아이콘 컬럼 채움
LOOP AT gt_alv_data ASSIGNING FIELD-SYMBOL(<ls_alv>).
  READ TABLE lt_atta_keys WITH KEY instid_a = <ls_alv>-ebeln
                          TRANSPORTING NO FIELDS.
  IF sy-subrc = 0.
    <ls_alv>-atta_icon = '@4P@'.        " 클립 아이콘 (예시)
  ELSE.
    <ls_alv>-atta_icon = ''.
  ENDIF.
ENDLOOP.

ALV 의 Field Catalog 에서 icon = 'X' 로 표시하면 아이콘이 렌더링됩니다. 사용자는 첨부 유무를 한눈에 보고 그 행만 더블 클릭해서 첨부 메뉴를 활성화할 수 있습니다.


흔히 빠뜨리는 함정

OBJTYPE 잘못 입력

존재하지 않는 BOR 객체를 OBJTYPE 에 넘기면 OBJTYPE_NOT_FOUND 예외 발생. 표준 BOR 객체명(BUS*) 또는 OAC3 에서 정의된 저장소명을 정확히 사용.

OBJKEY 길이 / 자리수

OBJKEY 는 BOR 객체별로 정해진 자리수가 있습니다. PO 는 10자리, 자재문서는 MBLNR(10) + MJAHR(4) = 14자리. 자리수 맞추지 않으면 GOS 가 객체를 찾지 못해 첨부 메뉴가 비어 있습니다.

ALV 더블 클릭마다 누적 등록

ALV 더블 클릭 이벤트에서 SWU_OBJECT_PUBLISH 를 호출하면 새 객체로 갱신되는데, 이전 객체도 메모리에 누적될 수 있습니다. 다건 시나리오에서는 첫 번째 호출 후 UNPUBLISH 단계를 명시적으로 처리하지 않아도 SAP 가 새 객체로 전환해 줍니다.

권한 / Authorization 차이

SAP 가 BOR 객체별로 표준 권한 체크를 합니다. 사용자가 PO 조회 권한은 있어도 첨부 추가 권한(S_BDS_FOLD·S_DOKU_AUT) 이 없으면 첨부 추가가 거부됩니다.

MODE 'E' 인데 ALV 가 ReadOnly

SWU_OBJECT_PUBLISH 가 'E' 모드로 등록돼도 ALV 자체가 ReadOnly 라면 헷갈릴 수 있습니다. ALV 의 행 변경과 GOS 첨부는 별개 흐름이므로 GOS 만 변경 모드로 두는 것은 정상.

Container 파라미터의 용도

CONTAINER 는 워크플로우 컨테이너 데이터 전달용입니다. 일반 첨부 시나리오에서는 비워두면 됩니다. SAP 워크플로우 / 이벤트 트리거 사용 시에만 채움.

첨부 후 화면 갱신

SWU_OBJECT_PUBLISH 호출 직후에는 GOS 메뉴가 즉시 활성화되지 않을 수 있습니다. ALV 의 PBO 가 다시 그려진 후에 메뉴가 갱신되므로 사용자에게 안내 메시지 + Enter 한 번 누르도록 가이드.

Z 객체 / 자체 BOR

회사 자체 객체에 첨부를 붙이려면 SWO1 으로 BOR 객체를 신규 정의하고 그 객체 타입을 SWU_OBJECT_PUBLISH 에 넘깁니다. 단순 ZAP* T-Code 만 만들고 표준 BUS2012 같은 BOR 만 호출하면 회사 객체 데이터에 첨부가 매핑되지 않습니다.


전체 코드 — 복사용 통합본 (ALV + 더블클릭 + GOS)

*&---------------------------------------------------------------------*
*& Report  Z_XX_GOS_ALV_DEMO
*&---------------------------------------------------------------------*
*& ALV 리포트 + 더블클릭으로 GOS 첨부 메뉴 등록
*&---------------------------------------------------------------------*
REPORT z_xx_gos_alv_demo.

TYPES: BEGIN OF ty_alv_data,
         atta_icon TYPE icon_d,
         ebeln     TYPE ekko-ebeln,
         bukrs     TYPE ekko-bukrs,
         lifnr     TYPE ekko-lifnr,
         bsart     TYPE ekko-bsart,
         aedat     TYPE ekko-aedat,
       END OF ty_alv_data.

DATA: gt_alv_data TYPE TABLE OF ty_alv_data,
      go_alv      TYPE REF TO cl_salv_table.

PARAMETERS: p_bukrs TYPE ekko-bukrs OBLIGATORY DEFAULT '1000'.

*---------------------------------------------------------------------*
*  Event Handler
*---------------------------------------------------------------------*
CLASS lcl_handler DEFINITION.
  PUBLIC SECTION.
    METHODS on_double_click
      FOR EVENT double_click OF cl_salv_events_table
      IMPORTING row column.
ENDCLASS.

CLASS lcl_handler IMPLEMENTATION.
  METHOD on_double_click.

    DATA ls_data TYPE ty_alv_data.

    " ★ 더블클릭한 행 데이터 추출
    READ TABLE gt_alv_data INTO ls_data INDEX row.
    CHECK sy-subrc = 0.

    " ★ 그 PO 를 GOS 객체로 등록
    CALL FUNCTION 'SWU_OBJECT_PUBLISH'
      EXPORTING
        objtype = 'BUS2012'
        objkey  = ls_data-ebeln
        mode    = 'A'
      EXCEPTIONS
        objtype_not_found = 1.

    IF sy-subrc <> 0.
      MESSAGE 'GOS 객체 등록 실패' TYPE 'I' DISPLAY LIKE 'E'.
    ELSE.
      MESSAGE |GOS 메뉴 활성화: { ls_data-ebeln }. System → Services for Object 확인| TYPE 'S'.
    ENDIF.

  ENDMETHOD.
ENDCLASS.

*---------------------------------------------------------------------*
*  Main
*---------------------------------------------------------------------*
START-OF-SELECTION.

  " 1) 데이터 조회
  SELECT ebeln, bukrs, lifnr, bsart, aedat
    FROM ekko
    INTO TABLE @DATA(lt_po)
   WHERE bukrs = @p_bukrs
   UP TO 200 ROWS.

  " 2) ALV 데이터로 변환
  gt_alv_data = VALUE #(
    FOR ls_po IN lt_po
      ( ebeln = ls_po-ebeln
        bukrs = ls_po-bukrs
        lifnr = ls_po-lifnr
        bsart = ls_po-bsart
        aedat = ls_po-aedat ) ).

  " 3) 첨부 유무 일괄 조회
  IF gt_alv_data IS NOT INITIAL.
    SELECT instid_a
      INTO TABLE @DATA(lt_atta_keys)
      FROM srgbrbrel
     FOR ALL ENTRIES IN @gt_alv_data
     WHERE instid_a = @gt_alv_data-ebeln
       AND typeid_a = 'BUS2012'
       AND catid_a  = 'BO'
       AND reltype  = 'ATTA'.

    LOOP AT gt_alv_data ASSIGNING FIELD-SYMBOL(<ls_alv>).
      READ TABLE lt_atta_keys WITH KEY instid_a = <ls_alv>-ebeln
                              TRANSPORTING NO FIELDS.
      IF sy-subrc = 0.
        <ls_alv>-atta_icon = '@4P@'.
      ENDIF.
    ENDLOOP.
  ENDIF.

  " 4) ALV 표시
  cl_salv_table=>factory(
    IMPORTING r_salv_table = go_alv
    CHANGING  t_table      = gt_alv_data ).

  " 5) 더블클릭 이벤트 등록
  DATA(lo_events) = go_alv->get_event( ).
  DATA(lo_handler) = NEW lcl_handler( ).
  SET HANDLER lo_handler->on_double_click FOR lo_events.

  " 6) 출력
  go_alv->display( ).

같이 보면 좋은 글:

  • "CL_GOS_MANAGER 첨부파일 활용 — 자체 화면에 표준 GOS 서비스 끼우기" — 자체 Dynpro 시나리오용 짝꿍 글
  • "BAPI_PO_CREATE1 — 구매오더 생성 BAPI 호출 방법" — PO 생성 후 GOS 자동 등록 흐름
  • "BAdI 찾는 방법 5가지 — CL_EXITHANDLER 디버깅·SE84·SXS_ATTR 메타테이블" — 첨부 BAdI 확장 시 활용

요약

단계 하는 일 핵심 포인트
1 OBJTYPE 결정 표준 BOR (BUS2012) 또는 OAC0 저장소
2 OBJKEY 자리수 맞춤 PO 10자리 · 자재문서 14자리 등
3 MODE 결정 'A' 조회 / 'E' 편집
4 호출 시점 선택 단일 객체 → START-OF-SELECTION / 다건 → ALV 더블클릭
5 첨부 유무 표시 SRGBRBREL FAE 일괄 조회 + 아이콘 컬럼
6 사용자 안내 System → Services for Object 위치 안내

SWU_OBJECT_PUBLISH 는 ALV 리포트에 표준 GOS 첨부 메뉴를 가장 가볍게 끼워 넣는 도구입니다. OBJTYPE + OBJKEY + MODE 3개만 정확히 채우면 호출 한 번으로 ALV 의 시스템 서비스 메뉴에 GOS 가 자동 등록됩니다.

다건 시나리오는 더블클릭 이벤트에서 각 행마다 재호출, 단일 객체는 START-OF-SELECTION 에서 한 번만. 자체 Dynpro 화면에 GOS 아이콘을 직접 박을 때는 CL_GOS_MANAGER 가 더 적합하고, ALV 조회 + 메뉴 통합에는 이 FM 이 더 가볍습니다.


Disclaimer — 이 포스트는 실무 정리 노트를 바탕으로 AI 보조로 정리되었습니다.

SWU_OBJECT_PUBLISH Function Module 시그니처 · SRGBRBREL 테이블 · BOR 객체(BUS2012 등) 동작은 SAP NetWeaver 표준(패키지 SWUG / SGOS · ECC 6.0 / S/4HANA on-premise) 기준이며, Z 자체 BOR 객체 · OAC0/OAC3 저장소 설정 · 권한 그룹에 따라 일부 동작이 다를 수 있으니 운영 시스템 적용 전 개발·QA 환경에서 검증하시기 바랍니다.