首页 > 代码库 > 一个完整的表维护程序

一个完整的表维护程序

Report  ZLET015_PG:

 1 *&---------------------------------------------------------------------*
 2 *& Report  ZLET015_PG
 3 *&
 4 *&---------------------------------------------------------------------*
 5 *& Program Name:               ZLET015_PG
 6 *& Description:                分公司储运部门对照表
 7 *& Function Description:       维护分公司储运部门对照表ZLET015
 8 *& Module:                     MMLE
 9 *& Created by:                 Cai_Zhijian
10 *& Created Date:                2013.11.13
11 *&---------------------------------------------------------------------*
12 
13 REPORT  zlet015_pg.
14 
15 INCLUDE zlet015_pg_class.
16 INCLUDE zlet015_pg_top.
17 INCLUDE zlet015_pg_f01.
18 INCLUDE zlet015_pg_m01.
19 
20 *----------------------------------------------------------------------*
21 *         INITIALIZATION.
22 *----------------------------------------------------------------------*
23 INITIALIZATION.
24 
25 * 获得要维护表的表名,存入g_tabname中
26   descr_ref ?= cl_abap_typedescr=>describe_by_data( gs_db ).
27   db_tab = descr_ref->get_ddic_header( ).
28   g_tabname = db_tab-tabname.
29 
30 *----------------------------------------------------------------------*
31 *         AT SELECTION-SCREEN OUTPUT
32 *----------------------------------------------------------------------*
33 AT SELECTION-SCREEN OUTPUT.
34 
35 * 设置选择画面输出格式
36   PERFORM frm_modify_screen.
37 
38   AT SELECTION-SCREEN.
39 * 权限检查
40   PERFORM frm_check_auth.
41 
42 *----------------------------------------------------------------------*
43 *         START-OF-SELECTION
44 *----------------------------------------------------------------------*
45 START-OF-SELECTION.
46 
47   PERFORM prepare_layout CHANGING gs_layout ."设置layout
48   REFRESH gt_fieldcat.
49   PERFORM prepare_field_catalog CHANGING gt_fieldcat ."设置Field Catalog
50   CALL SCREEN 0100.
View Code

INCLUDE zlet015_pg_class:

*&---------------------------------------------------------------------*
*&  包括                ZLET015_PG_CLASS
*&---------------------------------------------------------------------*
CLASS lcl_event_receiver DEFINITION.

  PUBLIC SECTION.

    METHODS:handle_data_changed
      FOR EVENT data_changed OF cl_gui_alv_grid
      IMPORTING er_data_changed.

ENDCLASS.                    "LCL_EVENT_RECEIVER DEFINITION
*&---------------------------------------------------------------------*
*&       CLASS (IMPLEMENTATION)  LCL_EVENT_RECEIVER
*&---------------------------------------------------------------------*
*        TEXT
*----------------------------------------------------------------------*
CLASS lcl_event_receiver IMPLEMENTATION.

*--DATA_CHANGED
  METHOD handle_data_changed.

    PERFORM handle_data_changed CHANGING er_data_changed.

  ENDMETHOD.                    "HANDLE_CHANGED_DATA

ENDCLASS.               "LCL_EVENT_RECEIVER
View Code

INCLUDE zlet015_pg_top:

*&---------------------------------------------------------------------*
*&  包括                ZLET015_PG_TOP
*&---------------------------------------------------------------------*
CONSTANTS:
  C_FLG_ON(1) TYPE C VALUE X.        "FLAG开
*&---------------------------------------------------------------------*
*&表申明
*&---------------------------------------------------------------------*
TABLES:
  zlet015.                    "分公司储运部门对照表

*----------------------------------------------------------------------*
* 全局类型定义
*----------------------------------------------------------------------*
TYPES:
*分公司描述
  BEGIN OF t_t001,
    bukrs TYPE t001-bukrs ,
    butxt TYPE t001-butxt,
    END OF t_t001,

*部门描述
  BEGIN OF t_zhrtorg,
    org_id TYPE zhrtorg-org_id,
    org_name TYPE zhrtorg-org_name,
    END OF t_zhrtorg.

*----------------------------------------------------------------------*
* 全局内部表定义
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
* 全局变量/工作区定义
*----------------------------------------------------------------------*
DATA: gs_db         TYPE zlet015,               "维护表的结构
  g_tabname(30) TYPE c.                     "存放维护表的表名

TYPES:t_db LIKE gs_db.

*ALV显示内表结构
DATA: BEGIN OF gs_data_wa.
INCLUDE TYPE t_db.
DATA: butxt TYPE t001-butxt,
      org_name TYPE zhrtorg-org_name,
      flag(1),
      rowmsg(100),
END OF gs_data_wa.

DATA: gt_data 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    type x030l,                      "存放变量的数据字典头信息
      descr_ref TYPE REF TO   cl_abap_typedescr. "分析ABAP类型描述的对象

*---------------------------------------------------------------------*
*         ALV DATA DECLARATION
*---------------------------------------------------------------------*
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,
      alv_container        TYPE scrfname VALUE T_COL,"ALV展示数据存放在此容器中
      alv_custom_container TYPE REF TO cl_gui_custom_container,
      gt_exclude    TYPE ui_functions,"存放排除按钮的内表
      gt_index_rows TYPE lvc_t_row,"用以存放要选择行的内表
      gs_index_rows TYPE lvc_s_row."用以存放要选择行的工作区

DATA: gf_valid(1) TYPE c,
      gf_error(1) TYPE c.
***带出描述
DATA: g_event_receiver   TYPE REF TO lcl_event_receiver.

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

PARAMETERS:
  p_insert  RADIOBUTTON GROUP z USER-COMMAND f  DEFAULT X ,
  p_modify  RADIOBUTTON GROUP z,
  p_disp    RADIOBUTTON GROUP z.

SELECTION-SCREEN SKIP.

SELECTION-SCREEN BEGIN OF BLOCK blk2 WITH FRAME TITLE text-002.

SELECT-OPTIONS:
  s_bukrs FOR zlet015-bukrs MODIF ID z01 OBLIGATORY,
  s_orgty  FOR zlet015-ORGID MODIF ID z01.
SELECTION-SCREEN END OF BLOCK blk2.

SELECTION-SCREEN END OF BLOCK blk1.
View Code

INCLUDE zlet015_pg_f01:

*&---------------------------------------------------------------------*
*&  包括                ZLET015_PG_F01
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Form  FRM_MODIFY_SCREEN
*&---------------------------------------------------------------------*
*  设置选择画面输出格式
*----------------------------------------------------------------------*
FORM frm_modify_screen .
  LOOP AT SCREEN.
    IF p_insert = c_flg_on.
      IF screen-group1 = Z01.
        screen-active = 0.
      ENDIF.
    ENDIF.

    MODIFY SCREEN.
  ENDLOOP.

ENDFORM.                    " FRM_MODIFY_SCREEN
*&---------------------------------------------------------------------*
*&      Form  PREPARE_LAYOUT
*&---------------------------------------------------------------------*
*      设置Layout
*----------------------------------------------------------------------*
*      <--P_GS_LAYOUT  text
*----------------------------------------------------------------------*
FORM prepare_layout  CHANGING  ps_layout TYPE lvc_s_layo.

  ps_layout-zebra = X .
  ps_layout-smalltitle = X .
  ps_layout-no_toolbar =  .
  IF p_disp = X OR p_modify = X.
    ps_layout-no_rowmark = X.
  ENDIF.
ENDFORM.                    " PREPARE_LAYOUT
*&---------------------------------------------------------------------*
*&      Form  PREPARE_FIELD_CATALOG
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_GT_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_structure_name       = g_tabname  "表结构
      i_client_never_display = X
    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
  PERFORM userexit_fieldcat CHANGING pt_fieldcat.

  ls_fieldcat-fieldname = BUTXT.
  ls_fieldcat-coltext   = 公司描述.
  ls_fieldcat-col_pos   = 2.

  ls_fieldcat-outputlen = 40.
  APPEND ls_fieldcat TO pt_fieldcat .

  ls_fieldcat-fieldname = ORG_NAME.
  ls_fieldcat-coltext   = 部门描述 .
  ls_fieldcat-col_pos   = 5.
  ls_fieldcat-outputlen = 40.
  APPEND ls_fieldcat TO pt_fieldcat .

  IF p_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-outputlen = 6.
    ls_fieldcat-col_pos = 0.
    APPEND ls_fieldcat TO pt_fieldcat .

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

ENDFORM.                    " PREPARE_FIELD_CATALOG
*&---------------------------------------------------------------------*
*&      Form  USEREXIT_FIELDCAT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_PT_FIELDCAT  text
*----------------------------------------------------------------------*
FORM userexit_fieldcat  CHANGING  pt_fieldcat TYPE lvc_t_fcat.
  DATA: ls_fieldcat TYPE lvc_s_fcat.
  LOOP AT pt_fieldcat INTO ls_fieldcat.
    CASE ls_fieldcat-fieldname.
      WHEN BUKRS.
        ls_fieldcat-coltext   = 分公司 .
        ls_fieldcat-col_pos   = 1.
        ls_fieldcat-outputlen = 8.
      WHEN ORGTYPE.
        ls_fieldcat-coltext   = 部门类型 .
        ls_fieldcat-col_pos   = 3.
        ls_fieldcat-outputlen = 8.
      WHEN ORGID.
        ls_fieldcat-coltext   = 部门编码 .
        ls_fieldcat-col_pos   = 4.
        ls_fieldcat-outputlen = 10.
      WHEN LVORM.
        ls_fieldcat-coltext   = 删除标记 .
        ls_fieldcat-col_pos   = 6.
        ls_fieldcat-outputlen = 8.
      WHEN BUNO.
        ls_fieldcat-coltext   = 创建人员 .
        ls_fieldcat-col_pos   = 7.
        ls_fieldcat-outputlen = 12.
      WHEN BUDAT.
        ls_fieldcat-coltext   = 创建日期 .
        ls_fieldcat-col_pos   = 8.
        ls_fieldcat-outputlen = 8.
      WHEN BUTIME.
        ls_fieldcat-coltext   = 创建时间 .
        ls_fieldcat-col_pos   = 9.
        ls_fieldcat-outputlen = 8.
      WHEN UPNO.
        ls_fieldcat-coltext   = 修改人员 .
        ls_fieldcat-col_pos   = 10.
        ls_fieldcat-outputlen = 12.
      WHEN UPDAT.
        ls_fieldcat-coltext   = 修改日期 .
        ls_fieldcat-col_pos   = 11.
        ls_fieldcat-outputlen = 8.
      WHEN UPTIME.
        ls_fieldcat-coltext   = 修改时间 .
        ls_fieldcat-col_pos   = 12.
        ls_fieldcat-outputlen = 8.
    ENDCASE.
    IF p_insert = X.
      IF ls_fieldcat-fieldname = BUKRS   OR
         ls_fieldcat-fieldname = ORGTYPE OR
         ls_fieldcat-fieldname = ORGID.
        ls_fieldcat-edit = X.
      ENDIF.

      "      IF ls_fieldcat-fieldname = ‘LVORM‘.
      "        ls_fieldcat-no_out = c_flg_on.
      "      ENDIF.

    ELSEIF p_modify = X.
      IF ls_fieldcat-fieldname = ORGID   OR
         ls_fieldcat-fieldname = LVORM.
        ls_fieldcat-edit = X.
      ENDIF.
    ENDIF.

    MODIFY pt_fieldcat FROM ls_fieldcat.
  ENDLOOP.

ENDFORM.                    " USEREXIT_FIELDCAT
*&---------------------------------------------------------------------*
*&      Form  LOAD_DATA_INTO_GRID
*&---------------------------------------------------------------------*
FORM load_data_into_grid .

  CASE X.
    WHEN p_insert.
      SET TITLEBAR 101.
      PERFORM userexit_select_data_insert CHANGING gt_data.
    WHEN p_modify.
      SET TITLEBAR 103.
      PERFORM userexit_select_data_modify CHANGING gt_data.
    WHEN p_disp.
      SET TITLEBAR 104.
      PERFORM userexit_select_data_display CHANGING gt_data.
    WHEN OTHERS.
  ENDCASE.

ENDFORM.                    " LOAD_DATA_INTO_GRID
*&---------------------------------------------------------------------*
*&      Form  USEREXIT_SELECT_DATA_INSERT
*&---------------------------------------------------------------------*
FORM userexit_select_data_insert  CHANGING  pt_data LIKE gt_data.

  APPEND gs_data_wa TO gt_data.
  CLEAR gs_data_wa.

ENDFORM.                    " USEREXIT_SELECT_DATA_INSERT
*&---------------------------------------------------------------------*
*&      Form  USEREXIT_SELECT_DATA_MODIFY
*&---------------------------------------------------------------------*
FORM userexit_select_data_modify  CHANGING  pt_data  LIKE gt_data.

  SELECT * FROM zlet015 INTO CORRESPONDING FIELDS OF TABLE  pt_data
    WHERE bukrs   IN  s_bukrs
    AND   orgtype IN  s_orgty.

  SORT pt_data.
  DELETE ADJACENT DUPLICATES FROM pt_data COMPARING ALL FIELDS.
  PERFORM frm_get_name.

  gt_data_old = gt_data.

ENDFORM.                    " USEREXIT_SELECT_DATA_MODIFY
*&---------------------------------------------------------------------*
*&      Form  USEREXIT_SELECT_DATA_DISPLAY
*&---------------------------------------------------------------------*
FORM userexit_select_data_display  CHANGING  pt_data  LIKE gt_data.

  SELECT * FROM zlet015 INTO CORRESPONDING FIELDS OF TABLE  pt_data
  WHERE bukrs   IN  s_bukrs
  AND   orgtype IN  s_orgty.

  IF  sy-subrc = 0.

    SORT pt_data.
    DELETE ADJACENT DUPLICATES FROM pt_data COMPARING ALL FIELDS.
    PERFORM frm_get_name.

  ENDIF.

ENDFORM.                    " USEREXIT_SELECT_DATA_DISPLAY
*&---------------------------------------------------------------------*
*&      Form  DISPLAY_ALV
*&---------------------------------------------------------------------*
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
      it_fieldcatalog               = gt_fieldcat
    EXCEPTIONS
      invalid_parameter_combination = 1
      program_error                 = 2
      too_many_lines                = 3
      OTHERS                        = 4.

ENDFORM.                    " DISPLAY_ALV
*&---------------------------------------------------------------------*
*&      Form  EXCLUDE_TB_FUNCTIONS
*&---------------------------------------------------------------------*
*          排除不必要的按钮
*----------------------------------------------------------------------*
*      -->P_GT_EXCLUDE  text
*----------------------------------------------------------------------*
FORM exclude_tb_functions  CHANGING pt_exclude TYPE ui_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 p_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.

  ELSE.

    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  INSERT_DATA
*&---------------------------------------------------------------------*
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 INTO gs_data_wa WHERE flag = X.

    l_tabix = sy-tabix.

*验证行数据正确性、手工添加部分信息
    PERFORM userexit_check_row_data CHANGING gs_data_wa
                                         l_iserror
                                         gs_data_wa-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.

*验证行数据在数据库中是否存在
      PERFORM userexit_check_data_row_exist USING  gs_data_wa
                                         CHANGING  l_iserror
                                                   gs_data_wa-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.
        gs_data_wa-buno   = sy-uname.  "创建者
        gs_data_wa-budat  = sy-datum.  "创建日期
        gs_data_wa-butime = sy-uzeit.  "创建时间
        MOVE-CORRESPONDING gs_data_wa TO gs_db.
        INSERT (g_tabname) FROM gs_db.
        COMMIT WORK AND WAIT.
        gs_data_wa-rowmsg = text-003. "插入成功
        l_isucc = l_isucc + 1.
      ENDIF.
    ENDIF.
    MODIFY gt_data FROM gs_data_wa."更新操作结果信息
    CLEAR:gs_data_wa.
  ENDLOOP.

  PERFORM display_message USING l_isucc gt_index_rows 添加."显示操作成功信息,并判断是否有非法数据

ENDFORM.                    " INSERT_DATA
*&---------------------------------------------------------------------*
*&      Form  USEREXIT_CHECK_ROW_DATA
*&---------------------------------------------------------------------*
FORM userexit_check_row_data  CHANGING p_datarow   LIKE gs_data_wa
                                       pf_error TYPE c
                                       p_errmsg TYPE any.

  DATA: l_bukrs  TYPE t001-bukrs,
        l_level9 TYPE zhrtorg-level9.

  CLEAR: pf_error, p_errmsg.
  DATA l_db_wa TYPE t_db.
  MOVE-CORRESPONDING p_datarow TO l_db_wa.

  "IF  p_insert = ‘X‘.

  IF l_db_wa-bukrs   IS INITIAL OR
     l_db_wa-orgtype IS INITIAL OR
     l_db_wa-orgid   IS INITIAL .

    p_errmsg = 数据不完整.
    pf_error = X.
    RETURN.
  ENDIF.

*  检查分公司是否存在

  SELECT SINGLE bukrs INTO l_bukrs FROM t001
    WHERE bukrs = l_db_wa-bukrs.

  IF sy-subrc <> 0.
    p_errmsg = 分公司不存在.
    pf_error = X.
    RETURN.
  ENDIF.

  SELECT SINGLE level9 INTO l_level9 FROM zhrtorg
    WHERE level9 = l_db_wa-orgid
    AND   effective_ate = sy-datum.

  IF sy-subrc <> 0.
    p_errmsg = 部门不存在或未生效.
    pf_error = X.
    RETURN.
  ENDIF.

  "ENDIF.

ENDFORM.                    " USEREXIT_CHECK_ROW_DATA
*&---------------------------------------------------------------------*
*&      Form  USEREXIT_CHECK_DATA_ROW_EXIST
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_GS_DATA_WA  text
*      <--P_L_ISERROR  text
*      <--P_GS_DATA_WA_ROWMSG  text
*----------------------------------------------------------------------*
FORM userexit_check_data_row_exist  USING    p_datarow LIKE gs_data_wa
                                    CHANGING  pf_error  TYPE c
                                              p_errmsg  TYPE c.
  CLEAR: pf_error, p_errmsg.
  DATA l_db_wa TYPE t_db.

  SELECT SINGLE * FROM (g_tabname)
    INTO l_db_wa
    WHERE bukrs = p_datarow-bukrs
    AND   orgtype = p_datarow-orgtype
    AND   orgid = p_datarow-orgid.

  IF sy-subrc = 0.
    pf_error = X.
    p_errmsg = 数据已经存在.
  ENDIF.

ENDFORM.                    " USEREXIT_CHECK_DATA_ROW_EXIST
*&---------------------------------------------------------------------*
*&      Form  DISPLAY_MESSAGE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_L_ISUCC  text
*      -->P_GT_INDEX_ROWS  text
*      -->P_0849   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  MODIFY_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
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 INTO gs_data_wa WHERE flag = X.
    CLEAR gs_db.
    l_tabix = sy-tabix.

*验证行数据正确性、手工添加部分信息
    PERFORM userexit_check_row_data CHANGING gs_data_wa
                                             l_iserror
                                             gs_data_wa-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_datab_equal USING gs_data_wa
                                                 ls_data_old
                                        CHANGING l_isequal.


      IF l_isequal = X."
        CLEAR gs_index_rows.
        gs_index_rows-index = l_tabix.
        gs_data_wa-rowmsg = 数据已经存在.
        APPEND gs_index_rows TO gt_index_rows."有错误则把当前行号存入GT_index_Rows,用来选择错误行


      ELSE.
        CLEAR gs_db.
        gs_data_wa-upno = sy-uname.
        gs_data_wa-updat = sy-datum.
        gs_data_wa-uptime = sy-uzeit.
        MOVE-CORRESPONDING gs_data_wa TO gs_db.
        MODIFY (g_tabname) FROM gs_db.
        l_isucc = l_isucc + 1.
        gs_data_wa-rowmsg = text-004.
        COMMIT WORK AND WAIT."提交数据库操作
        MODIFY gt_data_old FROM gs_data_wa INDEX l_tabix."把新表数据放入gt_data_old中
      ENDIF.
    ENDIF.
    MODIFY gt_data FROM gs_data_wa.

  ENDLOOP.

  PERFORM display_message USING l_isucc gt_index_rows 修改.
  CLEAR:gs_data_wa.

ENDFORM.                    " MODIFY_DATA
*&---------------------------------------------------------------------*
*&      Form  USEREXIT_COMPARE_DATAB_EQUAL
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_GS_DATA_WA  text
*      -->P_LS_DATA_OLD  text
*      <--P_L_ISEQUAL  text
*----------------------------------------------------------------------*
FORM userexit_compare_datab_equal  USING    ps_datarow1 LIKE gs_data_wa
                                             ps_datarow2 LIKE gs_data_wa
                                    CHANGING isequal     TYPE c.

  CLEAR: isequal.

  IF    ps_datarow1-bukrs   = ps_datarow2-bukrs
    AND ps_datarow1-orgtype = ps_datarow2-orgtype
    AND ps_datarow1-orgid   = ps_datarow2-orgid
    AND ps_datarow1-lvorm   = ps_datarow2-lvorm.


    isequal = X.

  ENDIF.

ENDFORM.                    " USEREXIT_COMPARE_DATAB_EQUAL
*&---------------------------------------------------------------------*
*&      Form  HANDLE_DATA_CHANGED
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_ER_DATA_CHANGED  text
*----------------------------------------------------------------------*
FORM handle_data_changed    USING ir_data_changed
                                   TYPE REF TO cl_alv_changed_data_protocol.
  DATA: ls_mod_cell TYPE lvc_s_modi,
        lv_value    TYPE lvc_value,
        l_name1     TYPE t001-butxt,
        l_name2     TYPE zhrtorg-org_name.

  LOOP AT ir_data_changed->mt_mod_cells
                           INTO ls_mod_cell.

***得到分公司描述
    IF ls_mod_cell-fieldname = BUKRS.
      CALL METHOD ir_data_changed->get_cell_value
        EXPORTING
          i_row_id    = ls_mod_cell-row_id
          i_fieldname = BUKRS
        IMPORTING
          e_value     = lv_value.

      IF lv_value IS NOT INITIAL.

        SELECT SINGLE butxt
          INTO l_name1
          FROM t001
         WHERE bukrs = lv_value.

        CALL METHOD ir_data_changed->modify_cell
          EXPORTING
            i_row_id    = ls_mod_cell-row_id
            i_fieldname = BUTXT
            i_value     = l_name1.
      ELSE.
        CALL METHOD ir_data_changed->modify_cell
          EXPORTING
            i_row_id    = ls_mod_cell-row_id
            i_fieldname = BUTXT
            i_value     = ‘‘.
      ENDIF.
    ENDIF.

***得到部门描述
    IF ls_mod_cell-fieldname = ORGID.
      CALL METHOD ir_data_changed->get_cell_value
        EXPORTING
          i_row_id    = ls_mod_cell-row_id
          i_fieldname = ORGID
        IMPORTING
          e_value     = lv_value.

      IF lv_value IS NOT INITIAL.

        SELECT SINGLE org_name
          INTO l_name2
          FROM zhrtorg
         WHERE org_id = lv_value
        AND  effective_ate = sy-datum.

        CALL METHOD ir_data_changed->modify_cell
          EXPORTING
            i_row_id    = ls_mod_cell-row_id
            i_fieldname = ORG_NAME
            i_value     = l_name2.

      ELSE.

        CALL METHOD ir_data_changed->modify_cell
          EXPORTING
            i_row_id    = ls_mod_cell-row_id
            i_fieldname = ORG_NAME
            i_value     = ‘‘.

      ENDIF.
    ENDIF.

    CLEAR lv_value.
  ENDLOOP.

ENDFORM.                    " HANDLE_DATA_CHANGED
*&---------------------------------------------------------------------*
*&      Form  FRM_CHECK_AUTH
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_check_auth .

  CASE c_flg_on.
    WHEN  p_insert.
      AUTHORITY-CHECK OBJECT ZMM_AUTH1
               ID ACTVT FIELD 01.

      IF sy-subrc <> 0 .

        MESSAGE text-m01 TYPE E.

      ENDIF.


    WHEN p_modify.
      AUTHORITY-CHECK OBJECT ZMM_AUTH1
               ID ACTVT FIELD 02.


      IF sy-subrc <> 0 .

        MESSAGE text-m02 TYPE E.

      ENDIF.

    WHEN p_disp.
      AUTHORITY-CHECK OBJECT ZMM_AUTH1
               ID ACTVT FIELD 03.

  ENDCASE.

  IF sy-subrc <> 0 .

    MESSAGE text-m03 TYPE E.

  ENDIF.





ENDFORM.                    " FRM_CHECK_AUTH
*&---------------------------------------------------------------------*
*&      Form  FRM_GET_NAME
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_get_name .

  DATA:lt_t001w TYPE TABLE OF t_t001,       "分公司描述
        ls_t001w TYPE t_t001,

        lt_zhrtorg TYPE TABLE OF t_zhrtorg,  "部门描述
        ls_zhrtorg TYPE t_zhrtorg,
        ls_data  LIKE LINE OF gt_data.

  IF gt_data IS NOT INITIAL.

    SELECT bukrs  butxt
              FROM t001
              INTO TABLE  lt_t001w
      FOR ALL ENTRIES IN gt_data
      WHERE  bukrs = gt_data-bukrs.


    SELECT  org_id  org_name
           INTO TABLE lt_zhrtorg
           FROM  zhrtorg
          FOR ALL ENTRIES IN gt_data
          WHERE org_id = gt_data-orgid
          AND effective_ate = sy-datum.


    SORT:lt_t001w,lt_zhrtorg.
    CLEAR:ls_data .

    LOOP AT gt_data INTO ls_data.
      READ TABLE lt_t001w INTO ls_t001w
                       WITH KEY bukrs = ls_data-bukrs.

      IF sy-subrc = 0.
        ls_data-butxt =  ls_t001w-butxt.
      ENDIF.

      READ TABLE lt_zhrtorg INTO ls_zhrtorg
                        WITH KEY org_id = ls_data-orgid.

      IF  sy-subrc = 0.
        ls_data-org_name = ls_zhrtorg-org_name.
      ENDIF.

      MODIFY gt_data FROM ls_data TRANSPORTING butxt org_name.

      CLEAR:ls_data,ls_zhrtorg,ls_t001w.


    ENDLOOP.

  ENDIF.


ENDFORM.                    " FRM_GET_NAME
View Code

INCLUDE zlet015_pg_m01:

*&---------------------------------------------------------------------*
*&  包括                ZLET015_PG_M01
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Module  STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
  SET PF-STATUS MAIN100.
  gs_variant-report = sy-repid.

  IF gr_alvgrid IS INITIAL.
    CREATE OBJECT gr_alvgrid      "第一次载入,建立对象
      EXPORTING
        i_parent          = cl_gui_container=>screen0.
***建立对象 带出描述
    CREATE OBJECT alv_custom_container
      EXPORTING
        container_name = alv_container.

    PERFORM load_data_into_grid.

    PERFORM display_alv .

    CALL METHOD gr_alvgrid->refresh_table_display.

    CALL METHOD gr_alvgrid->set_ready_for_input
      EXPORTING
        i_ready_for_input = 1.

***带出描述
    CREATE OBJECT g_event_receiver.
    SET HANDLER g_event_receiver->handle_data_changed FOR gr_alvgrid.

***带出描述
    CALL METHOD gr_alvgrid->register_edit_event
      EXPORTING
        i_event_id = cl_gui_alv_grid=>mc_evt_modified.

  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 p_insert = X.
          PERFORM insert_data.
        ELSEIF p_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 INTO gs_data_wa.
        gs_data_wa-flag = X.
        MODIFY gt_data FROM gs_data_wa TRANSPORTING flag
          WHERE flag = ‘‘.
      ENDLOOP.

    WHEN DESELALL.  "按取消全选按钮,检查数据完整性和数据修改,并取消全选

      CALL METHOD gr_alvgrid->check_changed_data
        IMPORTING
          e_valid = gf_valid.

      LOOP AT gt_data INTO gs_data_wa.
        gs_data_wa-flag = ‘‘.
        MODIFY gt_data FROM gs_data_wa TRANSPORTING flag
          WHERE flag = X.
      ENDLOOP.
    WHEN OTHERS.

      CALL METHOD gr_alvgrid->check_changed_data
        IMPORTING
          e_valid = gf_valid.
  ENDCASE.


ENDMODULE.                 " USER_COMMAND_0100  INPUT
View Code