Email-Versand in ABAP erfolgt über das BCS-Framework (Business Communication Services). Mit CL_BCS können E-Mails mit Text, HTML-Inhalt und Anhängen versendet werden.
BCS-Klassen
| Klasse | Beschreibung |
|---|---|
CL_BCS | Hauptklasse für E-Mail-Versand |
CL_DOCUMENT_BCS | E-Mail-Dokument (Body, Anhänge) |
CL_CAM_ADDRESS_BCS | Externe E-Mail-Adresse |
CL_SAPUSER_BCS | SAP-Benutzer als Empfänger |
Beispiele
1. Einfache E-Mail senden
DATA: lo_bcs TYPE REF TO cl_bcs, lo_document TYPE REF TO cl_document_bcs, lo_sender TYPE REF TO cl_sapuser_bcs, lo_recipient TYPE REF TO if_recipient_bcs.
TRY. " BCS-Instanz erstellen lo_bcs = cl_bcs=>create_persistent( ).
" Dokument erstellen DATA(lt_text) = VALUE soli_tab( ( line = 'Sehr geehrte Damen und Herren,' ) ( line = '' ) ( line = 'dies ist eine Testnachricht.' ) ( line = '' ) ( line = 'Mit freundlichen Grüßen' ) ( line = 'Ihr SAP-System' ) ).
lo_document = cl_document_bcs=>create_document( i_type = 'RAW' " Textformat i_text = lt_text i_subject = 'Testmail aus SAP' ).
lo_bcs->set_document( lo_document ).
" Absender (aktueller Benutzer) lo_sender = cl_sapuser_bcs=>create( sy-uname ). lo_bcs->set_sender( lo_sender ).
" Empfänger lo_recipient = cl_cam_address_bcs=>create_internet_address( 'empfaenger@example.com' ). lo_bcs->add_recipient( lo_recipient ).
" Senden DATA(lv_sent) = lo_bcs->send( ).
IF lv_sent = abap_true. COMMIT WORK. WRITE: / 'E-Mail wurde gesendet'. ENDIF.
CATCH cx_bcs INTO DATA(lx_error). WRITE: / 'Fehler:', lx_error->get_text( ).ENDTRY.2. HTML-E-Mail
TRY. DATA(lo_bcs) = cl_bcs=>create_persistent( ).
" HTML-Inhalt DATA(lt_html) = VALUE soli_tab( ( line = '<html><body>' ) ( line = '<h1>Willkommen</h1>' ) ( line = '<p>Dies ist eine <b>HTML-E-Mail</b>.</p>' ) ( line = '<table border="1">' ) ( line = '<tr><th>Position</th><th>Menge</th></tr>' ) ( line = '<tr><td>Material A</td><td>100</td></tr>' ) ( line = '<tr><td>Material B</td><td>250</td></tr>' ) ( line = '</table>' ) ( line = '</body></html>' ) ).
DATA(lo_document) = cl_document_bcs=>create_document( i_type = 'HTM' " HTML-Format i_text = lt_html i_subject = 'HTML-Testmail' ).
lo_bcs->set_document( lo_document ).
" Absender und Empfänger... lo_bcs->set_sender( cl_sapuser_bcs=>create( sy-uname ) ). lo_bcs->add_recipient( cl_cam_address_bcs=>create_internet_address( 'user@example.com' ) ).
lo_bcs->send( ). COMMIT WORK.
CATCH cx_bcs INTO DATA(lx_error). WRITE: / lx_error->get_text( ).ENDTRY.3. E-Mail mit Anhang
TRY. DATA(lo_bcs) = cl_bcs=>create_persistent( ).
" Hauptdokument (Body) DATA(lt_body) = VALUE soli_tab( ( line = 'Anbei finden Sie die angeforderten Daten.' ) ).
DATA(lo_document) = cl_document_bcs=>create_document( i_type = 'RAW' i_text = lt_body i_subject = 'Datenexport' ).
" CSV als Anhang erstellen DATA(lt_csv) = VALUE soli_tab( ( line = 'Kunde;Name;Ort' ) ( line = '1000;Müller GmbH;Berlin' ) ( line = '1001;Schmidt AG;Hamburg' ) ( line = '1002;Weber KG;München' ) ).
lo_document->add_attachment( i_attachment_type = 'CSV' i_attachment_subject = 'kunden_export.csv' i_att_content_text = lt_csv ).
lo_bcs->set_document( lo_document ). lo_bcs->set_sender( cl_sapuser_bcs=>create( sy-uname ) ). lo_bcs->add_recipient( cl_cam_address_bcs=>create_internet_address( 'user@example.com' ) ).
lo_bcs->send( ). COMMIT WORK.
CATCH cx_bcs INTO DATA(lx_error). WRITE: / lx_error->get_text( ).ENDTRY.4. Binärer Anhang (PDF, Excel)
TRY. DATA(lo_bcs) = cl_bcs=>create_persistent( ).
DATA(lt_body) = VALUE soli_tab( ( line = 'Anbei das PDF-Dokument.' ) ).
DATA(lo_document) = cl_document_bcs=>create_document( i_type = 'RAW' i_text = lt_body i_subject = 'PDF-Dokument' ).
" PDF-Daten (z.B. aus Smartform) DATA: lv_pdf_xstring TYPE xstring. " ... PDF generieren ...
" XString in SOLIX-Tabelle konvertieren DATA(lt_pdf_content) = cl_bcs_convert=>xstring_to_solix( lv_pdf_xstring ). DATA(lv_size) = xstrlen( lv_pdf_xstring ).
lo_document->add_attachment( i_attachment_type = 'PDF' i_attachment_subject = 'dokument.pdf' i_attachment_size = lv_size i_att_content_hex = lt_pdf_content ).
lo_bcs->set_document( lo_document ). lo_bcs->set_sender( cl_sapuser_bcs=>create( sy-uname ) ). lo_bcs->add_recipient( cl_cam_address_bcs=>create_internet_address( 'user@example.com' ) ).
lo_bcs->send( ). COMMIT WORK.
CATCH cx_bcs INTO DATA(lx_error). WRITE: / lx_error->get_text( ).ENDTRY.5. Mehrere Empfänger (TO, CC, BCC)
TRY. DATA(lo_bcs) = cl_bcs=>create_persistent( ).
" Dokument erstellen... DATA(lo_document) = cl_document_bcs=>create_document( i_type = 'RAW' i_text = VALUE soli_tab( ( line = 'Nachricht an mehrere Empfänger' ) ) i_subject = 'Info an Team' ). lo_bcs->set_document( lo_document ).
" Absender lo_bcs->set_sender( cl_sapuser_bcs=>create( sy-uname ) ).
" TO-Empfänger lo_bcs->add_recipient( i_recipient = cl_cam_address_bcs=>create_internet_address( 'chef@example.com' ) i_express = abap_true " Sofort senden ).
" CC-Empfänger lo_bcs->add_recipient( i_recipient = cl_cam_address_bcs=>create_internet_address( 'team@example.com' ) i_copy = abap_true " CC ).
" BCC-Empfänger lo_bcs->add_recipient( i_recipient = cl_cam_address_bcs=>create_internet_address( 'archiv@example.com' ) i_blind = abap_true " BCC ).
" SAP-Benutzer als Empfänger lo_bcs->add_recipient( i_recipient = cl_sapuser_bcs=>create( 'MUSTERMANN' ) ).
lo_bcs->send( ). COMMIT WORK.
CATCH cx_bcs INTO DATA(lx_error). WRITE: / lx_error->get_text( ).ENDTRY.6. Email Helper Klasse
CLASS zcl_email_sender DEFINITION. PUBLIC SECTION. TYPES: ty_recipients TYPE TABLE OF string WITH EMPTY KEY, ty_attachments TYPE TABLE OF string WITH EMPTY KEY.
METHODS: constructor.
METHODS: set_subject IMPORTING iv_subject TYPE string RETURNING VALUE(ro_self) TYPE REF TO zcl_email_sender.
METHODS: set_body_text IMPORTING iv_text TYPE string RETURNING VALUE(ro_self) TYPE REF TO zcl_email_sender.
METHODS: set_body_html IMPORTING iv_html TYPE string RETURNING VALUE(ro_self) TYPE REF TO zcl_email_sender.
METHODS: add_recipient IMPORTING iv_email TYPE string iv_copy TYPE abap_bool DEFAULT abap_false iv_blind TYPE abap_bool DEFAULT abap_false RETURNING VALUE(ro_self) TYPE REF TO zcl_email_sender.
METHODS: add_attachment_text IMPORTING iv_filename TYPE string iv_content TYPE string RETURNING VALUE(ro_self) TYPE REF TO zcl_email_sender.
METHODS: add_attachment_binary IMPORTING iv_filename TYPE string iv_content TYPE xstring RETURNING VALUE(ro_self) TYPE REF TO zcl_email_sender.
METHODS: send RETURNING VALUE(rv_success) TYPE abap_bool.
METHODS: get_error_message RETURNING VALUE(rv_message) TYPE string.
PRIVATE SECTION. DATA: mo_bcs TYPE REF TO cl_bcs, mo_document TYPE REF TO cl_document_bcs, mv_error TYPE string.
METHODS: string_to_soli IMPORTING iv_string TYPE string RETURNING VALUE(rt_lines) TYPE soli_tab.
METHODS: get_file_extension IMPORTING iv_filename TYPE string RETURNING VALUE(rv_extension) TYPE string.ENDCLASS.
CLASS zcl_email_sender IMPLEMENTATION. METHOD constructor. TRY. mo_bcs = cl_bcs=>create_persistent( ). CATCH cx_bcs. ENDTRY. ENDMETHOD.
METHOD set_subject. " Subject wird beim Dokument-Erstellen gesetzt ro_self = me. ENDMETHOD.
METHOD set_body_text. TRY. mo_document = cl_document_bcs=>create_document( i_type = 'RAW' i_text = string_to_soli( iv_text ) i_subject = 'Nachricht' ). CATCH cx_document_bcs. ENDTRY. ro_self = me. ENDMETHOD.
METHOD set_body_html. TRY. mo_document = cl_document_bcs=>create_document( i_type = 'HTM' i_text = string_to_soli( iv_html ) i_subject = 'Nachricht' ). CATCH cx_document_bcs. ENDTRY. ro_self = me. ENDMETHOD.
METHOD add_recipient. TRY. mo_bcs->add_recipient( i_recipient = cl_cam_address_bcs=>create_internet_address( iv_email ) i_copy = iv_copy i_blind = iv_blind ). CATCH cx_bcs. ENDTRY. ro_self = me. ENDMETHOD.
METHOD add_attachment_text. TRY. DATA(lv_ext) = get_file_extension( iv_filename ). mo_document->add_attachment( i_attachment_type = lv_ext i_attachment_subject = iv_filename i_att_content_text = string_to_soli( iv_content ) ). CATCH cx_document_bcs. ENDTRY. ro_self = me. ENDMETHOD.
METHOD add_attachment_binary. TRY. DATA(lv_ext) = get_file_extension( iv_filename ). DATA(lt_content) = cl_bcs_convert=>xstring_to_solix( iv_content ).
mo_document->add_attachment( i_attachment_type = lv_ext i_attachment_subject = iv_filename i_attachment_size = xstrlen( iv_content ) i_att_content_hex = lt_content ). CATCH cx_document_bcs. ENDTRY. ro_self = me. ENDMETHOD.
METHOD send. TRY. mo_bcs->set_document( mo_document ). mo_bcs->set_sender( cl_sapuser_bcs=>create( sy-uname ) ).
rv_success = mo_bcs->send( ).
IF rv_success = abap_true. COMMIT WORK. ENDIF.
CATCH cx_bcs INTO DATA(lx_error). mv_error = lx_error->get_text( ). rv_success = abap_false. ENDTRY. ENDMETHOD.
METHOD get_error_message. rv_message = mv_error. ENDMETHOD.
METHOD string_to_soli. SPLIT iv_string AT cl_abap_char_utilities=>newline INTO TABLE DATA(lt_lines). LOOP AT lt_lines INTO DATA(lv_line). APPEND VALUE #( line = lv_line ) TO rt_lines. ENDLOOP. ENDMETHOD.
METHOD get_file_extension. DATA(lv_pos) = find( val = iv_filename sub = '.' occ = -1 ). IF lv_pos > 0. rv_extension = to_upper( iv_filename+lv_pos ). ELSE. rv_extension = 'BIN'. ENDIF. ENDMETHOD.ENDCLASS.
" VerwendungDATA(lo_email) = NEW zcl_email_sender( ).
DATA(lv_success) = lo_email->set_body_html( '<html><body><h1>Report</h1><p>Daten im Anhang</p></body></html>')->add_recipient( 'empfaenger@example.com')->add_recipient( iv_email = 'cc@example.com' iv_copy = abap_true)->add_attachment_text( iv_filename = 'daten.csv' iv_content = 'A;B;C' && cl_abap_char_utilities=>newline && '1;2;3')->send( ).
IF lv_success = abap_false. WRITE: / lo_email->get_error_message( ).ENDIF.7. E-Mail aus Smartform
" Smartform als PDF generieren und per E-Mail sendenDATA: lv_pdf TYPE xstring, lt_lines TYPE TABLE OF tline, lv_function TYPE rs38l_fnam.
" Smartform-Funktionsbaustein ermittelnCALL FUNCTION 'SSF_FUNCTION_MODULE_NAME' EXPORTING formname = 'ZSMARFORM_ORDER' IMPORTING fm_name = lv_function EXCEPTIONS no_form = 1 no_function_module = 2 OTHERS = 3.
" PDF generierenDATA: ls_output_options TYPE ssfcompop, ls_control TYPE ssfctrlop.
ls_output_options-tdgetotf = abap_true.ls_control-no_dialog = abap_true.ls_control-getotf = abap_true.
CALL FUNCTION lv_function EXPORTING control_parameters = ls_control output_options = ls_output_options is_order = ls_order IMPORTING job_output_info = DATA(ls_job_info) EXCEPTIONS OTHERS = 1.
" OTF nach PDF konvertierenCALL FUNCTION 'CONVERT_OTF' EXPORTING format = 'PDF' IMPORTING bin_file = lv_pdf TABLES otf = ls_job_info-otfdata lines = lt_lines EXCEPTIONS OTHERS = 1.
" Per E-Mail sendenDATA(lo_email) = NEW zcl_email_sender( ).lo_email->set_body_text( 'Anbei Ihre Bestellbestätigung.' ).lo_email->add_recipient( 'kunde@example.com' ).lo_email->add_attachment_binary( iv_filename = 'bestellung.pdf' iv_content = lv_pdf).lo_email->send( ).8. E-Mail-Vorlagen
CLASS zcl_email_template DEFINITION. PUBLIC SECTION. METHODS: constructor IMPORTING iv_template_id TYPE string.
METHODS: set_placeholder IMPORTING iv_name TYPE string iv_value TYPE string RETURNING VALUE(ro_self) TYPE REF TO zcl_email_template.
METHODS: get_subject RETURNING VALUE(rv_subject) TYPE string.
METHODS: get_body RETURNING VALUE(rv_body) TYPE string.
PRIVATE SECTION. DATA: mv_subject TYPE string, mv_body TYPE string, mt_placeholders TYPE TABLE OF string.ENDCLASS.
CLASS zcl_email_template IMPLEMENTATION. METHOD constructor. " Vorlage aus Datenbank/Customizing laden CASE iv_template_id. WHEN 'ORDER_CONFIRMATION'. mv_subject = 'Bestellbestätigung {{ORDER_NO}}'. mv_body = |<html><body>| && |<h1>Vielen Dank für Ihre Bestellung</h1>| && |<p>Ihre Bestellnummer: <b>\{\{ORDER_NO\}\}</b></p>| && |<p>Kunde: \{\{CUSTOMER_NAME\}\}</p>| && |<p>Betrag: \{\{AMOUNT\}\} \{\{CURRENCY\}\}</p>| && |</body></html>|.
WHEN 'SHIPPING_NOTICE'. mv_subject = 'Versandbenachrichtigung {{DELIVERY_NO}}'. mv_body = '...'. ENDCASE. ENDMETHOD.
METHOD set_placeholder. REPLACE ALL OCCURRENCES OF |{\\{{iv_name}\\}}| IN mv_subject WITH iv_value. REPLACE ALL OCCURRENCES OF |{\\{{iv_name}\\}}| IN mv_body WITH iv_value. ro_self = me. ENDMETHOD.
METHOD get_subject. rv_subject = mv_subject. ENDMETHOD.
METHOD get_body. rv_body = mv_body. ENDMETHOD.ENDCLASS.
" VerwendungDATA(lo_template) = NEW zcl_email_template( 'ORDER_CONFIRMATION' ).lo_template->set_placeholder( iv_name = 'ORDER_NO' iv_value = '0000001234' ).lo_template->set_placeholder( iv_name = 'CUSTOMER_NAME' iv_value = 'Müller GmbH' ).lo_template->set_placeholder( iv_name = 'AMOUNT' iv_value = '1.234,50' ).lo_template->set_placeholder( iv_name = 'CURRENCY' iv_value = 'EUR' ).
DATA(lo_email) = NEW zcl_email_sender( ).lo_email->set_body_html( lo_template->get_body( ) ).lo_email->add_recipient( 'kunde@example.com' ).lo_email->send( ).9. E-Mail-Status prüfen
" Gesendete E-Mails in SOST anzeigen" Transaktion: SOST (SAPconnect-Sendeaufträge)
" Programmatisch Status prüfenDATA: lt_messages TYPE TABLE OF soos1.
CALL FUNCTION 'SO_OBJECT_READ' EXPORTING folder_id = 'OUTBOX' object_id = lv_object_id TABLES objhead = lt_objhead objcont = lt_objcont EXCEPTIONS OTHERS = 1.10. Sofortversand aktivieren
TRY. DATA(lo_bcs) = cl_bcs=>create_persistent( ).
" ... Dokument und Empfänger ...
" Sofortversand (nicht warten auf Job) lo_bcs->set_send_immediately( abap_true ).
lo_bcs->send( ). COMMIT WORK AND WAIT. " Warten auf Commit
CATCH cx_bcs INTO DATA(lx_error). " ...ENDTRY.
" Alternative: SAPconnect Job manuell startenCALL FUNCTION 'RSCP_START_SENDING' EXCEPTIONS OTHERS = 1.Wichtige Transaktionen
| Transaktion | Beschreibung |
|---|---|
| SOST | Sendeaufträge anzeigen |
| SCOT | SAPconnect Administration |
| SO01 | SAP Office Eingang |
Wichtige Hinweise / Best Practice
- COMMIT WORK nach send( ) nicht vergessen.
- cl_bcs=>create_persistent für dauerhaften Versand.
- HTM-Typ für HTML-E-Mails verwenden.
- Binäre Anhänge über solix-Tabelle.
- SOST zum Prüfen des Sendestatus.
- set_send_immediately für sofortigen Versand.
- Vorlagen für wiederkehrende E-Mail-Typen.
- Fehlerbehandlung mit TRY-CATCH.
- In ABAP Cloud: Alternative APIs nutzen.
- Kombinieren Sie mit Smartforms für PDF-Generierung.