cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Create GOS attachment from xstring document

Missschaaa
Participant
19,232

Hello everyone,

I'm now facing a problem which is well discussed here and in other forums. In spite of reading lots of tutorials, blogs and other questions here I was not able to solve it. I'm trying to upload a document (pdf, jpg, xlsx, docx) and attach it as GOS document to a business object. I'm doing this in FIORI app context so the uploaded file will imported to me as an xstring. So all I have to do is put this xstring into GOS document. I followed the guidelines here and tried it like this.

* Get folder id
  CALL FUNCTION 'SO_FOLDER_ROOT_ID_GET'
    EXPORTING
      region                = 'B'
    IMPORTING
      folder_id             = ls_fol_id
    EXCEPTIONS
      communication_failure = 1
      owner_not_exist       = 2
      system_failure        = 3
      x_error               = 4
      OTHERS                = 5.

* To get the extension from the file name
  IF iv_slug IS NOT INITIAL.
    SPLIT iv_slug AT '/' INTO lv_qmnum lv_file.
    CALL FUNCTION 'TRINT_FILE_GET_EXTENSION'
      EXPORTING
        filename  = lv_file
        uppercase = 'X'
      IMPORTING
        extension = lv_extensions.
  ENDIF.


* Transfer Importing Xstring to binary solix table
lt_solix = cl_bcs_convert=>xstring_to_solix( iv_xstring = is_media_resource-value ).

* Fill Doc Data
*  ls_doc_data-doc_size = XSTRLEN( is_media_resource-value ).
  ls_doc_data-obj_descr = 'TEST'.
  ls_doc_data-obj_name = lv_file.
  MOVE lv_extensions TO ld_doc_type.

  ls_object-objkey     =  lv_qmnum.
  ls_object-objtype    = 'BUS2038'.

* Create Document
  CALL FUNCTION 'SO_DOCUMENT_INSERT_API1'
    EXPORTING
      folder_id                  = ls_fol_id
      document_data              = ls_doc_data
      document_type              = ld_doc_type
    IMPORTING
      document_info              = ls_doc_info
    TABLES
      contents_hex               = lt_solix
    EXCEPTIONS
      folder_not_exist           = 1
      document_type_not_exist    = 2
      operation_no_authorization = 3
      parameter_error            = 4
      x_error                    = 5
      enqueue_error              = 6
      OTHERS                     = 7.

* To link the document attachment and business object
  IF sy-subrc = 0 AND ls_object-objkey IS NOT INITIAL.
    ls_object-instid  = lv_qmnum.
    ls_object-typeid  = 'BUS2038'.
    ls_object-catid   = 'BO'.
    ls_objtgt-instid =  ls_doc_info-doc_id.
    ls_objtgt-typeid  = 'MESSAGE'.
    ls_objtgt-catid   = 'BO'.

    TRY.
        cl_binary_relation=>create_link(
          EXPORTING
            is_object_a = ls_object
            is_object_b = ls_objtgt
            ip_reltype  = 'ATTA' ).
        COMMIT WORK AND WAIT.
      CATCH cx_obl_parameter_error cx_obl_model_error cx_obl_internal_error.
    ENDTRY.
  ENDIF.

Can anyone tell me what I did wrong? File gets transfered and uploaded correctly to business object, but when trying to open it, it only works for pdf files. All the other document types get opened with error that data is corrupt or document type gets not supported. Document type can not be the problem because I uploaded the files manually and can open them, so it must have to do with the creation here.

I tried several things, using the 'SO_OBJECT_INSERT' function instead, using the 'SCMS_XSTRING_TO_BINARY' function for convert instead, working with '&SO_FILENAME=' etc., working with document size. Nothing helped. Evertytime I got the same error when opening the uploaded document.

In some blogs it says that it has to do with SAP ECC 6 and unicode system that many user have problems, I have that too and dont know how to solve it. Maybe any ideas here?

Thanks a lot

Regards Michael

View Entire Topic
Sandra_Rossi
Active Contributor

Is it only due to lv_extensions to be 'EXT'. This works:

PARAMETERS file TYPE string LOWER CASE DEFAULT 'C:\Users\your.user\Documents\test.docx'.
PARAMETERS name TYPE string LOWER CASE DEFAULT 'test.docx'.
PARAMETERS instid TYPE string DEFAULT 'FR 1234567890'.
PARAMETERS typeid TYPE string DEFAULT 'BUS1011'.

START-OF-SELECTION.
  DATA xstring TYPE xstring.

  PERFORM read_bin_file USING file CHANGING xstring.

  DATA:
   lt_solix           TYPE solix_tab.
  DATA:
    ls_fol_id    TYPE soodk.
  
* Get folder id
  CALL FUNCTION 'SO_FOLDER_ROOT_ID_GET'
    EXPORTING
      region                = 'B'
    IMPORTING
      folder_id             = ls_fol_id
    EXCEPTIONS
      communication_failure = 1
      owner_not_exist       = 2
      system_failure        = 3
      x_error               = 4
      OTHERS                = 5.

* Transfer Importing Xstring to binary solix table
  lt_solix = cl_bcs_convert=>xstring_to_solix( iv_xstring = xstring ).

  DATA ls_doc_data LIKE sodocchgi1.
  DATA lv_extensions TYPE so_obj_tp.
  DATA ld_doc_type TYPE so_obj_tp.
  lv_extensions = 'EXT'.

* Fill Doc Data
  ls_doc_data-doc_size = xstrlen( xstring ).
  ls_doc_data-obj_descr = name.
  ls_doc_data-obj_name = name.
  MOVE lv_extensions TO ld_doc_type.

  DATA lt_header TYPE STANDARD TABLE OF solisti1.

  lt_header = VALUE #(
      ( |&SO_FILENAME={ name }| )
      ( |&SO_FORMAT=BIN | ) ).

* Create Document
  DATA ls_doc_info TYPE sofolenti1.
  CALL FUNCTION 'SO_DOCUMENT_INSERT_API1'
    EXPORTING
      folder_id                  = ls_fol_id
      document_data              = ls_doc_data
      document_type              = ld_doc_type
    IMPORTING
      document_info              = ls_doc_info
    TABLES
      object_header              = lt_header
      contents_hex               = lt_solix
    EXCEPTIONS
      folder_not_exist           = 1
      document_type_not_exist    = 2
      operation_no_authorization = 3
      parameter_error            = 4
      x_error                    = 5
      enqueue_error              = 6
      OTHERS                     = 7.

* To link the document attachment and business object
  IF sy-subrc = 0.

    DATA: ls_object TYPE sibflporb,
          ls_objtgt TYPE sibflporb.
    ls_object-instid  = instid.
    ls_object-typeid  = typeid.
    ls_object-catid   = 'BO'.
    ls_objtgt-instid =  ls_doc_info-doc_id.
    ls_objtgt-typeid  = 'MESSAGE'.
    ls_objtgt-catid   = 'BO'.

    TRY.
        cl_binary_relation=>create_link(
          EXPORTING
            is_object_a = ls_object
            is_object_b = ls_objtgt
            ip_reltype  = 'ATTA' ).
        COMMIT WORK AND WAIT.
      CATCH cx_obl_parameter_error cx_obl_model_error cx_obl_internal_error.
    ENDTRY.
  ENDIF.


FORM read_bin_file
      USING i_filename TYPE clike
      CHANGING e_file_xstring TYPE xstring.
  DATA l_filename TYPE string.
  DATA l_length TYPE i.
  DATA lt_x255 TYPE TABLE OF x255.
  l_filename = i_filename.
* Note: impossible de mettre dans une variable de type TABLE OF xstring sinon dump ASSIGN_TYPE_ILLEGAL_CAST
  CALL FUNCTION 'GUI_UPLOAD'
    EXPORTING
      filename   = l_filename
      filetype   = 'BIN'
    IMPORTING
      filelength = l_length
    TABLES
      data_tab   = lt_x255
    EXCEPTIONS
      OTHERS     = 17.
  IF sy-subrc = 0.
    CALL METHOD cl_swf_utl_convert_xstring=>table_to_xstring
      EXPORTING
        i_table  = lt_x255
        i_size   = l_length
      RECEIVING
        r_stream = e_file_xstring
      EXCEPTIONS
        OTHERS   = 3.
  ENDIF.
ENDFORM.                    "read_bin_file
Missschaaa
Participant
0 Likes

Hm did you tried it out for xlsx, docx and jpg format? I got the same error like before. But in my case I canot generate the xstring like that. It will send to me from fiori app in IS_MEDIA_RESOURCE parameter of CREATE_STREAM method. Its just an xstring but I do not have the filelength to put it in the conver method. Maybe thats the problem?

I think the problem is in this one

lt_solix = cl_bcs_convert=>xstring_to_solix( iv_xstring = is_media_resource-value ).

I tried three convertion methods and functions from xstring to binary solix. And got three different results of data in table lt_solix.

Sandra_Rossi
Active Contributor
0 Likes

You ran the program and it doesn't work for a valid .docx file stored on your laptop?

For me, it works for .docx. I don't see why it wouldn't work for .xlsx, .jpg.

If you receive a XSTRING, then you have the length implicitly (XSTRLEN).

Missschaaa
Participant
0 Likes

Yes, in the fiori app a nupload function should be implemented, so the gui part starts there. I can upload files there with browsing on my local pc and upload them. After uploading in the app the backend receives the XSTRING data. The interface between fiori app and SAP is the CREATE_STREAM method of the odata service. There I got the XSTRING in import parameter.

Sandra_Rossi
Active Contributor
0 Likes

If it works for a XSTRING uploaded from GUI, it will work for a XSTRING obtained from anywhere (provided it contains valid data of course).

Missschaaa
Participant
0 Likes

Does the xstring and the solix table has to look exactly the same for one file or does it look different for every upload? Then I can try upload it with GUI function and compare it with import from fiori app.

Sandra_Rossi
Active Contributor
0 Likes

A SOLIX table is a split of XSTRING into chunks of 255 bytes. I don't understand your question.

But your methodology is correct to test the XSTRING you receive from the Fiori app, put it onto your laptop, and upload it with my program.

Missschaaa
Participant

Funny, I tried out your program and it worked for me. Did some changes and in code and tried out several things. Without putting filelength it does not work. Without putting the lt_header parameter it says that file has to be corrected and if click on yes it looks good. With both parameter there are no problems.

When using the EXT file extension it leads to the "problem" that file will be downloaded when clicking on it and does not get opened directly from SAP window. So I also tried putting the XLS filename again and it also worked. So you are right the program works for me too even without EXT file ending.

So the only difference is the xstring. In your program it will be converted from upload file function. In my case I get it from FIORI app. Looks like it is not valid when getting it.