ABAP - SALV 实战案例 交货单拣配功能

  • 实现了交货单数据完成拣配的功能 

  • 完整代码
TYPES:BEGIN OF ty_data,
        sel    TYPE char1,
        status TYPE char1,
        vbeln  TYPE likp-vbeln,
        lfart  TYPE likp-lfart,
        vkorg  TYPE likp-vkorg,
        ernam  TYPE likp-ernam,
        kunnr  TYPE likp-kunnr,
        name1  TYPE kna1-name1,
        erdat  TYPE likp-erdat,
        color  TYPE lvc_t_scol,
        mesge  TYPE c LENGTH 150,
      END OF ty_data.

CLASS cl_view DEFINITION DEFERRED.
DATA: lo_view TYPE REF TO cl_view.
DATA:gr_container TYPE REF TO cl_gui_custom_container.

*Model(持久层):数据库数据
CLASS cl_model DEFINITION.
  PUBLIC SECTION.
    DATA t_data TYPE TABLE OF ty_data.
    DATA: lt_celltype TYPE salv_t_int4_column.
    DATA: ls_celltype LIKE LINE OF lt_celltype.
    METHODS:
      get_data.
ENDCLASS.

*VIEW(视图层):数据可视化
CLASS cl_view DEFINITION.
  PUBLIC SECTION.
    DATA view_data TYPE TABLE OF ty_data.
    DATA o_alv     TYPE REF TO cl_salv_table.
    METHODS:
      show_alv IMPORTING io_model TYPE REF TO cl_model.
  PRIVATE SECTION.
    METHODS:
      set_status CHANGING co_alv TYPE REF TO cl_salv_table.
    METHODS:
      set_layout CHANGING co_alv TYPE REF TO cl_salv_table.
    METHODS:
      set_column CHANGING co_alv TYPE REF TO cl_salv_table.
    METHODS:
      set_colors CHANGING co_alv TYPE REF TO cl_salv_table.
    METHODS:
      set_chebox CHANGING co_alv TYPE REF TO cl_salv_table.
    METHODS:
      set_events CHANGING co_alv TYPE REF TO cl_salv_table.
ENDCLASS.

* Controller(控制器层):用户在VIEW(视图)层交互后的处理,以及对视图层数据的反馈
CLASS lcl_event_handler DEFINITION.
  PUBLIC SECTION.

    TYPES:BEGIN OF ty_posnr_status,
            vbeln TYPE lips-vbeln,
            posnr TYPE lips-posnr,
            type  TYPE char1,
            mesge TYPE c LENGTH 100.
    TYPES END OF ty_posnr_status.

    TYPES:BEGIN OF cty_data,
            vbeln TYPE likp-vbeln,
            posnr TYPE lips-posnr,
            matnr TYPE lips-matnr,
            charg TYPE lips-charg,
            lfimg TYPE lips-lfimg.
    TYPES END OF cty_data.

    DATA lt_posnr_status TYPE TABLE OF ty_posnr_status.
    DATA lw_posnr_status TYPE ty_posnr_status.

    DATA lt_data TYPE TABLE OF cty_data.
    DATA lw_data TYPE cty_data.

    METHODS:
      on_link_click FOR EVENT link_click OF cl_salv_events_table
        IMPORTING row column.
    METHODS: on_user_command FOR EVENT added_function OF cl_salv_events_table
      IMPORTING e_salv_function.

  PRIVATE SECTION.
    METHODS:
      handler_command_jp,
      handler_command_sel,
      handler_command_cal,
      call_bapi.

ENDCLASS.

SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.

PARAMETERS:     p_werks TYPE likp-werks OBLIGATORY,
                p_vstel TYPE likp-vstel OBLIGATORY.

SELECT-OPTIONS: s_vbeln FOR  likp-vbeln OBLIGATORY,
                s_wadat FOR  likp-wadat,
                s_erdat FOR  likp-erdat.

SELECTION-SCREEN END OF BLOCK b1.

START-OF-SELECTION.

  CALL SCREEN 9000.

CLASS cl_model IMPLEMENTATION.
  METHOD get_data.

    SELECT likp~vbeln likp~lfart likp~vkorg likp~ernam likp~kunnr likp~erdat
     INTO CORRESPONDING FIELDS OF TABLE me->t_data
      FROM likp
     INNER JOIN lips  ON likp~vbeln = lips~vbeln
     WHERE likp~werks EQ p_werks
       AND likp~vbeln IN s_vbeln
       AND likp~wadat IN s_wadat
       AND likp~erdat IN s_erdat.

    CHECK me->t_data[] IS NOT INITIAL.

    SELECT kunnr,name1 INTO TABLE @DATA(lt_kna1)
      FROM kna1
       FOR ALL ENTRIES IN @me->t_data
     WHERE kunnr = @me->t_data-kunnr.

    SORT lt_kna1 BY kunnr.

    SELECT vbeln,kostk INTO TABLE @DATA(lt_vbuk)
      FROM vbuk
       FOR ALL ENTRIES IN @me->t_data
     WHERE vbeln = @me->t_data-vbeln.

    SORT lt_vbuk BY vbeln.

    LOOP AT me->t_data INTO DATA(lw_data).
      READ TABLE lt_kna1 INTO DATA(lw_kna1) WITH KEY kunnr = lw_data-kunnr BINARY SEARCH.
      IF sy-subrc = 0.
        lw_data-name1 = lw_kna1-name1.  " 供应商描述
      ENDIF.

      READ TABLE lt_vbuk INTO DATA(lw_vbuk) WITH KEY vbeln = lw_data-vbeln BINARY SEARCH.
      IF sy-subrc = 0.
        IF lw_vbuk-kostk = 'A'.
          lw_data-status = '1'.
        ELSEIF lw_vbuk-kostk = 'B'.
          lw_data-status = '2'.
        ELSEIF lw_vbuk-kostk = 'C'.
          lw_data-status = '3'.
        ENDIF.
      ENDIF.

      MODIFY me->t_data FROM lw_data.
    ENDLOOP.

  ENDMETHOD.

ENDCLASS.

CLASS cl_view IMPLEMENTATION.
  METHOD show_alv.
    CHECK gr_container IS NOT BOUND.

    CREATE OBJECT gr_container       " 创建控制器对象
      EXPORTING
        container_name = 'CTROL'.    " 屏幕上用户自定义控件名
    view_data  = io_model->t_data[].
    TRY.                             " SALV以控制器方式显示
        cl_salv_table=>factory(
          EXPORTING
            r_container    = gr_container
            container_name = 'CTROL'
          IMPORTING
            r_salv_table   = o_alv
          CHANGING
            t_table        = view_data ).
      CATCH cx_salv_msg INTO DATA(msg).
        MESSAGE  msg TYPE 'S' DISPLAY LIKE 'E'.
    ENDTRY.
    " 调用status设置方法
    me->set_status( CHANGING co_alv = o_alv ).
    " 调用layout设置方法
    me->set_layout( CHANGING co_alv = o_alv ).
    " 调用column设置方法
    me->set_column( CHANGING co_alv = o_alv ).
    " 调用chebox设置方法
    me->set_chebox( CHANGING co_alv = o_alv ).
    " 调用colors设置方法
    me->set_colors( CHANGING co_alv = o_alv ).
    " 调用events设置事件注册方法
    me->set_events( CHANGING co_alv = o_alv ).
    " 调用展示ALV方法
    o_alv->display( ).
  ENDMETHOD.

  METHOD set_status.
    DATA: lo_functions TYPE REF TO cl_salv_functions_list.
    " 设置默认的标准状态栏
    lo_functions = co_alv->get_functions( ).
    lo_functions->set_all( abap_true ).
    INCLUDE <icon>.
    DATA: l_icon TYPE string.

    " 添加全部选择按钮
    l_icon = icon_select_all.
    lo_functions->add_function( name = 'ALL'  tooltip = '全部选择'
                                icon = l_icon
                                position = if_salv_c_function_position=>right_of_salv_functions
                               ).
    " 添加取消全选按钮
    l_icon = icon_deselect_all.
    lo_functions->add_function( name = 'CAL'  tooltip = '取消全选'
                                icon = l_icon
                                position = if_salv_c_function_position=>right_of_salv_functions
                               ).
    " 添加拣配处理按钮按钮
    l_icon = icon_execute_object.
    lo_functions->add_function( name = 'JP'  text = '拣配处理' tooltip = '拣配处理'
                                icon = l_icon
                                position = if_salv_c_function_position=>right_of_salv_functions
                               ).

  ENDMETHOD.

  METHOD set_layout .
    DATA: lo_selections TYPE REF TO cl_salv_selections.
    DATA: lo_display    TYPE REF TO cl_salv_display_settings.
    " 取得Layout对象
    lo_display = co_alv->get_display_settings( ).
    " 设置Zebra显示(斑马纹输出)
    lo_display->set_striped_pattern( 'X' ).
    " 设置Title(报表标题)
    lo_display->set_list_header( '启泰-交货单拣配报表' ).
  ENDMETHOD.

  METHOD set_column.
    " 声明接收全体列对象的变量
    DATA: lo_columns TYPE REF TO cl_salv_columns.
    DATA: lo_columns_table TYPE REF TO cl_salv_columns_table.
    " 声明接收单个列对象的变量
    DATA: lo_column TYPE REF TO cl_salv_column.
    DATA: lo_column_table  TYPE REF TO cl_salv_column_table.

    " 声明信号灯变量
    DATA: ls_ddic TYPE salv_s_ddic_reference.
    DATA: lo_functional_settings TYPE REF TO cl_salv_functional_settings.
    DATA: lo_tooltips TYPE REF TO cl_salv_tooltips.

    " 获取全部列的对象
    lo_columns = co_alv->get_columns( ).

    " 设置自动优化列宽度
    lo_columns->set_optimize( 'X' ).

    ls_ddic-field = 'FIELD'.
    ls_ddic-table = 'SALV_S_DDIC_REFERENCE'.

    TRY.
        " 获取全部列的对象
        lo_columns_table = co_alv->get_columns( ).
        lo_columns_table->set_exception_column( 'STATUS' ).

        lo_column_table ?= lo_columns_table->get_column('STATUS').
        lo_column_table->set_ddic_reference( ls_ddic ).
        lo_column_table->set_short_text( '状态' ).
        lo_column_table->set_medium_text( '状态' ).
        lo_column_table->set_long_text( '状态' ).

        " 从全部列对象中获取单个列对象 给列命名
        lo_column = lo_columns->get_column( 'SEL' ).
        lo_column->set_short_text( '选择' ).

        lo_column = lo_columns->get_column( 'ERNAM' ).
        lo_column->set_short_text( '创建人' ).

        lo_column = lo_columns->get_column( 'MESGE' ).
        lo_column->set_short_text( '拣配信息' ).

        " 隐藏列
        lo_column = lo_columns->get_column( 'MATNR' ).
        lo_column->set_visible( value = if_salv_c_bool_sap=>false ).

        lo_column = lo_columns->get_column( 'LFIMG' ).
        lo_column->set_visible( value = if_salv_c_bool_sap=>false ).

        lo_column = lo_columns->get_column( 'CHARG' ).
        lo_column->set_visible( value = if_salv_c_bool_sap=>false ).

      CATCH cx_salv_not_found.
    ENDTRY.

    lo_functional_settings = co_alv->get_functional_settings( ).
    lo_tooltips = lo_functional_settings->get_tooltips( ).

    "单元格显示类型:异常灯、图标、符号。即这里针对的是类型为 异常列 所有的单元格
    lo_tooltips->add_tooltip(
      type = cl_salv_tooltip=>c_type_exception
      value = space
      tooltip = 'Undefined').
    lo_tooltips->add_tooltip(
      type = cl_salv_tooltip=>c_type_exception
      value = '1'
      tooltip = '未拣配').
    lo_tooltips->add_tooltip(
      type = cl_salv_tooltip=>c_type_exception
      value = '2'
      tooltip = '未完全拣配').
    lo_tooltips->add_tooltip(
      type = cl_salv_tooltip=>c_type_exception
      value = '3'
      tooltip = '已完全拣配').

  ENDMETHOD.

  METHOD set_chebox.
*   声明事件变量
*   声明接收全体列对象的变量
    DATA: lo_cols TYPE REF TO cl_salv_columns.
*   声明接收单个列对象的变量
    DATA: lo_column TYPE REF TO cl_salv_column_list.
*   获取全部列的对象
    lo_cols = co_alv->get_columns( ).
    TRY.
        lo_column ?= lo_cols->get_column( 'SEL' ).
        lo_column->set_cell_type( if_salv_c_cell_type=>checkbox_hotspot ).
        lo_column->set_output_length( 6 ).
      CATCH cx_salv_not_found.
    ENDTRY.
  ENDMETHOD.

  METHOD set_events.
    " 获取事件对象
    DATA: lo_events TYPE REF TO cl_salv_events_table.
    lo_events = co_alv->get_event( ).

    "事件注册
    DATA: lo_event_handler TYPE REF TO lcl_event_handler.
    CREATE OBJECT lo_event_handler.
    SET HANDLER lo_event_handler->on_link_click FOR lo_events.
    SET HANDLER lo_event_handler->on_user_command FOR lo_events.
  ENDMETHOD.

  METHOD set_colors.
    DATA: lo_cols_tab TYPE REF TO cl_salv_columns_table,
          lo_col_tab  TYPE REF TO cl_salv_column_table.
    DATA: ls_color TYPE lvc_s_colo.    " Colors strucutre

    lo_cols_tab = co_alv->get_columns( ).

    INCLUDE <color>.

    DATA: lt_s_color TYPE lvc_t_scol,
          ls_s_color TYPE lvc_s_scol.

    LOOP AT me->view_data INTO DATA(lw_data).
      IF lw_data-status = 3.
        ls_s_color-fname     = 'SEL'.
        ls_s_color-color-col = col_negative.
        APPEND ls_s_color TO lt_s_color.

        lw_data-color = lt_s_color.
        MODIFY me->view_data FROM lw_data.
      ENDIF.
      CLEAR: lt_s_color,ls_s_color.
    ENDLOOP.

    TRY.
        lo_cols_tab->set_color_column( 'COLOR' ).
      CATCH cx_salv_data_error.
    ENDTRY.

  ENDMETHOD.

ENDCLASS.

CLASS lcl_event_handler IMPLEMENTATION.

  METHOD on_link_click.
    READ TABLE lo_view->view_data ASSIGNING FIELD-SYMBOL(<lfa_data>) INDEX row.
    CHECK sy-subrc IS INITIAL.
    CHECK <lfa_data>-color IS INITIAL.
    IF <lfa_data>-sel IS INITIAL.
      <lfa_data>-sel = abap_true.
    ELSE.
      CLEAR <lfa_data>-sel.
    ENDIF.
    lo_view->o_alv->refresh( ).
  ENDMETHOD.

  METHOD on_user_command.
    CASE e_salv_function.
      WHEN 'JP'.
        me->handler_command_jp( ).
      WHEN 'ALL'.
        me->handler_command_sel( ).
      WHEN 'CAL'.
        me->handler_command_cal( ).
    ENDCASE.
    lo_view->o_alv->refresh( ).
  ENDMETHOD.

  METHOD handler_command_jp.

    READ TABLE lo_view->view_data TRANSPORTING NO FIELDS WITH KEY sel = abap_true.
    IF sy-subrc NE 0.
      MESSAGE '请先选择数据' TYPE 'I'.
      RETURN.
    ENDIF.

    DATA(view_data) = lo_view->view_data.
    DELETE view_data WHERE sel NE abap_true.

    SELECT vbeln,posnr,werks,lgort,matnr,lfimg
      FROM lips
       FOR ALL ENTRIES IN @view_data
     WHERE vbeln EQ @view_data-vbeln
       AND lfimg GT 0
      INTO TABLE @DATA(lt_lips).

    SELECT matnr,werks,lgort,charg,clabs,chdll
      FROM mchb
      FOR ALL ENTRIES IN @lt_lips
     WHERE matnr EQ @lt_lips-matnr
       AND werks EQ @lt_lips-werks
       AND clabs GT 0
      INTO TABLE @DATA(lt_mchb).

    SELECT vbeln,posnr,matnr,werks,lgort,charg,vmeng
      FROM vbbe
       FOR ALL ENTRIES IN @lt_mchb
     WHERE matnr EQ @lt_mchb-matnr
       AND werks EQ @lt_mchb-werks
       AND lgort EQ @lt_mchb-lgort
       AND charg EQ @lt_mchb-charg
      INTO TABLE @DATA(lt_vbbe).

    " ATP数量
    LOOP AT lt_mchb INTO DATA(lw_mchb).
      LOOP AT lt_vbbe INTO DATA(lw_vbbe) WHERE matnr = lw_mchb-matnr
                                           AND werks = lw_mchb-werks
                                           AND lgort = lw_mchb-lgort
                                           AND charg = lw_mchb-charg.
        lw_mchb-clabs = lw_mchb-clabs - lw_vbbe-vmeng.
      ENDLOOP.
      lw_mchb-chdll = lw_mchb-charg+0(8).
      MODIFY lt_mchb FROM lw_mchb.
    ENDLOOP.

    DELETE lt_mchb WHERE clabs = 0.
    SORT lt_mchb BY chdll DESCENDING.

    LOOP AT lt_lips INTO DATA(lw_lips).
      me->lw_posnr_status-vbeln = lw_lips-vbeln.
      me->lw_posnr_status-posnr = lw_lips-posnr.
      LOOP AT lt_mchb INTO lw_mchb WHERE matnr = lw_lips-matnr AND werks = lw_lips-werks.
        MOVE-CORRESPONDING lw_lips TO me->lw_data.
        IF lw_mchb-clabs GE lw_lips-lfimg.
          me->lw_data-charg = lw_mchb-charg.
          lw_mchb-clabs = lw_mchb-clabs - me->lw_data-lfimg.
          APPEND me->lw_data TO me->lt_data.CLEAR me->lw_data.
          me->lw_posnr_status-type  = 'A'.                " 无需批次拆分状态
          lw_lips-lfimg = 0.
          MODIFY lt_mchb FROM lw_mchb.                    " 更新库存
          EXIT.                                           " 退出mchb循环
        ELSE.
          me->lw_data-charg = lw_mchb-charg.
          me->lw_data-lfimg = lw_mchb-clabs.
          APPEND me->lw_data TO me->lt_data.CLEAR me->lw_data.
          lw_posnr_status-type  = 'B'.                    " 需要批次拆分状态
          lw_lips-lfimg = lw_lips-lfimg - lw_mchb-clabs.  " 还需数量要进入下一次循环
          lw_mchb-clabs = 0.
          MODIFY lt_mchb FROM lw_mchb.
        ENDIF.
      ENDLOOP.
      " status为空时表示没有进入mchb循环;数量没减完 说明库存不足
      IF lw_posnr_status EQ space  OR lw_lips-lfimg NE 0.
        lw_posnr_status-type  = 'C'.                     " 库存不足状态
      ENDIF.
      APPEND lw_posnr_status TO me->lt_posnr_status.CLEAR lw_posnr_status.
    ENDLOOP.

    IF me->lt_data[] IS NOT INITIAL.
      me->call_bapi( ).                                  " 调用Bapi进行交货单拣配过账
    ENDIF.

    REFRESH:me->lt_posnr_status,me->lt_data,lt_mchb,lt_vbbe.
  ENDMETHOD.

  METHOD call_bapi.
* 交货单修改变量
    DATA:ls_header_data TYPE bapiobdlvhdrchg,
         ls_header_ctro TYPE bapiobdlvhdrctrlchg,
         ls_item_data   TYPE bapiobdlvitemchg,
         lt_item_data   TYPE TABLE OF bapiobdlvitemchg,
         ls_item_ctro   TYPE bapiobdlvitemctrlchg,
         lt_item_ctro   TYPE TABLE OF bapiobdlvitemctrlchg,
         lt_item_spl    TYPE TABLE OF /spe/bapiobdlvitemchg,
         ls_item_spl    TYPE /spe/bapiobdlvitemchg,
         lt_return      TYPE STANDARD TABLE OF bapiret2.

* 交货单拣配变量
    DATA:ls_vbkok       TYPE vbkok.
    DATA:lt_vbpok       TYPE STANDARD TABLE OF vbpok.
    DATA:ls_vbpok       TYPE vbpok.
    DATA:lt_prott       TYPE STANDARD TABLE OF prott.
    DATA:ls_prott       TYPE prott.

*
    DATA lv_posnr TYPE lips-posnr.
    DATA lv_mesge TYPE bapiret2-message.

    LOOP AT lo_view->view_data ASSIGNING FIELD-SYMBOL(<fs_data>) WHERE sel EQ abap_true.

      LOOP AT me->lt_posnr_status INTO me->lw_posnr_status WHERE vbeln = <fs_data>-vbeln AND  type NE 'C'.
        " 无须批次拆分
        IF me->lw_posnr_status-type = 'A'.
          READ TABLE me->lt_data INTO me->lw_data WITH KEY vbeln = me->lw_posnr_status-vbeln
                                                           posnr = me->lw_posnr_status-posnr.
          " 交货单修改数据-通用内表参数
          ls_item_data-deliv_numb = me->lw_data-vbeln.            " 被修改的DN号
          ls_item_data-deliv_item = me->lw_data-posnr.            " 被修改的DN行项目
          ls_item_data-material   = me->lw_data-matnr.            " 物料编码
          ls_item_data-fact_unit_nom   = 1.                       " 销售数量转换成SKU的分子(因子)
          ls_item_data-fact_unit_denom = 1.                       " 销售数量转换为 SKU 的值(分母)
          ls_item_data-dlv_qty    = me->lw_data-lfimg.            " 数量
          ls_item_data-batch      = me->lw_data-charg.            " 批次
          APPEND ls_item_data TO lt_item_data.

          " 交货单修改数据-控制内表参数
          ls_item_ctro-deliv_numb = me->lw_data-vbeln.            " 被修改的DN号
          ls_item_ctro-deliv_item = me->lw_data-posnr.            " 被修改的DN行项目
          ls_item_ctro-chg_delqty = 'X'.                          " 数量修改标志
          APPEND ls_item_ctro TO lt_item_ctro.

          " 交货单过账数据
          ls_vbpok-vbeln_vl       = me->lw_data-vbeln.
          ls_vbpok-posnr_vl       = me->lw_data-posnr.
          ls_vbpok-vbeln          = me->lw_data-vbeln.
          ls_vbpok-posnn          = me->lw_data-posnr.
          ls_vbpok-pikmg          = me->lw_data-lfimg.
          ls_vbpok-lfimg          = me->lw_data-lfimg.
          APPEND ls_vbpok TO lt_vbpok.

          CLEAR:ls_item_data,ls_item_ctro,lw_data,ls_vbpok.
        ELSEIF me->lw_posnr_status-type = 'B'.

          lv_posnr = 900000.

          LOOP AT me->lt_data INTO me->lw_data WHERE vbeln = me->lw_posnr_status-vbeln
                                                  AND posnr = me->lw_posnr_status-posnr.
            lv_posnr = lv_posnr + 1.
            ls_item_data-deliv_numb      = me->lw_data-vbeln.     " 被拆分的DN号
            ls_item_data-hieraritem      = me->lw_data-posnr.     " 被拆分的DN行项目号
            ls_item_data-deliv_item      = lv_posnr.              " 拆分新的DN行项目号
            ls_item_data-dlv_qty         = me->lw_data-lfimg.     " 拆分出来DN行项目号的已交数量
            ls_item_data-dlv_qty_imunit  = me->lw_data-lfimg.     " 拆分出来DN行项目号的仓库保存实际交货数量
            ls_item_data-fact_unit_nom   = 1.                     " 销售数量转换成SKU的分子(因子)
            ls_item_data-fact_unit_denom = 1.                     " 销售数量转换为SKU 的值(分母)
            ls_item_data-batch           = me->lw_data-charg.     " 拆分出来DN行项目号批次
            ls_item_data-material        = me->lw_data-matnr.     " 物料编码
            ls_item_data-usehieritm      = '1'.                   " 按树的结构向下延伸一层
            APPEND ls_item_data TO lt_item_data.

            ls_item_ctro-deliv_numb      = me->lw_data-vbeln.     " BAPI控制的DN号
            ls_item_ctro-deliv_item      = lv_posnr.          " BAPI控制的DN行项目号
            ls_item_ctro-chg_delqty      = 'X'.                   " 数量修改标志
            APPEND ls_item_ctro TO lt_item_ctro.

            ls_item_spl-deliv_numb       = me->lw_data-vbeln.     " 被拆分的DN号
            ls_item_spl-deliv_item       = lv_posnr.              " 被拆分的DN行项目号
            APPEND ls_item_spl TO lt_item_spl.

            "交货单拣配数据
            ls_vbpok-vbeln_vl            = me->lw_data-vbeln.
            ls_vbpok-posnr_vl            = me->lw_data-posnr.
            ls_vbpok-vbeln               = me->lw_data-vbeln.
            ls_vbpok-posnn               = me->lw_data-posnr.
            ls_vbpok-pikmg               = me->lw_data-lfimg.
            ls_vbpok-lfimg               = me->lw_data-lfimg.
            APPEND ls_vbpok TO lt_vbpok.

            CLEAR:ls_item_data,ls_item_ctro,ls_item_spl,lw_data,ls_vbpok.
          ENDLOOP.

        ELSEIF me->lw_posnr_status-type = 'C'.
          <fs_data>-mesge = |物料:{ lw_data-matnr ALPHA = OUT }库存不足|.
        ENDIF.

      ENDLOOP.

      ls_header_data-deliv_numb = <fs_data>-vbeln.
      ls_header_ctro-deliv_numb = <fs_data>-vbeln.

      CHECK lt_item_data[] IS NOT INITIAL.

      CALL FUNCTION 'BAPI_OUTB_DELIVERY_CHANGE'
        EXPORTING
          header_data    = ls_header_data
          header_control = ls_header_ctro
          delivery       = <fs_data>-vbeln                   "
        TABLES
          item_data      = lt_item_data
          item_control   = lt_item_ctro
          return         = lt_return
          item_data_spl  = lt_item_spl.

      READ TABLE lt_return INTO DATA(lw_return) WITH KEY type = 'E'.
      IF sy-subrc NE 0.
        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'.
        WAIT UP TO 1 SECONDS.
        " vl01n /vl31n 过账抬头
        ls_vbkok-vbeln_vl   = <fs_data>-vbeln.
        ls_vbkok-komue      = 'X'.      "交货数量 = 捡配数量
        ls_vbkok-kzkodat    = 'X'.
        ls_vbkok-kodat      = sy-datum.
        CALL FUNCTION 'WS_DELIVERY_UPDATE'
          EXPORTING
            vbkok_wa       = ls_vbkok
            commit         = 'X'
            delivery       = <fs_data>-vbeln
            update_picking = 'X'
            synchron       = 'X'
            nicht_sperren  = 'X'         "L.S Inserted
          TABLES
            vbpok_tab      = lt_vbpok
            prot           = lt_prott
          EXCEPTIONS
            error_message  = 1
            OTHERS         = 2.

        LOOP AT lt_prott INTO ls_prott WHERE msgty CA 'E'.
          CALL FUNCTION 'MESSAGE_TEXT_BUILD'
            EXPORTING
              msgid               = ls_prott-msgid
              msgnr               = ls_prott-msgno
              msgv1               = ls_prott-msgv1
              msgv2               = ls_prott-msgv2
              msgv3               = ls_prott-msgv3
              msgv4               = ls_prott-msgv4
            IMPORTING
              message_text_output = lv_mesge.
          lv_mesge = |{ lv_mesge }/{ lv_mesge }|.
        ENDLOOP.

        IF lv_mesge NE space.
          <fs_data>-mesge = |交过单拣配失败:{ lv_mesge }|.
          <fs_data>-status = '1'.
          CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
        ELSE.
          <fs_data>-mesge = |交货单拣配成功|.
          <fs_data>-status = '3'.
          CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'.
          WAIT UP TO 1 SECONDS.
        ENDIF.

      ELSE.
        MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
           INTO <fs_data>-mesge
           WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
      ENDIF.

      CLEAR:ls_vbpok,ls_header_data,ls_header_ctro,ls_vbkok.

      REFRESH:lt_vbpok,lt_prott,lt_item_spl,lt_item_ctro,lt_return,lt_item_data.

    ENDLOOP.

  ENDMETHOD.

  METHOD handler_command_sel.
    LOOP AT lo_view->view_data ASSIGNING FIELD-SYMBOL(<fs_data>) WHERE color IS INITIAL.
      <fs_data>-sel = abap_true.
    ENDLOOP.
  ENDMETHOD.

  METHOD handler_command_cal.
    LOOP AT lo_view->view_data ASSIGNING FIELD-SYMBOL(<fs_data>) WHERE sel = abap_true.
      <fs_data>-sel = abap_false.
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.                    "lcl_event_handler IMPLEMENTATION


MODULE disalv_9000 OUTPUT.
* MVC - Model:Just Process Data
  DATA(lo_model) = NEW cl_model( ).
  lo_model->get_data( ).
  IF lines( lo_model->t_data[] ) = 0.
    MESSAGE '您输入的条件获取不到符合的数据' TYPE 'S' DISPLAY LIKE 'E'.
    LEAVE TO SCREEN 0.
  ENDIF.
* MVC - View: Data View
  IF lo_view IS NOT BOUND.
    lo_view  = NEW cl_view( ).
    lo_view->show_alv( lo_model ).
  ENDIF.
ENDMODULE.
*&---------------------------------------------------------------------*
*&      Module  STATUS_9000  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE status_9000 OUTPUT.
  SET PF-STATUS 'STATUS_9000'.
  SET TITLEBAR 'TITLE_9000'.
ENDMODULE.
MODULE user_command_9000 INPUT.
  CASE sy-ucomm.
    WHEN 'BACK'.
      LEAVE TO SCREEN 0.
    WHEN 'EXIT'.
      LEAVE PROGRAM.
    WHEN 'CANCEL'.
      LEAVE PROGRAM.
    WHEN 'SAVE'.
*      CALL METHOD gs_alv->check_changed_data.
  ENDCASE.
ENDMODULE.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值