En ABAP, los correos electronicos se envian a traves de Business Communication Services (BCS). La clase CL_BCS proporciona una interfaz simple para crear, formatear y enviar correos electronicos desde sistemas SAP.
Componentes de BCS
| Clase | Descripcion |
|---|---|
CL_BCS | Clase principal para envio de correos |
CL_DOCUMENT_BCS | Documento (cuerpo del correo + adjuntos) |
CL_CAM_ADDRESS_BCS | Direccion de correo externa |
CL_SAPUSER_BCS | Usuario SAP como destinatario |
Requisitos
- SAPconnect debe estar configurado (transaccion SCOT)
- Autorizaciones para envio de correos
- El servidor SMTP debe estar configurado
Ejemplos
1. Correo simple
DATA: lo_bcs TYPE REF TO cl_bcs, lo_document TYPE REF TO cl_document_bcs, lo_recipient TYPE REF TO if_recipient_bcs, lv_text TYPE string.
TRY. " Crear instancia BCS lo_bcs = cl_bcs=>create_persistent( ).
" Crear documento (cuerpo del correo) lv_text = 'Este es el texto del correo.'.
lo_document = cl_document_bcs=>create_document( i_type = 'RAW' i_text = CONV #( VALUE soli_tab( ( line = lv_text ) ) ) i_subject = 'Asunto de prueba' ).
" Establecer documento lo_bcs->set_document( lo_document ).
" Establecer destinatario lo_recipient = cl_cam_address_bcs=>create_internet_address( ). lo_bcs->add_recipient( lo_recipient ).
" Enviar lo_bcs->send( ). COMMIT WORK.
WRITE: / 'Correo enviado exitosamente'.
CATCH cx_bcs INTO DATA(lx_bcs). WRITE: / 'Error:', lx_bcs->get_text( ).ENDTRY.2. Correo con multiples lineas de texto
DATA: lt_text TYPE soli_tab.
" Crear varias lineaslt_text = VALUE #( ( line = 'Estimado/a cliente,' ) ( line = '' ) ( line = 'Este es un correo de notificacion automatica.' ) ( line = 'Su pedido ha sido procesado.' ) ( line = '' ) ( line = 'Saludos cordiales,' ) ( line = 'Su equipo SAP' )).
lo_document = cl_document_bcs=>create_document( i_type = 'RAW' i_text = lt_text i_subject = 'Confirmacion de pedido').3. Correo HTML
DATA: lt_html TYPE soli_tab.
lt_html = VALUE #( ( line = '<html>' ) ( line = '<head><style>' ) ( line = 'body { font-family: Arial; }' ) ( line = '.header { color: #0066cc; font-size: 18px; }' ) ( line = '.content { margin-top: 20px; }' ) ( line = '</style></head>' ) ( line = '<body>' ) ( line = '<div class="header">Confirmacion de pedido</div>' ) ( line = '<div class="content">' ) ( line = '<p>Estimado/a cliente,</p>' ) ( line = '<p>Su pedido <b>4711</b> ha sido procesado.</p>' ) ( line = '<table border="1">' ) ( line = '<tr><th>Posicion</th><th>Material</th><th>Cantidad</th></tr>' ) ( line = '<tr><td>10</td><td>MAT-001</td><td>5</td></tr>' ) ( line = '<tr><td>20</td><td>MAT-002</td><td>3</td></tr>' ) ( line = '</table>' ) ( line = '</div>' ) ( line = '</body></html>' )).
lo_document = cl_document_bcs=>create_document( i_type = 'HTM' " HTML i_text = lt_html i_subject = 'Confirmacion de pedido #4711').4. HTML dinamico desde tabla de datos
METHOD create_html_table. DATA: lt_html TYPE soli_tab.
" Encabezado HTML APPEND VALUE #( line = '<html><body>' ) TO lt_html. APPEND VALUE #( line = '<h2>Informe de ventas</h2>' ) TO lt_html. APPEND VALUE #( line = '<table border="1" cellpadding="5">' ) TO lt_html. APPEND VALUE #( line = '<tr style="background:#eee">' ) TO lt_html. APPEND VALUE #( line = '<th>Cliente</th><th>Cantidad</th><th>Ventas</th>' ) TO lt_html. APPEND VALUE #( line = '</tr>' ) TO lt_html.
" Lineas de datos LOOP AT it_sales INTO DATA(ls_sale). APPEND VALUE #( line = '<tr>' ) TO lt_html. APPEND VALUE #( line = |<td>{ ls_sale-customer }</td>| ) TO lt_html. APPEND VALUE #( line = |<td>{ ls_sale-quantity }</td>| ) TO lt_html. APPEND VALUE #( line = |<td>{ ls_sale-amount }</td>| ) TO lt_html. APPEND VALUE #( line = '</tr>' ) TO lt_html. ENDLOOP.
" Fin HTML APPEND VALUE #( line = '</table></body></html>' ) TO lt_html.
rt_html = lt_html.ENDMETHOD.5. Correo con adjunto (PDF, Excel, etc.)
DATA: lo_document TYPE REF TO cl_document_bcs, lt_content TYPE solix_tab, lv_size TYPE i.
" Cargar datos de archivo (por ejemplo, de XSTRING)lt_content = cl_document_bcs=>xstring_to_solix( iv_xstring ).lv_size = xstrlen( iv_xstring ).
" Crear documento principallo_document = cl_document_bcs=>create_document( i_type = 'RAW' i_text = VALUE soli_tab( ( line = 'Vea el informe adjunto.' ) ) i_subject = 'Informe mensual').
" Agregar adjuntolo_document->add_attachment( i_attachment_type = 'PDF' i_attachment_subject = 'Informe_2024.pdf' i_attachment_size = lv_size i_att_content_hex = lt_content).
lo_bcs->set_document( lo_document ).6. Adjuntar CSV
DATA: lt_csv TYPE soli_tab.
" Crear contenido CSVlt_csv = VALUE #( ( line = 'ID;Nombre;Cantidad;Precio' ) ( line = '1;Material A;10;100.00' ) ( line = '2;Material B;5;250.00' ) ( line = '3;Material C;20;75.50' )).
" Agregar como adjuntolo_document->add_attachment( i_attachment_type = 'CSV' i_attachment_subject = 'Datos_exportacion.csv' i_att_content_text = lt_csv).7. Multiples destinatarios (TO, CC, BCC)
DATA: lo_recipient TYPE REF TO if_recipient_bcs.
" Destinatario principal (TO)lo_recipient = cl_cam_address_bcs=>create_internet_address( i_address_name = 'Sr. Principal').lo_bcs->add_recipient( i_recipient = lo_recipient i_express = abap_true " Alta prioridad).
" Copia (CC)lo_recipient = cl_cam_address_bcs=>create_internet_address().lo_bcs->add_recipient( i_recipient = lo_recipient i_copy = abap_true " CC).
" Copia oculta (BCC)lo_recipient = cl_cam_address_bcs=>create_internet_address().lo_bcs->add_recipient( i_recipient = lo_recipient i_blind = abap_true " BCC).8. Enviar a usuario SAP
" Usuario SAP como destinatarioDATA(lo_sap_user) = cl_sapuser_bcs=>create( sy-uname ).
lo_bcs->add_recipient( lo_sap_user ).9. Establecer remitente
" Remitente personalizadoDATA(lo_sender) = cl_cam_address_bcs=>create_internet_address( i_address_name = 'Sistema SAP').
lo_bcs->set_sender( lo_sender ).10. Multiples adjuntos
" Primer adjunto (PDF)lo_document->add_attachment( i_attachment_type = 'PDF' i_attachment_subject = 'Informe.pdf' i_attachment_size = lv_size_pdf i_att_content_hex = lt_pdf_content).
" Segundo adjunto (Excel)lo_document->add_attachment( i_attachment_type = 'XLS' i_attachment_subject = 'Datos.xlsx' i_attachment_size = lv_size_xls i_att_content_hex = lt_excel_content).
" Tercer adjunto (Imagen)lo_document->add_attachment( i_attachment_type = 'PNG' i_attachment_subject = 'Logo.png' i_attachment_size = lv_size_img i_att_content_hex = lt_image_content).11. Clase completa para envio de correos
CLASS zcl_email_sender DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. TYPES: BEGIN OF ty_attachment, filename TYPE string, type TYPE char3, content TYPE xstring, END OF ty_attachment, ty_attachments TYPE TABLE OF ty_attachment WITH EMPTY KEY.
METHODS: send_email IMPORTING iv_to TYPE string iv_cc TYPE string OPTIONAL iv_subject TYPE string iv_body TYPE string iv_html TYPE abap_bool DEFAULT abap_false it_attachments TYPE ty_attachments OPTIONAL RAISING cx_bcs.
ENDCLASS.
CLASS zcl_email_sender IMPLEMENTATION. METHOD send_email. DATA: lo_bcs TYPE REF TO cl_bcs, lo_document TYPE REF TO cl_document_bcs, lt_body TYPE soli_tab.
" Crear BCS lo_bcs = cl_bcs=>create_persistent( ).
" Preparar cuerpo " Dividir texto en lineas de 255 caracteres DATA(lv_offset) = 0. DATA(lv_len) = strlen( iv_body ). WHILE lv_offset < lv_len. DATA(lv_chunk) = substring( val = iv_body off = lv_offset len = nmin( val1 = 255 val2 = lv_len - lv_offset ) ). APPEND VALUE #( line = lv_chunk ) TO lt_body. lv_offset = lv_offset + 255. ENDWHILE.
" Crear documento lo_document = cl_document_bcs=>create_document( i_type = COND #( WHEN iv_html = abap_true THEN 'HTM' ELSE 'RAW' ) i_text = lt_body i_subject = CONV #( iv_subject ) ).
" Agregar adjuntos LOOP AT it_attachments INTO DATA(ls_attach). DATA(lt_hex) = cl_document_bcs=>xstring_to_solix( ls_attach-content ).
lo_document->add_attachment( i_attachment_type = ls_attach-type i_attachment_subject = CONV #( ls_attach-filename ) i_attachment_size = xstrlen( ls_attach-content ) i_att_content_hex = lt_hex ). ENDLOOP.
lo_bcs->set_document( lo_document ).
" Destinatario TO lo_bcs->add_recipient( cl_cam_address_bcs=>create_internet_address( iv_to ) ).
" Destinatario CC IF iv_cc IS NOT INITIAL. lo_bcs->add_recipient( i_recipient = cl_cam_address_bcs=>create_internet_address( iv_cc ) i_copy = abap_true ). ENDIF.
" Enviar lo_bcs->send( ). COMMIT WORK. ENDMETHOD.ENDCLASS.12. Uso de la clase de correo
DATA: lo_sender TYPE REF TO zcl_email_sender, lt_attach TYPE zcl_email_sender=>ty_attachments.
CREATE OBJECT lo_sender.
" Correo simplelo_sender->send_email( iv_subject = 'Prueba' iv_body = 'Este es un correo de prueba.').
" Correo HTML con adjuntolt_attach = VALUE #( ( filename = 'Informe.pdf' type = 'PDF' content = lv_pdf_content )).
lo_sender->send_email( iv_subject = 'Informe mensual' iv_body = '<html><body><h1>Informe</h1><p>Vea el adjunto.</p></body></html>' iv_html = abap_true it_attachments = lt_attach).13. Verificar estado del correo
DATA: lo_bcs TYPE REF TO cl_bcs, lv_sent TYPE os_boolean, lv_requested TYPE os_boolean.
lo_bcs = cl_bcs=>create_persistent( )." ... configurar correo ...
" Enviar inmediatamente (no en cola)lo_bcs->set_send_immediately( abap_true ).
lv_sent = lo_bcs->send( i_with_error_screen = abap_true ).
IF lv_sent = abap_true. WRITE: / 'Correo enviado exitosamente'.ELSE. WRITE: / 'Error al enviar'.ENDIF.
COMMIT WORK.Resumen
| Tarea | Metodo/Clase |
|---|---|
| Crear correo | cl_bcs=>create_persistent( ) |
| Texto/HTML | cl_document_bcs=>create_document( ) |
| Agregar adjunto | lo_document->add_attachment( ) |
| Dest. externo | cl_cam_address_bcs=>create_internet_address( ) |
| Usuario SAP | cl_sapuser_bcs=>create( ) |
| CC/BCC | add_recipient( i_copy/i_blind = abap_true ) |
| Enviar | lo_bcs->send( ) + COMMIT WORK |
Notas importantes / Mejores practicas
- COMMIT WORK es obligatorio despues de
send( )- sino el correo no se envia. - SAPconnect (SCOT) debe estar configurado correctamente.
- Para HTML usar
i_type = 'HTM'encreate_document. - Los archivos adjuntos deben convertirse a
SOLIX_TAB(binario). - Probar primero en sistemas de desarrollo (SCOT -> Probar).
- Considerar los limites de tamano de correo del servidor SMTP.
- En ABAP Cloud: usar la API de correo apropiada (CL_BCS no disponible).