

























这个框架包含了 ALV 开发的核心功能:查询 / 新增 / 修改 / 删除、自定义工具栏、数据校验、保存、打印、F4 帮助、推送外围系统等通用能力,你可以基于此快速扩展业务逻辑。
REPORT zalv_general_framework_enhanced. INCLUDE <cl_alv_control>. "ALV控制相关的标准INCLUDE *&---------------------------------------------------------------------* *& 【通用定义区】- 保留ALV核心通用字段,业务字段按需扩展 *&---------------------------------------------------------------------* "ALV输出内表类型定义(保留通用控制字段,业务字段示例化) TYPES: BEGIN OF ts_alv_out, "=== ALV通用控制字段(核心保留,无需修改)=== sele TYPE ad_mark, "选择框字段(必选) status_doc TYPE rmpsp_dp_status,"状态显示字段(图标展示) status_pus TYPE char10, "推送状态字段 mess TYPE vec_message, "消息显示字段 styl TYPE lvc_t_styl, "单元格样式字段(控制编辑/颜色/F4) updkz TYPE updkz_d, "更新标识(I-新增 U-修改 D-删除) "=== 业务字段示例(替换为实际业务字段)=== znumber TYPE char20, "业务单号 matnr TYPE matnr, "物料编码 maktx TYPE maktx, "物料描述 werks TYPE werks_d, "工厂 lgort TYPE lgort_d, "库存地点 erfmg TYPE erfmg, "数量 erfme TYPE meins, "单位 charg TYPE charg_d, "批次 insmk TYPE char1, "库存类型(限制/冻结) END OF ts_alv_out. "打印模板相关类型(保留通用打印结构) TYPES: BEGIN OF ty_print_head, butxt TYPE t001-butxt, "公司名称 title TYPE char30, "打印标题 znumber TYPE char20, "业务单号 lgobe TYPE t001l-lgobe, "仓库描述 zcrdate TYPE sy-datum, "创建日期 department TYPE char30, "部门 zzdr TYPE char20, "制单人 zsum_lfimg TYPE erfmg, "合计数量 END OF ty_print_head. TYPES: BEGIN OF ty_print_item, znumber TYPE char20, "业务单号 matnr TYPE matnr, "物料编码 maktx TYPE maktx, "物料描述 erfmg TYPE erfmg, "数量 msehl TYPE t006a-msehl, "单位描述 lgort TYPE lgort_d, "库存地点 END OF ty_print_item. *&---------------------------------------------------------------------* *& 【全局变量区】- 保留ALV+打印核心变量 *&---------------------------------------------------------------------* DATA: go_alv TYPE REF TO cl_gui_alv_grid, "ALV网格对象 ok_code TYPE sy-ucomm, "屏幕操作码 gt_alv_out TYPE TABLE OF ts_alv_out, "ALV输出内表 gt_fcat TYPE lvc_t_fcat, "ALV字段目录 gs_layout TYPE lvc_s_layo, "ALV布局 "打印相关全局变量(保留通用结构) gs_print_head TYPE ty_print_head, gt_print_item TYPE TABLE OF ty_print_item, gs_print_item TYPE ty_print_item. *&---------------------------------------------------------------------* *& 【选择屏幕区】- 保留通用操作模式+查询条件模板 *&---------------------------------------------------------------------* SELECTION-SCREEN BEGIN OF BLOCK blk1 WITH FRAME TITLE TEXT-001. PARAMETERS: p_werks TYPE werks_d OBLIGATORY, "工厂(必选) p_biztype TYPE char4 AS LISTBOX VISIBLE LENGTH 20. "业务类型下拉框 SELECT-OPTIONS: s_number FOR gt_alv_out-znumber, "业务单号 s_matnr FOR gt_alv_out-matnr, "物料编码 s_erdat FOR sy-datum, "创建日期 s_lgort FOR gt_alv_out-lgort. "库存地点 SELECTION-SCREEN END OF BLOCK blk1. SELECTION-SCREEN BEGIN OF BLOCK blk2 WITH FRAME TITLE TEXT-002. PARAMETERS: p_ins TYPE boolean RADIOBUTTON GROUP rg1, "新增模式 p_mod TYPE boolean RADIOBUTTON GROUP rg1, "修改模式 p_del TYPE boolean RADIOBUTTON GROUP rg1, "删除模式 p_que TYPE boolean RADIOBUTTON GROUP rg1 DEFAULT 'X'. "查询模式 SELECTION-SCREEN END OF BLOCK blk2. *&---------------------------------------------------------------------* *& 【事件处理类】- 保留ALV核心事件+完整的工具栏/打印事件 *&---------------------------------------------------------------------* CLASS lcl_alv_event_handler DEFINITION. PUBLIC SECTION. CLASS-METHODS: "1. 工具栏自定义(保留新增/删除/保存/打印按钮逻辑) handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid IMPORTING e_object, "2. 数据修改完成(保留单元格编辑后联动逻辑模板) handle_data_changed_finished FOR EVENT data_changed_finished OF cl_gui_alv_grid IMPORTING e_modified et_good_cells, "3. 自定义按钮点击(保留新增/删除/保存/打印完整分支) handle_user_command FOR EVENT user_command OF cl_gui_alv_grid IMPORTING e_ucomm, "4. F4帮助事件(保留批次/F4自定义模板) handle_onf4 FOR EVENT onf4 OF cl_gui_alv_grid IMPORTING e_fieldname e_fieldvalue es_row_no er_event_data, "5. 热点点击事件(保留行热点操作模板) handle_hotspot_click FOR EVENT hotspot_click OF cl_gui_alv_grid IMPORTING e_row_id. ENDCLASS. CLASS lcl_alv_event_handler IMPLEMENTATION. "1. 工具栏自定义 - 保留按操作模式显示按钮的通用逻辑 METHOD handle_toolbar. "删除默认本地按钮 DELETE e_object->mt_toolbar WHERE function CS 'LOCAL'. "按操作模式添加自定义按钮 CASE abap_true. WHEN p_ins. "新增模式:新增+删除+保存 e_object->mt_toolbar = VALUE #( BASE e_object->mt_toolbar ( butn_type = 3 ) "分隔符 ( function = 'CRE' icon = 'ICON_CREATE' text = '新增' ) ( function = 'DEL' icon = 'ICON_DELETE' text = '删除' ) ( function = 'SAVE' icon = 'ICON_SAVE' text = '保存' ) ). WHEN p_mod. "修改模式:保存 e_object->mt_toolbar = VALUE #( BASE e_object->mt_toolbar ( butn_type = 3 ) ( function = 'SAVE' icon = 'ICON_SAVE' text = '保存' ) ). WHEN p_del. "删除模式:删除+保存 e_object->mt_toolbar = VALUE #( BASE e_object->mt_toolbar ( butn_type = 3 ) ( function = 'DEL' icon = 'ICON_DELETE' text = '删除' ) ( function = 'SAVE' icon = 'ICON_SAVE' text = '保存' ) ). WHEN p_que. "查询模式:打印 e_object->mt_toolbar = VALUE #( BASE e_object->mt_toolbar ( butn_type = 3 ) ( function = 'PRINT' icon = 'ICON_PRINT' text = '打印' ) ). ENDCASE. ENDMETHOD. "2. 数据修改完成 - 保留通用联动逻辑模板 METHOD handle_data_changed_finished. CHECK e_modified EQ abap_true. "仅处理有修改的数据 "读取第一个修改的单元格 READ TABLE et_good_cells ASSIGNING FIELD-SYMBOL(<ls_cell>) INDEX 1. CHECK sy-subrc EQ 0. "读取对应行数据 READ TABLE gt_alv_out ASSIGNING FIELD-SYMBOL(<ls_alv>) INDEX <ls_cell>-row_id. CHECK sy-subrc EQ 0. "=== 通用联动逻辑模板(替换为实际业务)=== CASE <ls_cell>-fieldname. WHEN 'MATNR'. "物料编码修改后自动填充描述+单位 "示例:物料描述联动 SELECT SINGLE maktx FROM makt INTO <ls_alv>-maktx WHERE matnr = <ls_alv>-matnr AND spras = sy-langu. "示例:物料单位联动 SELECT SINGLE meins FROM mara INTO <ls_alv>-erfme WHERE matnr = <ls_alv>-matnr. WHEN 'CHARG'. "批次修改后联动(示例) "SELECT SINGLE ... FROM 批次表 INTO <ls_alv>-... WHERE matnr = <ls_alv>-matnr AND charg = <ls_alv>-charg. WHEN 'WERKS' OR 'LGORT' OR 'INSMK'. "工厂/库存地/库存类型联动库存数量 "SELECT SINGLE labst/speme FROM mard INTO <ls_alv>-menge WHERE ... ENDCASE. "标记修改模式的更新标识 IF p_mod = abap_true. <ls_alv>-updkz = 'U'. ENDIF. "刷新ALV(保持行/列稳定) go_alv->refresh_table_display( is_stable = VALUE lvc_s_stbl( row = abap_true col = abap_true ) ). ENDMETHOD. "3. 自定义按钮点击 - 保留完整的按钮处理分支 METHOD handle_user_command. "检查未保存的修改(防止数据丢失) go_alv->check_changed_data( ). "标记选中行 PERFORM frm_mark_selected_rows USING 'X'. "按按钮功能处理 CASE e_ucomm. WHEN 'CRE'. "新增 PERFORM frm_create_new_row. WHEN 'DEL'. "删除 PERFORM frm_delete_selected_rows. WHEN 'SAVE'. "保存 PERFORM frm_check_data. "数据校验 PERFORM frm_save_data. "数据保存 WHEN 'PRINT'. "打印 PERFORM frm_print_data. "打印处理 ENDCASE. "刷新ALV+重置选中行 go_alv->refresh_table_display( is_stable = VALUE lvc_s_stbl( row = abap_true col = abap_true ) ). PERFORM frm_mark_selected_rows USING ''. ENDMETHOD. "4. F4帮助事件 - 保留批次F4模板 METHOD handle_onf4. CASE e_fieldname. WHEN 'CHARG'. "批次F4帮助(通用模板) PERFORM frm_open_batch_f4 USING es_row_no-row_id. WHEN OTHERS. ENDCASE. er_event_data->m_event_handled = abap_true. "标记事件已处理 ENDMETHOD. "5. 热点点击事件 - 保留通用模板 METHOD handle_hotspot_click. "示例:点击热点行跳转到详情屏幕 "READ TABLE gt_alv_out ASSIGNING FIELD-SYMBOL(<ls_alv>) INDEX e_row_id-index. "IF sy-subrc EQ 0. " SET PARAMETER ID 'MAT' FIELD <ls_alv>-matnr. " CALL TRANSACTION 'MM03' AND SKIP FIRST SCREEN. "ENDIF. ENDMETHOD. ENDCLASS. *&---------------------------------------------------------------------* *& 【初始化事件】- 保留下拉框+日期默认值通用逻辑 *&---------------------------------------------------------------------* INITIALIZATION. "1. 设置日期默认值(近30天) s_erdat-low = sy-datum - 30. s_erdat-high = sy-datum. s_erdat-sign = 'I'. s_erdat-option = 'BT'. INSERT s_erdat INTO TABLE s_erdat. "2. 初始化业务类型下拉框(通用模板) PERFORM frm_init_biztype_dropdown. *&---------------------------------------------------------------------* *& 【选择屏幕输出】- 保留下拉框赋值通用逻辑 *&---------------------------------------------------------------------* AT SELECTION-SCREEN OUTPUT. "重新赋值下拉框(权限过滤模板) PERFORM frm_init_biztype_dropdown. *&---------------------------------------------------------------------* *& 【选择屏幕校验】- 保留通用校验模板 *&---------------------------------------------------------------------* AT SELECTION-SCREEN. "1. 查询模式下单号必输校验(示例) IF p_que = abap_true AND s_number[] IS INITIAL AND p_biztype = 'Z001'. MESSAGE '该业务类型查询时单号不能为空!' TYPE 'E'. ENDIF. "2. 日期区间校验(通用模板) LOOP AT s_erdat ASSIGNING FIELD-SYMBOL(<ls_date>) WHERE sign = 'I' AND option = 'BT'. IF <ls_date>-high - <ls_date>-low > 120. MESSAGE '查询日期区间不能超过120天!' TYPE 'E'. ENDIF. ENDLOOP. *&---------------------------------------------------------------------* *& 【主程序入口】- 保留完整的通用流程 *&---------------------------------------------------------------------* START-OF-SELECTION. "1. 权限检查(通用模板) PERFORM frm_check_authority. "2. 获取业务数据(核心业务逻辑) PERFORM frm_get_business_data. "3. 显示ALV(通用逻辑) PERFORM frm_display_alv. *&---------------------------------------------------------------------* *& 【FORM:初始化业务类型下拉框】- 保留通用下拉框逻辑 *&---------------------------------------------------------------------* FORM frm_init_biztype_dropdown. DATA: lt_values TYPE vrm_values, lt_filtered TYPE vrm_values. "1. 查询业务类型配置表(替换为实际表) "SELECT zbiztype AS key, zbizname AS text FROM zt_biztype INTO TABLE lt_values WHERE werks = p_werks. "2. 权限过滤(通用模板) LOOP AT lt_values ASSIGNING FIELD-SYMBOL(<ls_val>). "AUTHORITY-CHECK OBJECT 'Z_BIZ' ID 'BIZTYPE' FIELD <ls_val>-key. "IF sy-subrc = 0. " APPEND <ls_val> TO lt_filtered. "ENDIF. ENDLOOP. "3. 赋值下拉框 CALL FUNCTION 'VRM_SET_VALUES' EXPORTING id = 'P_BIZTYPE' values = lt_filtered EXCEPTIONS id_illegal_name = 1. ENDFORM. *&---------------------------------------------------------------------* *& 【FORM:权限检查】- 保留通用权限模板 *&---------------------------------------------------------------------* FORM frm_check_authority. "示例:工厂权限检查 AUTHORITY-CHECK OBJECT 'M_MSEG_WWR' ID 'WERKS' FIELD p_werks. IF sy-subrc <> 0. MESSAGE '无工厂' && p_werks && '的操作权限!' TYPE 'E'. ENDIF. "示例:业务类型权限检查 "AUTHORITY-CHECK OBJECT 'Z_BIZ' ID 'BIZTYPE' FIELD p_biztype. "IF sy-subrc <> 0 AND p_biztype IS NOT INITIAL. " MESSAGE '无该业务类型的操作权限!' TYPE 'E'. "ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& 【FORM:获取业务数据】- 保留通用查询模板 *&---------------------------------------------------------------------* FORM frm_get_business_data. "清空输出内表 CLEAR gt_alv_out. "=== 通用查询逻辑模板(替换为实际业务表)=== IF p_ins = abap_true. "新增模式:初始化空行(按业务类型填充默认值) "PERFORM frm_init_new_row_by_biztype. ELSE. "查询/修改/删除模式:从业务表取数 SELECT znumber matnr maktx werks lgort erfmg erfme charg insmk FROM zt_biz_main "替换为实际业务表 INTO CORRESPONDING FIELDS OF TABLE gt_alv_out WHERE werks = p_werks AND znumber IN s_number AND matnr IN s_matnr AND lgort IN s_lgort AND erdat IN s_erdat. "补充ALV控制字段默认值 LOOP AT gt_alv_out ASSIGNING FIELD-SYMBOL(<ls_alv>). <ls_alv>-status_doc = icon_green_light. "默认绿色状态 <ls_alv>-styl = VALUE #( ( fieldname = 'CHARG' style = alv_style_f4 + alv_style_color_positive ) ). ENDLOOP. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& 【FORM:显示ALV】- 保留完整的ALV初始化逻辑 *&---------------------------------------------------------------------* FORM frm_display_alv. IF gt_alv_out IS INITIAL AND p_ins <> abap_true. MESSAGE '无符合条件的数据!' TYPE 'S'. RETURN. ENDIF. "1. 构建字段目录 PERFORM frm_build_fieldcatalog. "2. 设置ALV布局 gs_layout-cwidth_opt = abap_true. "列宽自适应 gs_layout-sel_mode = 'D'. "多行选择 gs_layout-stylefname = 'STYL'. "单元格样式字段 gs_layout-zebra = abap_true. "斑马纹 gs_layout-box_fname = 'SELE'. "选择框字段名 "3. 调用ALV屏幕 CALL SCREEN 100. ENDFORM. *&---------------------------------------------------------------------* *& 【FORM:构建字段目录】- 保留完整的字段属性控制 *&---------------------------------------------------------------------* FORM frm_build_fieldcatalog. CLEAR gt_fcat. "=== 通用字段目录模板(按操作模式控制编辑属性)=== gt_fcat = VALUE #( "选择框 ( fieldname = 'SELE' coltext = '选择' seltext_m = '选择' checkbox = abap_true ) "状态图标 ( fieldname = 'STATUS_DOC' coltext = '状态' seltext_m = '状态' outputlen = 10 ) "推送状态 ( fieldname = 'STATUS_PUS' coltext = '推送状态' seltext_m = '推送状态' outputlen = 10 ) "消息 ( fieldname = 'MESS' coltext = '消息' seltext_m = '消息' outputlen = 50 ) "业务单号(查询模式只读) ( fieldname = 'ZNUMBER' coltext = '业务单号' seltext_m = '业务单号' outputlen = 20 edit = COND #( WHEN p_ins = abap_true THEN abap_true ELSE abap_false ) ) "物料编码(新增/修改可编辑) ( fieldname = 'MATNR' coltext = '物料编码' seltext_m = '物料编码' outputlen = 18 edit = COND #( WHEN p_ins OR p_mod THEN abap_true ELSE abap_false ) f4availabl = abap_true ) "启用F4 "物料描述(只读) ( fieldname = 'MAKTX' coltext = '物料描述' seltext_m = '物料描述' outputlen = 40 ) "工厂(只读) ( fieldname = 'WERKS' coltext = '工厂' seltext_m = '工厂' outputlen = 4 ) "库存地点(新增/修改可编辑) ( fieldname = 'LGORT' coltext = '库存地点' seltext_m = '库存地点' outputlen = 4 edit = COND #( WHEN p_ins OR p_mod THEN abap_true ELSE abap_false ) ) "数量(新增/修改可编辑) ( fieldname = 'ERFMG' coltext = '数量' seltext_m = '数量' outputlen = 10 edit = COND #( WHEN p_ins OR p_mod THEN abap_true ELSE abap_false ) ) "单位(只读) ( fieldname = 'ERFME' coltext = '单位' seltext_m = '单位' outputlen = 3 ) "批次(启用F4,样式控制) ( fieldname = 'CHARG' coltext = '批次' seltext_m = '批次' outputlen = 10 f4availabl = abap_true ) "库存类型(下拉框) ( fieldname = 'INSMK' coltext = '库存类型' seltext_m = '库存类型' outputlen = 10 drdn_hndl = 1 drdn_alias = abap_true ) ). "补充字段参考信息(自动读取数据元素属性) DATA(lt_dfies) = cl_salv_data_descr=>read_structdescr( CAST cl_abap_structdescr( cl_abap_structdescr=>describe_by_data( VALUE ts_alv_out( ) ) ) ). SORT lt_dfies BY fieldname. LOOP AT gt_fcat ASSIGNING FIELD-SYMBOL(<fs_fcat>). READ TABLE lt_dfies ASSIGNING FIELD-SYMBOL(<fs_dfies>) WITH KEY fieldname = <fs_fcat>-fieldname BINARY SEARCH. IF sy-subrc EQ 0. <fs_fcat>-ref_table = <fs_dfies>-reftable. <fs_fcat>-ref_field = <fs_dfies>-reffield. <fs_fcat>-datatype = <fs_dfies>-datatype. <fs_fcat>-inttype = <fs_dfies>-inttype. ENDIF. ENDLOOP. "设置库存类型下拉框(通用模板) PERFORM frm_set_insmk_dropdown. ENDFORM. *&---------------------------------------------------------------------* *& 【FORM:设置库存类型下拉框】- 保留通用下拉框逻辑 *&---------------------------------------------------------------------* FORM frm_set_insmk_dropdown. DATA: lt_dral TYPE lvc_t_dral. "填充下拉框数据 lt_dral = VALUE #( handle = 1 ( value = '非限制库存' int_value = '' ) ( value = '冻结库存' int_value = 'S' ) ). "赋值给ALV go_alv->set_drop_down_table( it_drop_down_alias = lt_dral ). ENDFORM. *&---------------------------------------------------------------------* *& 【FORM:标记选中行】- 保留通用逻辑 *&---------------------------------------------------------------------* FORM frm_mark_selected_rows USING pv_flag TYPE char1. DATA: lt_selected_rows TYPE lvc_t_row. IF pv_flag = 'X'. "获取选中行并标记 go_alv->get_selected_rows( IMPORTING et_index_rows = lt_selected_rows ). MODIFY gt_alv_out FROM VALUE #( sele = '' ) TRANSPORTING sele WHERE sele = 'X'. LOOP AT lt_selected_rows ASSIGNING FIELD-SYMBOL(<ls_row>). READ TABLE gt_alv_out INDEX <ls_row>-index ASSIGNING FIELD-SYMBOL(<ls_alv>). IF sy-subrc EQ 0. <ls_alv>-sele = 'X'. ENDIF. ENDLOOP. ELSE. "清空选中标记 MODIFY gt_alv_out FROM VALUE #( sele = '' ) TRANSPORTING sele WHERE sele = 'X'. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& 【FORM:新增行】- 保留通用逻辑+业务类型默认值 *&---------------------------------------------------------------------* FORM frm_create_new_row. APPEND INITIAL LINE TO gt_alv_out ASSIGNING FIELD-SYMBOL(<ls_new>). "填充默认值 <ls_new>-werks = p_werks. "默认工厂 <ls_new>-updkz = 'I'. "新增标识 <ls_new>-status_doc = icon_yellow_light. "新增行黄色状态 <ls_new>-styl = VALUE #( ( fieldname = 'CHARG' style = alv_style_f4 + alv_style_color_positive ) ). "按业务类型填充默认值(模板) "CASE p_biztype. " WHEN 'Z001'. <ls_new>-bwart = '101'. " WHEN 'Z002'. <ls_new>-bwart = '102'. "ENDCASE. ENDFORM. *&---------------------------------------------------------------------* *& 【FORM:删除选中行】- 保留按模式处理的通用逻辑 *&---------------------------------------------------------------------* FORM frm_delete_selected_rows. LOOP AT gt_alv_out ASSIGNING FIELD-SYMBOL(<ls_alv>) WHERE sele = 'X'. IF p_ins = abap_true. "新增模式:直接删除 DELETE gt_alv_out INDEX sy-tabix. ELSE. "修改/删除模式:标记删除+状态更新 <ls_alv>-updkz = 'D'. <ls_alv>-status_doc = icon_red_light. "状态校验(模板) "IF <ls_alv>-zstatus = '1'."已提交审批 " MESSAGE '已提交审批的单据不允许删除!' TYPE 'S' DISPLAY LIKE 'E'. " CONTINUE. "ENDIF. ENDIF. ENDLOOP. ENDFORM. *&---------------------------------------------------------------------* *& 【FORM:数据校验】- 保留通用校验模板 *&---------------------------------------------------------------------* FORM frm_check_data. DATA: lv_error TYPE boolean. LOOP AT gt_alv_out ASSIGNING FIELD-SYMBOL(<ls_alv>) WHERE updkz <> ''. CLEAR lv_error. "1. 必输项校验 IF <ls_alv>-matnr IS INITIAL. <ls_alv>-mess = '物料编码不能为空!'. <ls_alv>-status_doc = icon_red_light. lv_error = abap_true. ENDIF. IF <ls_alv>-erfmg IS INITIAL OR <ls_alv>-erfmg <= 0. <ls_alv>-mess = '数量必须大于0!'. <ls_alv>-status_doc = icon_red_light. lv_error = abap_true. ENDIF. "2. 业务规则校验(模板) "IF <ls_alv>-bwart = '101' AND <ls_alv>-ebeln IS INITIAL. " <ls_alv>-mess = '101移动类型必须输入采购订单!'. " <ls_alv>-status_doc = icon_red_light. " lv_error = abap_true. "ENDIF. "3. 库存校验(模板) "SELECT SINGLE labst FROM mard INTO DATA(lv_stock) " WHERE matnr = <ls_alv>-matnr AND werks = <ls_alv>-werks AND lgort = <ls_alv>-lgort. "IF <ls_alv>-erfmg > lv_stock AND <ls_alv>-bwart = '201'. " <ls_alv>-mess = '库存不足,当前库存:' && lv_stock. " <ls_alv>-status_doc = icon_red_light. " lv_error = abap_true. "ENDIF. IF lv_error = abap_true. MESSAGE <ls_alv>-mess TYPE 'S' DISPLAY LIKE 'E'. EXIT. ENDIF. ENDLOOP. IF lv_error = abap_true. MESSAGE '数据校验不通过,请修正后重试!' TYPE 'E'. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& 【FORM:数据保存】- 保留完整的批量保存模板 *&---------------------------------------------------------------------* FORM frm_save_data. DATA: lt_biz_main TYPE TABLE OF zt_biz_main, "替换为实际业务表 lv_msg TYPE char100. "按业务单号分组保存(批量处理模板) LOOP AT gt_alv_out ASSIGNING FIELD-SYMBOL(<ls_alv>) WHERE updkz <> '' GROUP BY ( znumber = <ls_alv>-znumber ). "清空临时表 CLEAR lt_biz_main. "收集分组数据 LOOP AT GROUP <ls_alv> ASSIGNING FIELD-SYMBOL(<ls_group>). "填充修改人/修改时间(通用) <ls_group>-zmodify = sy-uname. <ls_group>-zmfdata = sy-datum. <ls_group>-zmftime = sy-uzeit. "按更新标识处理 CASE <ls_group>-updkz. WHEN 'I'. "新增 INSERT CORRESPONDING FIELDS OF <ls_group> INTO TABLE lt_biz_main. WHEN 'U'. "修改 UPDATE zt_biz_main FROM <ls_group> WHERE znumber = <ls_group>-znumber AND zitem = <ls_group>-zitem. WHEN 'D'. "删除 DELETE zt_biz_main WHERE znumber = <ls_group>-znumber AND zitem = <ls_group>-zitem. ENDCASE. ENDLOOP. "批量新增(如果有) IF lt_biz_main IS NOT INITIAL. INSERT zt_biz_main FROM TABLE lt_biz_main. ENDIF. "提交事务 COMMIT WORK AND WAIT. "更新ALV状态 MODIFY gt_alv_out FROM VALUE #( status_doc = icon_green_light mess = '' ) TRANSPORTING status_doc mess WHERE znumber = <ls_alv>-znumber. "推送审批(模板) "PERFORM frm_send_approval USING <ls_alv>-znumber CHANGING lv_msg. "IF lv_msg IS NOT INITIAL. " MODIFY gt_alv_out FROM VALUE #( status_pus = icon_red_light mess = lv_msg ) " TRANSPORTING status_pus mess " WHERE znumber = <ls_alv>-znumber. "ELSE. " MODIFY gt_alv_out FROM VALUE #( status_pus = icon_green_light mess = '推送成功' ) " TRANSPORTING status_pus mess " WHERE znumber = <ls_alv>-znumber. "ENDIF. ENDLOOP. MESSAGE '数据保存成功!' TYPE 'S'. ENDFORM. *&---------------------------------------------------------------------* *& 【FORM:批次F4帮助】- 保留通用F4模板 *&---------------------------------------------------------------------* FORM frm_open_batch_f4 USING pv_rowid TYPE int4. DATA: gt_batch TYPE TABLE OF ty_batch, "自定义批次结构 gs_batch TYPE ty_batch, lv_matnr TYPE matnr, lv_werks TYPE werks_d. "读取当前行物料/工厂 READ TABLE gt_alv_out ASSIGNING FIELD-SYMBOL(<ls_alv>) INDEX pv_rowid. IF sy-subrc <> 0 OR <ls_alv>-matnr IS INITIAL. MESSAGE '请先输入物料编码!' TYPE 'S' DISPLAY LIKE 'E'. RETURN. ENDIF. lv_matnr = <ls_alv>-matnr. lv_werks = <ls_alv>-werks. "查询批次数据(通用模板) SELECT charg clabs FROM mchb INTO CORRESPONDING FIELDS OF TABLE gt_batch WHERE matnr = lv_matnr AND werks = lv_werks AND clabs > 0. IF gt_batch IS INITIAL. MESSAGE '该物料无可用批次!' TYPE 'S'. RETURN. ENDIF. "调用批次选择屏幕(模板) "CALL SCREEN 200 STARTING AT 10 5 ENDING AT 80 20. "CHECK line_exists( gt_batch[ sele = 'X' ] ). "赋值选中批次 "READ TABLE gt_batch INTO gs_batch WITH KEY sele = 'X'. "<ls_alv>-charg = gs_batch-charg. ENDFORM. *&---------------------------------------------------------------------* *& 【FORM:打印处理】- 保留完整的SMARTFORM调用模板 *&---------------------------------------------------------------------* FORM frm_print_data. DATA: lv_fm_name TYPE rs38l_fnam, lv_formname TYPE tdsfname VALUE 'ZFORM_BIZ_PRINT', "替换为实际打印模板名 gs_ctrl TYPE ssfctrlop, gs_output TYPE ssfcompop, gt_job_info TYPE ssfcrescl, lt_znumber TYPE TABLE OF char20. "1. 校验选中数据 SELECT DISTINCT znumber FROM gt_alv_out INTO TABLE lt_znumber WHERE sele = 'X'. IF lt_znumber IS INITIAL. MESSAGE '请选择需要打印的数据!' TYPE 'E'. RETURN. ENDIF. "2. 获取SMARTFORM函数名 CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME' EXPORTING formname = lv_formname IMPORTING fm_name = lv_fm_name EXCEPTIONS no_form = 1 no_function_module = 2 OTHERS = 3. IF sy-subrc <> 0. MESSAGE '打印模板不存在!' TYPE 'E'. RETURN. ENDIF. "3. 设置打印参数 gs_ctrl-preview = abap_true. "预览模式 gs_ctrl-no_dialog = abap_false. "显示打印对话框 gs_output-tddest = 'LP01'. "默认打印机 "4. 打开打印任务 CALL FUNCTION 'SSF_OPEN' EXPORTING control_parameters = gs_ctrl output_options = gs_output EXCEPTIONS formatting_error = 1 internal_error = 2 send_error = 3 user_canceled = 4 OTHERS = 5. IF sy-subrc <> 0. MESSAGE '打印任务打开失败!' TYPE 'E'. RETURN. ENDIF. "5. 循环打印选中的单号 LOOP AT lt_znumber INTO DATA(lv_znumber). "填充打印表头 PERFORM frm_fill_print_head USING lv_znumber CHANGING gs_print_head. "填充打印表体 PERFORM frm_fill_print_item USING lv_znumber CHANGING gt_print_item. "调用SMARTFORM CALL FUNCTION lv_fm_name EXPORTING control_parameters = gs_ctrl output_options = gs_output is_head = gs_print_head TABLES it_item = gt_print_item EXCEPTIONS formatting_error = 1 internal_error = 2 send_error = 3 user_canceled = 4 OTHERS = 5. IF sy-subrc <> 0. MESSAGE '打印单号' && lv_znumber && '失败!' TYPE 'E'. EXIT. ENDIF. ENDLOOP. "6. 关闭打印任务 CALL FUNCTION 'SSF_CLOSE' IMPORTING job_output_info = gt_job_info EXCEPTIONS formatting_error = 1 internal_error = 2 send_error = 3 OTHERS = 4. IF gt_job_info-outputdone = abap_true. MESSAGE '打印任务执行完成!' TYPE 'S'. ELSE. MESSAGE '打印任务执行失败!' TYPE 'E'. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& 【FORM:填充打印表头】- 保留通用模板 *&---------------------------------------------------------------------* FORM frm_fill_print_head USING pv_znumber TYPE char20 CHANGING ps_print_head TYPE ty_print_head. "1. 查询公司名称 SELECT SINGLE butxt FROM t001 INTO ps_print_head-butxt WHERE bukrs = '1000'. "替换为实际公司代码 "2. 查询业务单头信息 "SELECT SINGLE zcrdate zcreator FROM zt_biz_head INTO CORRESPONDING FIELDS OF ps_print_head " WHERE znumber = pv_znumber. "3. 查询仓库描述 "SELECT SINGLE lgobe FROM t001l INTO ps_print_head-lgobe WHERE werks = p_werks AND lgort = ps_print_head-lgort. "4. 查询制单人信息 "SELECT SINGLE name department FROM user_addr INTO (ps_print_head-zzdr, ps_print_head-department) " WHERE bname = ps_print_head-zcreator. "5. 填充固定值 ps_print_head-znumber = pv_znumber. ps_print_head-title = '业务单打印凭证'. ps_print_head-zsum_lfimg = 0. "初始化合计数量 ENDFORM. *&---------------------------------------------------------------------* *& 【FORM:填充打印表体】- 保留通用模板 *&---------------------------------------------------------------------* FORM frm_fill_print_item USING pv_znumber TYPE char20 CHANGING pt_print_item TYPE TABLE OF ty_print_item. DATA: lv_sum TYPE erfmg. "清空表体 CLEAR gt_print_item. "查询打印表体数据 LOOP AT gt_alv_out INTO DATA(ls_alv) WHERE znumber = pv_znumber. "填充表体字段 gs_print_item-znumber = ls_alv-znumber. gs_print_item-matnr = ls_alv-matnr. gs_print_item-maktx = ls_alv-maktx. gs_print_item-erfmg = ls_alv-erfmg. gs_print_item-lgort = ls_alv-lgort. "查询单位描述 SELECT SINGLE msehl FROM t006a INTO gs_print_item-msehl WHERE msehi = ls_alv-erfme AND spras = sy-langu. APPEND gs_print_item TO gt_print_item. CLEAR gs_print_item. "累加合计数量 lv_sum = lv_sum + ls_alv-erfmg. ENDLOOP. "更新合计数量到表头 gs_print_head-zsum_lfimg = lv_sum. ENDFORM. *&---------------------------------------------------------------------* *& 【屏幕100 PBO】- 保留完整的ALV初始化 *&---------------------------------------------------------------------* MODULE status_100 OUTPUT. SET PF-STATUS 'STATUS_100'. "创建包含退出/返回的状态 SET TITLEBAR 'TITLE_100' WITH 'ALV通用框架 - 业务单管理'. ENDMODULE. MODULE init_alv OUTPUT. IF go_alv IS NOT BOUND. "创建ALV对象 go_alv = NEW cl_gui_alv_grid( i_lifetime = cl_gui_control=>lifetime_dynpro i_parent = cl_gui_container=>screen0 ). "注册F4字段 go_alv->register_f4_for_fields( VALUE #( ( fieldname = 'MATNR' register = abap_true internal = abap_true ) ( fieldname = 'CHARG' register = abap_true internal = abap_true ) ) ). "首次显示ALV go_alv->set_table_for_first_display( EXPORTING is_layout = gs_layout i_save = 'A' "允许保存布局 is_variant = VALUE disvariant( report = sy-cprog variant = COND #( WHEN p_ins THEN 'INS' WHEN p_mod THEN 'MOD' WHEN p_del THEN 'DEL' ELSE 'QUE' ) ) it_toolbar_excluding = VALUE #( ( cl_gui_alv_grid=>mc_fg_edit ) ) CHANGING it_outtab = gt_alv_out it_fieldcatalog = gt_fcat ). "注册事件 SET HANDLER: lcl_alv_event_handler=>handle_toolbar FOR go_alv, lcl_alv_event_handler=>handle_data_changed_finished FOR go_alv, lcl_alv_event_handler=>handle_user_command FOR go_alv, lcl_alv_event_handler=>handle_onf4 FOR go_alv, lcl_alv_event_handler=>handle_hotspot_click FOR go_alv. "激活工具栏+编辑事件 go_alv->set_toolbar_interactive( ). go_alv->register_edit_event( cl_gui_alv_grid=>mc_evt_modified ). ELSE. "刷新ALV go_alv->refresh_table_display( is_stable = VALUE lvc_s_stbl( row = abap_true col = abap_true ) ). ENDIF. ENDMODULE. *&---------------------------------------------------------------------* *& 【屏幕100 PAI】- 保留通用退出逻辑 *&---------------------------------------------------------------------* MODULE user_command_100 INPUT. CASE ok_code. WHEN '&F03' OR '&F15' OR '&EXIT' OR '&CANC'. LEAVE TO SCREEN 0. WHEN OTHERS. ENDCASE. ENDMODULE.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。