Serializing/De-serializing a flat internal table as an attachment
I did a bit of a fun thing of attaching a simple internal table with a flat structure as XML to a one order object and then reading it back. Below is some code if any one is interested.
—————————————————————————————————————————————————————–
FORM xml_exists USING iv_filename TYPE string
is_bo TYPE sibflporb
CHANGING cs_access_info TYPE skwf_cpprp
cv_exists TYPE abap_bool.
DATA: lt_access_info TYPE skwf_cpprps,
lt_bapiret2 TYPE TABLE OF bapiret2.
CALL FUNCTION ‘CRM_KW_DOC_GET_INFO’
EXPORTING
business_object = is_bo
IMPORTING
ios_file_access_info = lt_access_info
TABLES
return = lt_bapiret2.
READ TABLE lt_access_info INTO cs_access_info WITH KEY file_name = iv_filename.
IF sy–subrc EQ 0.
cv_exists = abap_true.
ENDIF.
ENDFORM.
—————————————————————————————————————————————————————–
FUNCTION Z_TESTG_FM_WRITE .
*”———————————————————————-
*”*”Local Interface:
*” IMPORTING
*” REFERENCE(IV_UPDATE_EXISTING) TYPE BOOLEAN
*” REFERENCE(IT_KEY_FIELDS) TYPE CRMT_ATTR_NAME_VALUE_T
*” REFERENCE(IT_TABLE_TO_ATTACH) TYPE ANY TABLE
*”———————————————————————-
INCLUDE crm_object_types_con.
DATA: ls_transaction_id LIKE LINE OF it_key_fields,
ls_filename LIKE LINE OF it_key_fields,
lv_xml_exists TYPE abap_bool,
ls_business_object TYPE sibflporb,
ls_sdok_property TYPE sdokpropty,
lt_properties TYPE sdokproptys,
ls_file_info TYPE sdokfilaci,
lt_file_info TYPE sdokfilacis,
ls_error TYPE skwf_error,
lv_xml_length TYPE int4,
lt_xml_bin TYPE sdokcntbins,
lv_filename TYPE c LENGTH 64,
ls_phio TYPE skwf_io,
ls_access_info TYPE skwf_cpprp,
lv_filename_str TYPE string,
lv_xml TYPE string,
lv_xml_xstring TYPE xstring,
lv_guid TYPE crmt_object_guid.
“Check whether document can be locked
CLEAR ls_transaction_id.
READ TABLE it_key_fields INTO ls_transaction_id WITH KEY field_name = ‘OBJECT_GUID’.
CHECK sy–subrc EQ 0.
CHECK ls_transaction_id IS NOT INITIAL.
lv_guid = ls_transaction_id–field_value.
CALL FUNCTION ‘CRM_ORDER_ENQUEUE’
EXPORTING
iv_guid = lv_guid
EXCEPTIONS
foreign_lock = 1
system_failure = 2
distributed_lock = 3
no_change_allowed = 4
transferring = 5
OTHERS = 6.
IF sy–subrc NE 0.
“Error Handling
ENDIF.
“Convert items table into an XML string
CALL TRANSFORMATION id
OPTIONS xml_header = ‘without_encoding’
SOURCE output = it_table_to_attach
RESULT XML lv_xml.
“Convert XML string to xstring
CALL FUNCTION ‘ECATT_CONV_STRING_TO_XSTRING’
EXPORTING
im_string = lv_xml
IMPORTING
ex_xstring = lv_xml_xstring.
IF sy–subrc NE 0.
“Error Handling
ELSE.
“Convert xstring to binary
CALL FUNCTION ‘SCMS_XSTRING_TO_BINARY’
EXPORTING
buffer = lv_xml_xstring
IMPORTING
output_length = lv_xml_length
TABLES
binary_tab = lt_xml_bin.
“set attachment details
ls_business_object–instid = lv_guid.
ls_business_object–typeid = ”.“gc_object_type-<<XXXXX>>.
ls_business_object–catid = ‘BO’.
“set dok properties
CLEAR ls_filename.
READ TABLE it_key_fields INTO ls_filename WITH KEY field_name = ‘FILENAME’.
CHECK sy–subrc EQ 0.
IF ls_filename IS NOT INITIAL.
lv_filename = ls_filename–field_value.
ELSE.
lv_filename = ‘INTERNALTABLE.XML’.
ENDIF.
ls_sdok_property–name = ‘KW_RELATIVE_URL’.
ls_sdok_property–value = lv_filename.
INSERT ls_sdok_property INTO TABLE lt_properties.
“Set file parameters
ls_file_info–file_name = lv_filename.
ls_file_info–file_size = lv_xml_length.
ls_file_info–mimetype = ‘application/xml’.
ls_file_info–binary_flg = abap_true.
ls_file_info–first_line = 1.
ls_file_info–last_line = lines( lt_xml_bin ).
APPEND ls_file_info TO lt_file_info.
IF iv_update_existing EQ abap_true.
lv_filename_str = lv_filename.
lv_xml_exists = abap_false.
PERFORM xml_exists USING lv_filename_str
ls_business_object
CHANGING ls_access_info
lv_xml_exists.
IF lv_xml_exists EQ abap_true.
“Attach the document to the BO
ls_phio–objtype = ls_access_info–objtype. “PHIO
ls_phio–class = ls_access_info–class.
ls_phio–objid = ls_access_info–objid.
CALL METHOD cl_crm_documents=>create_version_with_table
EXPORTING
business_object = ls_business_object
file_access_info = lt_file_info
* properties = lt_properties
phio = ls_phio
file_content_binary = lt_xml_bin
raw_mode = abap_true
iv_version_overwrite = abap_true
IMPORTING
error = ls_error.
ELSE.
“Attach the document to the BO
CALL METHOD cl_crm_documents=>create_with_table
EXPORTING
business_object = ls_business_object
properties = lt_properties
file_access_info = lt_file_info
file_content_binary = lt_xml_bin
IMPORTING
error = ls_error.
ENDIF.
ELSE.
“Attach the document to the BO
CALL METHOD cl_crm_documents=>create_with_table
EXPORTING
business_object = ls_business_object
properties = lt_properties
file_access_info = lt_file_info
file_content_binary = lt_xml_bin
IMPORTING
error = ls_error.
ENDIF.
IF ls_error–type EQ ‘E’.
“Error Handling
ENDIF.
CALL FUNCTION ‘CRM_ORDER_DEQUEUE’
EXPORTING
iv_guid = lv_guid
* iv_collect = ‘ ‘
* iv_enqueue_mode = ‘E’
iv_from_init = abap_false.
ENDIF.
ENDFUNCTION.
—————————————————————————————————————————————————————–
FUNCTION z_testg_fm_read.
*”———————————————————————-
*”*”Local Interface:
*” IMPORTING
*” REFERENCE(IT_KEY_FIELDS) TYPE CRMT_ATTR_NAME_VALUE_T
*” EXPORTING
*” REFERENCE(ET_TABLE_READ) TYPE ANY TABLE
*”———————————————————————-
INCLUDE crm_object_types_con.
DATA: ls_transaction_id LIKE LINE OF it_key_fields,
ls_filename LIKE LINE OF it_key_fields,
lt_properties TYPE sdokproptys,
lt_orig_io TYPE skwf_ios,
ls_orig_io TYPE skwf_io,
lt_bapiret TYPE bapiret2_t,
lt_access_info TYPE skwf_cpprps,
ls_access_info LIKE LINE OF lt_access_info,
lv_xml_xstring TYPE xstring,
lv_xml_string TYPE string,
lv_input_length TYPE i,
lv_filename TYPE c LENGTH 64,
ls_error TYPE bapiret2,
lt_ios_properties_result TYPE crm_kw_propst,
ls_sdokproptl TYPE sdokproptl,
lv_sdok_propv TYPE sdok_propv,
lv_doc_guid TYPE sdok_docid.
FIELD–SYMBOLS: <fs_ios_properties_result> TYPE crm_kw_props.
CLEAR ls_transaction_id.
READ TABLE it_key_fields INTO ls_transaction_id WITH KEY field_name = ‘OBJECT_GUID’.
CHECK sy–subrc EQ 0.
CHECK ls_transaction_id IS NOT INITIAL.
DATA(ls_bo) = VALUE sibflporb( instid = ls_transaction_id–field_value
objtype = ‘BUS2000280’“gc_object_type-social_application
catid = ‘BO’ ).
CLEAR ls_filename.
READ TABLE it_key_fields INTO ls_filename WITH KEY field_name = ‘FILENAME’.
CHECK sy–subrc EQ 0.
IF ls_filename IS NOT INITIAL.
lv_filename = ls_filename–field_value.
ELSE.
lv_filename = ‘INTERNALTABLE.XML’.
ENDIF.
DATA(ls_sdok_property) = VALUE sdokpropty( name = ‘KW_RELATIVE_URL’
value = lv_filename ).
APPEND ls_sdok_property TO lt_properties.
“Read the attachment properties from KM
CALL FUNCTION ‘CRM_KW_DOC_GET_INFO’
EXPORTING
business_object = ls_bo
newest_only = ‘X’
properties_query = lt_properties
IMPORTING
ios_file_access_info = lt_access_info
ios_properties_result = lt_ios_properties_result
TABLES
return = lt_bapiret.
READ TABLE lt_bapiret INTO ls_error WITH KEY type = zif_ndis_constants=>gc_type_error.
IF sy–subrc EQ 0.
“Error Handling
ENDIF.
IF lines( lt_access_info ) > 0.
“Identify the latest attachment if there are multiple
LOOP AT lt_ios_properties_result ASSIGNING <fs_ios_properties_result> WHERE objtype = zif_ndis_constants=>gc_phio.
CLEAR ls_sdokproptl.
READ TABLE <fs_ios_properties_result>–properties
INTO ls_sdokproptl WITH KEY name = ‘LAST_CHANGED_AT’.
IF ls_sdokproptl–value > lv_sdok_propv.
lv_sdok_propv = ls_sdokproptl–value.
lv_doc_guid = <fs_ios_properties_result>–objid.
ENDIF.
ENDLOOP.
READ TABLE lt_access_info INTO ls_access_info WITH KEY objid = lv_doc_guid.
ls_orig_io = VALUE #( objtype = ls_access_info–objtype
class = ls_access_info–class
objid = ls_access_info–objid ).
INSERT ls_orig_io INTO TABLE lt_orig_io.
“Read the attachment in binary form
cl_crm_documents=>get_document(
EXPORTING
io = ls_orig_io
IMPORTING
content_bin = DATA(lt_orig_xml_bin) ).
lv_input_length = ls_access_info–file_size.
“Convert the attachment from binary to xstring
CALL FUNCTION ‘SCMS_BINARY_TO_XSTRING’
EXPORTING
input_length = lv_input_length
IMPORTING
buffer = lv_xml_xstring
TABLES
binary_tab = lt_orig_xml_bin
EXCEPTIONS
failed = 1
OTHERS = 2.
IF sy–subrc NE 0.
“Error Handling
ELSE.
“Convert the attachment from xstring to string
CALL FUNCTION ‘ECATT_CONV_XSTRING_TO_STRING’
EXPORTING
im_xstring = lv_xml_xstring
IMPORTING
ex_string = lv_xml_string.
IF lv_xml_string IS NOT INITIAL.
“Convert the XML string into an internal table
CALL TRANSFORMATION id
SOURCE XML lv_xml_string
RESULT output = ET_TABLE_READ.
ENDIF.
ENDIF.
ENDIF.
ENDFUNCTION.
—————————————————————————————————————————————————————–
REPORT ztest.
DATA: ls_wa TYPE crmt_attr_name_value,
lt_key_fields TYPE crmt_attr_name_value_t,
lt_table TYPE crmt_attr_name_value_t.
ls_wa–field_name = ‘OBJECT_GUID’.
ls_wa–field_value = ‘0010568E5A181EE515A8811D9372791D’.
APPEND ls_wa TO lt_key_fields.
ls_wa–field_name = ‘FILENAME’.
ls_wa–field_value = ‘TESTG.XML’.
APPEND ls_wa TO lt_key_fields.
CALL FUNCTION ‘Z_TESTG_FM_WRITE’
EXPORTING
iv_update_existing = abap_true
it_key_fields = lt_key_fields
it_table_to_attach = lt_key_fields.
CALL FUNCTION ‘Z_TESTG_FM_READ’
EXPORTING
it_key_fields = lt_key_fields
IMPORTING
et_table_read = lt_table.
WRITE ‘Ok’.