INTRODUCTION: In this blog post, we will learn how to convert a GOS attachment to xstring and vice versa. What is GOS: The GOS is a toolbar that provides different functions such as adding an attachment, creating a document link, displaying all the attachments etc. The attachments are not generic for that transaction but are specific for a particular SAP object. Eg: See the screenshot below to know where is GOS toolbar located. GOS toolbar is highlighted. Here we are taking ME21N as reference. Part 1: Convert a GOS Attachment to xstring. Part 2: Attach a document to GOS using xstring. PART – 1: CONVERT A GOS ATTACHMENT TO XSTRING MAIN PART: We are going to read the GOS attachments from a purchase requisition and convert it to xstring. Let’s understand this process from below steps: 1. Generate relationship records for the attachments of PR. (Business object type – BUS2105 can be obtained from TCODE: SWO2 ) –> Check below screenshots to know how to get BO type of an SAP object from SWO2 (here we are seeing for PR) Path: SWO2 –> Material Management –> Purchasing –> PurchaseRequisition –> Passes to –> Req_overall –>Double click on Req_Overall –>Go inside any method or event to get BO Type 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 = wa_pr_list-banfn. (This is the PR number) wa_object-typeid = 'BUS2105'. "" 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. 2. Loop at links table to get the binary content of the attachments 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. 3. To convert binary data to xstring using FM SCMS_BINARY_TO_XSTRING. –> Check whether int_cont_solix table is filled or not. NOTE: For text document type ( wa_doc_data-obj_type) doesnt give you proper document size, hence multiply lines of int_cont_solix table with 255 to get correct size of text document. For other document types ( Excel, Word, Image, PDF) you can consider value of variable (wa_doc_data-obj_type) as document size. 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. –> If not convert (int_cont_bin) table to (int_cont_solix) using FM SO_SOLITAB_TO_SOLIXTAB to get document size. 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. * ENDIF. ENDLOOP. PART 2: ATTACH A DOCUMENT TO GOS USING XSTRING MAIN PART: We are going to create an attachment using the xstring we have and attach it to any business object (Purchase order in this case) Let’s understand this process from below steps: 1. Get the values of xstring from your ztable. ( Here it_attach is our internal table containing values of xstring.) DATA lv_extensions TYPE char10. DATA lv_file TYPE string. LOOP AT it_attach INTO wa_attach WHERE po_number = wa_item1-po_number AND status IS INITIAL . SPLIT wa_attach-po_att_name AT '.' INTO lv_file lv_extensions. CALL FUNCTION 'SO_FOLDER_ROOT_ID_GET' EXPORTING region = c_b IMPORTING folder_id = wa_fol_id EXCEPTIONS communication_failure = 1 owner_not_exist = 2 system_failure = 3 x_error = 4 OTHERS = 5. Using FM SCMS_XSTRING_TO_BINARY convert the xstring values from internal table to binary content. DATA : lv_solix_length TYPE i, it_content TYPE solix_tab."content OF FILE STORAGE CALL FUNCTION 'SCMS_XSTRING_TO_BINARY' EXPORTING buffer = wa_attach-po_att IMPORTING output_length = lv_solix_length TABLES binary_tab = it_content. "binary. 2. Now convert the obtained binary content to text using FM SO_SOLIXTAB_TO_SOLITAB. DATA: lt_data TYPE soli_tab. CALL FUNCTION 'SO_SOLIXTAB_TO_SOLITAB' EXPORTING ip_solixtab = it_content IMPORTING ep_solitab = lt_data. 3. Now we should use a set of function modules to convert this text content into attachment and attach it to GOS. –> SO_FOLDER_ROOT_ID_GET Using this FM , you are getting an address of where your file contents will be stored in SAP. –> SO_OBJECT_INSERT This FM Stores the file into the folder obtained using FM SO_FOLDER_ROOT_ID_GET. The content of the file is passed into this FM in a table (lt_data in this case). The output of this FM will be the object ID of your file. –> BINARY_RELATION_CREATE_COMMIT At this point, your file is already stored somewhere in SAP. Now using this FM you will link your object ID to purchase order(PO is used in our example, you can use any business object). DATA: wa_fol_id TYPE soodk, wa_object TYPE borident, wa_obj_data TYPE sood1, " OBJECT DEF AND CHANGE ATTRIBUTES ls_objhead TYPE soli, it_objhead TYPE STANDARD TABLE OF soli, wa_folmem_k TYPE sofmk, "folder content DATA wa_note TYPE borident, " bor OBJECT IDENTIFIER wa_object TYPE borident, lv_ep_note TYPE borident-objkey."“bor OBJECT KEY CONSTANTS : c_bus2012 TYPE swo_objtyp VALUE 'BUS2012' , c_atta(4) TYPE c VALUE 'ATTA', c_ext(3) TYPE c VALUE 'EXT', c_b(1) TYPE c VALUE 'B', c_x(1) TYPE c VALUE 'X', c_o(1) TYPE c VALUE 'O'. CALL FUNCTION 'SO_FOLDER_ROOT_ID_GET' EXPORTING region = c_b IMPORTING folder_id = wa_fol_id EXCEPTIONS communication_failure = 1 owner_not_exist = 2 system_failure = 3 x_error = 4 OTHERS = 5. “Prepare exporting parameters for FM SO_OBJECT_INSERT wa_object-objkey = lv_samref_po. " PO number wa_object-objtype = c_bus2012. " bus number *– wa_obj_data-objsns = c_o. " sensitivity of object (o-standard) wa_obj_data-objla = sy-langu. " language wa_obj_data-objdes = lv_file. "iv_slug. " slug value – description wa_obj_data-file_ext = lv_extensions. wa_obj_data-objlen = lines( lt_data ) * 255. TRANSLATE wa_obj_data-file_ext TO UPPER CASE. * "DOC & XLS are having encoding issue and resulting in error while opening file. Hence changing to DOCX & XLSX IF wa_obj_data-file_ext = 'DOC'. CONCATENATE '&SO_FILENAME=' lv_file '.' 'DOCX' INTO ls_objhead-line. ELSEIF wa_obj_data-file_ext = 'XLS'. CONCATENATE '&SO_FILENAME=' lv_file '.' 'XLSX' INTO ls_objhead-line. ELSE. CONCATENATE '&SO_FILENAME=' wa_attach-po_att_name INTO ls_objhead-line. ENDIF. APPEND ls_objhead TO it_objhead. * "For TXT file ASC encoding should be used. IF wa_obj_data-file_ext = 'TXT'. ls_objhead-line = '&SO_FORMAT=ASC'. ELSE. ls_objhead-line = '&SO_FORMAT=BIN'. ENDIF. APPEND ls_objhead TO it_objhead. CALL FUNCTION 'SO_OBJECT_INSERT' EXPORTING folder_id = wa_fol_id object_type = c_ext object_hd_change = wa_obj_data IMPORTING object_id = wa_obj_id TABLES objhead = it_objhead objcont = lt_data EXCEPTIONS active_user_not_exist = 1 communication_failure = 2 component_not_available = 3 dl_name_exist = 4 folder_not_exist = 5 folder_no_authorization = 6 object_type_not_exist = 7 operation_no_authorization = 8 owner_not_exist = 9 parameter_error = 10 substitute_not_active = 11 substitute_not_defined = 12 system_failure = 13 x_error = 14 OTHERS = 15. IF sy-subrc = 0 AND wa_object-objkey IS NOT INITIAL. wa_folmem_k-foltp = wa_fol_id-objtp. wa_folmem_k-folyr = wa_fol_id-objyr. wa_folmem_k-folno = wa_fol_id-objno. */Please note: wa_fol_id and wa_obj_id are different work areas wa_folmem_k-doctp = wa_obj_id-objtp. wa_folmem_k-docyr = wa_obj_id-objyr. wa_folmem_k-docno = wa_obj_id-objno. lv_ep_note = wa_folmem_k. wa_note-objtype = 'MESSAGE'. wa_note-objkey = lv_ep_note. CALL FUNCTION 'BINARY_RELATION_CREATE_COMMIT' EXPORTING obj_rolea = wa_object obj_roleb = wa_note relationtype = c_atta EXCEPTIONS no_model = 1 internal_error = 2 unknown = 3 OTHERS = 4. * IF sy-subrc EQ 0. * Commit it COMMIT WORK. ENDIF. ENDLOOP. Source: sap.com