ABAP 开发外挂报表批量创建和更改 采购 info record/采购信息记录 (RFC:ME_INFORECORD_MAINTAIN)

笔者在网上搜了很多文章,发现批量做这个修改的都是用的BDC录屏,虽然录屏很简单,但是既然要作为教程写在这里,我想还是BAPI或者RFC好一点,这部,刚好让笔者找到了.
具体功能:
上传一个excel文档,文档里是要创建或者修改的数据,点击执行则执行完毕了
在这里插入图片描述
上传的格式如下
在这里插入图片描述
在这里插入图片描述

也可以写成在选择屏幕上给个按钮,下载模板的形式,这里只为了演示,所以不做(甚至连ALV输出都没写)。
程序提供了正式运行和测试运行两种方式,在代码里用一个标识 ZMARK 来判断.
具体代码如下,仅供参考:

*&---------------------------------------------------------------------*
*& Report ZCYCLE11
*&---------------------------------------------------------------------*
*& 测试 ME_INFORECORD_MAINTAIN
*1.因为函数ME_INFORECORD_MAINTAIN不允许同时有净价和条件,所以需要分两次调用来实现创建/修改;
*2.因为函数ME_INFORECORD_MAINTAIN报错不明显,返回的报错信息仅当参考,因为需要自己debug去看具体的报错原因,
*  比如:如果单位错了,函数会报一个不相干的错误;
*3.RFC ZALSM_EXCEL_TO_INTERNAL_TABLE 来获取上传的excel文件
*&---------------------------------------------------------------------*
REPORT zcycle11.

DATA : BEGIN OF it_tab OCCURS 0,
         zkey2 TYPE n,          "行项目号
         zmark TYPE c,          "是否测试标志 , X 标识测试
         matnr LIKE eina-matnr, "物料编码
         werks LIKE eine-werks, "工厂
         lifnr LIKE eina-lifnr, "供应商
         ekorg LIKE eine-ekorg, "采购组织
         esokz LIKE eine-esokz, "采购信息记录分类
         ekgrp LIKE eine-ekgrp, "采购组
         waers LIKE eine-waers, "货币码
         mwskz LIKE eine-mwskz, "税码
         aplfz LIKE eine-aplfz, "计划交货时间(天)
         netpr LIKE eine-netpr, "净价
         bprme LIKE eine-bprme, "采购单位
         peinh LIKE eine-peinh, "价格单位
         datab LIKE konh-datab, "有效期起始日
         datbi LIKE konh-datbi, "有效期截至日
         umrez LIKE eina-umrez, "单位转换分子
         umren LIKE eina-umren, "单位转换分母
       END OF it_tab.

DATA : BEGIN OF et_tab OCCURS 0, "结果记录表
         zresult TYPE c,
         message TYPE char100,
         zkey    TYPE n,
         infnr   LIKE eine-infnr, "采购信息记录号
       END OF et_tab.

DATA : st_tab LIKE TABLE OF et_tab.

DATA:lv_mode TYPE c.   " I 为新增 , M 为修改
DATA:ls_eina TYPE eina,
     ls_eine TYPE eine.
DATA:ls_mara TYPE mara.

*-----------BAPI数据定义--------------------------
DATA:i_eina  TYPE mewieina,
     i_einax TYPE mewieinax,
     i_eine  TYPE mewieine,
     i_einex TYPE mewieinex.
DATA:lv_test TYPE bapiflag-bapiflag.
DATA:lt_return2 TYPE mewi_t_return,
     ls_return2 LIKE LINE OF lt_return2.
DATA:lt_con_vali TYPE TABLE OF mewivalidity,
     ls_con_vali TYPE mewivalidity.
DATA:lt_condition TYPE TABLE OF mewicondition,
     ls_condition TYPE mewicondition.
DATA:e_eina TYPE mewieina,
     e_eine TYPE mewieine.

"SALV 输出定义
DATA: i_table      TYPE REF TO cl_salv_table.
DATA: lr_columns   TYPE REF TO cl_salv_columns_table.
DATA: lr_functions TYPE REF TO cl_salv_functions.


"定义上载的EXCELDATA:gs_upload TYPE alsmex_tabline,
     gt_upload TYPE TABLE OF alsmex_tabline.

SELECTION-SCREEN : BEGIN OF BLOCK b WITH FRAME TITLE TEXT-001.
  PARAMETERS : p1 TYPE string.
SELECTION-SCREEN : END OF BLOCK b.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p1.
  PERFORM frm_fn."路径搜索帮助打开

START-OF-SELECTION.
  PERFORM upload_data.  "上传数据
  PERFORM process_data. "处理上传的数据
  PERFORM deal_data.    "BAPI生成info record
  PERFORM salv_show.    "SALV输出


FORM deal_data.
  LOOP AT it_tab.
    CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
      EXPORTING
        input        = it_tab-matnr
      IMPORTING
        output       = it_tab-matnr
      EXCEPTIONS
        length_error = 1
        OTHERS       = 2.
    "补齐供应商的前导零
    CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
      EXPORTING
        input  = it_tab-lifnr
      IMPORTING
        output = it_tab-lifnr.

    SELECT SINGLE * INTO CORRESPONDING FIELDS OF ls_eina
      FROM eina
       WHERE matnr = it_tab-matnr
        AND lifnr = it_tab-lifnr.
    IF sy-subrc <> 0.
      lv_mode = 'I'."新增
    ELSE.
      SELECT SINGLE * INTO CORRESPONDING FIELDS OF ls_eine
        FROM eine
        WHERE infnr = ls_eina-infnr
          AND ekorg = it_tab-ekorg "采购组织
          AND esokz = it_tab-esokz "采购信息记录分类
          AND werks = it_tab-werks."工厂
      IF sy-subrc = 0.
        lv_mode = 'M'."修改
        i_eina-info_rec = ls_eina-infnr."采购信息记录号
        i_eine-info_rec = ls_eina-infnr."
        i_einex-info_rec = 'X'.
*        i_einax-vendor = 'X'.
*        i_einax-material = 'X'.
      ELSE.
        lv_mode = 'I'."新增
      ENDIF.
    ENDIF.

    i_eina-vendor = it_tab-lifnr."供应商
    i_eina-material = it_tab-matnr."物料编码
    i_einax-vendor = 'X'.
    i_einax-material = 'X'.
    "
    i_eine-purch_org = it_tab-ekorg."采购组织
    IF i_eine-purch_org IS NOT INITIAL.
      i_einex-purch_org = 'X'.
    ENDIF.
    i_eine-info_type = it_tab-esokz."信息类别
    IF i_eine-info_type IS NOT INITIAL.
      i_einex-info_type = 'X'.
    ENDIF.
    i_eine-plant = it_tab-werks."工厂
    IF i_eine-plant IS NOT INITIAL.
      i_einex-plant = 'X'.
    ENDIF.
    i_eine-pur_group = it_tab-ekgrp."采购组
    IF i_eine-pur_group IS NOT INITIAL.
      i_einex-pur_group = 'X'.
    ENDIF.
    i_eine-currency = it_tab-waers."货币码
    IF i_eine-currency IS NOT INITIAL.
      i_einex-currency = 'X'.
    ENDIF.
    i_eine-tax_code = it_tab-mwskz."税码
    IF i_eine-tax_code IS NOT INITIAL.
      i_einex-tax_code = 'X'.
    ENDIF.
    i_eine-plnd_delry = it_tab-aplfz."计划交货时间(天)
    IF i_eine-plnd_delry IS NOT INITIAL.
      i_einex-plnd_delry = 'X'.
    ENDIF.

    i_eine-net_price = it_tab-netpr."净价
    IF i_eine-net_price IS NOT INITIAL.
      i_einex-net_price = 'X'.
    ENDIF.

    "对采购单位进行一次转换
    CALL FUNCTION 'CONVERSION_EXIT_CUNIT_INPUT'
      EXPORTING
        input          = it_tab-bprme
*       LANGUAGE       = SY-LANGU
      IMPORTING
        output         = it_tab-bprme
      EXCEPTIONS
        unit_not_found = 1
        OTHERS         = 2.

    "对单位进行校验
    SELECT SINGLE * INTO ls_mara
      FROM mara
      WHERE matnr = it_tab-matnr.
    IF sy-subrc = 0.
      IF ls_mara-bstme IS NOT INITIAL.
        IF ls_mara-bstme <> it_tab-bprme.
          et_tab-zresult = 'E'.
          et_tab-message = '采购单位与采购订单计量单位不一致'.
          APPEND et_tab.
          CLEAR et_tab.
          CONTINUE.
        ENDIF.
      ELSE.
        IF ls_mara-meins <> it_tab-bprme.
          et_tab-zresult = 'E'.
          et_tab-message = '采购单位与基本单位不一致'.
          APPEND et_tab.
          CLEAR et_tab.
          CONTINUE.
        ENDIF.
      ENDIF.
    ENDIF.
*** 因为上面已经要求单位要一致,所以这里分子分母要为空,如果没有要求单位一致,那么就一定要输出单位转换的分子分母
    i_eine-conv_num1 = it_tab-umrez. "单位转换分子
    IF i_eine-conv_num1 IS NOT INITIAL.
      i_einex-conv_num1 = 'X'.
    ENDIF.

    i_eine-conv_den1 = it_tab-umren. "单位转换分母
    IF i_eine-conv_den1 IS NOT INITIAL.
      i_einex-conv_den1 = 'X'.
    ENDIF.

    i_eine-orderpr_un = it_tab-bprme."采购单位
    IF i_eine-orderpr_un IS NOT INITIAL.
      i_einex-orderpr_un = 'X'.
    ENDIF.
    i_eine-price_unit = it_tab-peinh."价格单位
    IF i_eine-price_unit IS NOT INITIAL.
      i_einex-price_unit = 'X'.
    ENDIF.

    "i_eine-nrm_po_qty = '1'."标准采购订单数量
    "i_einex-nrm_po_qty = 'X'.

    ls_con_vali-plant = it_tab-werks."工厂
    ls_con_vali-valid_from = it_tab-datab."有效起始日
    ls_con_vali-valid_to = it_tab-datbi."有效截止日
    APPEND ls_con_vali TO lt_con_vali.

    ls_condition-cond_type = 'PB00'."固定值
    ls_condition-currency = it_tab-waers."货币码
    ls_condition-cond_value = it_tab-netpr."净价
    ls_condition-cond_p_unt = it_tab-peinh."条件定价单位
    ls_condition-cond_unit = it_tab-bprme."条件单位
    APPEND ls_condition TO lt_condition.

    lv_test = it_tab-zmark."是否测试,如果为'X',则为测试

    CLEAR:lt_return2.
    IF lv_mode = 'I'.  "新建
      CALL FUNCTION 'ME_INFORECORD_MAINTAIN'
        EXPORTING
          i_eina  = i_eina
*         I_EINAX =
          i_eine  = i_eine
          i_einex = i_einex
          testrun = lv_test
        IMPORTING
          e_eina  = e_eina
          e_eine  = e_eine
        TABLES
*         TXT_LINES     =
*         cond_validity = lt_con_vali
*         condition     = lt_condition
*         COND_SCALE_VALUE       =
*         COND_SCALE_QUAN        =
          return  = lt_return2.

      READ TABLE lt_return2 INTO ls_return2 WITH KEY type = 'E'.
      IF sy-subrc <> 0 AND lv_test = ''.
        "创建时需要将数据写入到数据库里,不然报错
        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
          EXPORTING
            wait = 'X'.
        "因为净价和条件不能同时维护,所以分开维护
        CLEAR:i_einex-net_price.
        CLEAR:lt_return2.
        i_eina-info_rec = e_eina-info_rec."采购信息记录号
        i_eine-info_rec = e_eina-info_rec."采购信息记录号
        i_einex-info_rec = 'X'.
        CALL FUNCTION 'ME_INFORECORD_MAINTAIN'
          EXPORTING
            i_eina        = i_eina
*           I_EINAX       =
            i_eine        = i_eine
            i_einex       = i_einex
            testrun       = lv_test
          IMPORTING
            e_eina        = e_eina
            e_eine        = e_eine
          TABLES
*           TXT_LINES     =
            cond_validity = lt_con_vali   "第二次运行增加有效期信息
            condition     = lt_condition  "第二次运行增加条件信息
*           COND_SCALE_VALUE       =
*           COND_SCALE_QUAN        =
            return        = lt_return2.
      ENDIF.
    ELSE.  "修改
      "对数据进行修改
      CALL FUNCTION 'ME_INFORECORD_MAINTAIN'
        EXPORTING
          i_eina  = i_eina
          i_einax = i_einax
          i_eine  = i_eine
          i_einex = i_einex
          testrun = lv_test
        IMPORTING
          e_eina  = e_eina
          e_eine  = e_eine
        TABLES
*         TXT_LINES     =
*         cond_validity = lt_con_vali
*         condition     = lt_condition
*         COND_SCALE_VALUE       =
*         COND_SCALE_QUAN        =
          return  = lt_return2.

      "理论上这里可以不用commit就能更改条件
      CLEAR:i_einex-net_price."一定要清空这个变量,不然程序会报错
      CALL FUNCTION 'ME_INFORECORD_MAINTAIN'
        EXPORTING
          i_eina        = i_eina
*         I_EINAX       =
          i_eine        = i_eine
          i_einex       = i_einex
          testrun       = lv_test
        IMPORTING
          e_eina        = e_eina
          e_eine        = e_eine
        TABLES
*         TXT_LINES     =
          cond_validity = lt_con_vali   "第二次运行增加有效期信息
          condition     = lt_condition  "第二次运行增加条件信息
*         COND_SCALE_VALUE       =
*         COND_SCALE_QUAN        =
          return        = lt_return2.
    ENDIF.

    IF lv_test IS INITIAL."正式运行
      READ TABLE lt_return2 INTO ls_return2 WITH KEY type = 'E'.
      IF sy-subrc = 0.
        CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
        et_tab-zresult = 'E'.
        et_tab-message = '创建失败'.
        APPEND et_tab.
        CLEAR et_tab.
      ELSE.
        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
          EXPORTING
            wait = 'X'.
        et_tab-zkey = it_tab-zkey2."行项目号
        et_tab-infnr = e_eina-info_rec."采购信息记录号
        et_tab-zresult = 'S'.
        et_tab-message = '创建成功'.
        APPEND et_tab.
        CLEAR et_tab.
      ENDIF.
    ELSE. "测试运行 lv_text = 'X'
      READ TABLE lt_return2 INTO ls_return2 WITH KEY type = 'E'.
      IF sy-subrc = 0.
        LOOP AT lt_return2 INTO ls_return2.
          IF sy-tabix = 1.
            et_tab-message = ls_return2-message.
          ELSE.
            et_tab-message =  et_tab-message && ';' && ls_return2-message.
          ENDIF.
        ENDLOOP.
        et_tab-zresult = 'E'.
        APPEND et_tab.
        CLEAR et_tab.
      ELSE.
        et_tab-zresult = 'S'.
        et_tab-message = '试运行成功'.
        APPEND et_tab.
        CLEAR:et_tab.
      ENDIF.
    ENDIF.

    CLEAR:i_eina,i_einax,
          i_eine,i_einex,
          lt_con_vali,lt_condition,
          ls_eina.
    CLEAR:lt_return2.

  ENDLOOP.
ENDFORM.

FORM salv_show.
  st_tab[] = et_tab[].
  TRY.
      cl_salv_table=>factory(
        IMPORTING
          r_salv_table = i_table
        CHANGING
          t_table      = st_tab ).
    CATCH cx_salv_msg.
  ENDTRY.


  " 功能按钮
  lr_functions = i_table->get_functions( ).
  lr_functions->set_all( abap_true ).


  " 列自适应
  lr_columns = i_table->get_columns( ).
  lr_columns->set_optimize( 'X').

  "设置列名称
  "lr_columns->get_column( 'CHRG2' )->set_long_text( '批次22' )."

  " alv输出
  i_table->display( ).

ENDFORM.

FORM frm_fn .
  CALL FUNCTION 'WS_FILENAME_GET'             "Get file name
    EXPORTING
      mask             = ',*.* ,*.*.' "',*.xls,*.xlsx.'
      mode             = '0'
      title            = TEXT-h10
    IMPORTING
      filename         = p1
    EXCEPTIONS
      inv_winsys       = 1
      no_batch         = 2
      selection_cancel = 3
      selection_error  = 4
      OTHERS           = 5.
  IF sy-subrc <> 0.
*            MESSAGE E016 WITH I_PATH.
  ENDIF.
ENDFORM.

FORM upload_data.
  DATA: lv_xls LIKE rlgrap-filename .
  IF p1 IS INITIAL.
    MESSAGE '导入文件地址不能为空!' TYPE 'E'.
    STOP.
  ENDIF.
  CLEAR lv_xls.
  lv_xls = p1.
  "从第二行第一列开始读取
  CALL FUNCTION 'ALSM_EXCEL_TO_INTERNAL_TABLE'
    EXPORTING
      filename                = lv_xls
      i_begin_col             = 1
      i_begin_row             = 2
      i_end_col               = 18 " 读取多少列
      i_end_row               = 9999 "读取多少行
    TABLES
      intern                  = gt_upload
    EXCEPTIONS
      inconsistent_parameters = 1
      upload_ole              = 2
      OTHERS                  = 3.
  IF sy-subrc NE 0 .
    MESSAGE  '从本地文件导入到SAP失败' TYPE 'E'.
  ENDIF.
  CLEAR gs_upload.
  SORT gt_upload BY row col.
ENDFORM.

FORM process_data.
  DATA : l_index TYPE i.
  DATA : l_type  TYPE c.
  FIELD-SYMBOLS : <fs>.
  LOOP AT gt_upload INTO gs_upload . "把上传的excel数据转换到内表 it_tab 中
    MOVE gs_upload-col TO l_index.
    ASSIGN COMPONENT l_index OF STRUCTURE it_tab TO <fs>.
    DESCRIBE FIELD <fs> TYPE l_type. "获取cell里的数据类型
    IF l_type = 'C'. "如果这个cell里的数据是 C 类型,则condense以下
      <fs> = gs_upload-value.
      CONDENSE <fs>.
    ELSE.
      <fs> = gs_upload-value.
    ENDIF.

    AT END OF row.
      APPEND it_tab.
      CLEAR it_tab.
    ENDAT.
  ENDLOOP.
ENDFORM.
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值