项目需求:编写一个程序能够将实时的物料库存数据通过发送邮件的形式发送到对应的邮件。现有标准的事务码MB5B来查看对应的库存数据。可以在程序中使用submit将参数传递到MB5B中,然后将获取的数据返回到程序中,然后在执行发送邮件的逻辑。
使用代码如下:
*&---------------------------------------------------------------------*
*& Report ZMMR118
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zmmr118.
TABLES:mkpf,mseg,sscrfields,mara,t001,t001l,mchb,mbew,bseg.
TYPES:BEGIN OF ty_alv,
index TYPE i,
matnr TYPE mseg-matnr,
werks TYPE mseg-werks,
name1 TYPE t001w-name1,
start_date TYPE sy-datum, "开始日期
end_date TYPE sy-datum, "结束日期
anfmenge TYPE mseg-menge, "期初库存
endmenge TYPE mseg-menge, "期末库存
maktx TYPE makt-maktx,
bwkey TYPE bwkey,
charg TYPE charg_d,
sobkz TYPE sobkz,
meins TYPE meins,
END OF ty_alv.
DATA:gs_alv TYPE ty_alv,
gt_alv TYPE TABLE OF ty_alv,
ls_data TYPE REF TO data.
FIELD-SYMBOLS: TYPE STANDARD TABLE,
TYPE any.
DATA: gs_layout TYPE lvc_s_layo.
DATA: gt_fieldcat TYPE lvc_t_fcat,
gs_fieldcat TYPE lvc_s_fcat.
DATA: gv_title TYPE string.
"弹窗
DATA : l_answer TYPE c LENGTH 1,
ls_field TYPE sval,
lt_field TYPE STANDARD TABLE OF sval.
DATA:gs_functxt TYPE smp_dyntxt.
*******************************
*屏幕处理
*******************************
SELECTION-SCREEN BEGIN OF BLOCK blk1 WITH FRAME TITLE TEXT-001.
SELECT-OPTIONS : s_matnr FOR mseg-matnr,
s_mfrpn FOR mara-mfrpn,
s_bukrs FOR t001-bukrs,
s_hkont FOR bseg-hkont,
s_werks FOR mseg-werks DEFAULT '1000',
s_lgort FOR t001l-lgort,
s_charg FOR mchb-charg,
s_bwtar FOR mbew-bwtar,
s_bwart FOR mseg-bwart.
PARAMETERS p_sobkz TYPE mseg-sobkz.
SELECT-OPTIONS : s_budat FOR mkpf-budat DEFAULT sy-datum.
SELECTION-SCREEN END OF BLOCK blk1.
SELECTION-SCREEN BEGIN OF BLOCK blk2 WITH FRAME TITLE TEXT-002.
PARAMETERS: p_lgbst TYPE c RADIOBUTTON GROUP g1 DEFAULT 'X',
p_bwbst TYPE c RADIOBUTTON GROUP g1,
p_sbbst TYPE c RADIOBUTTON GROUP g1.
SELECTION-SCREEN END OF BLOCK blk2.
SELECTION-SCREEN: FUNCTION KEY 1.
*******************************
*主程序入口
*******************************
*&--------------------------------------------------------------
**初始化处理
*&--------------------------------------------------------------
INITIALIZATION.
sscrfields-functxt_01 = '@1S@接收邮箱维护'."定义按钮
*&--------------------------------------------------------------
**选择屏幕控制
*&--------------------------------------------------------------
AT SELECTION-SCREEN OUTPUT.
*&-------------------------------------------------------------*
*& 参数输入检查
*&-------------------------------------------------------------*
AT SELECTION-SCREEN.
* //为控件页签单击事件, 选择不同页签显示不同子屏幕.
CASE sscrfields-ucomm.
WHEN 'FC01'."系统预留的功能码
PERFORM frm_view_call USING 'ZTMM2099'.
WHEN OTHERS.
ENDCASE.
*&-------------------------------------------------------------
**程序开始处理
*&-------------------------------------------------------------
START-OF-SELECTION.
********************************
*获取数据
********************************
PERFORM frm_get_data.
IF sy-batch = 'X'.
PERFORM frm_send_email USING 'C'.
ELSE.
* ALV显示
PERFORM frm_set_alv. "设置ALV属性
PERFORM frm_dis_alv. "调用ALV
ENDIF.
END-OF-SELECTION.
*&---------------------------------------------------------------------*
*& Form FRM_GET_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_get_data .
DATA lv_index TYPE i.
CALL METHOD cl_salv_bs_runtime_info=>set
EXPORTING
display = abap_false
metadata = abap_false
data = abap_true.
SUBMIT rm07mlbd "Tcode MB5B
WITH matnr IN s_matnr "物料编号
WITH mfrpn IN s_mfrpn "制造商零件编号
WITH bukrs IN s_bukrs "公司代码
WITH hkont IN s_hkont "总账科目
WITH werks IN s_werks "工厂
WITH lgort IN s_lgort "存储位置
WITH charg IN s_charg "批次
WITH bwtar IN s_bwtar "评估类型
WITH bwart IN s_bwart "移动类型
WITH sobkz EQ p_sobkz "特殊库存标识
WITH DATUM IN s_budat "选择日期
"库存类型
WITH lgbst EQ p_lgbst "参储位置/批次库存
WITH bwbst EQ p_bwbst "已评估库存
WITH sbbst EQ p_sbbst "特殊库存
"清单范围
* WITH PA_WDZER EQ SPACE
* WITH PA_WDZEW EQ 'X'
* WITH PA_WDWIZ EQ 'X'
* WITH PA_WDWUW EQ 'X'
* WITH PA_WDWEW EQ 'X'
* WITH PA_NDZER EQ SPACE
* WITH PA_NDSTO EQ 'X'
"设置
* WITH PA_SFLVA EQ 'T1'
WITH pa_sumfl EQ 'X'
WITH p_grid EQ 'X'
* WITH XCHAR EQ SPACE
* WITH XNOMCHB EQ SPACE
* WITH XNOMCHB EQ SPACE
* WITH NOSTO EQ SPACE
* WITH PA_DBSTD EQ 'X'
* VIA SELECTION-SCREEN
AND RETURN
.
TRY.
CALL METHOD cl_salv_bs_runtime_info=>get_data_ref
IMPORTING
r_data = ls_data.
ASSIGN ls_data->* TO .
CATCH cx_salv_bs_sc_runtime_info.
ENDTRY.
cl_salv_bs_runtime_info=>clear_all( ).
IF IS ASSIGNED.
LOOP AT ASSIGNING .
MOVE-CORRESPONDING TO gs_alv.
gs_alv-matnr = |{ gs_alv-matnr ALPHA = OUT }|.
lv_index = lv_index + 1.
gs_alv-index = lv_index.
APPEND gs_alv TO gt_alv.
CLEAR gs_alv.
ENDLOOP.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_ALV
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_set_alv .
DATA: l_colpos TYPE lvc_s_fcat-col_pos VALUE 0.
*&---------------------------------------------------------------------*
*& 定义宏
*&---------------------------------------------------------------------*
DEFINE macro_fill_fcat.
CLEAR gs_fieldcat.
&1 = &1 + 1.
gs_fieldcat-col_pos = &1.
gs_fieldcat-fieldname = &2.
gs_fieldcat-coltext = &3.
APPEND gs_fieldcat TO gt_fieldcat.
END-OF-DEFINITION.
FIELD-SYMBOLS: TYPE lvc_s_fcat.
CLEAR gt_fieldcat.
macro_fill_fcat: l_colpos 'INDEX' '序号' ,
l_colpos 'MATNR' '物料编号' ,
l_colpos 'MAKTX' '物料描述' ,
l_colpos 'BWKEY' '估值范围' ,
l_colpos 'WERKS' '工厂' ,
l_colpos 'CHARG' '批次' ,
l_colpos 'SOBKZ' '特殊库存标识' ,
l_colpos 'NAME1' '名称' ,
l_colpos 'START_DATE' '开始日期' ,
l_colpos 'END_DATE' '结束日期' ,
l_colpos 'ANFMENGE' '期初库存' ,
l_colpos 'ENDMENGE' '期末库存' ,
l_colpos 'MEINS' '基本计量单位' .
CLEAR gs_layout.
gs_layout-zebra = 'X'.
gs_layout-cwidth_opt = 'X'.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_DIS_ALV
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_dis_alv .
DATA: lv_grid TYPE lvc_s_glay.
lv_grid-edt_cll_cb = 'X'.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
i_callback_program = sy-repid
i_callback_pf_status_set = 'PF_STATUS_SET'
i_callback_user_command = 'FRM_USER_COMMAND'
i_grid_settings = lv_grid
is_layout_lvc = gs_layout
it_fieldcat_lvc = gt_fieldcat
TABLES
t_outtab = gt_alv.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form PF_STATUS_SET
*&---------------------------------------------------------------------*
* gui状态
*----------------------------------------------------------------------*
* -->TR_EXTAB text
*----------------------------------------------------------------------*
FORM pf_status_set USING pr_extab TYPE slis_t_extab.
SET PF-STATUS 'STANDARD' .
ENDFORM. " PF_STATUS_SET
*&---------------------------------------------------------------------*
*& Form frm_user_command
*&---------------------------------------------------------------------*
* 用戶响应事件
*----------------------------------------------------------------------*
* -->R_UCOMM text
* -->RS_SELFIELD text
*----------------------------------------------------------------------*
FORM frm_user_command USING r_ucomm LIKE sy-ucomm
rs_selfield TYPE slis_selfield.
*刷新alv
DATA:lob_grid TYPE REF TO cl_gui_alv_grid.
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = lob_grid.
CALL METHOD lob_grid->check_changed_data.
CASE r_ucomm.
WHEN '&UPD'.
PERFORM frm_send_email USING 'C'.
ENDCASE.
rs_selfield-refresh = 'X'.
gs_layout-cwidth_opt = 'X'.
gs_layout-no_toolbar = 'X'.
CALL METHOD lob_grid->set_frontend_layout
EXPORTING
is_layout = gs_layout.
CALL METHOD lob_grid->refresh_table_display.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_VIEW_CALL
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> P_
*&---------------------------------------------------------------------*
FORM frm_view_call USING fu_view TYPE dd02v-tabname.
DATA:dba_sellist LIKE vimsellist OCCURS 0,
excl_cua_funct LIKE vimexclfun OCCURS 0,
x_header LIKE vimdesc OCCURS 0 WITH HEADER LINE,
x_namtab LIKE vimnamtab OCCURS 0,
dpl_sellist LIKE vimsellist.
CALL FUNCTION 'VIEW_GET_DDIC_INFO'
EXPORTING
viewname = fu_view
* VARIANT_FOR_SELECTION = ' '
* ZDM_CALL =
TABLES
sellist = dba_sellist
x_header = x_header
x_namtab = x_namtab
EXCEPTIONS
no_tvdir_entry = 1
table_not_found = 2
OTHERS = 3.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
DATA:lockuser TYPE sy-uname,
answer(1) TYPE c.
CALL FUNCTION 'VIEW_ENQUEUE'
EXPORTING
view_name = fu_view
action = 'E'
enqueue_mode = 'E'
EXCEPTIONS
foreign_lock = 1
system_failure = 2
table_not_found = 5
client_reference = 7.
IF sy-subrc NE 0.
MESSAGE 'Data locked' TYPE 'S' DISPLAY LIKE 'E'.
RETURN.
ENDIF.
CALL FUNCTION 'VIEW_MAINTENANCE'
EXPORTING
* CORR_NUMBER = ' '
view_action = 'U'
view_name = fu_view
* RFC_DESTINATION_FOR_UPGRADE = ' '
* CLIENT_FOR_UPGRADE = ' '
* COMPLEX_SELCONDS_USED = ' '
* NO_WARNING_FOR_CLIENTINDEP = ' '
* OC_INST =
TABLES
dba_sellist = dba_sellist
excl_cua_funct = excl_cua_funct
x_header = x_header
x_namtab = x_namtab
* DPL_SELLIST =
EXCEPTIONS
missing_corr_number = 1
no_database_function = 2
no_editor_function = 3
no_value_for_subset_ident = 4
OTHERS = 5.
CALL FUNCTION 'VIEW_ENQUEUE'
EXPORTING
view_name = fu_view
action = 'D'
enqueue_mode = 'E'
EXCEPTIONS
foreign_lock = 1
system_failure = 2
table_not_found = 5
client_reference = 7.
ENDFORM.
**&---------------------------------------------------------------------*
**& Form FRM_SEND_EMAIL
**&---------------------------------------------------------------------*
**& text
**&---------------------------------------------------------------------*
**& --> p1 text
**& <-- p2 text
**&---------------------------------------------------------------------*
FORM frm_send_email USING p_x.
"------发送邮件参数定义
DATA: ls_sendemail TYPE zsxx_send_email01,
ls_receiver TYPE zsxx_receiver.
DATA: lt_to TYPE TABLE OF so_rec_ext,
ls_to TYPE so_rec_ext,
lt_body TYPE TABLE OF solisti1,
ls_body TYPE solisti1,
i_body LIKE solisti1 OCCURS 0 WITH HEADER LINE,
lt_meg TYPE TABLE OF bapiret2,
ls_attach TYPE zzs_attach01,
ls_obj TYPE zzs_obj,
lt_obj TYPE TABLE OF zzs_obj.
DATA: lt_line TYPE ztts_lines.
DATA: lt_cs TYPE TABLE OF sysid,
ls_cs TYPE sysid.
"-----生成excel附件
CLEAR lt_line.
PERFORM frm_to_excel TABLES lt_line USING p_x.
"----附件处理
ls_obj-obj_descr = '每日库存数量明细'.
ls_obj-doc_type = 'XLS'.
ls_obj-obj_name = '每日库存数量明细'.
ls_obj-head_start = 1.
ls_obj-head_num = 1.
DESCRIBE TABLE ls_sendemail-attach-lines LINES ls_obj-body_start.
ls_obj-body_start = ls_obj-body_start + 1.
APPEND LINES OF lt_line TO ls_sendemail-attach-lines.
DESCRIBE TABLE ls_sendemail-attach-lines LINES ls_obj-body_num.
ls_obj-body_num = ls_obj-body_num + 1.
ls_obj-doc_size = ( ls_obj-body_num - ls_obj-body_start ) * 255.
ls_obj-obj_langu = sy-langu.
APPEND ls_obj TO lt_obj.
CLEAR ls_obj.
ls_sendemail-attach-obj_pro = lt_obj.
*************** begin add by 2021/11/05 ****************
IF lt_line IS INITIAL.
EXIT .
ENDIF.
*************** end add by 2021/11/05 *****************
"----收件邮箱
SELECT * FROM ztmm2099 INTO TABLE @DATA(lt_zt2099) WHERE zsx = @p_x.
LOOP AT lt_zt2099 INTO DATA(ls_zt2099).
ls_to = ls_zt2099-zemail.
APPEND ls_to TO lt_to.
CLEAR ls_to.
ENDLOOP.
ls_sendemail-to = lt_to.
"---邮件标题
ls_sendemail-subject = sy-datum(4) && '-' && sy-datum+4(2) && '-' && sy-datum+6(2) && ' -From ERP:' && gv_title && '每日库存数量提醒!'.
"---邮件内容
CLEAR: ls_body, lt_body[].
ls_body-line =' '.
APPEND ls_body TO lt_body.
CLEAR ls_body.
ls_body-line ='各部门请知悉:
'.
APPEND ls_body TO lt_body.
CLEAR ls_body.
ls_body-line = ' 您好!
'.
APPEND ls_body TO lt_body.
CLEAR ls_body.
ls_body-line = ' 附件是' && gv_title && '物料库存数据明细,请查阅!
'.
APPEND ls_body TO lt_body.
CLEAR ls_body.
ls_body-line = ' '.
APPEND ls_body TO lt_body.
CLEAR ls_body.
ls_body-line = ' 广汽埃安新能源汽车有限公司
'.
APPEND ls_body TO lt_body.
CLEAR ls_body.
ls_body-line = ' '.
CLEAR ls_body.
ls_body-line = ' ' && sy-datum(4) && '-' && sy-datum+4(2) && '-' && sy-datum+6(2) && '
'.
APPEND ls_body TO lt_body.
CLEAR ls_body.
ls_body-line = 'FISystem'.
APPEND ls_body TO lt_body.
CLEAR ls_body.
ls_body-line = '================================================================================'.
APPEND ls_body TO lt_body.
CLEAR ls_body.
ls_body-line = '本邮件为系统自动发送,请勿直接回复,谢谢!'.
APPEND ls_body TO lt_body.
ls_sendemail-body = lt_body.
* "----抄送人
* ls_receiver-email = lt_cs.
CALL FUNCTION 'ZXX_SEND_EMAIL01'
EXPORTING
i_sendemail = ls_sendemail
i_receiver = ls_receiver
TABLES
t_messages = lt_meg.
WAIT UP TO 2 SECONDS.
CLEAR: ls_sendemail,lt_obj,lt_to..
READ TABLE lt_meg TRANSPORTING NO FIELDS WITH KEY type = 'E'.
IF sy-subrc <> 0.
"发送成功
MESSAGE '邮件已生成,具体查看T-CODE:SBWP发件箱来查看邮件是否发送成功!' TYPE 'S'..
ELSE.
"发送失败
DATA:gv_msg TYPE char100.
LOOP AT lt_meg INTO DATA(ls_meg) WHERE type = 'E'.
CONCATENATE gv_msg ls_meg-message INTO gv_msg.
CLEAR ls_meg.
ENDLOOP.
MESSAGE gv_msg TYPE 'E'.
ENDIF.
ENDFORM.
*
*
*
**&---------------------------------------------------------------------*
**& Form FRM_TO_EXCEL
**&---------------------------------------------------------------------*
**& text
**&---------------------------------------------------------------------*
**& --> LT_LINE
**&---------------------------------------------------------------------*
FORM frm_to_excel TABLES pt_line TYPE table USING p_x.
"---参数及常量定义
CONSTANTS:
c_tab TYPE c VALUE cl_bcs_convert=>gc_tab,
c_crlf TYPE c VALUE cl_bcs_convert=>gc_crlf,
c_mimetype TYPE char64 VALUE 'APPLICATION/MSEXCEL;charset=utf-16le'.
DATA v_xattach TYPE xstring.
DATA lv_string TYPE string.
DATA lv_shsl TYPE string.
DATA lv_hhsl TYPE string.
DATA lv_netpr TYPE string.
"-------附件内容
CLEAR lv_string.
CONCATENATE lv_string
'物料编码' c_tab
* '物料描述' c_tab
* '估值范围' c_tab
'工厂' c_tab
'批次' c_tab
* '特殊库存标识' c_tab
'名称' c_tab
'开始日期' c_tab
'结束日期' c_tab
'期初库存' c_tab
'期末库存' c_tab
'基本计量单位' c_crlf "c_crlf 换行
INTO lv_string.
DATA: lv_string1 TYPE string,
lv_string2 TYPE string,
lv_string3 TYPE string,
lv_string4 TYPE string.
LOOP AT gt_alv INTO gs_alv .
CLEAR: lv_string1, lv_string2, lv_string3, lv_string4.
lv_string1 = gs_alv-start_date .
lv_string2 = gs_alv-end_date .
lv_string3 = gs_alv-anfmenge.
lv_string4 = gs_alv-endmenge .
CONCATENATE lv_string
gs_alv-matnr c_tab
* gs_alv-maktx c_tab
* gs_alv-bwkey c_tab
gs_alv-werks c_tab
gs_alv-charg c_tab
* gs_alv-sobkz c_tab
gs_alv-name1 c_tab
lv_string1 c_tab
lv_string2 c_tab
lv_string3 c_tab
lv_string4 c_tab
gs_alv-meins c_crlf "c_crlf 换行
INTO lv_string.
CLEAR gs_alv.
ENDLOOP.
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
EXPORTING
text = lv_string
mimetype = c_mimetype
IMPORTING
buffer = v_xattach
EXCEPTIONS
failed = 1
OTHERS = 2.
IF sy-subrc = 0.
CONCATENATE cl_abap_char_utilities=>byte_order_mark_little
v_xattach INTO v_xattach IN BYTE MODE.
ENDIF.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = v_xattach
TABLES
binary_tab = pt_line.
ENDFORM.
参数名字:通过对应的事务码进入选择屏幕后,F1可进入如下界面。
**注意:**在程序中使用submit调用标准程序传递数据时,需要传递所有必要的参数,否则会到至在后台调用程序的时候失败。
**扩展: **也可在FUNCTION中调用其他的报表程序得到数据,然后返回给外围系统。