小甲:老师,我又郁闷了,你作为国内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这样维护:
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.*&---------------------------------------------------------------------**& 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. E
...