Im ABAP Kochbuch haben wir im Kapitel „GOS“ beschrieben, wie man eigene Objekte (in diesem Fall Tickets) an die GOS anbindet und es somit dem Anwender ermöglicht, Anhänge zu erfassen. Nicht behandelt hingegen wurde das Auslesen und Anlegen von GOS-Anhängen per Programm – was für den einen oder anderen Entwickler aber durchaus nützlich sein könnte. Um hier Abhilfe zu schaffen liefern wir die entsprechenden Informationen an dieser Stelle gerne nach.

Allgemeines

Wie im Buch-Kapitel bereits beschrieben hängen die GOS an Business-Objekten. Um die Anhänge zu einem Beleg oder Stammdatum auslesen zu können müssen also der Businessobjekttyp und der Aufbau des Schlüssels bekannt sein. Die eigentlichen GOS-Anhänge werden im SAP-System wie SAP-Office-Dokumente behandelt, d.h. die bekannten Funktionsbausteine mit dem Präfix SO_DOCUMENT* können zur Manipulation der Anhänge verwendet werden. Die Verknüpfung zum Business-Objekt ist in der Tabelle SRGBTBREL abgelegt. Aus Gründen der Release-Sicherheit empfehlen wir allerdings, Methoden zu verwenden, die von der Klasse CL_BINARY_RELATION zur Verfügung gestellt werden.

Auslesen von Anlagen

Kümmern wir uns nun zuerst um das Lesen von Anlagen. Die Verknüpfung des Businessobjekts zu den GOS-Anhängen kann über die Methode CL_BINARY_RELATION=>READ_LINKS_OF_BINRELS ausgelesen werden. Ergebnis ist eine Menge von Verknüpfungen zu Zieldokumenten. Deren Informationen und Inhalte werden dann mit dem Baustein SO_DOCUMENT_READ_API1 gelesen. Die genaue Verfahrensweise ist in dem folgenden Beispielreport beschrieben:

REPORT z_read_gos.
 
 TYPES
   : BEGIN OF gys_key
   ,   foltp TYPE so_fol_tp
   ,   folyr TYPE so_fol_yr
   ,   folno TYPE so_fol_no
   ,   objtp TYPE so_obj_tp
   ,   objyr TYPE so_obj_yr
   ,   objno TYPE so_obj_no
   ,   forwarder TYPE so_usr_nam
   , END OF gys_key
   .
 
 DATA
     " Schlüssel des Business-Objekts
   : gs_object   TYPE sibflporb
 
     " Verknüpfungen zum Objekt
   , gt_links    TYPE obl_t_link
   , gs_links    TYPE obl_s_link
 
     " Verknüpfungsoptionen
   , gt_relopt   TYPE obl_t_relt
   , gs_relopt   TYPE obl_s_relt
 
     " Schlüssel einer Verknüpfung
   , gs_key      TYPE gys_key
 
     " Dokumenten-ID
   , gd_doc_id   TYPE so_entryid
 
     " Dokumenten-Grunddaten
   , gs_doc_data TYPE sofolenti1
 
     " Dokumenteninhalt Text und Binär
   , gt_contx    TYPE solix_tab
   , gt_cont     TYPE soli_tab
   .
 
 PARAMETERS
     " Eingabefelder für die ID des Business-Objekts
   : p_instid    TYPE sibfboriid OBLIGATORY DEFAULT '000000000000001331'
   , p_typeid    TYPE sibftypeid OBLIGATORY DEFAULT 'BUS1001006'
   , p_catid     TYPE sibfcatid  OBLIGATORY DEFAULT 'BO'
   .
 
 START-OF-SELECTION.
 
   " Businessobjekt-ID übernehmen
   gs_object-instid  = p_instid.
   gs_object-typeid  = p_typeid.
   gs_object-catid   = p_catid.
 
   " Verknüpfungstypen:
   gs_relopt-sign = 'I'.
   gs_relopt-option = 'EQ'.
 
   " Anhänge
   gs_relopt-low = 'ATTA'.
   APPEND gs_relopt TO gt_relopt.
   " Notizen
   gs_relopt-low = 'NOTE'.
   APPEND gs_relopt TO gt_relopt.
   " URLs
   gs_relopt-low = 'URL'.
   APPEND gs_relopt TO gt_relopt.
 
   TRY.
       " Verknüpfungen zum Objekt lesen
       cl_binary_relation=>read_links_of_binrels(
         EXPORTING
           is_object           = gs_object
           it_relation_options = gt_relopt
           ip_role             = 'GOSAPPLOBJ'
         IMPORTING
           et_links            = gt_links ).
       LOOP AT gt_links INTO gs_links WHERE typeid_b = 'MESSAGE'.
         " Optional: Schlüsselkomponenten extrahieren
         gs_key = gs_links-instid_b.
         WRITE: / 'foltp', gs_key-foltp
              , / 'folyr', gs_key-folyr
              , / 'folno', gs_key-folno
              , / 'objtp', gs_key-objtp
              , / 'objyr', gs_key-objyr
              , / 'objno', gs_key-objno
              .
         " Die Dokumenten-ID für SAPOffice entspricht der ermittelten
         "   Instanz-ID
         gd_doc_id = gs_links-instid_b.
 
         " Dokumenteninhalte löschen
         CLEAR
           : gt_cont
           , gt_contx
           .
         " Dokument lesen
         CALL FUNCTION 'SO_DOCUMENT_READ_API1'
           EXPORTING
             document_id                = gd_doc_id
           IMPORTING
             document_data              = gs_doc_data
           TABLES
             object_content             = gt_cont
             contents_hex               = gt_contx
           EXCEPTIONS
             document_id_not_exist      = 1
             operation_no_authorization = 2
             x_error                    = 3
             OTHERS                     = 4.
         IF sy-subrc <> 0.
           " Fehlerbehandlung: Lesen des Dokuments
         ELSE.
           " Ausgabe einiger Kopfdaten
           WRITE: /  gs_doc_data-object_id
                ,    gs_doc_data-obj_type
                ,    gs_doc_data-obj_name
                ,    gs_doc_data-obj_descr
                .
         ENDIF.
         SKIP.
         IF NOT gt_cont[] IS INITIAL.
           " Es gibt Inhalt im Textformat
           WRITE: 7 'TXT'.
         ENDIF.
         IF NOT gt_contx[] IS INITIAL.
           " Es gibt Inhalt im Binärformat
           WRITE: 14 'BIN'.
         ENDIF.
       ENDLOOP.
 
     CATCH cx_obl_parameter_error cx_obl_internal_error cx_obl_model_error.
       " Fehlerbehandlung: Lesen der Verknüpfungen
   ENDTRY.

Mit den im Sourcecode angegebenen Beispielparametern werden die Anlagen zum Material mit der Nummer 1331 ausgelesen; das Businessobjekt „Material“ hat den Objekttyp „BUS1001006“, die Materialnummer liegt im internen Format vor (mit führenden Nullen). Ausgegeben werden hier lediglich einige Kopfdaten des Dokuments sowie die Information, welche Inhaltstabellen (Text / binär) gefüllt sind.

Neue Anlage zum Businessobjekt

Um eine neue Anlage zum Businessobjekt zu erfassen sind folgende Schritte notwendig:

  • Ermittlung des GOS-Verzeichnisses im SAP Office (FuBa SO_FOLDER_ROOT_ID_GET)
  • Erstellen des SAP Office Dokuments (FuBa SO_DOCUMENT_INSERT_API1)
  • Erstellen der Verknüpfung zum Businessobjekt (Methode CL_BINARY_RELATION=>CREATE_LINK)

Im folgenden Beispielreport wird eine Datei vom Frontend-Rechner geladen, diese als SAP Office Dokument eingecheckt und abschließend die Verknüpfung zum Businessobjekt hergestellt.

 REPORT z_create_gos.
 
 DATA
     " Ordner
   : gs_folder   TYPE soodk
 
     " Verknüpfung: Quelle & Ziel
   , gs_object   TYPE sibflporb
   , gs_objtgt   TYPE sibflporb
 
     " Dokumenten-Grunddaten
   , gs_doc_info TYPE sofolenti1
   , gs_doc_data TYPE sodocchgi1
   , gd_doc_type TYPE soodk-objtp
 
     " Dokumenteninhalt binär
   , gt_contx    TYPE solix_tab
 
     " Dateiinformationen
   , gd_file     TYPE string
   , gd_flen     TYPE i
   .
 PARAMETERS
     " Eingabefelder für die ID des Business-Objekts
   : p_instid    TYPE sibfboriid OBLIGATORY DEFAULT '000000000000001331'
   , p_typeid    TYPE sibftypeid OBLIGATORY DEFAULT 'BUS1001006'
   , p_catid     TYPE sibfcatid  OBLIGATORY DEFAULT 'BO'
     " Dateiname
   , p_file      TYPE fileextern OBLIGATORY VISIBLE LENGTH 40
   .
 
 START-OF-SELECTION.
 
   gd_file = p_file.
 
   " Datei hochladen
   CALL FUNCTION 'GUI_UPLOAD'
     EXPORTING
       filename   = gd_file
       filetype   = 'BIN'
     IMPORTING
       filelength = gd_flen
     TABLES
       data_tab   = gt_contx
     EXCEPTIONS
       OTHERS     = 1.
 
   IF sy-subrc <> 0.
     WRITE: / 'Dateifehler!'.
     STOP.
   ENDIF.
 
   " Root-Folder der GOS ermitteln
   CALL FUNCTION 'SO_FOLDER_ROOT_ID_GET'
     EXPORTING
       region    = 'B'
     IMPORTING
       folder_id = gs_folder.
 
   " Dateiinfo in Dokumenteninfo übernehmen
   CALL FUNCTION 'CH_SPLIT_FILENAME'
     EXPORTING
       complete_filename = gd_file
     IMPORTING
       extension         = gd_doc_type
       name              = gs_doc_data-obj_descr
       name_with_ext     = gs_doc_data-obj_name.
   TRANSLATE gd_doc_type TO UPPER CASE.
 
   gs_doc_data-doc_size = gd_flen.
 
   " Dokument anlegen
   CALL FUNCTION 'SO_DOCUMENT_INSERT_API1'
     EXPORTING
       folder_id     = gs_folder
       document_data = gs_doc_data
       document_type = gd_doc_type
     IMPORTING
       document_info = gs_doc_info
     TABLES
       contents_hex  = gt_contx.
 
   " Businessobjekt-ID übernehmen
   gs_object-instid  = p_instid.
   gs_object-typeid  = p_typeid.
   gs_object-catid   = p_catid.
 
   " Dokumentdaten als Ziel
   CONCATENATE gs_folder gs_doc_info-object_id 
      INTO gs_objtgt-instid RESPECTING BLANKS.
   " Alternative:
   " gs_objtgt-instid = gs_doc_info-doc_id.
   gs_objtgt-typeid  = 'MESSAGE'.
   gs_objtgt-catid   = 'BO'.
 
   TRY.
       " Verknüpfung anlegen
       cl_binary_relation=>create_link(
         EXPORTING
           is_object_a = gs_object
           is_object_b = gs_objtgt
           ip_reltype  = 'ATTA' ).
       COMMIT WORK AND WAIT.
     CATCH cx_obl_parameter_error cx_obl_model_error cx_obl_internal_error.
   ENDTRY.

Anmerkungen

Die Beispielcodings wurden in einem SAP System mit Releasestand ECC 6.0 geschrieben. Auf eine Fehlerbehandlung wurde weitestgehend verzichtet. Für die fehlerfreie Funktion kann keine Garantie gegeben werden.