Technical Articles
Email attachment with Title (more than 50 characters long) using class CL_BCS
Introduction: In this blog post we will see how we can have a file attachment title when it is over 50 characters long.
If we use the CL_BCS class to build email functionality, we use the method ADD_ATTACHMENT from the class CL_DOCUMENT_BCS to attach any document.
Generally, we pass all the mandatory importing parameters including (I_ATTACHMENT_SUBJECT) which build the attached document’s title. And since this parameter can take up to 50 characters(data element SO_OBJ_DES), obviously it truncates to fit it within the limit.
lo_document_ref->add_attachment(
EXPORTING
i_attachment_type = 'xls'
i_attachment_subject = CONV so_obj_des( 'Check if we can accommodate an Attachment file with more than 50 characters long' )
i_attachment_size = CONV so_obj_len( out_length )
i_attachment_language = sy-langu
i_att_content_hex = it_binary_tab ).
So, when we trigger an e-mail, the attachment title will get truncated in SAP.
And same issue will be outside SAP too.
To extend the attachment title by more than 50 characters, we can leverage the optional importing parameter I_ATTACHMENT_HEADER in the same method ADD_ATTACHMENT of the class CL_DOCUMENT_BCS.
And need to pass a blank( space ) in the mandatory importing parameter (I_ATTACHMENT_SUBJECT) when calling the attachment method.
DATA(lt_atta_hdr) = VALUE soli_tab( ( line = 'Check if we can accommodate an Attachment file with more than 50 characters long.xlsx' ) ).
lo_document_ref->add_attachment(
EXPORTING
i_attachment_type = 'xls'
i_attachment_subject = space
i_attachment_size = CONV so_obj_len( out_length )
i_attachment_header = lt_atta_hdr
i_attachment_language = sy-langu
i_att_content_hex = it_binary_tab ).
Though there is no attachment Title in the SAP
But outside of SAP, we can see an attachment title in its entirety and uncut.
Please refer to the detailed code logic below.
PARAMETERS : p_email TYPE ad_smtpadr. "abc@gmail.com
DATA: e_xstring TYPE xstring,
mt_data TYPE REF TO data,
out_length TYPE i,
it_binary_tab TYPE solix_tab.
FIELD-SYMBOLS <tab> TYPE ANY TABLE.
SELECT bname,
persnumber,
addrnumber
FROM usr21
INTO TABLE @DATA(lt_usr21)
UP TO 20 ROWS.
IF sy-subrc EQ 0.
GET REFERENCE OF lt_usr21 INTO mt_data.
ASSIGN mt_data->* TO <tab>.
TRY .
cl_salv_table=>factory(
EXPORTING
list_display = abap_false
IMPORTING
r_salv_table = DATA(mo_salv_table)
CHANGING
t_table = <tab> ).
CATCH cx_salv_msg.
ENDTRY.
"get colums & aggregation infor to create fieldcat
DATA(mo_columns) = mo_salv_table->get_columns( ).
DATA(mo_aggreg) = mo_salv_table->get_aggregations( ).
DATA(mt_fcat) = cl_salv_controller_metadata=>get_lvc_fieldcatalog(
r_columns = mo_columns
r_aggregations = mo_aggreg ).
IF cl_salv_bs_a_xml_base=>get_version( ) EQ if_salv_bs_xml=>version_25 OR
cl_salv_bs_a_xml_base=>get_version( ) EQ if_salv_bs_xml=>version_26.
DATA(mo_result_data) = cl_salv_ex_util=>factory_result_data_table(
r_data = mt_data
t_fieldcatalog = mt_fcat
).
CASE cl_salv_bs_a_xml_base=>get_version( ).
WHEN if_salv_bs_xml=>version_25.
DATA(lv_version) = if_salv_bs_xml=>version_25.
WHEN if_salv_bs_xml=>version_26.
lv_version = if_salv_bs_xml=>version_26.
ENDCASE.
DATA(m_file_type) = if_salv_bs_xml=>c_type_xlsx.
DATA(m_flavour) = if_salv_bs_c_tt=>c_tt_xml_flavour_export.
"transformation of data to excel
cl_salv_bs_tt_util=>if_salv_bs_tt_util~transform(
EXPORTING
xml_type = m_file_type
xml_version = lv_version
r_result_data = mo_result_data
xml_flavour = m_flavour
gui_type = if_salv_bs_xml=>c_gui_type_gui
IMPORTING
xml = e_xstring ).
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = e_xstring
IMPORTING
output_length = out_length
TABLES
binary_tab = it_binary_tab.
ENDIF.
ENDIF.
DATA(lo_send_request_ref) = cl_bcs=>create_persistent( ).
*Populate sender name
DATA(lo_sender_ref) = cl_sapuser_bcs=>create( sy-uname ).
IF lo_send_request_ref IS BOUND.
IF lo_sender_ref IS BOUND.
*Add sender to send request
lo_send_request_ref->set_sender(
EXPORTING
i_sender = lo_sender_ref ).
ENDIF.
ENDIF.
DATA(lo_recipient_ref) = cl_cam_address_bcs=>create_internet_address( p_email ).
IF lo_recipient_ref IS BOUND.
*Add recipient to send request
lo_send_request_ref->add_recipient(
EXPORTING
i_recipient = lo_recipient_ref
i_express = abap_true ).
ENDIF.
DATA(lt_content_txt) = VALUE soli_tab( ( line = 'Hello Team,' )
( line = 'This e-mail has been automatically generated. Please do not reply to this e-mail.' )
( line = 'Thank You!' ) ).
* Create document for e-mail content
DATA(lo_document_ref) = cl_document_bcs=>create_document(
i_type = 'RAW'
i_text = lt_content_txt
i_subject = 'Test Email' ).
IF lo_document_ref IS BOUND.
DATA(lt_atta_hdr) = VALUE soli_tab( ( line = 'Check if we can accommodate an Attachment file with more than 50 characters long.xlsx' ) ).
lo_document_ref->add_attachment(
EXPORTING
i_attachment_type = 'xls'
i_attachment_subject = space
i_attachment_size = CONV so_obj_len( out_length )
i_attachment_header = lt_atta_hdr
i_attachment_language = sy-langu
i_att_content_hex = it_binary_tab ).
* Add document to send request
lo_send_request_ref->set_document( lo_document_ref ).
ENDIF.
* Set parameter to send e-mail immediately
lo_send_request_ref->set_send_immediately(
EXPORTING
i_send_immediately = abap_true ).
* Send email
DATA(lv_sent_to_all) = lo_send_request_ref->send( ).
* If e-mail is successful then do commit work
IF lv_sent_to_all = abap_true.
COMMIT WORK AND WAIT.
ENDIF.
This completes the functionality.
I appreciate you reading the content. I sincerely hope you enjoyed it. Feel free to contribute your insights and recommendations.
Thanks. I didn't pay attention to the max length before, but I knew the trick to pass the file name through the "header" parameter, because it's required when you need to have an extension of more than 3 characters, like "xlsx" (see notes 1459896 and 1582868), as you did but you didn't mention it explicitly although it could have been part of your demonstration ("... title more than 50 characters long and file extension more than 3 characters").
I didn't know that the file name could be indicated alone, but the SAP notes recommend to indicate &SO_FILENAME= right before the text e.g.
The "header" parameter accepts other "instructions" like &SO_FORMAT, &SO_CODEPAGE, etc.
Thank you Sandra for reading the article and sharing the trick. I didn't know about &SO_FILENAME and other parameters.
The only reason, I didn't mention about file extension length( 3 or 4) as I have tested the same functionality with extensions .xls (though it says the file could be corrupted as per image attached but choosing 'Yes', it opened correctly and without any error) and with .xml attachments.
For both of the file extensions (with length 3), it worked quite well. But it could be nice addition to the article.
Yes, it's nice to use .xlsx extension if your attachment is in xlsx format, .xls extension if xls format, .csv extension if .csv format, etc., to avoid this popup.
Just wondering why you mix using CALL METHOD with the functional way of invoke methods.
Thank you Matthew for reading the blog. Please help me to understand which specific method(s) in this demonstration you are referring to.
Yasho Ratna Gupta Since 7.40, the words "CALL METHOD" are obsolete for calling methods (except if the name of method or instance or class is provided in a variable, or if using PARAMETER-TABLE).
Obsolete:
Fine (without CALL METHOD):
A "functional method call" means calling a functional method, i.e. which has a returning parameter.
Obsolete:
Fine:
Thank you Sandra for this valuable piece of information. I was not aware that CALL METHOD is obsolete now with SAP newer releases. I have updated the blog as per the suggestions.
It was the mix of CALL METHOD and the modern approach that concerned. It's not good to mix styles.
I totally agree Matthew. Thank you for pointing out!