文章目录
前言
SAP可以把一些信息发到外部的Email地址,比如把PO的信息发送给供应商。
实现这个事情主要的问题有两个:配置系统和写ABAP实现
配置系统:(这是470以上系统的配置,如果是47C或者以下,会用到RFC(SM59))
1.设置Profile参数
2.SAP发邮件用户的维护
3.SICF
4.SCOT
5.SOST (查看发送状况)
【场景】物流与采购部门不会去经常查看SAP中货物的在库时间所以导致经常有呆滞料的产生,为了解决这个问题,在SAP中开发库龄报表给用户查看,并且将马上呆滞的物料发送邮件给飞书。
一、系统配置
基本是参考note:455140(Configuration of e-mail, fax, paging or SMS using SMTP),这里稍作整理
sdn找了很多broadcasting的文章,基本都是在介绍和使用broadcasting的强大功能,但是涉及到后台是如何配置的,找 basis ,没有basis guy,自己动手。如果需要详解了解,可以参考note.另外,这里的配置只是为broadcasting的set mail服务的,所以省略了一些无关的步骤
主要有下面几个步骤:
1. 配置参数文件Profile parameter(RZ10)
a)icm/server_port_<*> = PROT=SMTP,PORT=<port>
事务码RZ10进去,选择实例参数文件,选择扩展。来到参数配置界面,默认情况下已经有一个参数文件icm/server_port_0 = PORT=HTTP,PORT=XXXX(每个服务可能不一样),那么这里的<*>就是要根据你的参数文件的具体情况,如果已经有了_0,这里你就需要设成_1,以此类推,PORT一般设置成25,这里还有一个选项是TIMEOUT可以设定等待邮件服务器回复时间的最大值。这里我的参数文件: icm/server_port_1 = PROT=SMTP,PORT=25
b)is/SMTP/virt_host_<*> = <host>:<port>,<port>,...;
定义虚拟邮件主机,主要用来接收邮件的,_<*>的设置通上。要注意,参数值最后是有一个分号的。
这里我的参数文件是is/SMTP/virt_host_0 = *:25;
完成后保存,激活。
配置完需要重启服务,参数才能生效
2. 配置用户(SU01)
a)对于每一个client,需要创建一个用户作为邮件的接收者,比如我创建了一个用户叫做MAILUSER,用户的类型设置为service,并给该用户赋profile S_A.SCON
b)对于每个用户来说,如果需要发送或者接收邮件的话,也需要在为其配置email地址,在su01中的general的E-mail中配置即可,通讯方式为remote email
3. client assignment(SICF)
执行这个事务码,进去后,点执行,进去后可以看到STMP servers,默认应该是灰色的,双击SMTP servers,配置以下几个地方
a)Host data ,对于 Profile Parameter Number,输入 "is/STMP/virt_host_<*>"中的<*>的值,一般可能是0,如果不存在的话,下面会有提示的。
b)Service data,输入接收邮件的相关信息,client以及前面创建的MAILUSER和密码、语言等信息。
c)Handler list,在第一个位置输入CL_SMTP_EXT_SAPCONNECT
完成以上配置后,右键点击SMTP servers,选择激活。
4.SAP connect administration(SCOT) 邮件服务器配置
a)Default domain,这个邮件的默认域名比如sap.com,那么如果在你发送邮件的时候收件人地址如果只写test的话,系统会自动加上@sap.com,如果收件人地址是全的话,这个domain不维护关系也不大
b)Nodes,维护SMTP节点,双击后弹出对话框,维护以下信息
勾上 "Node in user"
在MAIL HOST和MAIL PORT下面,指定发送邮件服务器的地址,比如如果是163的话,就应该是smtp.163.com
选中Internet的Set,弹出新对话框,指定接收地址的地址区域,一般用*表示所有邮件都用SMTP来发送。其他信息用默认。
(这里SAPconnect的信息可以有两种方式显示的,如果双击SMTP节点弹出的是JOB的信息的话,选择菜单中SYSTEM STATUS,切换到为另一种显示方式即可。
c)Send job,选择菜单中的View-->Jobs,可以检查是否已经有Jobs被调度了,选择Jobs->Create,并指定Job名称,选择SAP&CONNECTALL变式,并选择Schedule Job
选择 Schedule periodiacally,指定时间间隔,比如10分钟,选择创建。
到这里,基本配置成功了。可以在SBWP中,选择发送邮件,来测试配置是否成功,输入收件人的邮件地址,点击发送。如果配置成功的话,收一下邮件,应该收到了来自登陆SAP GUI的账号中配置的邮件地址的邮件了。
注意:如果只是使用SAP发送而不接收外部回复回来的邮件,即相当于一个Mail Client的功能,只需要2、4两步就可以了,也不需要更改系统参数。而且最重要的工作是Mail服务器的设置,把SAP Application的IP放到白名单,不要密码验证。
二、SAP邮件服务器配置
1、配置步骤
1.打开T-Code SCOT 进入SMTP配置页面
2.创建一个服务节点
3.开始设置
4.上述信息维护好后点击Settings
5.选择不设置TLS,并且填写SMTP AUTH授权账号(邮件服务器申请的公共账号密码)
6.设置default domain
7.设置邮件发送后台作业,点击Send Jobs,进入到该页签下,设置邮件发送方式以及接收地址类型
8.点击Schedule Job for All Address Types之后,跳转到如下页面
9.点击完continue之后,会自动跳转到Define Job页面(注:此处可以设置邮件的刷新频率,默认10min)
10.点击Step会验证我们的连接状态,下图是成功示例:
11.上图状态是成功状态,我们按F3返回后,点击Start condition.
12.点击start condition之后,我们会跳转到start time.
13.这写维护好以后,在linux的服务器上的hosts文件中维护邮件服务器的地址就ok了。
2、设置邮件系统内部发送
1.配置步骤如上所示,多节点配置只需要在此基础上,增加如下配置即可:
2.如若点击No send between SAP users. 则不会在SAP系统中发送邮件(T-code:SBWP),反正则发送。
三、ABAP代码实现
使用SAP的标准类CL_BCS进行邮件发送,网上有很多文章对这个类有详细的解读
在这里插入代码片 "获取发件人,收件人,抄送人的信息
SELECT
*
INTO TABLE @DATA(lt_mail_addr)
FROM
zmail
WHERE
zprogram = 'ZRMM003' AND
zactive = 'X'.
READ TABLE lt_mail_addr INTO DATA(ls_mail_addr) INDEX 1.
IF sy-subrc eq 0.
gv_receiver_addr = ls_mail_addr-ZRECEIVER. "收件人
gv_send_addr = ls_mail_addr-zsend. "发件人
gv_cc_addr = ls_mail_addr-zcc. "抄送人
ENDIF.
"获取附件
"调用其他程序获取附件内容
CALL METHOD cl_salv_bs_runtime_info=>set
EXPORTING
display = abap_false
metadata = abap_false
data = abap_true.
"获取附件内容
SUBMIT zrmm002 AND RETURN.
TRY.
CALL METHOD cl_salv_bs_runtime_info=>get_data_ref
IMPORTING
r_data = go_data.
ASSIGN go_data->* TO <go_data>.
CATCH cx_salv_bs_sc_runtime_info .
MESSAGE '调用失败' TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.
cl_salv_bs_runtime_info=>clear_all( ).
MOVE-CORRESPONDING <go_data> TO gt_data.
"分割符 #
gv_tab = cl_bcs_convert=>gc_tab.
"字段描述
CONCATENATE gv_string
'零件号' gv_tab
'项目号' gv_tab
'中文描述' gv_tab
'英文描述' gv_tab
'供应商名称' gv_tab
'保质期' gv_tab
'采购周期' gv_tab
'类型' gv_tab
'保存温度' gv_tab
'保存湿度' gv_tab
'SQE' gv_tab
'备注' gv_crlf
INTO gv_string.
* "字段值
LOOP AT gt_data INTO gs_data.
DO 12 TIMES.
ASSIGN COMPONENT sy-index OF STRUCTURE gs_data TO <fs>.
IF <fs> IS ASSIGNED.
IF <fs> IS INITIAL.
<fs> = '空'.
ENDIF.
ENDIF.
ENDDO.
gv_ztemperature = gs_data-ztemperature.
gv_zhumidity = gs_data-zhumidity.
REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>newline IN gv_ztemperature WITH ''.
REPLACE ALL OCCURRENCES OF '"' IN gv_ztemperature WITH ''.
REPLACE ALL OCCURRENCES OF '"' IN gv_zhumidity WITH ''.
REPLACE ALL OCCURRENCES OF '(' IN gs_data WITH ''.
REPLACE ALL OCCURRENCES OF ')' IN gs_data WITH ''.
CONCATENATE gv_string
gs_data-zpartno gv_tab
gs_data-zproject gv_tab
gs_data-zchinese gv_tab
gs_data-zenglish gv_tab
gs_data-zsupplier gv_tab
gs_data-zvalidity gv_tab
gs_data-zleadtime gv_tab
gs_data-ztype gv_tab
gv_ztemperature gv_tab
gv_zhumidity gv_tab
gs_data-zsqe gv_tab
gs_data-zremarks gv_crlf
INTO gv_string.
CLEAR:gs_data,
gv_ztemperature,
gv_zhumidity.
ENDLOOP.
TRY.
cl_bcs_convert=>string_to_solix(
EXPORTING
iv_string = gv_string
iv_codepage = '4103' "suitable for MS Excel, leave empty
iv_add_bom = 'X' "for other doc types
IMPORTING
et_solix = gt_mailhex
ev_size = gv_size ).
"邮件正文
gv_documnet = '库存到期提醒邮件,系统自动发送请勿回复,附件为到期零件数据,有问题请联系相关部门,谢谢!'.
APPEND gv_documnet TO gt_contents.
gv_length = gv_size.
"创建文档连接
go_document = cl_document_bcs=>create_document(
i_type = 'RAW'
i_subject = '库存到期邮件提醒'
i_length = gv_length
i_language = sy-langu
i_importance = '1'
i_text = gt_contents
).
gv_subject = '库存到期邮件提醒.XLSX'.
"添加附件
CALL METHOD go_document->add_attachment
EXPORTING
* I_ATTACHMENT_TYPE = 'BIN'
i_attachment_type = 'XLS'
i_attachment_subject = gv_subject
i_attachment_size = gv_size
i_att_content_hex = gt_mailhex.
"持续发送请求
go_request = cl_bcs=>create_persistent( ).
"发件人
go_sender = cl_sapuser_bcs=>create( gv_send_addr ).
go_request->set_sender( go_sender ).
"收件人
go_bcs_receiver = cl_cam_address_bcs=>create_internet_address( gv_receiver_addr ).
"添加收件人
CALL METHOD go_request->add_recipient
EXPORTING
i_recipient = go_bcs_receiver.
"抄送人
go_bcs_cc = cl_cam_address_bcs=>create_internet_address( gv_cc_addr ).
"添加抄送人
CALL METHOD go_request->add_recipient
EXPORTING
i_recipient = go_bcs_cc
i_copy = 'X'.
"发送邮件
go_request->set_send_immediately( 'X' )."设置立即发送
CALL METHOD go_request->set_document( go_document ).
CALL METHOD go_request->send(
EXPORTING
i_with_error_screen = 'X'
RECEIVING
result = gv_result ).
COMMIT WORK.
CATCH cx_bcs INTO go_fail.
ENDTRY.
四、注意事项
1.应用服务器的hosts文件设置IP与域名的映射关系
2.添加附件时注意特殊符号的影响