Example: Adding Attachments
The
Collections of the
print workbench enable you to attach documents to an e-mail. In the standard
SAP system, these documents are application forms of the print workbench. You
can also include other documents that exist as references to instances of
class CL_DOCUMENT_BCS. The
documents can be text documents, images, or they can have other formats. In
this example, a calendar entry is generated in vCalendar format. vCalendar
format is a standard format for swapping calendar entries, which is used by
most Personal Information Managers (PIM).
For detailed
information about collections, see the documentation for the
print workbench.

Attachments are not displayed in the correspondence request preview.
You can use this example for a booking confirmation for classroom training. The following vCalendar entry should be output, whereby data in <<...>> should be replaced by text variables:
BEGIN:vCalendar
VERSION:1.0
BEGIN:vEvent
ORGANIZER:MAILTO:<<sender>>
ATTENDEE;ROLE=ATTENDEE:<<Learner
name>> < <<Learner Mail address>> <
DTSTART:<<Start date>>T<<Start time>>
DTEND:<<End date>>T<<End time>>
LOCATION:<<Ort>>
<<Room>>
SUMMARY;ENCODING=QUOTED-PRINTABLE:<<Course
name>>
DESCRIPTION: <<Course name>>
CATEGORIES;ENCODING=QUOTED-PRINTABLE:EDUCATION
CLASS:PUBLIC
END:vEvent
END:vCalendar
We recommend that you do not generate a document in an exit of the print workbench. You should create a special modularization unit for this purpose, for example, an ABAP class so that you can reuse the attachment in multiple application forms. The code for this example is delivered in the method CREATE_VCAL of class CL_LSO_CRP_RENDER_EXAMPLE. This class has example status, it is not intended for productive use.
The method for creating a vCalendar entry has as its import parameter IM_READER a reference to an instance of class IF_LSO_CRP_RENDER_READER and as return parameter RESULT a reference to an instance of class CL_DOCUMENT_BCS.
You must first identify the text variables required for setting up the vCalendar entry.
METHOD create_vcal.
“ IMPORTING IM_READER TYPE REF TO IF_LSO_CRP_RENDER_READER
“ RETURNING RESULT TYPE REF TO CL_DOCUMENT_BCS
DATA: BEGIN OF ls_data,
sender TYPE lsoppvar-sender, "sender
kbgda TYPE ppvar-kbgda, "begin date
kndda TYPE ppvar-endda, "end date
kbtim TYPE ppvar-kbtim, "begin time first day
ketim TYPE ppvar-ketim, "end time last day
kstxt TYPE ppvar-kstxt, "training text
b_ort TYPE ppvar-b_ort, "training location
rstxt TYPE ppvar-rstxt, "room text
amail TYPE lsoppvar-amail, "recipient eMail
astxt TYPE ppvar-astxt, "recipient
END OF ls_data.
You can read these text variables using an instance of class CL_LSO_CRP_RENDER_READER. If an exception is triggered, processing must be cancelled, since the vCalendar entry will otherwise be incomplete.
DATA: lr_data TYPE REF TO data.
TRY.
GET REFERENCE OF ls_data INTO lr_data.
CALL METHOD im_reader->read_value
CHANGING
value = lr_data.
CATCH cx_root.
EXIT.
ENDTRY.
You can now set up the entry as a table of type SOLI_TAB with the text variables. This table type is required later for the BCSdocument:
DATA: lt_soli TYPE soli_tab .
DATA: l_subject TYPE so_obj_des.
DATA: ls_soli LIKE LINE OF lt_soli.
CONCATENATE text-001 ls_data-kstxt INTO l_subject SEPARATED BY space.
* BEGIN:VCALENDAR
ls_soli-line = 'BEGIN:VCALENDAR'.
APPEND ls_soli TO lt_soli.
* BEGIN:VCALENDAR
ls_soli-line = 'VERSION:1.0'.
APPEND ls_soli TO lt_soli.
* BEGIN:VEVENT
ls_soli-line = 'BEGIN:VEVENT'.
APPEND ls_soli TO lt_soli.
* ORGANIZER
CONCATENATE 'ORGANIZER:MAILTO:' ls_data-sender-smail INTO ls_soli-line.
APPEND ls_soli TO lt_soli.
* ATTENDEE
CONCATENATE 'ATTENDEE;ROLE=ATTENDEE:' ls_data-astxt '<' ls_data-amail '> '
INTO ls_soli-line.
APPEND ls_soli TO lt_soli.
* DTSTART
CONCATENATE 'DTSTART:' ls_data-kbgda 'T' INTO ls_soli-line.
IF NOT ls_data-kbtim IS INITIAL.
CONCATENATE ls_soli-line ls_data-kbtim INTO ls_soli-line.
ENDIF.
APPEND ls_soli TO lt_soli.
* DTEND
CONCATENATE 'DTEND:' ls_data-kndda 'T' INTO ls_soli-line.
IF NOT ls_data-kbtim IS INITIAL.
CONCATENATE ls_soli-line ls_data-ketim INTO ls_soli-line.
ENDIF.
APPEND ls_soli TO lt_soli.
* LOCATION
IF NOT ls_data-b_ort IS INITIAL OR NOT ls_data-rstxt IS INITIAL.
CONCATENATE 'LOCATION:' ls_data-b_ort ls_data-rstxt INTO ls_soli-line
SEPARATED BY space.
APPEND ls_soli TO lt_soli.
ENDIF.
* CATEGORIES
ls_soli-line = 'CATEGORIES;ENCODING=QUOTED-PRINTABLE:EDUCATION'.
APPEND ls_soli TO lt_soli.
* CLASS
ls_soli-line = 'CLASS:PUBLIC'.
APPEND ls_soli TO lt_soli.
* SUMMARY
CONCATENATE 'SUMMARY;ENCODING=QUOTED-PRINTABLE:' l_subject INTO ls_soli-line.
APPEND ls_soli TO lt_soli.
* DESCRIPTION
CONCATENATE 'DESCRIPTION:' l_subject INTO ls_soli-line.
APPEND ls_soli TO lt_soli.
* END:VEVENT
ls_soli-line = 'END:VEVENT'.
APPEND ls_soli TO lt_soli.
* END:VCALENDAR
ls_soli-line = 'END:VCALENDAR'.
APPEND ls_soli TO lt_soli.
Finally, you must insert line breaks in each line:
FIELD-SYMBOLS: <fs_soli> LIKE ls_soli.
* Add CR/LF
LOOP AT lt_soli ASSIGNING <fs_soli>.
<fs_soli>-line+253(2) = cl_abap_char_utilities=>cr_lf.
ENDLOOP.
The full vCalendar entry has now been created in table lt_soli and can be used to generate a BCS document:
TRY.
result = cl_document_bcs=>create_document(
i_type = 'VCS'
i_subject = l_subject
i_text = lt_soli
).
CATCH cx_document_bcs. "#EC NO_HANDLER
ENDTRY.
To be able to use this method, you must implement a user exit in the form class Collection of the print workbench. The exit has the following tasks:
...
1. Instantiating a reader class for text variables. The reader class is bound to the current context of the output document, by means of which participation-specific data is read.
2. Calling the method to generate a vCalendar entry.
3. The vCalendar entry generated must be added to table G_TAB_BCS_ATTACHMENTS.
For the first task, you must first read the correspondence request header LS_DFKKCOH of the correspondence tool. The ID of this is stored in the global tables XT_RANGES and XT_RANGES1 of the print workbench. You can generate an instance of the read class for text variables using the correspondence request header.
FORM user_exit_fill_attachment.
FIELD-SYMBOLS: <fs_range1> LIKE LINE OF xt_ranges.
FIELD-SYMBOLS: <fs_range2> LIKE LINE OF xt_ranges1.
DATA: lr_document TYPE REF TO cl_document_bcs.
DATA: ls_fkk_key TYPE lso_crp_fkk_key.
DATA: lr_reader TYPE REF TO if_lso_crp_render_reader.
READ TABLE xt_ranges ASSIGNING <fs_range1> INDEX 1.
CHECK sy-subrc IS INITIAL.
READ TABLE xt_ranges1 ASSIGNING <fs_range2> INDEX 1.
CHECK sy-subrc IS INITIAL.
ls_fkk_key-cotyp = <fs_range1>-low.
ls_fkk_key-cokey = <fs_range2>-low.
TRY.
lr_reader = cl_lso_crp_render_reader=>get( fkk_key = ls_fkk_key ).
The actual generation of the vCalendar entry can now be handled by simply calling a method:
* Create Appointment
lr_document = cl_lso_crp_render_example=>create_vcal( lr_reader ).
If no errors occur, the variable LR_DOCUMENT now contains a reference to the required vCalendar entry, which will be appended as an attachment:
* Add Appointment as Attachment
CHECK lr_document IS BOUND.
APPEND lr_document TO g_tab_bcs_attachments.
CATCH cx_lso_crp_exception.
ENDTRY.
ENDFORM. "USER_EXIT_FILL_ATTACHMENT
When you check the syntax of this exit in the print workbench, the variables XT_RANGES and XT_RANGES1 will be indicated as missing since they were declared in the main program. However, you can still generate the include without errors.