ABAP ALV之自建表可编辑内表的增删改查
【摘要】 序HELLO,这里是百里,一个学习中的ABAPER,在工作中,我们会遇到一些自建表进行维护数据,这些自建表需要给用户进行配置操作,如权限,关联性,基础数据等等,标准SAP中没有,但是有十分重要的字段. 我们可以通过SAP的SE11创建完表以后,通过表格维护生成器,在SM30里面,或者SE16N进行维护.我们也可以封装SM30进行操作. 为什么要用ALV的方式自开发增删改查使用封装自建表的S...
序
HELLO,这里是百里,一个学习中的ABAPER,在工作中,我们会遇到一些自建表进行维护数据,这些自建表需要给用户进行配置操作,如权限,关联性,基础数据等等,标准SAP中没有,但是有十分重要的字段. 我们可以通过SAP的SE11创建完表以后,通过表格维护生成器,在SM30里面,或者SE16N进行维护.我们也可以封装SM30进行操作.
为什么要用ALV的方式自开发增删改查
使用封装自建表的SM30时,会遇到锁屏的情况,就是一个人操作,另外一个人不能操作.会很难受,虽然可以减少部分的代码操作量.但是当公司很多时,会出现相互卡的情况,这就很难受.此时就出现了我们的需求.通过传统的增删改查直接操作内表.避免上述说出出现的相互制约的情况 .
技术解析
有的小伙伴私信我,说我只是单独把某个知识点拉出来,讲虽然能看懂,但是不知道怎么才能灵活组合应用,那么这个需求来了.讲内表,标准表,数据触发,指针等多项内容均放在一起的案例. 不过可能代码会比较多,但是只要学会了这个,真就ALV你肯定会了.
没有什么特别复杂的技术,就会单纯的通过edit进行逻辑操作. 但是其中会遇到一些问题,比如说慎用modify .
比如获取选择框.是多项技能的组合应用.
获取选择框
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = gv_grid.
ALV CHANGED DATA
光标移动失焦触发.
LOOP AT pcl_data->mt_mod_cells INTO ls_cells.
READ TABLE gt_data INTO gs_data INDEX ls_cells-row_id.
..........
ENDLOOP.
屏幕刷新函数
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = lo_grid.
lw_stable-row = 'X'.
lw_stable-col = 'X'.
lo_grid->refresh_table_display(
EXPORTING
is_stable = lw_stable
EXCEPTIONS
finished = 1
OTHERS = 2 ).
本质上是技术上的活灵活用.将多种基础内容合并在一起,这样才算是业务结合学习内容实际. 算是真实开发.
实际案例
今天的这个案例讲的是一个自建立表,我们要给他实现增加,删除,修改,查询的功能.同时,增加权限检查. 本案例会从如何自建立表及表格函数生成器到最后权限检查都讲解一遍,并加入多种基础并经常使用的技巧.如果是新手会很友好.
建表开始
我们通过SE11进行自建立表的创建.注意的是,自建立表一定要以Z或者Y开头,一般都是附加模块及号码 表示自建表顺序 .
数据准备
我们基础表建立完成后,就开始在SE38中开发程序.
"数据准备
types : BEGIN OF ty_DAta ,
zhh TYPE i,
EKORG TYPE ZSDT0015-EKORG ,
MATNR TYPE ZSDT0015-MATNR ,
VKORG TYPE ZSDT0015-VKORG ,
ZLSMATNR TYPE ZSDT0015-ZLSMATNR ,
ERNAM TYPE ZSDT0015-ERNAM ,
ERDAT TYPE ZSDT0015-ERDAT ,
ERZET TYPE ZSDT0015-ERZET ,
END OF ty_DAta .
data : gs_data TYPE ty_DAta .
data : gt_data TYPE TABLE of ty_DAta .
DATA : lv_num TYPE I VALUE IS INITIAL.
data : flag TYPE c.
data : ls_zsdt0015 TYPE ZSDT0015 .
DATA : ls_data TYPE ty_data.
DATA : lt_rows TYPE lvc_t_row.
DATA : GT_LSDATA TYPE TABLE OF ty_DAta .
" ALV 常量 .
*--------------------------------------------------------------------*
* ALV变量
*--------------------------------------------------------------------*
DATA: wa_layout TYPE lvc_s_layo.
DATA:wa_fieldcat TYPE lvc_s_fcat,
gt_fieldcat TYPE lvc_t_fcat.
DATA gs_grid TYPE lvc_s_glay. "新
DATA: gv_grid TYPE REF TO cl_gui_alv_grid.
DATA:gs_glay TYPE lvc_s_glay.
DATA : gv_error TYPE c.
DATA : bs1 TYPE c.
选择屏幕
TABLES : EKKO ,EKPO,VBAK .
SELECTION-SCREEN BEGIN OF BLOCK block WITH FRAME TITLE text-001 .
"select-OPTIONS s_EKORG for EKKO-EKORG .
PARAMETERS p_EKORG TYPE EKORG OBLIGATORY .
select-OPTIONS s_MATNR for EKPO-MATNR .
"select-OPTIONS s_VKORG for VBAK-VKORG .
PARAMETERS p_VKORG TYPE VKORG OBLIGATORY .
SELECTION-SCREEN END OF BLOCK block .
子例程建立
*&---------------------------------------------------------------------*
*& 包含 ZSDR026AF
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Form get_Data
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM get_Data .
SELECT * FROM ZSDT0015 AS A INTO CORRESPONDING FIELDS OF TABLE gt_data where EKORG = p_EKORG and VKORG = p_VKORG .
SORT gt_data by ERZET ." DESCENDING .
GT_LSDATA = Gt_DATA .
ENDFORM.
*&---------------------------------------------------------------------*
*& Form diaplay_data
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM display_data .
PERFORM set_alv_layout.
PERFORM bulid_fieldcat.
PERFORM call_alv_func.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form set_alv_layout
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM set_alv_layout .
CLEAR: wa_layout.
wa_layout-zebra = 'X'. "斑马线
wa_layout-cwidth_opt = 'X'. "自动列宽
ENDFORM.
*&---------------------------------------------------------------------*
*& Form bulid_fieldcat
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM bulid_fieldcat .
DEFINE add_col.
* ADD 1 TO pos.
* lw_fieldcat-col_pos = pos.
wa_fieldcat-fieldname = &1.
wa_fieldcat-ref_field = &2.
wa_fieldcat-ref_table = &3.
wa_fieldcat-scrtext_l = &4.
wa_fieldcat-outputlen = &5.
wa_fieldcat-no_zero = &6.
wa_fieldcat-edit = &7.
wa_fieldcat-edit_mask = &8.
wa_fieldcat-key = &9.
CASE wa_fieldcat-fieldname.
WHEN 'EKORG' or 'MATNR' or 'VKORG' or 'ZLSMATNR'.
IF FLAG is INITIAL .
wa_fieldcat-edit = 'X' .
" wa_fieldcat-checkbox = 'X' .
" wa_fieldcat-edit_mask = 'X'.
ELSE .
wa_fieldcat-edit = 'X' .
ENDIF.
WHEN OTHERS.
ENDCASE .
APPEND wa_fieldcat TO gt_fieldcat.
CLEAR : wa_fieldcat.
END-OF-DEFINITION.
REFRESH: gt_fieldcat.
add_col 'EKORG' space space '采购组织' space space space space space.
add_col 'MATNR' 'MATNR' 'MARA' '物料号' space space space space space.
add_col 'VKORG' space space '销售组织' space space space space space.
add_col 'ZLSMATNR' 'MATNR' 'MARA' 'ZLSMATNR物料号' space space space space space.
add_col 'ERNAM' space space '修改者' space space space space space.
add_col 'ERDAT' space space '修改日期' space space space space space.
add_col 'ERZET' space space '修改时间' space space space space space.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form call_alv_func
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM call_alv_func .
DATA :gt_event TYPE slis_t_event,
gs_event TYPE slis_alv_event.
MOVE 'DATA_CHANGED' TO gs_event-name.
MOVE 'ALV_DATA_CHANGED' TO gs_event-form.
APPEND gs_event TO gt_event.
gs_glay-edt_cll_cb = abap_true. " 选中复选款,立刻触发data changed 事件
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
i_callback_program = sy-repid "回调程序
i_callback_pf_status_set = 'SET_PF_STATUS'
i_callback_user_command = 'USER_COMMAND'
i_grid_settings = gs_glay
is_layout_lvc = wa_layout
it_fieldcat_lvc = gt_fieldcat "需要显示的内表的列
i_save = 'A'
it_events = gt_event
TABLES
t_outtab = gt_data "需要显示的数据
EXCEPTIONS
program_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
ENDIF.
ENDFORM.
FORM refresh_alv .
DATA: lo_grid TYPE REF TO cl_gui_alv_grid,
lw_stable TYPE lvc_s_stbl.
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = lo_grid.
lw_stable-row = 'X'.
lw_stable-col = 'X'.
lo_grid->refresh_table_display(
EXPORTING
is_stable = lw_stable
EXCEPTIONS
finished = 1
OTHERS = 2 ).
ENDFORM.
" 用户子程序
FORM user_command USING r_ucomm LIKE sy-ucomm
rs_selfield TYPE slis_selfield.
CASE r_ucomm.
WHEN '&C1' .
" 输入料号 对应修改材料名称等信息.
" PERFORM frm_process_print .
WHEN '&INSERT' .
IF FLAG IS INITIAL.
MESSAGE '新增前请先点编辑按钮' TYPE 'E' .
ELSE.
PERFORM FORM_INSERT.
PERFORM refresh_alv.
ENDIF.
WHEN '&UPDATE' .
PERFORM FORM_UPDATE .
PERFORM refresh_alv.
WHEN '&DEL' .
IF FLAG IS INITIAL .
MESSAGE '删除请先点编辑按钮' TYPE 'E' .
ELSE .
PERFORM FORM_DEL .
PERFORM refresh_alv.
ENDIF.
WHEN '&DATA_SAVE'.
PERFORM FORM_SAVE .
PERFORM refresh_alv.
ENDCASE.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FORM_INSERT
*&---------------------------------------------------------------------*
*& text 新增按钮
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM form_insert .
CLEAR ls_data .
ls_data-zhh = lines( gt_data ) + 1.
ls_data-EKORG = p_EKORG.
ls_data-MATNR = ''.
ls_data-VKORG = p_VKORG.
ls_data-ZLSMATNR = '' .
ls_data-ERNAM = sy-uname.
ls_data-ERDAT = sy-datum.
ls_data-ERZET = sy-uzeit.
INSERT ls_data INTO gt_data INDEX lines( gt_data ) + 1.
SORT gt_data by ERZET DESCENDING .
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FORM_UPDATE
*&---------------------------------------------------------------------*
*& text 修改按钮 ,如果不点这个按钮只能查询
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM form_update .
" 修改flag
FLAG = 'X' .
PERFORM bulid_fieldcat .
REFRESH gt_data .
gt_data = GT_LSDATA .
PERFORM refresh_alv .
MESSAGE '可以编辑' TYPE 'S' .
ENDFORM.
"得到选择框
FORM get_grid.
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = gv_grid.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FORM_DEL
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM form_del .
PERFORM get_grid.
CALL METHOD gv_grid->get_selected_rows
IMPORTING
et_index_rows = lt_rows.
LOOP AT lt_rows INTO DATA(LS_ROWS).
CLEAR ls_data .
READ TABLE gt_data INTO ls_data INDEX ls_rows-index.
MOVE-CORRESPONDING ls_data to ls_zsdt0015 .
DELETE ZSDT0015 FROM ls_zsdt0015 . " 删除透明表数据
DELETE gt_data INDEX ls_rows-index. " 删除内表
ENDLOOP.
" 更新当前序号
LOOP AT gt_data ASSIGNING FIELD-SYMBOL(<lfs_item>).
lv_num = lv_num + 1.
<lfs_item>-zhh = lv_num.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FORM_SAVE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM form_save .
IF FLAG = 'X'.
LOOP AT GT_DATA INTO GS_DATA.
MOVE-CORRESPONDING gs_data TO ls_zsdt0015.
MODIFY ZSDT0015 FROM ls_zsdt0015 .
CLEAR GS_DATA .
ENDLOOP.
MESSAGE '保存成功' TYPE 'I' .
SORT gt_data .
ELSE .
MESSAGE '未点编辑只能看' TYPE 'I' .
ENDIF.
ENDFORM.
FORM set_pf_status USING rt_extab TYPE slis_t_extab.
DATA : lw_tab LIKE LINE OF rt_extab.
REFRESH rt_extab.
IF gv_error IS INITIAL.
ELSE.
" 删除按钮
lw_tab-fcode = '&PRINT'.
APPEND lw_tab TO rt_extab.
ENDIF.
SET PF-STATUS 'STD' EXCLUDING rt_extab.
" SET TITLEBAR 'TIT_1000'.
ENDFORM.
FORM alv_data_changed USING pcl_data TYPE REF TO cl_alv_changed_data_protocol.
DATA:
l_name(100),
ls_cells TYPE lvc_s_modi.
FIELD-SYMBOLS: <f_field> TYPE any .
IF FLAG = 'X'.
LOOP AT pcl_data->mt_mod_cells INTO ls_cells.
READ TABLE gt_data INTO gs_data INDEX ls_cells-row_id.
gs_data-ERNAM = sy-uname.
gs_data-ERDAT = sy-datum.
gs_data-ERZET = sy-uzeit.
MODIFY gt_data FROM GS_DATA TRANSPORTING ERNAM ERDAT ERZET WHERE zhh = GS_DATA-zhh and EKORG = gs_Data-ekorg and MATNR = gs_Data-matnr and VKORG = gs_Data-VKORG and ZLSMATNR = GS_DATA-ZLSMATNR.
CLEAR gs_Data.
ENDLOOP.
ENDIF.
DATA: ls_stbl TYPE lvc_s_stbl.
PERFORM refresh_alv .
ENDFORM.
*&---------------------------------------------------------------------*
*& Form check_auth
*&---------------------------------------------------------------------*
*& text 权限检查
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM check_auth .
SELECT SINGLE ekorg
FROM T024E
INTO @DATA(ls_ekorg)
WHERE ekorg = @p_ekorg.
AUTHORITY-CHECK OBJECT 'M_EINF_EKO'
ID 'ACTVT' DUMMY
ID 'EKORG' FIELD ls_ekorg .
IF sy-subrc NE 0.
MESSAGE '没有权限查看采购组织' && p_ekorg && '权限' TYPE 'E'.
STOP.
ENDIF.
SELECT SINGLE vkorg INTO @DATA(lv_vkorg) FROM ztsd001 WHERE zrecon_no = @p_VKORG.
IF sy-subrc EQ 0 .
AUTHORITY-CHECK OBJECT 'V_VBAK_VKO'
ID 'VKORG' FIELD lv_vkorg
ID 'VTWEG' DUMMY
ID 'SPART' DUMMY
ID 'ACTVT' FIELD '03'.
IF sy-subrc <> 0.
MESSAGE '你无该销售组织权限,请检查!' TYPE 'S' DISPLAY LIKE 'E'..
LEAVE LIST-PROCESSING.
ENDIF.
ENDIF.
ENDFORM.
程序调用
" 数据准备
INCLUDE ZSDR026AD .
" 选择屏幕
INCLUDE ZSDR026AS .
" 子程序
INCLUDE ZSDR026AF .
"INITIALIZATION .
INITIALIZATION .
"at SELECTION-SCREEN
at SELECTION-SCREEN .
" 权限检查
PERFORM check_auth.
"at SELECTION-SCREEN OUTPUT .
at SELECTION-SCREEN OUTPUT .
"START-OF-SELECTION .
START-OF-SELECTION .
PERFORM get_Data .
"end-of-SELECTION .
end-of-SELECTION .
PERFORM display_data.
结果
选择屏幕界面
ALV输入界面
当我们什么都不做的时候,就是对应的查询界面,当我们点新增和删除时会触发管制
当我们需要点击编辑后才能进行界面编辑
当操作后点击上方保存按钮后进行数据保存.
当我们未点击编辑按钮时,点击保存会提示,不点编辑只能看字样.
技术总结
今天百里将以往的资料融汇贯通,讲述了一个自建表如何通过ALV的形式,进行增删改查.这种方式虽然开发比封装SM30会慢一些,但是优点就是只需要少量替换代码就可以快速使用,总体技术难度不高.不过对技能知识结构的要求比较多,就是说你得知识点泛一些.
不过是技术就有一些弊端或者bug ,本程序存在着一个可能的问题,就是modify 及DELETE 的使用 毕竟对于使用不熟练的人,这里举例是一个极理想情况即每次修改都修改全部字段,可能会造成大面积修改的问题. 有机会百里会出一期update的使用方法.毕竟modify太危险了,虽然他很快也算方便 .
百里鸡汤
操千曲而后晓声,观千剑而后识器。——《文心雕龙》
这里是百里,一个努力的学习者. 努力学习好好记录,点滴进步,就是成功.
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)