SAP请求传输完自动发送邮件

文摘   2024-11-26 18:18   北京  

小甲:老师,我又郁闷了,你作为国内ABAP一。。。

老白:捏住!又来这一套,这回是啥事儿啊?

小甲:嘿嘿,我这不是去一个公司做实施项目嘛,他们的PRD和DEV、QAS不在同一个传输域,是完全独立的一个系统,彼此间网络是不是能物理连通都不清楚,我们的请求传输到QAS后,需要BASIS手工下载后再传输到PRD。这就导致啥呢,首先传输完毕后我们在DEV的请求日志里面看不到传输结果,因为到QAS后就断开了,其次有时候BASIS在传输完后也没有立即给我们反馈,也不知道是不是请求已经传输了,是不是传输有错误,总之,就导致挺忐忑的吧。

老白:那怎么着才能让你不忐忑呢?

小甲:我觉着如果请求传输完立马给我发一个邮件,告诉我传输的结果,我既能及时知道了请求已经传输,也能知道是不是出错了,就很爽!

老白:每天传那么多请求,有那么多系统要照看,你觉着BASIS能抽出空来给你及时发邮件吗?

小甲:谁说让BASIS发邮件了啊?系统发啊!系统自动发!增强、出口、BADI、Plug in,用啥我不管,反正是能发就行。

老白:这又是让我给你写程序了吧?

小甲:明知故问。。。

老白:好一个狂徒!我要是不写呢?

小甲:这么好的一个点子,我不信你能经得起诱惑,嘿嘿

老白:苍天哪大地啊,我竟然被你拿捏的死死的。。。话说这个程序似乎真的挺有用的,事不宜迟我这就动手!

小甲:切,高明的猎手往往以猎物的姿态。。。

老白:你嘟囔啥呢?

小甲:没啥没啥,你赶紧写呀

老白:已经写好了,过来看看吧。下面这个就是请求传输完系统自动发送的邮件,传输完的瞬间就收到了呢,因为是选中两个请求一起传的,所以有两条

小甲:哇塞,牛X了!给我讲讲怎么实现的呗

老白:其实很简单,有一个BADI,CTS_IMPORT_FEEDBACK,就是在请求传输完触发的,只要实现这个BADI的FEEDBACK_AFTER_IMPORT方法,然后配置一个请求所有者的邮箱配置表,在方法里面按照配置表发送邮件就好了。但是呢,这个发邮件的过程跟一般程序不太一样,如果按照一般的方式,你肯定无法收到邮件。

小甲:这就奇怪了,BADI都有了,我还不是想干啥干啥?有啥不一样?

老白:因为Client 000!众所周知啊,请求的传输是TP触发000 Client的JOB RDDIMPDP来实现数据字典、程序、表内容等等的写入的,所以呢,这个BADI也是在000 Client触发的,它是运行在000 Client的,又因为000 Client一般不允许登录,也没有配置发邮件所需要的SCOT配置,故而无法发送。

小甲:这个好办,我反手就是一个RFC!我用RFC连接到PRD的生产Client再发送总可以了吧?

老白:这个固然是可以,但是你RFC用谁的账号设置呢?谁肯让你用呢?

小甲:那我要是用RFC连到DEV呢?在DEV随便建一个账号

老白:你不是说PRD完全独立的一个系统吗?说不定网络之间都不通,不能保证能建RFC哦。再说了,即便是能建,这个做法也很烦啊

小甲:说的也是,那老师你说怎么解决这个问题呢?

老白:如果你能跟BASIS说得上话呢,就让BASIS协助在000配置一下SCOT,然后邮箱配置表配置为跨Client,一次配置所有Client都能用,然后直接发邮件就可以了。

小甲:那要是不认识BASIS也说不上话呢?

老白:那就使用SAP Event配合JOB,BADI的代码在000 Client触发Event后,生产Client的JOB就启动了,然后根据表内存的数据,就能发送了呀

小甲:老师,实不相瞒,这个SAP Event触及到我的知识盲区了。。

老白:就是事务码SM62,好了,给你说了,现在你已经会了

小甲:。。。

老白:我看看总共都是做了哪些开发啊,啰里啰嗦的还不少,罗列一下哈

1、创建表ZCTS01 和 ZCTS02,注意都没有MANDT字段!ZCTS02用来维护请求所有者的账户和邮箱,需要生成表格维护,以使用SM30来维护账号对应的邮箱

ZCTS01:TRGUID  GUID_22TRKORR  TRKORRTARCLIENT  TRTARCLIRETCODE  TRRETCODEOWNER  TR_AS4USERERDAT  ERDATERZET  ERZETERNAM  ERNAM
ZCTS02:OWNER TR_AS4USERONLYE XFELD "仅传输错误才发送邮件EMAIL AD_SMTPADR


表ZCTS02在PRD这样维护:

2、BADI实现

METHOD if_ex_cts_import_feedback~feedback_after_import.  DATA lv_guid TYPE guid_22.  DATA ls_reqt TYPE scts_imp.  DATA ls_save TYPE zcts01.  DATA lt_save TYPE TABLE OF zcts01.
CALL FUNCTION 'GUID_CREATE' IMPORTING ev_guid_22 = lv_guid.
LOOP AT requests INTO ls_reqt. MOVE-CORRESPONDING ls_reqt TO ls_save. ls_save-trguid = lv_guid. ls_save-erdat = sy-datum. ls_save-erzet = sy-uzeit. ls_save-ernam = sy-uname. APPEND ls_save TO lt_save. ENDLOOP. MODIFY zcts01 FROM TABLE lt_save. CALL FUNCTION 'DB_COMMIT'.
"如果000 Client DDIC账号可以发送邮件, "则可以使用SUMIT的方法,否则使用下面BP_EVENT_RAISE的方法* SUBMIT zcts_import_feedback* WITH p_eparm = lv_guid* AND RETURN.
CALL FUNCTION 'BP_EVENT_RAISE' EXPORTING eventid = 'CTS_IMPORT_FEEDBACK' eventparm = lv_guid EXCEPTIONS OTHERS = 5.ENDMETHOD.


3、邮件发送程序

*&---------------------------------------------------------------------**& Report  ZCTS_IMPORT_FEEDBACK*&*&---------------------------------------------------------------------**& 请求传输完毕给请求所有者发送邮件程序*& BADI CTS_IMPORT_FEEDBACK在请求传输结束触发*& 因为BADI是在000 Client运行,使用BP_EVENT_RAISE触发此程序*& 1、维护表ZCTS02*& 2、在目标系统SM62创建Event*& 3、定义JOB CTS_IMPORT_FEEDBACK*&---------------------------------------------------------------------*REPORT zcts_import_feedback NO STANDARD PAGE HEADING.
DATA gv_eparm TYPE tbtcm-eventparm.DATA gv_sendm TYPE ad_smtpadr. "发送邮箱DATA: BEGIN OF gt_trlog OCCURS 0, trkorr TYPE zcts01-trkorr , as4text TYPE e07t-as4text , tarclient TYPE zcts01-tarclient, owner TYPE zcts01-owner , retcode TYPE zcts01-retcode , result TYPE char10, END OF gt_trlog.
PARAMETERS p_eparm TYPE guid_22 NO-DISPLAY.
INITIALIZATION. "xxxxxxxx.com改成公司域名 CONCATENATE sy-sysid sy-mandt '@xxxxxxxx.com' INTO gv_sendm.
START-OF-SELECTION. PERFORM getdata. PERFORM prepare_mail.
*&---------------------------------------------------------------------**& Form getdata*&---------------------------------------------------------------------*FORM getdata. IF p_eparm IS INITIAL. CALL FUNCTION 'GET_JOB_RUNTIME_INFO' IMPORTING eventparm = gv_eparm EXCEPTIONS no_runtime_info = 1. ELSE. gv_eparm = p_eparm. ENDIF. IF gv_eparm IS INITIAL. MESSAGE s000(oo) WITH '未获取EVENTPARM'. LEAVE PROGRAM. ENDIF.
SELECT zcts01~trkorr e07t~as4text zcts01~tarclient e070~as4user AS owner "zcts01~owner中文乱码 zcts01~retcode INTO CORRESPONDING FIELDS OF TABLE gt_trlog FROM zcts01 INNER JOIN e070 ON e070~trkorr = zcts01~trkorr LEFT JOIN e07t ON e07t~trkorr = zcts01~trkorr AND e07t~langu = sy-langu WHERE zcts01~trguid = gv_eparm. IF gt_trlog[] IS INITIAL. MESSAGE s000(oo) WITH '未获取ZCTS01表数据'. LEAVE PROGRAM. ENDIF.ENDFORM. "getdata

*&---------------------------------------------------------------------**& Form prepare_mail*&---------------------------------------------------------------------*FORM prepare_mail. DATA lt_trlog LIKE TABLE OF gt_trlog WITH HEADER LINE. DATA lt_owner TYPE TABLE OF tr_as4user WITH HEADER LINE. DATA lt_body TYPE TABLE OF solisti1 WITH HEADER LINE. DATA ls_cts02 TYPE zcts02. DATA lv_smtp TYPE ad_smtpadr. DATA lv_subje TYPE so_obj_des.
LOOP AT gt_trlog. lt_owner = gt_trlog-owner. COLLECT lt_owner. ENDLOOP.
LOOP AT lt_owner. MESSAGE s000(oo) WITH '账号:' lt_owner. CLEAR: lt_trlog[],lt_body[]. LOOP AT gt_trlog WHERE owner = lt_owner. MOVE-CORRESPONDING gt_trlog TO lt_trlog. IF lt_trlog-retcode < 4. lt_trlog-result = '成功'. ELSEIF lt_trlog-retcode < 8. lt_trlog-result = '警告'. ELSE. lt_trlog-result = '错误'. ENDIF. APPEND lt_trlog. CLEAR lt_trlog. ENDLOOP.
SELECT SINGLE * INTO ls_cts02 FROM zcts02 WHERE owner = lt_owner. CHECK sy-subrc = 0.
IF ls_cts02-onlye = 'X'. READ TABLE lt_trlog WITH KEY retcode = '0008'. CHECK sy-subrc = 0. ENDIF.
PERFORM itab_to_mail_body TABLES lt_trlog lt_body USING '请求传输结果列表:' '请求,描述,目标CLIENT,结果' 'TRKORR,AS4TEXT,TARCLIENT,RESULT' 999. CONCATENATE sy-sysid sy-mandt '请求传输结果' INTO lv_subje SEPARATED BY space. PERFORM sendmail TABLES lt_body USING gv_sendm ls_cts02-email lv_subje. ENDLOOP.ENDFORM. "prepare_mail
*&---------------------------------------------------------------------**& 内表写到邮件表格(指定列方式)*&---------------------------------------------------------------------*FORM itab_to_mail_body TABLES t_intab t_body STRUCTURE solisti1 USING pv_text pv_coldesc pv_field pv_toline. DATA: lt_conts TYPE TABLE OF solisti1 WITH HEADER LINE, lt_title TYPE TABLE OF char40 WITH HEADER LINE, lt_field TYPE TABLE OF char40 WITH HEADER LINE. DATA: subrc TYPE sy-subrc, charc TYPE char2048, charstr TYPE string, str TYPE string, lines TYPE num6, omitnum TYPE i, ftype. FIELD-SYMBOLS <fs_fld>.
CHECK t_intab[] IS NOT INITIAL. CHECK pv_field IS NOT INITIAL.
SPLIT pv_coldesc AT ',' INTO TABLE lt_title. SPLIT pv_field AT ',' INTO TABLE lt_field.
str = lines( t_intab ). CONDENSE str. CONCATENATE '[' str '条]' pv_text INTO str. CALL FUNCTION 'SCMS_STRING_TO_FTEXT' EXPORTING text = str TABLES ftext_tab = lt_conts.
APPEND: `<style type="text/css">.solid{BORDER-TOP: 1px solid;` TO lt_conts, `BORDER-RIGHT:1px solid;BORDER-BOTTOM: 1px solid; ` TO lt_conts, `BORDER-LEFT: 1px solid}</style><table border=1 ` TO lt_conts, `cellpadding=2 style='border-collapse:collapse;font- ` TO lt_conts, `size:10.5pt'><tbody><tr style="background:#DDD9C4;">` TO lt_conts. IF pv_toline > 0. LOOP AT lt_title. CONCATENATE '<td class="solid">' lt_title '</td>' INTO lt_conts-line. APPEND lt_conts. ENDLOOP. APPEND `</tr>` TO lt_conts. ENDIF. LOOP AT t_intab FROM 0 TO pv_toline. APPEND '<tr>' TO lt_conts. CLEAR omitnum. LOOP AT lt_field. ASSIGN COMPONENT lt_field OF STRUCTURE t_intab TO <fs_fld>. CHECK sy-subrc = 0.
omitnum = omitnum + 1. DESCRIBE FIELD <fs_fld> TYPE ftype. CASE ftype. WHEN 'I' OR 'P' OR 'F' OR 'a' OR 'e' OR 'b' OR 's'. charc = abs( <fs_fld> ). CONDENSE charc NO-GAPS. IF <fs_fld> < 0. CONCATENATE '-' charc INTO charc. ENDIF. charstr = charc. WHEN 'D' OR 'T'. IF <fs_fld> IS INITIAL OR <fs_fld> = ''. charc = ''. ELSE. WRITE <fs_fld> TO charc. ENDIF. charstr = charc. WHEN 'X' OR 'y' OR 'g'. charstr = <fs_fld>. WHEN OTHERS. WRITE <fs_fld> TO charc. charstr = charc. ENDCASE. CONCATENATE '<td class="solid">' charstr '</td>' INTO lt_conts-line. APPEND lt_conts. ENDLOOP. APPEND `</tr>` TO lt_conts. ENDLOOP. IF lines( t_intab ) > pv_toline. APPEND '<tr>' TO lt_conts. DO omitnum TIMES. lt_conts-line = '<td class="solid">...</td>'. APPEND lt_conts. ENDDO. APPEND '</tr>' TO lt_conts. ENDIF. APPEND '</tbody></table> <br/> ' TO lt_conts.
APPEND LINES OF lt_conts TO t_body.ENDFORM. "itab_to_mail_body
*&---------------------------------------------------------------------**& Form sendmail*&---------------------------------------------------------------------*FORM sendmail TABLES mail_body USING pv_sender pv_smtp p_odes. DATA lr_email TYPE REF TO cl_bcs. DATA lr_body TYPE REF TO cl_document_bcs. DATA lr_receiver TYPE REF TO cl_cam_address_bcs. DATA lr_sender TYPE REF TO if_sender_bcs. DATA l_result TYPE os_boolean.
TRY . lr_email = cl_bcs=>create_persistent( ).
lr_body = cl_document_bcs=>create_document( i_type = 'HTM' i_text = mail_body[] i_subject = p_odes ). lr_email->set_document( lr_body ).
lr_receiver = cl_cam_address_bcs=>create_internet_address( pv_smtp ). lr_email->add_recipient( i_recipient = lr_receiver ).
IF pv_sender IS INITIAL. lr_sender = cl_sapuser_bcs=>create( sy-uname ). ELSE. CALL METHOD cl_cam_address_bcs=>create_internet_address EXPORTING i_address_string = pv_sender i_address_name = 'DDIC' RECEIVING result = lr_sender. ENDIF.
lr_email->set_sender( lr_sender ). lr_email->set_send_immediately( 'X' ). lr_email->set_status_attributes( i_requested_status = 'E' "去掉邮件回执 i_status_mail = 'E' ). l_result = lr_email->send( i_with_error_screen = '' ). CATCH cx_root. ENDTRY.
IF l_result = 'X'. MESSAGE s000(oo) WITH '邮件已发送'. sy-subrc = 0. COMMIT WORK. ELSE. sy-subrc = 4. MESSAGE s000(oo) WITH '发送邮件失败'. ENDIF.ENDFORM. "sendmail


4、使用事务代码SM62定义SAP Event:CTS_IMPORT_FEEDBACK,并写入传输请求中。

好了,现在可以把请求传到PRD了,最后,请BASIS兄弟帮助在生产机创建一个后台JOB,下面几个需要注意的点:


小甲:这就行了?我先在QAS系统配置好试试哈

一刻钟以后。。。

小甲:收到邮件了!好爽啊!哈哈哈哈,不过老师我还有个想法。。。

老白:还有想法?差不多得了哈

小甲:我不信老师对我这个点子没兴趣

老白:要不说好奇害死猫呢,又被你拿捏了,你说说吧

小甲:我虽然知道请求已经传输了,也知道了传输的结果,但是我还是在DEV的请求日志里面看不到PRD的传输结果,我心里别扭!有没有啥办法让我在DEV看到PRD的传输日志呢?就像是DEV传QAS那样,如果有错误我双击还能看到具体的错误是啥,总之我需要在DEV看到完整的日志!

老白:这个好办,把PRD的日志拿到DEV不就好了嘛

小甲:我连日志在哪儿放着都不知道怎么拿。。。老师你再出手一次吧,嘿嘿嘿嘿

老白:我不是给你说过嘛,请求有两个文件,一个控制文件和一个数据文件,其中那个K开头的控制文件就记录着传输的信息,传输一次这个文件就多一些内容,只要把这个文件再拿回来覆盖掉DEV原有的文件,就可以看到完整的传输记录了。另外,双击所看到的详细日志,也是存在DIR_TRANS的log目录下面,只要是把这些文件拿过来放到DEV就可以看到完整的传输日志了

小甲:通过RFC可以把文件拿回来覆盖现有的,可是不能互通的系统咋办呢?难道让BASIS给下载下来?那他们估计不同意啊

老白:我想想啊。。。ding!我有一个好主意,既然是邮件都发了,何不把这几个文件作为附件发过来呢?然后收到邮件把这些附件导入到系统不就行了?

小甲:牛X!老师牛X!我也茅厕。。不是,茅塞顿开了呢!老师你改造一下发邮件的程序,我写一个牛X的上传程序,动动手指就能上传,保证你看了给我大拇指!

老白:嚯,牛逼起来啊。。。好了,邮件发送程序改好了,发送邮件的时候会把控制文件和日志文件一起当做附件发出来

*&---------------------------------------------------------------------**& Report  ZCTS_IMPORT_FEEDBACK*&*&---------------------------------------------------------------------**& 请求传输完毕给请求所有者发送邮件程序*& BADI CTS_IMPORT_FEEDBACK在请求传输结束触发*& 因为BADI是在000 Client运行,账号为DDIC,*& 如果账号DDIC不能直接发送邮件,或者没有配置000 Client的SCOT*& 则可以使用BP_EVENT_RAISE触发此程序*& 1、维护表ZCTS02*& 2、在打算发邮件的Client SM62创建Event*& 3、定义JOB CTS_IMPORT_FEEDBACK*& 4、如果是用SUBMIT的方式,在000 Client维护SCOT*& 5、如果需要发送日志附件,把常量gv_atta的值改为'X',否则设置为''*&---------------------------------------------------------------------*REPORT zcts_import_feedback NO STANDARD PAGE HEADING.
CONSTANTS gv_atta VALUE 'X'. "是否需要发送附件DATA gv_eparm TYPE tbtcm-eventparm.DATA gv_sendm TYPE ad_smtpadr. "发送邮箱DATA: BEGIN OF gt_trlog OCCURS 0, trkorr TYPE zcts01-trkorr , as4text TYPE e07t-as4text , tarclient TYPE zcts01-tarclient, owner TYPE zcts01-owner , retcode TYPE zcts01-retcode , result TYPE char10, END OF gt_trlog.DATA: BEGIN OF gt_atta OCCURS 0, type TYPE so_obj_tp , size TYPE so_obj_len, desc TYPE so_obj_des, cont TYPE solix_tab , END OF gt_atta.
PARAMETERS p_eparm TYPE guid_22 NO-DISPLAY.
INITIALIZATION. CONCATENATE sy-sysid sy-mandt '@hisense.com' INTO gv_sendm.
START-OF-SELECTION. PERFORM getdata. PERFORM prepare_mail.
*&---------------------------------------------------------------------**& Form getdata*&---------------------------------------------------------------------*FORM getdata. IF p_eparm IS INITIAL. CALL FUNCTION 'GET_JOB_RUNTIME_INFO' IMPORTING eventparm = gv_eparm EXCEPTIONS no_runtime_info = 1. ELSE. gv_eparm = p_eparm. ENDIF. IF gv_eparm IS INITIAL. MESSAGE s000(oo) WITH '未获取EVENTPARM'. LEAVE PROGRAM. ENDIF.
SELECT zcts01~trkorr e07t~as4text zcts01~tarclient e070~as4user AS owner "zcts01~owner中文乱码 zcts01~retcode INTO CORRESPONDING FIELDS OF TABLE gt_trlog FROM zcts01 INNER JOIN e070 ON e070~trkorr = zcts01~trkorr LEFT JOIN e07t ON e07t~trkorr = zcts01~trkorr AND e07t~langu = sy-langu WHERE zcts01~trguid = gv_eparm. IF gt_trlog[] IS INITIAL. MESSAGE s000(oo) WITH '未获取ZCTS01表数据'. LEAVE PROGRAM. ENDIF.ENDFORM. "getdata
*&---------------------------------------------------------------------**& Form prepare_mail*&---------------------------------------------------------------------*FORM prepare_mail. DATA lt_trlog LIKE TABLE OF gt_trlog WITH HEADER LINE. DATA lt_owner TYPE TABLE OF tr_as4user WITH HEADER LINE. DATA lt_body TYPE TABLE OF solisti1 WITH HEADER LINE. DATA ls_cts02 TYPE zcts02. DATA lv_smtp TYPE ad_smtpadr. DATA lv_subje TYPE so_obj_des. DATA lv_trans TYPE text255.
CALL FUNCTION 'RSPO_R_SAPGPARAM' EXPORTING name = 'DIR_TRANS' IMPORTING value = lv_trans EXCEPTIONS error = 1 OTHERS = 0.
LOOP AT gt_trlog. lt_owner = gt_trlog-owner. COLLECT lt_owner. ENDLOOP.
LOOP AT lt_owner. MESSAGE s000(oo) WITH '账号:' lt_owner. CLEAR: lt_trlog[],lt_body[],gt_atta,gt_atta[]. LOOP AT gt_trlog WHERE owner = lt_owner. MOVE-CORRESPONDING gt_trlog TO lt_trlog. IF lt_trlog-retcode < 4. lt_trlog-result = '成功'. ELSEIF lt_trlog-retcode < 8. lt_trlog-result = '警告'. ELSE. lt_trlog-result = '错误'. ENDIF. APPEND lt_trlog. CLEAR lt_trlog.
IF gv_atta = 'X'. PERFORM get_request_cofile USING lv_trans gt_trlog-trkorr 'C'. PERFORM get_request_cofile USING lv_trans gt_trlog-trkorr 'L'. ENDIF. ENDLOOP.
SELECT SINGLE * INTO ls_cts02 FROM zcts02 WHERE owner = lt_owner. CHECK sy-subrc = 0.
IF ls_cts02-onlye = 'X'. READ TABLE lt_trlog WITH KEY retcode = '0008'. CHECK sy-subrc = 0. ENDIF.
PERFORM mail_body TABLES lt_trlog lt_body USING '传输结果:' '请求,描述,目标CLIENT,结果' 'TRKORR,AS4TEXT,TARCLIENT,RESULT' 999. CONCATENATE sy-sysid sy-mandt '请求传输结果' INTO lv_subje SEPARATED BY space. PERFORM sendmail TABLES lt_body USING gv_sendm ls_cts02-email lv_subje. ENDLOOP.ENDFORM. "prepare_mail
*&---------------------------------------------------------------------**&*&---------------------------------------------------------------------*FORM get_request_cofile USING pv_trans pv_trkorr pv_file. DATA lv_afile LIKE rcgfiletr-ftappl. DATA lv_xstr TYPE xstring. DATA lv_blen TYPE i. DATA lv_index TYPE i.
CHECK pv_trans IS NOT INITIAL AND pv_trkorr IS NOT INITIAL.
CASE pv_file. WHEN 'C'. CONCATENATE 'K' pv_trkorr+4(6) '.' pv_trkorr(3) INTO gt_atta-desc. CONCATENATE pv_trans '/cofiles/' gt_atta-desc INTO lv_afile.
OPEN DATASET lv_afile FOR INPUT IN BINARY MODE. IF sy-subrc = 0. READ DATASET lv_afile INTO lv_xstr. CLOSE DATASET lv_afile.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY' EXPORTING buffer = lv_xstr IMPORTING output_length = lv_blen TABLES binary_tab = gt_atta-cont. gt_atta-size = lv_blen. gt_atta-type = 'BIN'. APPEND gt_atta. ENDIF. WHEN 'L'. DO 26 TIMES. lv_index = sy-index - 1. CONCATENATE pv_trkorr(3) sy-abcde+lv_index(1) pv_trkorr+4(6) '.' sy-sysid INTO gt_atta-desc. CONCATENATE pv_trans '/log/' gt_atta-desc INTO lv_afile. OPEN DATASET lv_afile FOR INPUT IN BINARY MODE. IF sy-subrc = 0. READ DATASET lv_afile INTO lv_xstr. CLOSE DATASET lv_afile.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY' EXPORTING buffer = lv_xstr IMPORTING output_length = lv_blen TABLES binary_tab = gt_atta-cont. gt_atta-size = lv_blen. gt_atta-type = 'BIN'. APPEND gt_atta. ENDIF. ENDDO. ENDCASE.ENDFORM. "get_REQUEST_COFILE
*&---------------------------------------------------------------------**& 内表写到邮件表格(指定列方式)*&---------------------------------------------------------------------*FORM mail_body TABLES t_intab t_body STRUCTURE solisti1 USING pv_text pv_coldesc pv_field pv_toline. DATA: lt_conts TYPE TABLE OF solisti1 WITH HEADER LINE, lt_title TYPE TABLE OF char40 WITH HEADER LINE, lt_field TYPE TABLE OF char40 WITH HEADER LINE. DATA: subrc TYPE sy-subrc, charc TYPE char2048, charstr TYPE string, str TYPE string, lines TYPE num6, omitnum TYPE i, ftype. FIELD-SYMBOLS <fs_fld>.
CHECK t_intab[] IS NOT INITIAL. CHECK pv_field IS NOT INITIAL.
SPLIT pv_coldesc AT ',' INTO TABLE lt_title. SPLIT pv_field AT ',' INTO TABLE lt_field.
str = lines( t_intab ). CONDENSE str. CONCATENATE '[' str '条]' pv_text INTO str. CALL FUNCTION 'SCMS_STRING_TO_FTEXT' EXPORTING text = str TABLES ftext_tab = lt_conts.
APPEND: `<style type="text/css">.solid{BORDER-TOP: 1px ` TO lt_conts, `solid;BORDER-RIGHT:1px solid;BORDER-BOTTOM: ` TO lt_conts, `1px solid;BORDER-LEFT: 1px solid}</style> ` TO lt_conts, `<table border=1 cellpadding=2 ` TO lt_conts, `style='border-collapse:collapse; ` TO lt_conts, `font-size:10.5pt'><tbody> ` TO lt_conts, `<tr style="background:#DDD9C4;"> ` TO lt_conts. IF pv_toline > 0. LOOP AT lt_title. CONCATENATE '<td class="solid">' lt_title '</td>' INTO lt_conts-line. APPEND lt_conts. ENDLOOP. APPEND `</tr>` TO lt_conts. ENDIF. LOOP AT t_intab FROM 0 TO pv_toline. APPEND '<tr>' TO lt_conts. CLEAR omitnum. LOOP AT lt_field. ASSIGN COMPONENT lt_field OF STRUCTURE t_intab TO <fs_fld>. CHECK sy-subrc = 0.
omitnum = omitnum + 1. DESCRIBE FIELD <fs_fld> TYPE ftype. CASE ftype. WHEN 'I' OR 'P' OR 'F' OR 'a' OR 'e' OR 'b' OR 's'. charc = abs( <fs_fld> ). CONDENSE charc NO-GAPS. IF <fs_fld> < 0. CONCATENATE '-' charc INTO charc. ENDIF. charstr = charc. WHEN 'D' OR 'T'. IF <fs_fld> IS INITIAL OR <fs_fld> = ''. charc = ''. ELSE. WRITE <fs_fld> TO charc. ENDIF. charstr = charc. WHEN 'X' OR 'y' OR 'g'. charstr = <fs_fld>. WHEN OTHERS. WRITE <fs_fld> TO charc. charstr = charc. ENDCASE. CONCATENATE '<td class="solid">' charstr '</td>' INTO lt_conts-line. APPEND lt_conts. ENDLOOP. APPEND `</tr>` TO lt_conts. ENDLOOP. IF lines( t_intab ) > pv_toline. APPEND '<tr>' TO lt_conts. DO omitnum TIMES. lt_conts-line = '<td class="solid">...</td>'. APPEND lt_conts. ENDDO. APPEND '</tr>' TO lt_conts. ENDIF. APPEND '</tbody></table> <br/> ' TO lt_conts.
APPEND LINES OF lt_conts TO t_body.ENDFORM. "itab_to_mail_body
*&---------------------------------------------------------------------**& Form sendmail*&---------------------------------------------------------------------*FORM sendmail TABLES mail_body USING pv_sender pv_smtp p_odes. DATA lr_email TYPE REF TO cl_bcs. DATA lr_body TYPE REF TO cl_document_bcs. DATA lr_receiver TYPE REF TO cl_cam_address_bcs. DATA lr_sender TYPE REF TO if_sender_bcs. DATA l_result TYPE os_boolean.
TRY . lr_email = cl_bcs=>create_persistent( ).
lr_body = cl_document_bcs=>create_document( i_type = 'HTM' i_text = mail_body[] i_subject = p_odes ). lr_email->set_document( lr_body ).
LOOP AT gt_atta. lr_body->add_attachment( i_attachment_type = gt_atta-type i_attachment_subject = gt_atta-desc i_attachment_size = gt_atta-size i_att_content_hex = gt_atta-cont ). ENDLOOP.
lr_receiver = cl_cam_address_bcs=>create_internet_address( pv_smtp ). lr_email->add_recipient( i_recipient = lr_receiver ).
IF pv_sender IS INITIAL. lr_sender = cl_sapuser_bcs=>create( sy-uname ). ELSE. lr_sender = cl_cam_address_bcs=>create_internet_address( i_address_string = pv_sender i_address_name = 'DDIC' ). ENDIF.
lr_email->set_sender( lr_sender ). lr_email->set_send_immediately( 'X' ). lr_email->set_status_attributes( i_requested_status = 'E' "去掉邮件回执 i_status_mail = 'E' ). l_result = lr_email->send( i_with_error_screen = '' ). CATCH cx_root. ENDTRY. IF l_result = 'X'. MESSAGE s000(oo) WITH '邮件已发送'. sy-subrc = 0. COMMIT WORK. ELSE. sy-subrc = 4. MESSAGE s000(oo) WITH '发送邮件失败'. ENDIF.ENDFORM. "sendmail


小甲:我的上传程序也好了!老师你LOOK LOOK


老白:就一个ALV?怎么没有上传按钮呢?

小甲:不需要上传按钮!只要是把文件拖进来就可以了,甚至可以直接把邮件附件拖进来呢,然后点保存就行了,老师我们测试一下试试,把邮件的附件全选然后拖到ALV里面,然后点保存按钮就妥了

老白:果然很快捷!给你一个大拇指!下面我们看下日志里面是不是已经有了新系统的传输信息哈

小甲:天哪!完美!走老师,我请你喝羊汤去!

老白:走!


码农干货铺
永远要保持一种无论何时何地都逼着自己更努力更优秀来享受更好生活的学习状态
 最新文章