In almost all project there is a requirement on which some program which scheduled in background will send mail to business user on periodic basis (i.e. daily, weekly etc.). This mail can serve different purpose as per the requirement for example list of daily failed batch job, Daily sales report etc.
This function can be achievable by using of standard BCS class, by using of BCS class we can send mails with attachment or without attachment, but sometimes business user don’t want to put additional effort to open mail attachment hence they require mail without attachment with all content in mail body itself.
BCS classes can did this by sending mail without attachment and make mail body by using ‘RAW’ format or ‘HTML’ format.
While sending mail by using RAW format, alignment is major concern because if you are sending big list then you have to create border and fixed position for text so that it can easily readable, but sometime RAW format output distorted based on different screen sizes, to overcome this we can create our own HTML page and send it in mail as mail body.
For easy understanding, I had created a program on which I am selecting data from VBAK table and send mail as an HTML Body of selected records:
REPORT yso NO STANDARD PAGE HEADING.
*-----------------------------------------------------------------------
* Type Declarations
*-----------------------------------------------------------------------
TYPES : BEGIN OF gts_vbak,
vbeln TYPE vbak-vbeln,
auart TYPE vbak-auart,
kunnr TYPE vbak-kunnr,
augru TYPE vbak-augru,
bezei TYPE bezei40,
erdat TYPE vbak-erdat,
erdat1 TYPE char10,
END OF gts_vbak.
TYPES : gtt_vbak TYPE TABLE OF gts_vbak.
*-----------------------------------------------------------------------
* Constant Declarations
*-----------------------------------------------------------------------
CONSTANTS : gc_x(1) TYPE c VALUE 'X',
gc_a(1) TYPE c VALUE 'A',
gc_i(1) TYPE c VALUE 'I'.
*-----------------------------------------------------------------------
* Data Declarations
*-----------------------------------------------------------------------
DATA : gt_vbak TYPE gtt_vbak,
gs_vbak TYPE gts_vbak,
gt_page TYPE soli_tab,
gs_page TYPE soli,
gv_auart TYPE auart,
gv_erdat TYPE erdat,
gv_augru TYPE augru,
gv_email TYPE adr6-smtp_addr,
gv_prev_date TYPE d,
gv_no_data_flag(1) TYPE c.
DATA :sent_to_all TYPE os_boolean,
send_request TYPE REF TO cl_bcs,
document TYPE REF TO cl_document_bcs,
recipient TYPE REF TO if_recipient_bcs,
bcs_exception TYPE REF TO cx_bcs,
subject TYPE so_obj_des.
*-----------------------------------------------------------------------
* Seletion - Criteria
*-----------------------------------------------------------------------
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
SELECT-OPTIONS : s_erdat FOR gv_erdat OBLIGATORY,
s_email FOR gv_email OBLIGATORY NO INTERVALS,
s_auart FOR gv_auart NO INTERVALS,
s_augru for gv_augru no INTERVALS.
SELECTION-SCREEN END OF BLOCK b1.
*-----------------------------------------------------------------------
* start-of-selection
*-----------------------------------------------------------------------
START-OF-SELECTION.
*& Get Data
CLEAR : gv_no_data_flag.
REFRESH gt_page.
PERFORM f_get_data CHANGING gt_vbak gv_no_data_flag.
*-----------------------------------------------------------------------
* END-OF-SELECTION
*-----------------------------------------------------------------------
END-OF-SELECTION.
IF NOT gv_no_data_flag IS INITIAL.
PERFORM f_create_mail_body.
PERFORM f_send_mail.
ELSE.
WRITE : / text-i05.
ENDIF.
*-----------------------------------------------------------------------
* Form routines
*----------------------------------------------------------------------
*&---------------------------------------------------------------------*
*& Form F_GET_DATA
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* <--P_GT_VBAK text
*----------------------------------------------------------------------*
FORM f_get_data CHANGING p_gt_vbak TYPE gtt_vbak
p_no_data_flag TYPE char1.
DATA : lv_count TYPE i.
SELECT a~vbeln a~auart a~erdat a~augru a~kunnr b~bezei
FROM vbak AS a INNER JOIN tvaut AS b
ON a~augru = b~augru
INTO CORRESPONDING FIELDS OF TABLE p_gt_vbak
WHERE ( a~erdat IN s_erdat OR
a~aedat IN s_erdat ) AND
a~auart IN s_auart AND
a~augru in s_augru and
b~spras EQ sy-langu. "#EC CI_BUFFJOIN
* --- flag set for no data selection
DESCRIBE TABLE p_gt_vbak LINES lv_count.
IF lv_count GT 0.
p_no_data_flag = gc_x.
ENDIF.
ENDFORM. " F_GET_DATA
*&---------------------------------------------------------------------*
*& Form F_CREATE_MAIL_BODY
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM f_create_mail_body .
DATA :
lv_page_header TYPE soli-line,
lv_font_size TYPE numc4,
lv_font_type TYPE char20,
lv_font_color TYPE soli-line,
lv_border TYPE numc4,
lv_cellpadding TYPE numc4,
lv_caption TYPE string,
lv_cell_value TYPE string,
lv_width TYPE char20,
lv_cell_color TYPE char20.
lv_page_header = text-i08. "Sales Order Alert
lv_font_size = 6.
PERFORM add_page_header USING lv_page_header lv_font_size
lv_font_type lv_font_color.
lv_border = 2. "create border width for table
lv_caption = text-i08.
** Creating HTML Table Header(Label)
PERFORM start_table USING lv_border lv_cellpadding lv_caption.
IF NOT gt_vbak[] IS INITIAL.
PERFORM start_row.
lv_cell_value = text-h01.
lv_width = 100.
PERFORM add_header_cell USING lv_cell_value lv_width.
lv_cell_value = text-h02.
PERFORM add_header_cell USING lv_cell_value lv_width.
lv_cell_value = text-h03.
PERFORM add_header_cell USING lv_cell_value lv_width.
lv_cell_value = text-h04.
PERFORM add_header_cell USING lv_cell_value lv_width.
lv_cell_value = text-h05.
PERFORM add_header_cell USING lv_cell_value lv_width.
CLEAR : lv_cell_value,lv_width.
PERFORM end_row.
ENDIF.
** Creating HTML Table Body
LOOP AT gt_vbak INTO gs_vbak.
WRITE gs_vbak-erdat TO gs_vbak-erdat1. "to change date format
PERFORM start_row.
lv_cell_value = gs_vbak-vbeln .
PERFORM add_item_cell USING lv_cell_value lv_cell_color.
lv_cell_value = gs_vbak-auart.
PERFORM add_item_cell USING lv_cell_value lv_cell_color.
lv_cell_value = gs_vbak-kunnr .
PERFORM add_item_cell USING lv_cell_value lv_cell_color.
lv_cell_value = gs_vbak-bezei .
PERFORM add_item_cell USING lv_cell_value lv_cell_color.
lv_cell_value = gs_vbak-erdat1.
PERFORM add_item_cell USING lv_cell_value lv_cell_color.
PERFORM end_row.
CLEAR lv_cell_value .
ENDLOOP.
PERFORM end_table.
perform add_page_footer.
ENDFORM. " F_CREATE_MAIL_BODY
*&---------------------------------------------------------------------*
*& Form F_SEND_MAIL
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM f_send_mail .
DATA: lv_address TYPE adr6-smtp_addr,
lv_error_msg TYPE string,
ls_email LIKE LINE OF s_email.
TRY.
* -------- create persistent send request ------------------------
send_request = cl_bcs=>create_persistent( ).
subject = text-i07.
document = cl_document_bcs=>create_document(
i_type = 'HTM'
i_text = gt_page
i_subject = subject ).
* add document to send request
CALL METHOD send_request->set_document( document ).
LOOP AT s_email INTO ls_email.
lv_address = ls_email-low.
recipient = cl_cam_address_bcs=>create_internet_address(
lv_address ).
CALL METHOD send_request->add_recipient
EXPORTING
i_recipient = recipient
i_express = gc_x.
CLEAR ls_email.
ENDLOOP.
CALL METHOD send_request->send(
EXPORTING
i_with_error_screen = gc_x
RECEIVING
result = sent_to_all ).
IF sent_to_all = gc_x.
FORMAT COLOR COL_POSITIVE INVERSE.
WRITE text-s08. "Mail dispatched successfully
ENDIF.
COMMIT WORK.
CATCH cx_bcs INTO bcs_exception.
lv_error_msg = bcs_exception->get_text( ).
FORMAT COLOR COL_NEGATIVE INVERSE.
WRITE:/ text-e03, "Mail trigger failed. Error:
lv_error_msg.
EXIT.
ENDTRY.
ENDFORM. " F_SEND_MAIL
*&---------------------------------------------------------------------*
*& Form ADD_PAGE_HEADER
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_LV_PAGE_HEADER text
* -->P_LV_FONT_SIZE text
*----------------------------------------------------------------------*
FORM add_page_header USING p_lv_page_header TYPE soli-line
p_lv_font_size TYPE numc4
p_lv_font_type TYPE char20
p_lv_font_color TYPE soli-line.
DATA: lw_page_line TYPE LINE OF soli_tab.
MOVE '<html>' TO lw_page_line. APPEND lw_page_line TO gt_page.
MOVE '<head>' TO lw_page_line. APPEND lw_page_line TO gt_page.
MOVE p_lv_page_header TO lw_page_line. APPEND lw_page_line TO gt_page.
MOVE '</head>' TO lw_page_line. APPEND lw_page_line TO gt_page.
MOVE '<body>' TO lw_page_line. APPEND lw_page_line TO gt_page.
IF p_lv_font_size IS NOT INITIAL
OR p_lv_font_type IS NOT INITIAL
OR p_lv_font_color IS NOT INITIAL.
MOVE '<font' TO lw_page_line.
IF p_lv_font_size IS NOT INITIAL.
CONCATENATE lw_page_line ' size="' p_lv_font_size '"' INTO
lw_page_line.
ENDIF.
IF p_lv_font_type IS NOT INITIAL.
CONCATENATE lw_page_line ' face="' p_lv_font_type '"' INTO
lw_page_line.
ENDIF.
IF p_lv_font_color IS NOT INITIAL.
CONCATENATE lw_page_line ' color="' p_lv_font_color '"' INTO
lw_page_line.
ENDIF.
CONCATENATE lw_page_line '>' INTO lw_page_line SEPARATED BY space.
APPEND lw_page_line TO gt_page.
ENDIF.
ENDFORM. " ADD_PAGE_HEADER
*&---------------------------------------------------------------------*
*& Form START_TABLE
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_LV_BORDER text
* -->P_LV_CELLPADDING text
* -->P_LV_CAPTION text
*----------------------------------------------------------------------*
FORM start_table USING p_lv_border TYPE numc4
p_lv_cellpadding TYPE numc4
p_lv_caption TYPE string.
DATA: lw_page_line TYPE soli.
IF p_lv_border IS NOT INITIAL
OR p_lv_cellpadding IS NOT INITIAL.
MOVE '<table cellspacing="10"' TO lw_page_line.
IF p_lv_border IS NOT INITIAL.
CONCATENATE lw_page_line ' border="' p_lv_border '"' INTO
lw_page_line.
ENDIF.
IF p_lv_cellpadding IS NOT INITIAL.
CONCATENATE lw_page_line ' cellpadding="' p_lv_cellpadding '"'
INTO lw_page_line.
ENDIF.
CONCATENATE lw_page_line ' >' INTO lw_page_line.
ELSE.
MOVE '<table cellspacing="10">' TO lw_page_line.
ENDIF.
APPEND lw_page_line TO gt_page.
IF p_lv_caption IS NOT INITIAL.
CONCATENATE '<font face="verdana" color="#CC0066"><h2>'
p_lv_caption ' </h2></font>' INTO lw_page_line.
APPEND lw_page_line TO gt_page.
MOVE '<tr> </tr>' TO lw_page_line.
APPEND lw_page_line TO gt_page.
ENDIF.
ENDFORM. " START_TABLE
*&---------------------------------------------------------------------*
*& Form START_ROW
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM start_row .
DATA: lw_page_line TYPE soli.
MOVE '<tr>' TO lw_page_line.
APPEND lw_page_line TO gt_page.
ENDFORM. " START_ROW
*&---------------------------------------------------------------------*
*& Form ADD_HEADER_CELL
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_LV_CELL_VALUE text
* -->P_LV_WIDTH text
*----------------------------------------------------------------------*
FORM add_header_cell USING p_lv_cell_value TYPE string
p_lv_width TYPE char20.
DATA: lw_page_line TYPE soli.
MOVE '<th align="left"' TO lw_page_line.
IF p_lv_width IS NOT INITIAL.
CONCATENATE lw_page_line 'width="' p_lv_width '">'
INTO lw_page_line SEPARATED BY space.
ELSE.
CONCATENATE lw_page_line '>'
INTO lw_page_line SEPARATED BY space.
ENDIF.
CONCATENATE lw_page_line p_lv_cell_value '</th>'
INTO lw_page_line.
APPEND lw_page_line TO gt_page.
ENDFORM. " ADD_HEADER_CELL
*&---------------------------------------------------------------------*
*& Form END_ROW
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM end_row .
DATA: lw_page_line TYPE soli.
MOVE '</tr>' TO lw_page_line.
APPEND lw_page_line TO gt_page.
ENDFORM. " END_ROW
*&---------------------------------------------------------------------*
*& Form ADD_ITEM_CELL
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_LV_CELL_VALUE text
* -->P_LV_CELL_COLOR text
*----------------------------------------------------------------------*
FORM add_item_cell USING p_lv_cell_value TYPE string
p_lv_cell_color TYPE char20.
DATA: lw_page_line TYPE soli.
CONCATENATE '<td> <font color="' p_lv_cell_color '">' p_lv_cell_value
'</font></td>' INTO lw_page_line.
APPEND lw_page_line TO gt_page.
ENDFORM. " ADD_ITEM_CELL
*&---------------------------------------------------------------------*
*& Form END_TABLE
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM end_table .
DATA: lw_page_line TYPE soli.
MOVE '</table>' TO lw_page_line.
APPEND lw_page_line TO gt_page.
ENDFORM. " END_TABLE
*&---------------------------------------------------------------------*
*& Form ADD_PAGE_FOOTER
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
form ADD_PAGE_FOOTER .
DATA: lw_page_line TYPE LINE OF SOLI_TAB.
MOVE '</font>' TO lw_page_line. APPEND lw_page_line TO gt_page.
MOVE '</body>' TO lw_page_line. APPEND lw_page_line TO gt_page.
MOVE '</html>' TO lw_page_line. APPEND lw_page_line TO gt_page.
endform. " ADD_PAGE_FOOTER
Above program contains different reusable subroutines for creation of html page and finally all subroutine appending lines in global internal table gt_page this table is responsible for mail body creation, following are the function of subroutines :
add_page_header: This routine should call once in program execution and responsible to set page attributes like page heading, font, font type, color.
start_table: Whenever table creation is required this routine should call with parameter like border(thickness of cell border, if set 0 then no border will appear), cellpadding (space between cell and variable) and caption(table caption).
End_table:This routine called when complete table has been built for display, each start_table call should end with end_table call.
Start_row: create new row in table.
End_row: notifying for end of row, should call to end each start_row function.
add_header_cell: will create a header lable for table created, will take parameter like caption for label and width for column.
add_item_cell: will create item row for table created, will take parameter like caption for item row, generally this routine should call in loop processing.
Below screenshot refering HTML Email body in SOST transaction:
And here is the Microsoft Outlook E-Mail looks like:
Thanks and Regards,
Gagan Choudha