ABAP - 程序模板 - 表维护

 *&---------------------------------------------------------------------*
*& Program Code:
*& Program Name: ZLET006
*& Author      : 00103808
*& Date        : 2011/07/06
*& Module      : LE
*& Responsible : 运输路线交货日期维护
*& Description :
*&---------------------------------------------------------------------*
*& Version     : V1.0                  Creat by 00103808 in 2011.07.06
*&
*&---------------------------------------------------------------------*

REPORT  zlet006 MESSAGE-ID zle01.

INCLUDE:zlet006_top,
        zlet006_screen,
        zlet006_form.

* MAIN CONTROL
*&---------------------------------------------------------------------*
* INITIALIZATION
*&---------------------------------------------------------------------*
INITIALIZATION.
  descr_ref ?= cl_abap_typedescr=>describe_by_data( gs_db ).
  db_tab = descr_ref->get_ddic_header( ).
  g_tabname = db_tab-tabname.

*&---------------------------------------------------------------------*
* START-OF-SELECTION
*&---------------------------------------------------------------------*
START-OF-SELECTION.
  SELECT * FROM t001 WHERE bukrs IN s_bukrs.
    AUTHORITY-CHECK OBJECT 'F_BKPF_BUK'
             ID 'BUKRS' FIELD t001-bukrs
             ID 'ACTVT' FIELD '03'.
    IF sy-subrc <> 0.
      MESSAGE i000 WITH '您没有公司代码' t001-bukrs '的权限'.
*      EXIT.
      STOP.
    ENDIF.
  ENDSELECT.
  PERFORM prepare_layout CHANGING gs_layout ."设置layout
  REFRESH gt_fieldcat.
  PERFORM prepare_field_catalog CHANGING gt_fieldcat ."设置Field Catalog
  CALL SCREEN '100'.
*&---------------------------------------------------------------------*
* END-OF-SELECTION
*&---------------------------------------------------------------------*
END-OF-SELECTION.

 

************************************************************************************************************************

*&---------------------------------------------------------------------*
*&  包括                ZLET006_TOP
*&---------------------------------------------------------------------*

*&---------------------------------------------------------------------*
* DATA DECLARATION
*&---------------------------------------------------------------------*
TABLES:zle_plannedgi,t001.

DATA: gs_db TYPE zle_plannedgi,"维护表的结构
      g_tabname(30TYPE c."存放维护表的表名
TYPES: t_db LIKE gs_db.

DATABEGIN OF gs_data_wa.
INCLUDE TYPE t_db.
DATA:  flag(1),
       rowmsg(20),
       text(70),
END OF gs_data_wa.

DATABEGIN OF gs_data_alv.
INCLUDE TYPE t_db.
DATA:  flag(1),
       rowmsg(20),
       text(70),
END OF gs_data_alv.

DATA: gs_decomp LIKE gs_data_wa,
      gt_data LIKE STANDARD TABLE OF gs_data_wa,
      gt_data_alv LIKE STANDARD TABLE OF gs_data_wa,"ALV数据内表
      gt_data_old LIKE STANDARD TABLE OF gs_data_wa.

DATA: ok_code TYPE sy-ucomm,
      save_ok TYPE sy-ucomm.
DATA: db_tab LIKE x030l,  "存放变量的数据字典头信息
      descr_ref TYPE REF TO cl_abap_typedescr. "分析ABAP类型描述的对象
*&---------------------------------------------------------------------*
* ALV DATA
*&---------------------------------------------------------------------*
DATA: gr_alvgrid    TYPE REF TO cl_gui_alv_grid ,"ALV对象
      gt_fieldcat   TYPE lvc_t_fcat ,
      gs_layout     TYPE lvc_s_layo ,
      gs_variant    TYPE disvariant,
      gt_exclude    TYPE ui_functions,"存放排除按钮的内表
      gt_index_rows TYPE lvc_t_row,"用以存放要选择行的内表
      gs_index_rows TYPE lvc_s_row."用以存放要选择行的工作区


DATA: gf_valid(1TYPE c,
      gf_error(1TYPE c.

 

******************************************************************************************************************************

 

*&---------------------------------------------------------------------*
*&  包括                ZLET006_SCREEN
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
* SELECTION-SCREEN
*&---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
SELECTION-SCREEN SKIP 1.
PARAMETERS:  r_insert  RADIOBUTTON GROUP rg1 DEFAULT 'X' USER-COMMAND uc,
             r_delete  RADIOBUTTON GROUP rg1,
             r_modify  RADIOBUTTON GROUP rg1,
             r_disp    RADIOBUTTON GROUP rg1.

SELECTION-SCREEN END OF BLOCK b1.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE text-002.
SELECT-OPTIONS:s_bukrs FOR zle_plannedgi-bukrs OBLIGATORY DEFAULT 'C11',
               s_route FOR zle_plannedgi-route,
               s_lfart FOR zle_plannedgi-lfart,
               s_zkcyf FOR zle_plannedgi-zkcyf.
PARAMETERS:   s_dtype TYPE zle_plannedgi-dtype OBLIGATORY DEFAULT 'Y' ."NO INTERVALS NO-EXTENSION.

SELECTION-SCREEN BEGIN OF BLOCK b3 WITH FRAME TITLE text-003.
PARAMETERS:  r_week   RADIOBUTTON GROUP rg2 DEFAULT 'X' USER-COMMAND uc2,
             r_year   RADIOBUTTON GROUP rg2 .
SELECTION-SCREEN END OF BLOCK b3.

SELECTION-SCREEN END OF BLOCK b2.
*&---------------------------------------------------------------------*
* AT SELECTION-SCREEN OUTPUT
*&---------------------------------------------------------------------*
AT SELECTION-SCREEN OUTPUT.
  FIELD-SYMBOLS <fs> TYPE ANY.

  LOOP AT SCREEN.
    IF r_insert NE 'X'.
      IF screen-name CS 'R_WEEK' OR screen-name CS 'R_YEAR'.
        screen-invisible = 1.
      ENDIF.
    ELSE.
      IF r_week EQ 'X'.
        IF screen-name CS 'S_ZKCYF' OR screen-name CS 'S_DTYPE'.
          screen-input = 0.
        ENDIF.
        REFRESH:s_zkcyf.
        s_dtype = 'W'.

      ELSE.
         s_dtype = 'Y'.
      ENDIF.
      IF screen-name CS '-HIGH'.
        screen-input = 0.
      ENDIF.
    ENDIF.
    MODIFY SCREEN.
  ENDLOOP.

 

******************************************************************************************************************************


*&--------------------------------------------------------------------*
*&      Form  prepare_layout
*&--------------------------------------------------------------------*
*       设置Layout
*---------------------------------------------------------------------*
*      -->PS_LAYOUT  text
*---------------------------------------------------------------------*
FORM prepare_layout CHANGING ps_layout TYPE lvc_s_layo.


  ps_layout-zebra = 'X' .

  ps_layout-cwidth_opt = 'X'.

  ps_layout-no_toolbar = ' '.
  IF r_disp = 'X' OR r_delete = 'X'.
    ps_layout-no_rowmark = 'X'.
  ENDIF.
ENDFORM.                    " prepare_layout


*&---------------------------------------------------------------------*
*&      Form  prepare_field_catalog
*&---------------------------------------------------------------------*
*       根据维护表的结构初始化ALV的Field Catalog
*----------------------------------------------------------------------*
*      -->PT_FIELDCAT  text
*----------------------------------------------------------------------*
FORM prepare_field_catalog CHANGING pt_fieldcat TYPE lvc_t_fcat .
  DATA: ls_fieldcat TYPE lvc_s_fcat,
        l_rows TYPE i.

  CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
    EXPORTING
*   I_BUFFER_ACTIVE              =
      i_structure_name             = g_tabname  "表结构
      i_client_never_display       = 'X'
*   I_BYPASSING_BUFFER           =
*   I_INTERNAL_TABNAME           =
    CHANGING
      ct_fieldcat                  = pt_fieldcat
    EXCEPTIONS
      inconsistent_interface       = 1
      program_error                = 2
      OTHERS                       = 3
            .
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
*UserExit,用于自定义Field Catalog
  FIELD-SYMBOLS <fs_fieldcat> TYPE LINE OF lvc_t_fcat.
  LOOP AT pt_fieldcat ASSIGNING <fs_fieldcat>.
    IF <fs_fieldcat>-fieldname = 'DTYPE'.
      <fs_fieldcat>-col_pos = <fs_fieldcat>-col_pos - 1.
    ELSEIF <fs_fieldcat>-fieldname = 'ZKCYF'.
      <fs_fieldcat>-col_pos = <fs_fieldcat>-col_pos + 1.
    ENDIF.
  ENDLOOP.

  PERFORM userexit_fieldcat CHANGING pt_fieldcat.

  DESCRIBE TABLE pt_fieldcat LINES l_rows.
  l_rows = l_rows + 1.
  CLEAR ls_fieldcat .
  ls_fieldcat-fieldname = 'TEXT' .
  ls_fieldcat-coltext   = '配置文本' .
  ls_fieldcat-col_pos   = l_rows.
  APPEND ls_fieldcat TO pt_fieldcat .


  IF r_disp <> 'X'.  "除了显示模式,其他模式都显示选择列和操作结果列
    CLEAR ls_fieldcat .
    ls_fieldcat-fieldname = 'FLAG' .
    ls_fieldcat-coltext   = '选择' .
    ls_fieldcat-edit = 'X'.
    ls_fieldcat-checkbox = 'X'.
    ls_fieldcat-key = 'X'.
*  ls_fieldcat-emphasize = 'X'.
    ls_fieldcat-col_pos = 0.
    APPEND ls_fieldcat TO pt_fieldcat .

    DESCRIBE TABLE pt_fieldcat LINES l_rows.
    CLEAR ls_fieldcat .
    ls_fieldcat-fieldname = 'ROWMSG' .
    ls_fieldcat-coltext   = '操作结果' .
    ls_fieldcat-col_pos   = l_rows.
    APPEND ls_fieldcat TO pt_fieldcat .
  ENDIF.



ENDFORM .                    "prepare_field_catalog

*&---------------------------------------------------------------------*
*&      Form  load_data_into_grid
*&---------------------------------------------------------------------*
*       根据当前操作模式调用数据并显示
*----------------------------------------------------------------------*
FORM load_data_into_grid .
  IF r_insert = 'X'.
    SET TITLEBAR '100'.
    PERFORM userexit_select_data_insert CHANGING gt_data.
  ENDIF.
  IF r_disp = 'X'.
    SET TITLEBAR '101'.
    PERFORM userexit_select_data_display CHANGING gt_data.
  ENDIF.
  IF r_delete = 'X'.
    SET TITLEBAR '102'.
    PERFORM userexit_select_data_delete CHANGING gt_data.
  ENDIF.
  IF r_modify = 'X'.
    SET TITLEBAR '103'.
    PERFORM userexit_select_data_modify CHANGING gt_data.
  ENDIF.
  PERFORM frm_format_alvdata.

ENDFORM.                    " load_data_into_grid

*&---------------------------------------------------------------------*
*&      Form  USEREXIT_FIELDCAT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->PT_FIELDCAT  text
*----------------------------------------------------------------------*
FORM userexit_fieldcat CHANGING pt_fieldcat TYPE lvc_t_fcat.
  DATA: ls_fieldcat TYPE lvc_s_fcat.

  IF s_dtype NE 'W'.
    LOOP AT pt_fieldcat INTO ls_fieldcat.
      IF ls_fieldcat-fieldname+0(4) = 'FILD'.
        CONCATENATE ls_fieldcat-fieldname+4(2'号' INTO ls_fieldcat-scrtext_l.
        ls_fieldcat-scrtext_m = ls_fieldcat-scrtext_l.
        ls_fieldcat-scrtext_s = ls_fieldcat-scrtext_l.
        ls_fieldcat-reptext = ls_fieldcat-scrtext_l.
      ELSEIF ls_fieldcat-fieldname+0(5) = 'LFART'.
        ls_fieldcat-scrtext_l = '交货类型'.
        ls_fieldcat-scrtext_m = ls_fieldcat-scrtext_l.
        ls_fieldcat-scrtext_s = ls_fieldcat-scrtext_l.
        ls_fieldcat-reptext = ls_fieldcat-scrtext_l.
      ELSEIF ls_fieldcat-fieldname+0(5) = 'ZKCYF'.
        ls_fieldcat-scrtext_l = '库存年月'.
        ls_fieldcat-scrtext_m = ls_fieldcat-scrtext_l.
        ls_fieldcat-scrtext_s = ls_fieldcat-scrtext_l.
        ls_fieldcat-reptext = ls_fieldcat-scrtext_l.
      ELSEIF ls_fieldcat-fieldname+0(5) = 'DTYPE'.
        ls_fieldcat-scrtext_l = '日期标识'.
        ls_fieldcat-scrtext_m = ls_fieldcat-scrtext_l.
        ls_fieldcat-scrtext_s = ls_fieldcat-scrtext_l.
        ls_fieldcat-reptext = ls_fieldcat-scrtext_l.
      ENDIF.
      MODIFY pt_fieldcat FROM ls_fieldcat.
      CLEAR ls_fieldcat.
    ENDLOOP.
  ELSE.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'ZKCYF'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD8'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD9'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD10'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD11'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD12'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD13'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD14'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD15'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD16'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD17'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD18'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD19'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD20'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD21'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD22'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD23'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD24'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD25'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD26'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD27'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD28'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD29'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD30'.
    DELETE pt_fieldcat WHERE fieldname+0(6) = 'FILD31'.
    LOOP AT pt_fieldcat INTO ls_fieldcat.
      IF ls_fieldcat-fieldname+0(4) = 'FILD'.
        CONCATENATE '星期' ls_fieldcat-fieldname+4(2INTO ls_fieldcat-scrtext_l.
        ls_fieldcat-scrtext_m = ls_fieldcat-scrtext_l.
        ls_fieldcat-scrtext_s = ls_fieldcat-scrtext_l.
        ls_fieldcat-reptext = ls_fieldcat-scrtext_l.
      ELSEIF ls_fieldcat-fieldname+0(5) = 'LFART'.
        ls_fieldcat-scrtext_l = '交货类型'.
        ls_fieldcat-scrtext_m = ls_fieldcat-scrtext_l.
        ls_fieldcat-scrtext_s = ls_fieldcat-scrtext_l.
        ls_fieldcat-reptext = ls_fieldcat-scrtext_l.
      ELSEIF ls_fieldcat-fieldname+0(5) = 'ZKCYF'.
        ls_fieldcat-scrtext_l = '库存年月'.
        ls_fieldcat-scrtext_m = ls_fieldcat-scrtext_l.
        ls_fieldcat-scrtext_s = ls_fieldcat-scrtext_l.
        ls_fieldcat-reptext = ls_fieldcat-scrtext_l.
      ELSEIF ls_fieldcat-fieldname+0(5) = 'DTYPE'.
        ls_fieldcat-scrtext_l = '日期标识'.
        ls_fieldcat-scrtext_m = ls_fieldcat-scrtext_l.
        ls_fieldcat-scrtext_s = ls_fieldcat-scrtext_l.
        ls_fieldcat-reptext = ls_fieldcat-scrtext_l.
      ENDIF.
      MODIFY pt_fieldcat FROM ls_fieldcat.
      CLEAR ls_fieldcat.
    ENDLOOP.
  ENDIF.

  IF r_insert = 'X' OR r_modify = 'X'.
    LOOP AT pt_fieldcat INTO ls_fieldcat.
      ls_fieldcat-edit = 'X'.
      IF ls_fieldcat-fieldname = 'BUKRS' OR ls_fieldcat-fieldname = 'ROUTE' OR
         ls_fieldcat-fieldname = 'LFART' OR ls_fieldcat-fieldname = 'ZKCYF' OR
         ls_fieldcat-fieldname = 'DTYPE' .
        ls_fieldcat-f4availabl = 'X'.
      ENDIF.
      MODIFY pt_fieldcat FROM ls_fieldcat.
    ENDLOOP.
  ENDIF.
ENDFORM.                    "userexit_fieldcat
*&---------------------------------------------------------------------*
*&      Form  USEREXIT_SELECT_DATA_INSERT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->PT_DATA    text
*----------------------------------------------------------------------*
FORM userexit_select_data_insert CHANGING pt_data LIKE gt_data.
  CLEAR gs_data_wa.
  gs_data_wa-bukrs = s_bukrs-low.
  gs_data_wa-route = s_route-low.
  gs_data_wa-lfart = s_lfart-low.
  gs_data_wa-zkcyf = s_zkcyf-low.
  gs_data_wa-dtype = s_dtype.

  APPEND gs_data_wa TO gt_data.
  CLEAR gs_data_wa.
ENDFORM.                    "userexit_select_data_insert
*&---------------------------------------------------------------------*
*&      Form  USEREXIT_SELECT_DATA_DISPLAY
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_GT_DATA  text
*----------------------------------------------------------------------*
FORM userexit_select_data_display  CHANGING pt_data LIKE gt_data.

  SELECT * INTO CORRESPONDING FIELDS OF TABLE pt_data
           FROM (g_tabname)
          WHERE bukrs IN s_bukrs
            AND route IN s_route
            AND lfart IN s_lfart
            AND zkcyf IN s_zkcyf
            AND dtype EQ s_dtype.

ENDFORM.                    " USEREXIT_SELECT_DATA_DISPLAY
*&---------------------------------------------------------------------*
*&      Form  USEREXIT_SELECT_DATA_DELETE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_GT_DATA  text
*----------------------------------------------------------------------*
FORM userexit_select_data_delete  CHANGING pt_data LIKE gt_data.
  PERFORM userexit_select_data_display CHANGING pt_data.
ENDFORM.                    " USEREXIT_SELECT_DATA_DELETE
*&---------------------------------------------------------------------*
*&      Form  USEREXIT_SELECT_DATA_MODIFY
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_GT_DATA  text
*----------------------------------------------------------------------*
FORM userexit_select_data_modify  CHANGING pt_data LIKE gt_data.
  PERFORM userexit_select_data_display CHANGING pt_data.
ENDFORM.                    " USEREXIT_SELECT_DATA_MODIFY

*----------------------------------------------------------------------*
*  MODULE STATUS_0100 OUTPUT
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
  DATA: lt_rxtab TYPE slis_t_extab.
  DATA: l_rxtab TYPE LINE OF slis_t_extab.

  IF r_disp EQ 'X'.
    l_rxtab-fcode = 'ALL'.
    APPEND l_rxtab TO lt_rxtab.
    l_rxtab-fcode = 'DESEALL'.
    APPEND l_rxtab TO lt_rxtab.
  ENDIF.

  SET PF-STATUS 'MAIN100' EXCLUDING lt_rxtab.
  gs_variant-report = sy-repid.
  IF gr_alvgrid IS INITIAL .
    CREATE OBJECT gr_alvgrid      "第一次载入,建立对象
      EXPORTING
        i_parent          = cl_gui_container=>screen0.
    PERFORM load_data_into_grid.
    PERFORM display_alv .
  ELSE.
    CALL METHOD gr_alvgrid->refresh_table_display.
    IF gf_error IS NOT INITIAL.   "判断修改后是否有不合法数据,有则选中错误行
      CALL METHOD gr_alvgrid->set_selected_rows
        EXPORTING
          it_index_rows = gt_index_rows.
      CLEAR gf_error.
      REFRESH gt_index_rows.
    ENDIF.
  ENDIF.
ENDMODULE.                 " STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0100  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
  save_ok = ok_code.
  CLEAR: ok_code,gf_valid.
  CASE save_ok.
    WHEN 'SAVE'.   "按SAVE 按钮后,提交操作
      CALL METHOD gr_alvgrid->check_changed_data
        IMPORTING
          e_valid = gf_valid.  "数据合法性标识,有非法数据则不进行操作
      IF gf_valid = 'X'.
        IF r_insert = 'X'.
          PERFORM insert_data.
        ELSEIF r_delete = 'X'.
          PERFORM delete_data.
        ELSEIF r_modify = 'X'.
          PERFORM modify_data.
        ENDIF.
      ENDIF.
    WHEN 'BACK'.
      SET SCREEN 0 . "按返回 按钮,返回选择屏幕
    WHEN 'EXIT'.
      LEAVE PROGRAM"退出程序
    WHEN 'ALL'.  "按全选按钮,检查数据完整性和数据修改,并全选
      CALL METHOD gr_alvgrid->check_changed_data
        IMPORTING
          e_valid = gf_valid.
      LOOP AT gt_data_alv INTO gs_data_alv.
        gs_data_alv-flag = 'X'.
        MODIFY gt_data_alv FROM gs_data_alv TRANSPORTING flag WHERE flag = ''.
      ENDLOOP.
    WHEN 'DESEALL'.  "按取消全选按钮,检查数据完整性和数据修改,并取消全选
      CALL METHOD gr_alvgrid->check_changed_data
        IMPORTING
          e_valid = gf_valid.
      LOOP AT gt_data_alv INTO gs_data_alv.
        gs_data_alv-flag = ''.
        MODIFY gt_data_alv FROM gs_data_alv TRANSPORTING flag WHERE flag = 'X'.
      ENDLOOP.
  ENDCASE.
ENDMODULE.                 " USER_COMMAND_0100  INPUT
*&---------------------------------------------------------------------*
*&      Form  INSERT_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM insert_data .
  DATA: l_isucc TYPE i VALUE 0,"成功操作的记录
        l_iserror TYPE c,  "行信息错误指示
        l_tabix LIKE sy-tabix. "行号
  REFRESH gt_index_rows. " 用以存放要选择行的内表
  LOOP AT gt_data_alv INTO gs_data_alv WHERE flag = 'X'.
    l_tabix = sy-tabix.
*验证行数据正确性、手工添加部分信息
    PERFORM userexit_check_row_data USING gs_data_alv
                     CHANGING l_iserror gs_data_alv-rowmsg.
    CLEAR gs_decomp.
    PERFORM frm_decomp_data USING gs_data_alv CHANGING gs_decomp.  "反编译ALV数据
    IF l_iserror = 'X'."判断行信息是否有错误
      CLEAR gs_index_rows.
      gs_index_rows-index = l_tabix.
      APPEND gs_index_rows TO gt_index_rows. "有错误则把当前行号存入GT_index_Rows,用来选择错误行
    ELSE.
*验证行数据在数据库中是否存在
      PERFORM userexit_check_data_row_exist USING gs_data_alv
                       CHANGING l_iserror gs_data_alv-rowmsg.
      IF l_iserror = 'X'."存在则把当前行号存入GT_index_Rows,用来选择错误行
        CLEAR gs_index_rows.
        gs_index_rows-index = l_tabix.
        APPEND gs_index_rows TO gt_index_rows.
      ELSE."插入数据
        CLEAR gs_db.
        MOVE-CORRESPONDING gs_decomp TO gs_db.
        INSERT (g_tabname) FROM gs_db.
        COMMIT WORK AND WAIT.
        gs_data_alv-rowmsg = text-004"插入成功
        l_isucc = l_isucc + 1.
      ENDIF.
    ENDIF.
    MODIFY gt_data_alv FROM gs_data_alv TRANSPORTING rowmsg."更新操作结果信息

  ENDLOOP.
  PERFORM display_message USING l_isucc gt_index_rows '添加'."显示操作成功信息,并判断是否有非法数据
ENDFORM.                    " INSERT_DATA
*&---------------------------------------------------------------------*
*&      Form  delete_data
*&---------------------------------------------------------------------*
*       根据ALV的输入删除数据
*----------------------------------------------------------------------*
FORM delete_data .
  DATA lt_delete LIKE TABLE OF gs_db."存放要删除的信息
  DATA l_isucc TYPE i VALUE 0."成功删除的条数
  DATA l_succ TYPE string."条数的文本
  REFRESH gt_index_rows.

  LOOP AT gt_data_alv INTO gs_data_alv WHERE flag = 'X'.
    CLEAR gs_db.
    CLEAR gs_decomp.
    PERFORM frm_decomp_data USING gs_data_alv CHANGING gs_decomp.
    MOVE-CORRESPONDING gs_decomp TO gs_db.
    APPEND gs_db TO lt_delete.
    gs_data_alv-rowmsg = text-005."删除成功
    MODIFY gt_data_alv FROM gs_data_alv TRANSPORTING rowmsg.
    l_isucc = l_isucc + 1.
  ENDLOOP.
  DELETE (g_tabname) FROM TABLE lt_delete.

  l_succ = l_isucc.
  CONCATENATE '成功删除了' l_succ '条记录' INTO l_succ.
  MESSAGE l_succ TYPE 'S'.
ENDFORM.                    " delete_data*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Form  modify_data
*&---------------------------------------------------------------------*
*       根据ALV的输入修改数据、若数据主键不存在,则新建数据,删除原数据
*----------------------------------------------------------------------*
FORM modify_data .
  DATA: l_isucc TYPE i VALUE 0,"成功操作的条数
        l_iserror TYPE c,"行信息错误指示
        l_tabix LIKE sy-tabix,"行号
        ls_data_old LIKE gs_data_wa,"原数据表工作取
        l_isequal TYPE c."原行与新行主键相同指示
  LOOP AT gt_data_alv INTO gs_data_alv WHERE flag = 'X'.
    CLEAR gs_db.
    l_tabix = sy-tabix.
*验证行数据正确性、手工添加部分信息
    PERFORM userexit_check_row_data USING gs_data_alv
                     CHANGING l_iserror gs_data_alv-rowmsg.
    IF l_iserror = 'X'."判断行信息是否有错误
      CLEAR gs_index_rows.
      gs_index_rows-index = l_tabix.
      APPEND gs_index_rows TO gt_index_rows."有错误则把当前行号存入GT_index_Rows,用来选择错误行
    ELSE.
*验证当前行与原行数据主键是否相同
      READ TABLE gt_data_old INDEX l_tabix INTO ls_data_old.
      PERFORM userexit_compare_key_equal USING gs_data_alv ls_data_old CHANGING l_isequal.
      CLEAR gs_decomp.
      PERFORM frm_decomp_data USING gs_data_alv CHANGING gs_decomp.  "反编译ALV数据
      IF l_isequal = 'X'."主键相同则直接更新
        MOVE-CORRESPONDING gs_decomp TO gs_db.
        MODIFY (g_tabname) FROM gs_db.
        l_isucc = l_isucc + 1.
        gs_data_alv-rowmsg = text-006.
        COMMIT WORK AND WAIT."提交数据库操作
      ELSE."主键不相同,则判断新行数据主键在数据库中是否存在
        MOVE-CORRESPONDING gs_decomp TO gs_db.
        PERFORM userexit_check_data_row_exist USING gs_data_alv
                         CHANGING l_iserror ls_data_old-rowmsg.  "不需要返回错误信息,故放入ls_data_old中
        IF l_iserror = 'X'."存在
          gs_data_alv-rowmsg = '修改失败,已存在相同主键条目'.
          CLEAR gs_index_rows.
          gs_index_rows-index = l_tabix.
          APPEND gs_index_rows TO gt_index_rows."有错误则把当前行号存入GT_index_Rows,用来选择错误行
        ELSE."不存在,则新建数据
          INSERT (g_tabname) FROM gs_db.
          l_isucc = l_isucc + 1.
          gs_data_alv-rowmsg = text-006.
          CLEAR gs_db.
          MOVE-CORRESPONDING ls_data_old TO gs_db.
          DELETE (g_tabname) FROM gs_db."删除原行数据
          COMMIT WORK AND WAIT."提交数据库操作
        ENDIF.

      ENDIF.
    ENDIF.

    MODIFY gt_data_alv FROM gs_data_alv TRANSPORTING text rowmsg.
    CLEAR:gs_data_alv.
  ENDLOOP.

  gt_data_old = gt_data_alv."把新表数据放入gt_data_old中
*显示操作成功信息,并判断是否有非法数据
  PERFORM display_message USING l_isucc gt_index_rows '修改'.
ENDFORM.                    " modify_data
*&---------------------------------------------------------------------*
*&      Form  DISPLAY_ALV
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM display_alv.
*排除不要的按钮
  PERFORM exclude_tb_functions USING gt_exclude.
  CALL METHOD gr_alvgrid->set_table_for_first_display
    EXPORTING
   is_variant                    = gs_variant
   i_save                        = 'A'
    is_layout                     = gs_layout
     it_toolbar_excluding         = gt_exclude
    CHANGING
      it_outtab                     = gt_data_alv
      it_fieldcatalog               = gt_fieldcat
EXCEPTIONS
  invalid_parameter_combination = 1
  program_error                 = 2
  too_many_lines                = 3
  OTHERS                        = 4 .
  IF sy-subrc <> 0.
*--Exception handling
  ENDIF.
ENDFORM.                    "display_alv
*&---------------------------------------------------------------------*
*&      Form  EXCLUDE_TB_FUNCTIONS
*&---------------------------------------------------------------------*
*       去除不要的ALV工具栏按钮
*----------------------------------------------------------------------*
*      <--P_LT_EXCLUDE  text
*----------------------------------------------------------------------*
FORM exclude_tb_functions CHANGING pt_exclude TYPE ui_functions.
* Only allow to change data not to create new entries (exclude
* generic functions).

  DATA ls_exclude TYPE ui_func.

  ls_exclude = cl_gui_alv_grid=>mc_fc_current_variant.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_save_variant.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_average.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_load_variant.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_minimum.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_maximum.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_maintain_variant.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_views.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_graph.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_sum.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_subtot.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_filter.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_sort_dsc.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_sort_asc.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_check.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_detail.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_refresh.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_loc_delete_row.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_loc_move_row.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_loc_cut.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_loc_paste.
  APPEND ls_exclude TO pt_exclude.
  ls_exclude = cl_gui_alv_grid=>mc_fc_loc_undo.
  APPEND ls_exclude TO pt_exclude.

  IF r_insert <> 'X'."插入模式能使用插入行、复制行等按钮
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_paste_new_row.
    APPEND ls_exclude TO pt_exclude.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_paste_new_row.
    APPEND ls_exclude TO pt_exclude.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_copy.
    APPEND ls_exclude TO pt_exclude.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_append_row.
    APPEND ls_exclude TO pt_exclude.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_copy_row.
    APPEND ls_exclude TO pt_exclude.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_insert_row.
    APPEND ls_exclude TO pt_exclude.
  ENDIF.

ENDFORM.                               " EXCLUDE_TB_FUNCTIONS
*&---------------------------------------------------------------------*
*&      Form  DISPLAY_MESSAGE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_SUCC         text
*      -->PT_INDEX_ROWS  text
*      -->P_TYPE         text
*----------------------------------------------------------------------*
FORM display_message USING p_succ TYPE i
                           pt_index_rows TYPE lvc_t_row
                           p_type TYPE c.
  DATA: l_succ  TYPE string,
        l_rows_i    TYPE i,
        l_rows(10)  TYPE c,
        l_msg(70)   TYPE c.
  l_succ = p_succ.
  DESCRIBE TABLE pt_index_rows LINES l_rows_i."统计错误行数
  IF l_rows_i IS INITIAL.
    CONCATENATE '成功' p_type '了' l_succ '条记录' INTO l_msg.
  ELSE.
    l_rows = l_rows_i.
    CONCATENATE '成功' p_type '了' l_succ '条记录,高亮行数据不正确' INTO l_msg.
    gf_error = 'X'."设置信息表示有错误行
  ENDIF.
  MESSAGE l_msg TYPE 'S'.
ENDFORM.                    "DISPLAY_MESSAGE

*&---------------------------------------------------------------------*
*&      Form  userexit_check_data_row_exist
*&---------------------------------------------------------------------*
*       验证数据行主键在数据库中是否存在
*----------------------------------------------------------------------*
*      -->P_DATAROW  数据行
*      -->PF_ERROR   存在标识,‘X’为存在
*      -->P_ERRMSG   返回信息
*----------------------------------------------------------------------*
FORM userexit_check_data_row_exist
                    USING p_datarow LIKE gs_data_wa
                    CHANGING pf_error TYPE c
                             p_errmsg TYPE c.
  DATA l_db_wa TYPE t_db.
  DATA:l_data TYPE dats,
       l_max(2).
  FIELD-SYMBOLS <fs> TYPE ANY.
  DATA:l_field(50).


  SELECT SINGLE * FROM (g_tabname) INTO l_db_wa
     WHERE bukrs = p_datarow-bukrs
       AND route = p_datarow-route
       AND lfart = p_datarow-lfart
       AND zkcyf = p_datarow-zkcyf
       AND dtype = p_datarow-dtype.

  IF sy-subrc = 0.
    pf_error = 'X'.
    p_errmsg = text-007.
    EXIT.
  ENDIF.

  IF pf_error NE 'X'.
    CLEAR: l_data,l_max,l_field.
    l_data+0(2) = '20'.
    l_data+2(4) = l_db_wa-zkcyf.
    l_data+6(2) = '01'.

    CALL FUNCTION 'BKK_GET_MONTH_LASTDAY'
      EXPORTING
        i_date = l_data
      IMPORTING
        e_date = l_data.
    l_max = l_data+6(2).
    DO 3 TIMES.
      l_max = l_max + 1.
      IF l_max GT 31EXIT.ENDIF.
      CONCATENATE 'L_DB_WA-' 'FILD' l_max INTO l_field.
      ASSIGN (l_field) TO <fs>.
      IF sy-subrc = 0 AND <fs> NE space.
        p_errmsg = '维护时间超过当月日期范围'.
        pf_error = 'X'.
        EXIT.
      ENDIF.
    ENDDO.
  ENDIF.

ENDFORM.                    "userexit_check_data_row_exist
*&---------------------------------------------------------------------*
*&      Form  userexit_check_row_data
*&---------------------------------------------------------------------*
*       验证行信息,并可添加行信息
*----------------------------------------------------------------------*
*      -->P_DATAROW  数据行
*      -->PF_ERROR   错误标识
*      -->P_ERRMSG   错误信息
*----------------------------------------------------------------------*
FORM userexit_check_row_data
                    USING p_datarow LIKE gs_data_wa
                    CHANGING pf_error TYPE c
                             p_errmsg TYPE c.
  DATA:l_htype  LIKE  dd01v-datatype.
  CLEAR: pf_error, p_errmsg.
  DATA l_db_wa TYPE t_db.
  DATA:l_data TYPE dats,
       l_max(2).
  FIELD-SYMBOLS <fs> TYPE ANY.
  DATA:l_field(50).

  MOVE-CORRESPONDING p_datarow TO l_db_wa.

  IF  l_db_wa-bukrs IS INITIAL OR l_db_wa-route IS INITIAL
   OR l_db_wa-lfart IS INITIAL "OR l_db_wa-ZKCYF IS INITIAL
   OR l_db_wa-dtype IS INITIAL.

    p_errmsg = '数据不完整'.
    pf_error = 'X'.
  ELSE.
    IF r_insert EQ 'X'.
      IF r_week EQ 'X'.
        SELECT SINGLE * FROM zle_plannedgi
         WHERE bukrs EQ l_db_wa-bukrs
           AND route EQ l_db_wa-route
           AND lfart EQ l_db_wa-lfart.

        IF sy-subrc = 0.
          p_errmsg = '已存在同交货类型同路线的记录'.
          pf_error = 'X'.
        ENDIF.
      ELSE.
        SELECT SINGLE * FROM zle_plannedgi
         WHERE bukrs EQ l_db_wa-bukrs
           AND route EQ l_db_wa-route
           AND lfart EQ l_db_wa-lfart
           AND zkcyf EQ l_db_wa-zkcyf.
        IF sy-subrc = 0.
          p_errmsg = '已存在同交货类型同路线的记录'.
          pf_error = 'X'.
        ENDIF.
      ENDIF.
    ELSEIF r_modify EQ 'X'.
    ENDIF.
  ENDIF.

  IF pf_error NE 'X'.
    IF l_db_wa-dtype NE 'W' AND l_db_wa-zkcyf IS INITIAL.
      p_errmsg = '数据不完整'.
      pf_error = 'X'.
    ENDIF.
  ENDIF.

  IF pf_error NE 'X' AND l_db_wa-zkcyf IS NOT INITIAL.
    CALL FUNCTION 'NUMERIC_CHECK'
      EXPORTING
        string_in        = l_db_wa-zkcyf
     IMPORTING
*   STRING_OUT       =
       htype            = l_htype.

    IF l_htype NE 'NUMC'.
      p_errmsg = '年月格式错误'.
      pf_error = 'X'.
    ENDIF.
  ENDIF.


  IF ( r_insert EQ  'X' AND r_year EQ 'X' AND l_db_wa-zkcyf NE space )
    OR ( r_modify EQ  'X' AND l_db_wa-dtype NE 'W').
    CLEAR: l_data,l_max,l_field.
    l_data+0(2) = '20'.
    l_data+2(4) = l_db_wa-zkcyf.
    l_data+6(2) = '01'.

    CALL FUNCTION 'BKK_GET_MONTH_LASTDAY'
      EXPORTING
        i_date = l_data
      IMPORTING
        e_date = l_data.
    l_max = l_data+6(2).
    DO 3 TIMES.
      l_max = l_max + 1.
      IF l_max GT 31EXIT.ENDIF.
      CONCATENATE 'L_DB_WA-' 'FILD' l_max INTO l_field.
      ASSIGN (l_field) TO <fs>.
      IF sy-subrc = 0 AND <fs> NE space.
        p_errmsg = '维护时间超过当月日期范围'.
        pf_error = 'X'.
        EXIT.
      ENDIF.
    ENDDO.
  ENDIF.


ENDFORM.                    "userexit_check_row_data

*&---------------------------------------------------------------------*
*&      Form  userexit_compare_key_equal
*&---------------------------------------------------------------------*
*       判断两个数据行主键是否相等
*----------------------------------------------------------------------*
*      -->ROWDATA1   数据行1
*      -->ROWDATA2   数据行2
*      -->ISEQUAL    相等标识
*----------------------------------------------------------------------*
FORM userexit_compare_key_equal USING ps_datarow1 LIKE gs_data_wa
                                      ps_datarow2 LIKE gs_data_wa
                             CHANGING isequal TYPE c.
  IF ps_datarow1-bukrs = ps_datarow2-bukrs
    AND ps_datarow1-route = ps_datarow2-route
    AND ps_datarow1-lfart = ps_datarow2-lfart
    AND ps_datarow1-zkcyf = ps_datarow2-zkcyf
    AND ps_datarow1-dtype = ps_datarow2-dtype.
    isequal = 'X'.
  ENDIF.
ENDFORM.                    "userexit_compare_key_equal
*&---------------------------------------------------------------------*
*&      Form  FRM_FORMAT_ALVDATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_format_alvdata .
  DATA:l_colname(50),
       l_index(2),
       l_data(2).
  FIELD-SYMBOLS <fs> TYPE ANY.

  LOOP AT gt_data INTO gs_data_wa.
    DO 31 TIMES.
      l_index = sy-index.
      CONCATENATE  'GS_DATA_WA-' 'FILD' l_index INTO l_colname.
      ASSIGN (l_colname) TO <fs>.
      IF <fs> IS NOT INITIAL.
        IF NOT gs_data_alv-text IS INITIAL.
          CONCATENATE gs_data_alv-text ',' <fs> INTO gs_data_alv-text.
        ELSE.
          gs_data_alv-text = <fs>.
        ENDIF.
        l_data = <fs>.
        CONCATENATE  'GS_DATA_ALV-' 'FILD' l_data INTO l_colname.
        ASSIGN (l_colname) TO <fs>.
        <fs> = 'X'.
      ELSE.
        EXIT.
      ENDIF.
    ENDDO.
    gs_data_alv-bukrs  = gs_data_wa-bukrs .
    gs_data_alv-route  = gs_data_wa-route .
    gs_data_alv-lfart  = gs_data_wa-lfart .
    gs_data_alv-zkcyf  = gs_data_wa-zkcyf .
    gs_data_alv-dtype  = gs_data_wa-dtype .

    APPEND gs_data_alv TO gt_data_alv .
    CLEAR:gs_data_wa,gs_data_alv.
  ENDLOOP.

  APPEND LINES OF gt_data_alv TO gt_data_old.

ENDFORM.                    " FRM_FORMAT_ALVDATA
*&---------------------------------------------------------------------*
*&      Form  FRM_DECOMP_DATA
*&---------------------------------------------------------------------*
*       反编译ALV输出数据为数据库数据存储格式
*----------------------------------------------------------------------*
*      -->P_GS_DATA_ALV  text
*----------------------------------------------------------------------*
FORM frm_decomp_data  USING    ps_alv LIKE gs_data_alv
                      CHANGING ps_decomp LIKE gs_decomp.
  FIELD-SYMBOLS <fs> TYPE ANY.
  DATA:l_colname(50),
       l_num(2),
       l_index(2),
       l_data(2).

  CLEAR:l_colname,l_num,l_data.

  DO 31 TIMES.
    l_num = sy-index.
    CONCATENATE  'PS_ALV-' 'FILD' l_num INTO l_colname.
    ASSIGN (l_colname) TO <fs>.
    CLEAR l_colname.
    IF <fs> IS NOT INITIAL.
      DO 31 TIMES.
        l_index = sy-index.
        CONCATENATE  'PS_DECOMP-' 'FILD' l_index INTO l_colname.
        ASSIGN (l_colname) TO <fs>.
        IF <fs> IS INITIAL.
          <fs> = l_num.
          EXIT.
        ENDIF.
      ENDDO.
    ENDIF.
  ENDDO.
  ps_decomp-bukrs  = ps_alv-bukrs .
  ps_decomp-route  = ps_alv-route .
  ps_decomp-lfart  = ps_alv-lfart .
  ps_decomp-zkcyf  = ps_alv-zkcyf .
  ps_decomp-dtype  = ps_alv-dtype .

ENDFORM.                    " FRM_DECOMP_DATA

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值