After discussing how to send e-mails from SAP in yesterday’s post, today I want to take it a bit further and explain how to add attachments or even executable SAP transactions to these mails.
Sending e-mails with attachments from SAP
Attaching a file to an e-mail in SAP ERP is not really hard. Basically, it consists of three steps:
- Create a document (FM SO_DOCUMENT_INSERT_API1)
- Attach some binary content to that document (FM SO_ATTACHMENT_INSERT_API1)
- Send the document (FM SO_OLD_DOCUMENT_SEND_API1)
Sounds like a bit of function module action, right? Luckily, there’s another catch-em-all function module available in function group SOI1: The function module SO_NEW_DOCUMENT_ATT_SEND_API1 will do everything you want in one simple step.
When it comes to the attached file, there are three common options of how the attachment is created:
- It is uploaded to SAP ERP by the user, using for example CL_GUI_FRONTEND_SERVICES.
- It is read from a previously uploaded file using the OPEN DATASET command
- It is generated from the program itself, e.g. by submitting a report to spool and converting that to PDF within SAP (there will be another article describing how to do this soon)
In my example, I’m going to attach just a few lines of text as a .txt file in order to make it not too complicated – the basic steps remain the same anyway.
You should already know how to fill the parameters that are related to the e-mail itself, so I’m not going over that again (if you don’t, read yesterday’s post). Instead, let’s focus on the parameters and input tables required to make the file attachment work.
Compared to SO_NEW_DOCUMENT_SEND_API1, the function module SO_NEW_DOCUMENT_ATT_SEND_API1 has one additional mandatory parameter which is called packing_list. This parameter is a bit tricky. To understand it, you must be aware that all of the email content – email body as well as attachments – goes into the same tables. The packing list defines which lines of these tables belong to which objects (email body or attachments). The packing list also contains the metadata of the e-mail parts, including the document type (e.g. “RAW”). From a technical perspective, we’re now sending a so-called multipart e-mail (MIME type multipart/mixed) instead of a plain text one (MIME type text/plain).
Let’s look at the necessary steps we need to execute. I’m omitting the variable definitions here, you’ll find the entire sample program on the second page of this article. First, we fill our content table with the e-mail body content.
* Fill the mail contents ls_objcont-line = 'Test e-mail with attachment'. APPEND ls_objcont TO lt_objcont. ls_objcont-line = 'Second line of text'. APPEND ls_objcont TO lt_objcont.
We now have two lines of text in our content table. Now we need to tell the packing list about that.
* E-mail body starts at first line ls_packing_list-body_start = 1. * Length equals the table length DESCRIBE TABLE lt_objcont LINES lv_body_length. ls_packing_list-body_num = lv_body_length. * The doc type for the e-mail body is now defined here ls_packing_list-doc_type = 'RAW'. * The remaining fields stay empty for the first line APPEND ls_packing_list TO lt_packing_list.
Quite easy so far. Now we just append the content of the attachment directly after the content of the e-mail body.
* Fill in the next lines, these contain the attachment ls_objcont-line = 'First line of attached txt file'. APPEND ls_objcont TO lt_objcont. ls_objcont-line = 'Second line of attached txt file'. APPEND ls_objcont TO lt_objcont. ls_objcont-line = 'Third line of attached txt file'. APPEND ls_objcont TO lt_objcont.
And again, the packing list needs to know about that attachment. This time, the calculation is a bit trickier and we have to fill more fields.
* Create the packing list entry for the attachment CLEAR ls_packing_list. ls_packing_list-head_start = 1. ls_packing_list-head_num = 1. * The attachment starts where the e-mail body stopped ls_packing_list-body_start = 1 + lv_body_length. DESCRIBE TABLE lt_objcont LINES lv_attc_length. * Substract the length of the email body from total lv_attc_length = lv_attc_length - lv_body_length. ls_packing_list-body_num = lv_attc_length. * Fill the rest of the fields for the attachment ls_packing_list-doc_type = 'RAW'. ls_packing_list-obj_name = 'textfile.txt'. ls_packing_list-obj_descr = 'Some text file'. ls_packing_list-doc_size = 255 * lv_attc_length. APPEND ls_packing_list TO lt_packing_list.
Almost done! All you need to do now is fill the receivers and document metadata parameters. Then you can supply all this data to the function module SO_NEW_DOCUMENT_ATT_SEND_API1 and fire off your e-mail. You can monitor it with the SCOT transaction just like before.
Be aware which tables you’re using, though. In this example, both our e-mail body and the attachment were plain ASCII text. If you’re sending a binary file as an attachment (such as a PDF), you will need to use the CONTENTS_BIN table instead of the CONTENTS_TXT. The packing list needs to know about this by setting the flag TRANSF_BIN in the respective packing list entry.
And that’s it! Check out the next page to find out how to attach executable transaction or even program links to an e-mail sent from SAP.