12-07-2015 10:24 AM
Hi,
this is my first question in SCN so don't hesitate to tell me if it's placed in the wrong place.
We have following scenario which isn't working fine because it causes wrong formatting:
We have a dynpro where we want to display a long text (the goal is to send an e-mail at the end). The long text is a template text on entering the screen and this template we get by using a text module by SAP smart forms. We put this text module in a custom control using the method set_text_as_stream from class cl_gui_textedit. When the user is done with editing the text we want to send this text by e-mail. So we read the text with method get_text_as_stream from class cl_gui_textedit. And here we have the problem with the wrong formatting of the text module after the user changed it. We use the function module CONVERT_STREAM_TO_ITF_TEXT to convert the text to ITF to get more information about the formatting which was made in the custom control. After that we try to interprete this ITF-text to get a clean formated e-mail text. But our experience shows that the e-mail text isn't always right formated. For example when have a carriage return in the template text we lose this when we interprete the ITF-text and two words which were initial separated by the carriage return stick together.
As a conclusion: Do you know a way to avoid this formatting problems? If you know a better way to solve our scenario (template text on a dynpro which is sent by e-mail) please tell me and I'll try to adapt it.
Thanks.
Manuel
12-07-2015 11:25 AM
12-07-2015 12:04 PM
Hi,
sorry for the wrong term (we are programing in german): replace dynpro by screen.
12-07-2015 1:50 PM
12-07-2015 3:38 PM
Hi Fred,
thanks for your examples. But they don't fit for my scenario. Sending mails is not my problem and I know how to attach files to an e-mail. None of the examples combines all of my scenario (smartform in screen and sending text from screen).
Regards,
Manuel
12-08-2015 10:17 AM
Fetching the template text:
DATA: ls_languages2 TYPE ssfrlang,
lv_textmodule TYPE tdsfname,
gt_text TYPE tttext255,
lt_lines2 TYPE tsftext.
ls_languages2-langu1 = 'D'.
lv_textmodule = 'example_text'.
CALL FUNCTION 'SSFRT_READ_TEXTMODULE'
EXPORTING
i_textmodule = lv_textmodule
i_languages = ls_languages2
IMPORTING
o_text = lt_lines2
EXCEPTIONS
error = 1
language_not_found = 2
OTHERS = 3.
Replacing variables in the text and returning ttext255:
PERFORM replace_variables_lief USING lt_lines2
CHANGING gt_text.
FORM replace_variables_lief USING pit_lines TYPE tsftext
CHANGING pet_text TYPE tttext255.
DATA: lo_abap_typedescr TYPE REF TO cl_abap_typedescr,
lo_abap_structdescr TYPE REF TO cl_abap_structdescr,
ls_components TYPE abap_compdescr,
ls_tline TYPE tline,
lt_text255 TYPE TABLE OF so_text255,
lv_field TYPE string,
lv_linecnt TYPE i,
lv_param TYPE string,
lv_string(5000) TYPE c,
lv_tabix TYPE sytabix,
lv_text255 TYPE so_text255.
FIELD-SYMBOLS: <lv_field> TYPE any.
CONSTANTS: lc_struct TYPE string VALUE 'GS_HEADER_LIEF'.
CALL METHOD cl_abap_structdescr=>describe_by_name
EXPORTING
p_name = 'structure_name'
RECEIVING
p_descr_ref = lo_abap_typedescr
EXCEPTIONS
type_not_found = 1
OTHERS = 2.
IF sy-subrc = 0.
lo_abap_structdescr ?= lo_abap_typedescr.
ENDIF.
DESCRIBE TABLE pit_lines LINES lv_linecnt.
LOOP AT pit_lines INTO ls_tline.
lv_tabix = sy-tabix.
IF ls_tline-tdformat = '*'.
IF lv_tabix > 1.
* Replacing variable
IF lo_abap_structdescr IS BOUND.
LOOP AT lo_abap_structdescr->components
INTO ls_components.
CONCATENATE lc_struct
'-'
ls_components-name
INTO lv_field.
UNASSIGN <lv_field>.
ASSIGN (lv_field) TO <lv_field>.
IF <lv_field> IS ASSIGNED.
CONCATENATE '&'
ls_components-name
'&'
INTO lv_param.
REPLACE ALL OCCURRENCES OF lv_param
IN lv_string WITH <lv_field>.
ENDIF.
ENDLOOP.
ENDIF.
REPLACE ALL OCCURRENCES OF '<(>,<)>' IN lv_string WITH ','.
* new line: prepare last passage and save it
REFRESH lt_text255.
CALL FUNCTION 'IQAPI_WORD_WRAP'
EXPORTING
textline = lv_string
outputlen = 255
TABLES
out_lines = lt_text255
EXCEPTIONS
outputlen_too_large = 1
OTHERS = 2.
IF sy-subrc = 0.
IF lt_text255 IS INITIAL.
CLEAR lv_text255.
APPEND lv_text255 TO pet_text.
ENDIF.
LOOP AT lt_text255 INTO lv_text255.
SHIFT lv_text255 LEFT DELETING LEADING space.
IF lines( lt_text255 ) = sy-tabix.
CONCATENATE lv_text255 cl_abap_char_utilities=>cr_lf INTO lv_text255.
ENDIF.
APPEND lv_text255 TO pet_text.
ENDLOOP.
ENDIF.
CLEAR lv_string.
ENDIF.
IF lv_tabix = 1
AND lv_tabix = lv_linecnt.
APPEND lv_text255 TO pet_text.
EXIT.
ENDIF.
ENDIF.
CONCATENATE lv_string
ls_tline-tdline
INTO lv_string
SEPARATED BY space.
IF lv_tabix = lv_linecnt.
* Replacing variables
IF lo_abap_structdescr IS BOUND.
LOOP AT lo_abap_structdescr->components
INTO ls_components.
CONCATENATE lc_struct
'-'
ls_components-name
INTO lv_field.
UNASSIGN <lv_field>.
ASSIGN (lv_field) TO <lv_field>.
IF <lv_field> IS ASSIGNED.
CONCATENATE '&'
ls_components-name
'&'
INTO lv_param.
REPLACE ALL OCCURRENCES OF lv_param
IN lv_string WITH <lv_field>.
ENDIF.
ENDLOOP.
ENDIF.
REPLACE ALL OCCURRENCES OF '<(>,<)>' IN lv_string WITH ','.
REFRESH lt_text255.
CALL FUNCTION 'IQAPI_WORD_WRAP'
EXPORTING
textline = lv_string
outputlen = 255
TABLES
out_lines = lt_text255
EXCEPTIONS
outputlen_too_large = 1
OTHERS = 2.
IF sy-subrc = 0.
IF lt_text255 IS INITIAL.
CLEAR lv_text255.
APPEND lv_text255 TO pet_text.
ENDIF.
LOOP AT lt_text255 INTO lv_text255.
SHIFT lv_text255 LEFT DELETING LEADING space.
IF lines( lt_text255 ) = sy-tabix.
CONCATENATE lv_text255 cl_abap_char_utilities=>cr_lf INTO lv_text255.
ENDIF.
APPEND lv_text255 TO pet_text.
ENDLOOP.
ENDIF.
CLEAR lv_string.
ELSE.
ENDIF.
ENDLOOP.
ENDFORM.
Initializing the custom control for the screen and passing the text to the custom control:
DATA: go_container_textedit TYPE REF TO cl_gui_custom_container,
go_editor TYPE REF TO cl_gui_textedit.
CREATE OBJECT: go_container_textedit EXPORTING container_name = 'CU_CONTROL',
go_editor EXPORTING parent = go_container_textedit.
CALL METHOD go_editor->set_readonly_mode
EXPORTING
readonly_mode = '0'.
CALL METHOD go_editor->set_text_as_stream
EXPORTING
text = gt_text.
Reading the text and putting it into an e-mail (this is where we get the ugly formatting). Formatting means keeping CRLFs for example. We want to send the text exactly formated as the user saw it on the screen:
CLASS cl_bcs DEFINITION LOAD.
DATA: lo_send_request TYPE REF TO cl_bcs,
lo_document TYPE REF TO cl_document_bcs,
lo_sender TYPE REF TO if_sender_bcs,
lo_recipient TYPE REF TO if_recipient_bcs,
lt_message_body TYPE bcsy_text,
lv_sent_to_all TYPE os_boolean,
lv_betreff TYPE so_obj_des,
lt_betreff_ui TYPE tttext255,
ls_betreff_ui LIKE LINE OF lt_betreff_ui,
lv_betreff_ui TYPE string,
lv_mail_abs TYPE ad_smtpadr.
CLEAR: lv_betreff_ui.
CALL METHOD go_editor->get_text_as_stream
IMPORTING
text = gt_text.
DATA: lt_itf TYPE TABLE OF tline,
ls_itf TYPE tline,
ls_itf_next TYPE tline,
lv_conctext TYPE string,
lv_tdformat_bef TYPE char2.
CLEAR: lv_conctext, lv_tdformat_bef.
"Here we start interpreting the text to get a text which is at least better formated as the text we get directly from the screen
CALL FUNCTION 'CONVERT_STREAM_TO_ITF_TEXT'
TABLES
text_stream = gt_text
itf_text = lt_itf.
LOOP AT lt_itf INTO ls_itf.
SHIFT ls_itf-tdline LEFT DELETING LEADING space.
READ TABLE lt_itf INTO ls_itf_next INDEX sy-tabix + 1.
IF sy-subrc = 0.
IF ls_itf_next-tdformat <> '='.
IF ls_itf-tdformat <> '='.
REPLACE ALL OCCURRENCES OF '<(>&<)>' IN ls_itf-tdline WITH '&'.
APPEND ls_itf-tdline TO lt_message_body.
CLEAR ls_itf-tdline.
IF ( ls_itf-tdformat = '*' OR lv_tdformat_bef = '*' ) AND ls_itf_next-tdformat = '*'.
APPEND ls_itf-tdline TO lt_message_body.
CLEAR lv_tdformat_bef.
ENDIF.
ELSE.
CONCATENATE lv_conctext ls_itf-tdline INTO lv_conctext.
REPLACE ALL OCCURRENCES OF '<(>&<)>' IN lv_conctext WITH '&'.
APPEND lv_conctext TO lt_message_body.
CLEAR lv_conctext.
IF lv_tdformat_bef = '*' AND ls_itf_next-tdformat <> ''.
APPEND lv_conctext TO lt_message_body.
CLEAR lv_tdformat_bef.
ENDIF.
ENDIF.
ELSE.
lv_conctext = ls_itf-tdline.
lv_tdformat_bef = '*'.
ENDIF.
ELSE.
CONCATENATE lv_conctext ls_itf-tdline INTO lv_conctext.
REPLACE ALL OCCURRENCES OF '<(>&<)>' IN lv_conctext WITH '&'.
APPEND lv_conctext TO lt_message_body.
ENDIF.
ENDLOOP.
"create send request
lo_send_request = cl_bcs=>create_persistent( ).
CALL METHOD go_editor_betreff->get_text_as_stream
IMPORTING
text = lt_betreff_ui.
LOOP AT lt_betreff_ui INTO ls_betreff_ui.
CONCATENATE lv_betreff_ui ls_betreff_ui INTO lv_betreff_ui.
ENDLOOP.
lv_betreff = lv_betreff_ui.
lo_document = cl_document_bcs=>create_document(
i_type = 'RAW'
i_text = lt_message_body
i_subject = lv_betreff ).
* Pass the document to send request
lo_send_request->set_document( lo_document ).
lv_mail_abs = gv_mail_abs.
"Create sender
lo_sender = cl_cam_address_bcs=>create_internet_address( lv_mail_abs ).
"Set sender
lo_send_request->set_sender( lo_sender ).
"Create recipient
lo_recipient = cl_cam_address_bcs=>create_internet_address( gv_mail ).
*Set recipient
lo_send_request->add_recipient(
EXPORTING
i_recipient = lo_recipient i_express = 'X' ).
lo_send_request->add_recipient( lo_recipient ).
CALL METHOD lo_send_request->set_message_subject( lv_betreff_ui ).
* Send email
lo_send_request->send(
EXPORTING
i_with_error_screen = 'X'
RECEIVING
result = lv_sent_to_all ).
COMMIT WORK.
12-08-2015 12:14 PM
To be honest I can't fully understand what result should be produced by the ITF conversion before the composition of the e-mail. (But probably this is the point where sometimes the CRLF's disappear.)
Basically, the text table returned by the GET_TEXT_AS_STREAM method should contain all the CRLF characters from the textedit control.
However, very long rows entered in the textedit can be splitted into multiple ones in the outgoing e-mail because of the 'RAW' format.
So I'd go directly with this:
CALL METHOD editor->get_text_as_stream
IMPORTING
text = lt_message_body.
lo_document = cl_document_bcs=>create_document(
i_type = 'TXT'
i_text = lt_message_body
i_subject = lv_betreff ).
whithout the conversion stuff.
12-10-2015 9:56 AM
Hi Gabor,
we have tried your suggestion and this is what we got (very bad formatting):
Text on screen:
Text in Mail: