SAP常规批导程序ABAP代码实现实例

        以下以销售订单批导为例展示一个完整的常规批导程序。

一、选择屏幕部分

*&---缓存类型定义
TYPES:BEGIN OF ty_temp,
        number TYPE zenumber,    "排序号
        id     TYPE icon_d,    "成功/失败
        msg    TYPE bapi_msg,  "消息
        total  TYPE int2,      "总条目
        curr   TYPE int2,      "当前条目
      END OF ty_temp.
*----------------------------------------------------------------------*
*   全局变量定义
*----------------------------------------------------------------------*
DATA:gt_data TYPE REF TO data.
*&---缓存表
DATA:gt_temp TYPE TABLE OF ty_temp,
     gs_temp TYPE ty_temp.
*&---进度条
DATA:gv_per  TYPE p,
     gv_stxt TYPE string,
     gv_num  TYPE i VALUE 0, "数据总数
     gv_sign TYPE i VALUE 0. "当前的进度
*----------------------------------------------------------------------*
*   常量定义
*----------------------------------------------------------------------*

*----------------------------------------------------------------------*
*   ALV定义
*----------------------------------------------------------------------*
DATA: gt_fieldcat TYPE lvc_t_fcat,
      gs_fieldcat TYPE lvc_s_fcat,
      gt_events   TYPE slis_t_event,   "事件存储内表
      gs_events   TYPE slis_alv_event.
DATA:gs_layout TYPE lvc_s_layo.

*----------------------------------------------------------------------*
*   FIELD-SYMBOLS定义
*----------------------------------------------------------------------*
FIELD-SYMBOLS:<ft_data>  TYPE STANDARD TABLE,
              <fs_temp>  TYPE ty_temp,
              <fs_data>,
              <fs_value>.
*----------------------------------------------------------------------*
*  选择屏幕
*----------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK blk WITH FRAME TITLE TEXT-t01.

  PARAMETERS:rb_down TYPE char1 RADIOBUTTON GROUP grp1 USER-COMMAND cre,
             rb_upld TYPE char1 RADIOBUTTON GROUP grp1 DEFAULT 'X'.
  PARAMETERS:p_path TYPE rlgrap-filename MODIF ID m2 .

SELECTION-SCREEN END OF BLOCK blk.

SELECTION-SCREEN BEGIN OF BLOCK blk2 WITH FRAME TITLE TEXT-t02.
  PARAMETERS:p_a RADIOBUTTON GROUP grp2 DEFAULT 'X' MODIF ID m3,
             p_b RADIOBUTTON GROUP grp2 MODIF ID m3,
             p_c RADIOBUTTON GROUP grp2 MODIF ID m3.
SELECTION-SCREEN END OF BLOCK blk2.
*&-----------------------------------------------------------------*
*& 初始化处理
*&-----------------------------------------------------------------*
INITIALIZATION.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_path.
  CALL FUNCTION 'KD_GET_FILENAME_ON_F4'
    CHANGING
      file_name = p_path.

*&-----------------------------------------------------------------*
*& 选择屏幕控制
*&-----------------------------------------------------------------*
AT SELECTION-SCREEN OUTPUT.
  LOOP AT SCREEN.
    IF screen-group1 = 'M2'.
      IF rb_upld = 'X'.
        screen-active = 1.
      ELSE.
        screen-active = 0.
      ENDIF.
      MODIFY SCREEN.
    ENDIF.
  ENDLOOP.
*&-----------------------------------------------------------------*
*& 程序开始处理
*&-----------------------------------------------------------------*
START-OF-SELECTION.

  IF  rb_down = 'X'.
    "下载模板
    PERFORM frm_download_file.
  ELSEIF rb_upld = 'X'.
    "获取数据
    PERFORM frm_get_data.
    "处理数据
    PERFORM frm_process_data.
    "ALV展示
    PERFORM frm_display_alv.
  ENDIF.
*&------------------------------------------------------------------*
*& 程序结束处理
*&------------------------------------------------------------------*
END-OF-SELECTION.

二、FORM部分

1、下载模板

        使用的是事务码SMW0中导入的模板

FORM frm_download_file .
  DATA: lv_file              TYPE rlgrap-filename,
        lv_objid             TYPE wwwdata-objid,
        ls_key               LIKE wwwdatatab,
        lv_subrc             TYPE sy-subrc,
        lv_filename          TYPE string,
        lv_path              TYPE string,
        lv_fullpath          TYPE string,
        lv_default_file_name TYPE string.

  lv_objid = sy-repid.
*&--------获得要保存文件的路径名
  CASE 'X'.
    WHEN p_a.
      lv_default_file_name =  TEXT-001 && '.xlsx'.
      lv_objid = lv_objid && '_A'.
    WHEN p_b.
      lv_default_file_name =  TEXT-002 && '.xlsx'.
      lv_objid = lv_objid && '_B'.
    WHEN p_c.
      lv_default_file_name =  TEXT-003 && '.xlsx'.
      lv_objid = lv_objid && '_C'.
    WHEN OTHERS.
  ENDCASE.

  CALL METHOD cl_gui_frontend_services=>file_save_dialog
    EXPORTING
      window_title         = '请选择路径'
      default_file_name    = lv_default_file_name
      file_filter          = 'Excel 文件 (*.xlsx)'
    CHANGING
      filename             = lv_filename
      path                 = lv_path
      fullpath             = lv_fullpath
    EXCEPTIONS
      cntl_error           = 1
      error_no_gui         = 2
      not_supported_by_gui = 3
      OTHERS               = 4.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
               WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

  lv_file = lv_fullpath.

  IF lv_fullpath IS NOT INITIAL.
    SELECT SINGLE *
      FROM wwwdata
      INTO CORRESPONDING FIELDS OF ls_key
      WHERE objid = lv_objid
        AND relid = 'MI'.
    CALL FUNCTION 'DOWNLOAD_WEB_OBJECT'
      EXPORTING
        key         = ls_key
        destination = lv_file
      IMPORTING
        rc          = lv_subrc.
    IF lv_subrc = 0.
      MESSAGE '模板下载成功' TYPE 'S'.
    ENDIF.
  ELSE.
    MESSAGE '下载取消!' TYPE 'S' DISPLAY LIKE 'E'.
  ENDIF.
ENDFORM.

2、获取数据

FORM frm_get_data .
  DATA:lt_return TYPE bapiret2_t,
       ls_return TYPE bapiret2,
       lv_msg    TYPE char220.

  "获取内表字段
  CALL FUNCTION 'ZFM_GET_FIELDCAT'
    EXPORTING
      i_path      = p_path
      i_end_col   = 50
    TABLES
      et_fieldcat = gt_fieldcat
      et_return   = lt_return.

  IF lt_return IS NOT INITIAL.
    "返回报错处理
    LOOP AT lt_return INTO ls_return WHERE type = 'E'.
      lv_msg = lv_msg && ls_return-message.
    ENDLOOP.
    IF lv_msg IS NOT INITIAL.
      MESSAGE lv_msg TYPE 'S' DISPLAY LIKE 'E'.
      STOP.
    ENDIF.
  ENDIF.

  "创建动态内表
  CALL METHOD cl_alv_table_create=>create_dynamic_table
    EXPORTING
      it_fieldcatalog = gt_fieldcat
    IMPORTING
      ep_table        = gt_data.
  ASSIGN gt_data->* TO <ft_data>.

  "获取内表值
  CALL FUNCTION 'ZFM_GET_UPLOAD_DATA'
    TABLES
      et_data = <ft_data>.

  "删除字段选择框
  DELETE gt_fieldcat WHERE fieldname = 'CHECK'.
ENDFORM.

 3、ALV展示

FORM frm_display_alv .

*&---LAYOUT定义
  CLEAR gs_layout.
  gs_layout-box_fname     = 'CHECK'.
  gs_layout-zebra             = 'X'.   "设置Grid的行颜色变换显示
  gs_layout-cwidth_opt = 'X'.   "设置Grid的字段列宽度自动适应
*&---ALV显示
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
    EXPORTING
      i_callback_program       = sy-repid
      i_callback_pf_status_set = 'FRM_SET_PF_STATUS'
      i_callback_user_command  = 'FRM_USER_COMMAND'
      is_layout_lvc            = gs_layout
      it_fieldcat_lvc          = gt_fieldcat
*     IT_EVENTS                = I_EVENTS[]
      i_save                   = 'A'
    TABLES
      t_outtab                 = <ft_data>
    EXCEPTIONS
      program_error            = 1
      OTHERS                   = 2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
ENDFORM.

4、GUI状态和标题栏

FORM frm_set_pf_status USING pt_extab TYPE slis_t_extab.
  DATA lv_title TYPE char20.
  CASE 'X'.
    WHEN p_a.
      lv_title = TEXT-004.
    WHEN p_b.
      lv_title = TEXT-005.
    WHEN p_c.
      lv_title = TEXT-006.
    WHEN OTHERS.
  ENDCASE.

  SET PF-STATUS 'STANDARD' .
  SET TITLEBAR 'TITLE_STD' WITH lv_title.
ENDFORM.

5、usercommand

FORM frm_user_command USING pv_ucomm LIKE sy-ucomm
                             ps_selfield TYPE slis_selfield.
  DATA: lv_grid  TYPE REF TO cl_gui_alv_grid.
  DATA: lv_flag  TYPE c.

*&将变更的数据刷新
  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = lv_grid.
  CALL METHOD lv_grid->check_changed_data.
  ps_selfield-refresh = 'X'.
  CASE pv_ucomm.
    WHEN 'ZLOAD'.  "导入
      PERFORM frm_save_data.
  ENDCASE.
  CALL METHOD lv_grid->refresh_table_display.

ENDFORM.

6、处理数据

FORM frm_process_data .

  DATA:lt_sort TYPE abap_sortorder_tab,
       ls_sort TYPE abap_sortorder.

  IF <ft_data> IS NOT INITIAL.
    LOOP AT <ft_data> ASSIGNING <fs_data>.
      "单位转换
      CALL FUNCTION 'ZFM_CONVERSION_EXIT'
        EXPORTING
          iv_fieldname = 'KMEIN'
          iv_exit      = zgl0_cunit_in
        CHANGING
          cs_data      = <fs_data>.

      CALL FUNCTION 'ZFM_CONVERSION_EXIT'
        EXPORTING
          iv_fieldname = 'VRKME'
          iv_exit      = zgl0_cunit_in
        CHANGING
          cs_data      = <fs_data>.
    ENDLOOP.

    "针对动态内表排序
    ls_sort-name = 'NUMBER'.
    ls_sort-descending = ''.
    APPEND ls_sort TO lt_sort.
    "针对动态内表排序
    ls_sort-name = 'POSNR'.
    ls_sort-descending = ''.
    APPEND ls_sort TO lt_sort.
    SORT <ft_data> BY (lt_sort).
  ENDIF.
ENDFORM.

7、导入按钮逻辑

FORM frm_save_data .

  DATA:lv_flag   TYPE char1,
       lv_number TYPE zenumber,
       lv_field  TYPE fieldname VALUE 'NUMBER',
       lv_index  TYPE i.
  DATA:ls_req      TYPE zssdi001_req,
       ls_item     TYPE zssdi001_item_in,
       ls_cond     TYPE zssdi001_cond_in,
       ls_config   TYPE zssdi001_config_in,
       ls_schedule TYPE zssdi001_schedule_in,
       ls_resp     TYPE zsrest_out,
       lv_etenr    TYPE vbep-etenr.
  "导入前检查
  PERFORM frm_before_import CHANGING lv_flag.
  CHECK lv_flag IS INITIAL.

  READ TABLE gt_fieldcat TRANSPORTING NO FIELDS WITH KEY fieldname = 'VC_FLAG'.
  IF sy-subrc = 0.
    lv_index = sy-tabix + 1.
  ENDIF.

  LOOP AT <ft_data> ASSIGNING <fs_data>.
    PERFORM frm_convent_data_out USING <fs_data> 'NUMBER' CHANGING lv_number.
    READ TABLE gt_temp ASSIGNING <fs_temp> WITH KEY number = lv_number BINARY SEARCH.
    IF sy-subrc <> 0.
      CONTINUE.
    ENDIF.

    AT NEW (lv_field).
      CLEAR:ls_req,ls_resp.
      MOVE-CORRESPONDING <fs_data> TO ls_req-req-head.
    ENDAT.

    AT NEW ('POSNR').
      CLEAR:ls_item.
      MOVE-CORRESPONDING <fs_data> TO ls_item.
      "特征值
      CLEAR:lv_flag.
      PERFORM frm_convent_data_out USING <fs_data> 'VC_FLAG' CHANGING lv_flag.
      IF lv_flag = 'X'.
        LOOP AT gt_fieldcat INTO gs_fieldcat FROM lv_index.
          CLEAR:ls_config.
          ls_config-charc = gs_fieldcat-fieldname.
          PERFORM frm_convent_data_out USING <fs_data> gs_fieldcat-fieldname CHANGING ls_config-value_long.
          APPEND ls_config TO ls_item-config.
        ENDLOOP.
      ENDIF.
    ENDAT.

    "条件类型
    CLEAR:ls_cond.
    MOVE-CORRESPONDING <fs_data> TO ls_cond.
    IF ls_cond-kschl IS NOT INITIAL.
      APPEND ls_cond TO ls_item-cond.
    ENDIF.
    "计划行
    CLEAR:lv_etenr.
    PERFORM frm_convent_data_out USING <fs_data> 'ETENR' CHANGING lv_etenr.
    IF lv_etenr <> 0.
      MOVE-CORRESPONDING <fs_data> TO ls_schedule.
      APPEND ls_schedule TO ls_item-schedule.
    ENDIF.

    AT END OF ('POSNR').
      IF ls_item-posnr IS NOT INITIAL.
        APPEND ls_item TO ls_req-req-item.
      ENDIF.
    ENDAT.

    AT END OF (lv_field).
      "调用函数生成凭证
      CALL FUNCTION 'ZFM_SDI001'
        EXPORTING
          i_req  = ls_req
        IMPORTING
          o_resp = ls_resp.

      "更改缓存表消息及状态字段
      IF ls_resp-msgty = 'S'.
        <fs_temp>-id = icon_led_green.
      ELSE.
        <fs_temp>-id = icon_led_red.
      ENDIF.
      <fs_temp>-msg = ls_resp-msgtx.
      "显示进度条
      gv_sign = gv_sign + 1 ."每次进度+1
      gv_per = gv_sign / gv_num * 100  . "进度/总数*100得到百分比
      gv_stxt = |当前条目 { gv_sign } / 总条目 { gv_num }|.
      CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
        EXPORTING
          percentage = gv_per
          text       = gv_stxt.
    ENDAT.
  ENDLOOP.

  "回写ALV
  LOOP AT <ft_data> ASSIGNING <fs_data>.
    CLEAR:lv_number.
    PERFORM frm_convent_data_out USING <fs_data> 'NUMBER' CHANGING lv_number.
    READ TABLE gt_temp ASSIGNING <fs_temp> WITH KEY number = lv_number BINARY SEARCH.
    IF sy-subrc = 0.
      "状态
      PERFORM frm_convent_data_in USING 'ID' <fs_temp>-id  CHANGING <fs_data>.
      "消息
      PERFORM frm_convent_data_in USING 'MSG' <fs_temp>-msg  CHANGING <fs_data>.
    ENDIF.
  ENDLOOP.

ENDFORM.

8、获取和写入动态结构的字段值

FORM frm_convent_data_out  USING    p_data
                                p_fieldname
                       CHANGING  c_value.

  ASSIGN COMPONENT p_fieldname OF STRUCTURE p_data TO <fs_value>.
  IF sy-subrc = 0.
    c_value = <fs_value>.
  ENDIF.
ENDFORM.

FORM frm_convent_data_in  USING   p_fieldname
                                   p_value
                          CHANGING p_data.
  ASSIGN COMPONENT p_fieldname  OF STRUCTURE p_data TO <fs_value>.
  IF sy-subrc = 0.
    <fs_value> = p_value.
  ENDIF.
ENDFORM.

9、导入前数据的处理

FORM frm_before_import  CHANGING p_flag.
  DATA:lv_number   TYPE zenumber,
       lv_checkbox TYPE char1,
       lv_id       TYPE icon-id.

  CLEAR:gt_temp.
*&---筛选出选中的数据
  LOOP AT <ft_data> ASSIGNING <fs_data>.
    CLEAR:lv_checkbox,lv_id.
    PERFORM frm_convent_data_out USING <fs_data> 'CHECK' CHANGING lv_checkbox.
    PERFORM frm_convent_data_out USING <fs_data> 'ID' CHANGING lv_id.
    "判断当前行选中且数据未被导入
    IF lv_checkbox = 'X' AND lv_id <> icon_led_green.
      CLEAR:gs_temp.
      PERFORM frm_convent_data_out USING <fs_data> 'NUMBER' CHANGING gs_temp-number.
      APPEND gs_temp TO gt_temp.
    ENDIF.
  ENDLOOP.
*&---去掉重复数据
  IF gt_temp IS NOT INITIAL.
    SORT gt_temp BY number.
    DELETE ADJACENT DUPLICATES FROM gt_temp COMPARING number.
    "进度条-总条数
    CLEAR:gv_sign,gv_per,gv_stxt,gv_num.
    gv_num = lines( gt_temp ).
    "选中所有相同序列行
    LOOP AT <ft_data> ASSIGNING <fs_data>.
      CLEAR:lv_number.
      PERFORM frm_convent_data_out USING <fs_data> 'NUMBER' CHANGING lv_number.
      READ TABLE gt_temp TRANSPORTING NO FIELDS WITH KEY number = lv_number.
      IF sy-subrc = 0.
        PERFORM frm_convent_data_in USING 'CHECK' 'X'  CHANGING <fs_data>.
      ENDIF.
    ENDLOOP.
  ELSE.
    p_flag = 'X'.
    MESSAGE s001(zgl01) DISPLAY LIKE 'E' .
  ENDIF.

ENDFORM.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值