quarta-feira, 26 de outubro de 2022

Salvando arquivos utilizando o GOS - Business document

Utilizado para salvar um anexo dentro de uma integração PI/PO.

Criei um programa teste baseado nesse link

https://sapintegrationhub.com/abap/attach-any-file-sap-business-document-gos/

O programa basicamente seleciona um arquivo qualquer no PC e grava no formato GOS, no caso da integração é so pular alguns passos, já que o anexo em si já vem em formato binário X64.

Incluí nesse programa a rotina de gravar e de importar o arquivo do GOS.

Arquivos gravados podem ser consultados na tabela SOOD somente dados de informação 

Imaginei que teria que criar um objeto(BO) na transação SWO1 mas não é necessário, fiz um teste criando no objeto VBRK mesmo para ver. no meu caso vou usar o objeto VBAK vc pode consultar na tabela TOBJB

**** INCLUDE ZSZKF01 **

*&---------------------------------------------------------------------*
*& Include          ZSZKF01
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Include          ZATTACH_FILE_FORMS
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Form OPEN_FILE_DIALOG
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM open_file_dialog USING p_path.
  DATA: ls_file_table LIKE LINE OF gt_file_table,
        lv_rc         TYPE i.
  CLEAR p_path.
  REFRESH: gt_file_table.
  CALL METHOD cl_gui_frontend_services=>file_open_dialog
    EXPORTING
      window_title     = 'Select File'
      default_filename = '*.pdf'
      multiselection   = 'X'
    CHANGING
      file_table       = gt_file_table
      rc               = lv_rc.
  READ TABLE gt_file_table INDEX 1 INTO ls_file_table.
  p_path = ls_file_table-filename.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form UPLOAD_FILE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM upload_file USING p_path.
  DATA:    lv_len TYPE i.
  CALL FUNCTION 'GUI_UPLOAD'
    EXPORTING
      filename   = p_path
      filetype   = 'BIN'
    IMPORTING
      filelength = lv_len
    TABLES
      data_tab   = gt_content.
  PERFORM exception.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form CONVERT_TO_BIN
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM convert_to_bin .

  CALL FUNCTION 'SO_CONVERT_CONTENTS_BIN'
    EXPORTING
      it_contents_bin = gt_content[]
    IMPORTING
      et_contents_bin = gt_content[].
  PERFORM exception.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_FOLDER_ROOT_ID
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM get_folder_root_id .
  CALL FUNCTION 'SO_FOLDER_ROOT_ID_GET'
    EXPORTING
      region    = 'B'
    IMPORTING
      folder_id = gs_fol_id
    EXCEPTIONS
      OTHERS    = 1.
  PERFORM exception.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form SAP_OFFICE_OBJECT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM sap_office_object USING p_vbeln.
  DATA:
    ls_obj_data TYPE sood1,
    lt_objhead  TYPE STANDARD TABLE OF soli.

  ls_obj_data-objsns   = 'O'.
  ls_obj_data-objla    = sy-langu.
  ls_obj_data-objdes   = gv_fname.
  ls_obj_data-file_ext = gv_ext.
  ls_obj_data-objlen   = lines( gt_content ) * 255.
  CONDENSE ls_obj_data-objlen.
  CALL FUNCTION 'SO_OBJECT_INSERT'
    EXPORTING
      folder_id             = gs_fol_id
      object_type           = 'EXT'
      object_hd_change      = ls_obj_data
    IMPORTING
      object_id             = gs_obj_id
    TABLES
      objhead               = lt_objhead
      objcont               = gt_content
    EXCEPTIONS
      active_user_not_exist = 35
      folder_not_exist      = 6
      object_type_not_exist = 17
      owner_not_exist       = 22
      parameter_error       = 23
      OTHERS                = 1000.
  PERFORM exception.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form CREATE_BINARY_RELATION
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM create_binary_relation USING p_vbeln p_botype.
  DATA:
    ls_folmem_k TYPE sofmk,
    ls_note     TYPE borident,
    lv_ep_note  TYPE borident-objkey,
    ls_object   TYPE borident.
  ls_object-objkey = p_vbeln.
  ls_object-objtype = p_botype.
  ls_note-objtype   = 'MESSAGE'.
  CONCATENATE gs_fol_id-objtp gs_fol_id-objyr gs_fol_id-objno gs_obj_id-objtp gs_obj_id-objyr gs_obj_id-objno INTO ls_note-objkey.
  CALL FUNCTION 'BINARY_RELATION_CREATE_COMMIT'
    EXPORTING
      obj_rolea    = ls_object
      obj_roleb    = ls_note
      relationtype = 'ATTA'
    EXCEPTIONS
      OTHERS       = 1.
  PERFORM exception.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form SPLIT_FILE_PATH
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> P_PATH
*&      --> P_EXT
*&      --> P_FNAME
*&---------------------------------------------------------------------*
FORM split_file_path  USING    p_path.
  DATA: lv_filename TYPE pcfile-path.
  CHECK p_path IS NOT INITIAL.
  lv_filename = p_path.
  CALL FUNCTION 'PC_SPLIT_COMPLETE_FILENAME'
    EXPORTING
      complete_filename = lv_filename
*     CHECK_DOS_FORMAT  =
    IMPORTING
*     DRIVE             =
      extension         = gv_ext
*     NAME              =
      name_with_ext     = gv_fname
*     PATH              =
    EXCEPTIONS
      invalid_drive     = 1
      invalid_extension = 2
      invalid_name      = 3
      invalid_path      = 4
      OTHERS            = 5.
  PERFORM exception.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form EXCEPTION
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM exception .
  IF sy-subrc <> 0.
    MESSAGE ID     sy-msgid
          TYPE   sy-msgty
          NUMBER sy-msgno
          WITH   sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form import_gos
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM import_gos USING p_key p_path p_botype.

  DATA : wa_object       TYPE sibflporb,
         int_rel_options TYPE obl_t_relt,
         wa_rel_options  TYPE obl_s_relt,
         int_links       TYPE obl_t_link,
         wa_links        TYPE obl_s_link.
  wa_rel_options-low = 'ATTA'. "" Attachemnts
  wa_rel_options-sign = 'I'.
  wa_rel_options-option = 'EQ'.
  APPEND wa_rel_options TO int_rel_options.
  wa_object-instid = p_key.
  wa_object-typeid = p_botype. "" PR
  wa_object-catid  = 'BO'. "" Business Object
  REFRESH int_links[].
  TRY.
      CALL METHOD cl_binary_relation=>read_links_of_binrels
        EXPORTING
          is_object           = wa_object          " Start object
          it_relation_options = int_rel_options    " Link Types
          ip_role             = 'GOSAPPLOBJ'       " Role type
        IMPORTING
          et_links            = int_links.         " Table with Relationship Records
    CATCH cx_obl_parameter_error. " Incorrect Calling of Interface
    CATCH cx_obl_internal_error.  " Internal Error of Relationship Service
    CATCH cx_obl_model_error.     " Error with Model Roles
  ENDTRY.


  DATA : lv_doc_id      TYPE sofolenti1-doc_id,
         int_cont_bin   TYPE TABLE OF solisti1,
         int_cont_solix TYPE TABLE OF solix,
         wa_doc_data    TYPE sofolenti1.
  LOOP AT int_links INTO wa_links.
    lv_doc_id = wa_links-instid_b.
    REFRESH int_cont_bin[].
    REFRESH int_cont_solix[].
    CALL FUNCTION 'SO_DOCUMENT_READ_API1'
      EXPORTING
        document_id                = lv_doc_id
      IMPORTING
        document_data              = wa_doc_data
      TABLES
        contents_hex               = int_cont_solix
        object_content             = int_cont_bin
      EXCEPTIONS
        document_id_not_exist      = 1
        operation_no_authorization = 2
        x_error                    = 3
        OTHERS                     = 4.
    IF sy-subrc <> 0.
* Implement suitable error handling here
    ENDIF.

    DATA: lv_lines    TYPE char20,
          lv_doc_size TYPE i,
          lv_xstring  TYPE xstring.
    IF int_cont_solix IS NOT INITIAL.
      IF wa_doc_data-obj_type = 'TXT'.
        lv_lines = lines( int_cont_solix ) * 255.
        SHIFT lv_lines LEFT DELETING LEADING ' '.
        lv_doc_size = lv_lines.
      ENDIF.
      "" Convert the binary data to Xstring
      CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
        EXPORTING
          input_length = lv_doc_size
        IMPORTING
          buffer       = lv_xstring
        TABLES
          binary_tab   = int_cont_solix
        EXCEPTIONS
          failed       = 1
          OTHERS       = 2.
      IF sy-subrc <> 0.
* Implement suitable error handling here
      ENDIF.
    ELSE.
      CALL FUNCTION 'SO_SOLITAB_TO_SOLIXTAB'
        EXPORTING
          ip_solitab  = int_cont_bin
        IMPORTING
          ep_solixtab = int_cont_solix.
*
      IF wa_doc_data-obj_type = 'TXT'.
        lv_lines = lines( int_cont_solix ) * 255.
        SHIFT lv_lines LEFT DELETING LEADING ' '.
        lv_doc_size = lv_lines.
      ENDIF.
*
      "" Convert the binary data to Xstring
      CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
        EXPORTING
          input_length = lv_doc_size
        IMPORTING
          buffer       = lv_xstring
        TABLES
          binary_tab   = int_cont_solix
        EXCEPTIONS
          failed       = 1
          OTHERS       = 2.
      IF sy-subrc <> 0.
* Implement suitable error handling here
      ENDIF.
      DATA:    lv_len TYPE i.
    ENDIF.
      data l_filename type string.
      CONCATENATE P_PATH wa_doc_data INTO l_filename SEPARATED BY '\'.
      CALL FUNCTION 'GUI_DOWNLOAD'
        EXPORTING
*         BIN_FILESIZE                    =
          filename = l_filename
          filetype = 'BIN'
*         APPEND   = ' '
*         WRITE_FIELD_SEPARATOR           = ' '
*   IMPORTING
*         FILELENGTH                      =
        TABLES
          data_tab = int_cont_solix.

  ENDLOOP.
ENDFORM.

******* PROGRAMA ZSZK

REPORT zszk.

DATA: gt_file_table TYPE filetable,   "Uploaded file information
      gt_content    TYPE soli_tab,    "Uploaded files content
      gs_fol_id     TYPE soodk,       "Folder ID
      gs_obj_id     TYPE soodk.       "Object ID
DATA: gv_ext   TYPE sood1-file_ext,   "File extension
      gv_fname TYPE sood1-objdes.     "File name
INCLUDE zszkf01.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
  PARAMETERS: p_path  TYPE string OBLIGATORY.                    "File path
SELECTION-SCREEN END OF BLOCK b1.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-002.
  PARAMETERS: p_botype TYPE tojtb-name OBLIGATORY DEFAULT 'ZSZK', "Business obj type
              "p_doc_no TYPE vbeln OBLIGATORY.     "Business document number
              p_key    LIKE swotobjid-objkey,
              p_imp    AS CHECKBOX.
SELECTION-SCREEN END OF BLOCK b2.

INITIALIZATION.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_path.
  PERFORM open_file_dialog USING p_path.            "Open file upload dialog box

START-OF-SELECTION.
  IF p_imp IS INITIAL.
    PERFORM upload_file USING p_path.                  "Upload file
    PERFORM convert_to_bin.                      "Convert file content to BIN
    PERFORM get_folder_root_id.                  "Get folder ID
    PERFORM split_file_path USING p_path.         "Find file extension and file name
    PERFORM sap_office_object USING p_KEY.          "Create SAP office object
    PERFORM create_binary_relation USING p_KEY p_botype. "Link office object and ment
  ELSE.
    PERFORM import_gos USING p_key p_path p_botype.
  ENDIF.