**1**
**写在前面**
生产订单修改记录报表对于项目上并不陌生。通常会在增强中编写逻辑来判断生产订单主要信息是否有变更,有则保存到日志表,并通过查询报表展示,帮助用户查看生产订单发生的修改。
本文档的代码,只是在原有代码基础上做了一些优化。通过配置表的方式,设置监控字段,灵活监控生产订单这些字段值的变更,也方便迁移到其他项目使用。
**利弊不谈,只是换个方式解决问题,感兴趣的读者可以试试,也一起测试一下是否有BUG。**
**如果仅仅实施一次,也不需要像本文档这么复杂,直接在增强中写死需要监控的字段就可以了。**
**2**
**实现过程**
**2.1**
**实施保存增强**
CMOD实施订单保存增强
保存时调用日志记录函数
**2.2**
**自建表**
创建监控字段配置表,配置需要监控的生产订单字段
其中“表名”和“删除标识”是自定义的域
维护上对应结构的字段,可以根据“表名”字段的搜索帮助中的结构找到对应字段。例如找到抬头对应的结构为CAUFVDB,可从CAUFVDB结构中找到要监控的抬头字段,工艺、组件同理。
创建更改日志表,用于存放更改的记录
增强中的函数ZPP_CO02_LOG则根据配置表维护的数据,监控对应的数据改变,并保存到日志表中。
创建查询报表将日志表中的数据进行展示,效果如下
**3**
**参考代码(看作者置顶留言)**
**3.1**
**增强函数**
FUNCTION zpp_co02_log.*"----------------------------------------------------------------------*"*"本地接口:*" TABLES*" HEADER_TABLE STRUCTURE CAUFVDB*" HEADER_TABLE_OLD STRUCTURE CAUFVDB*" POSITION_TABLE STRUCTURE AFPOB*" POSITION_TABLE_OLD STRUCTURE AAFPO*" SEQUENCE_TABLE STRUCTURE AFFLB*" SEQUENCE_TABLE_OLD STRUCTURE AAFFL*" OPERATION_TABLE STRUCTURE AFVGB*" OPERATION_TABLE_OLD_AFVC STRUCTURE AAFVC*" OPERATION_TABLE_OLD_AFVV STRUCTURE AAFVV*" COMPONENT_TABLE STRUCTURE RESBB*" COMPONENT_TABLE_OLD STRUCTURE ARESB*" RELATION_TABLE STRUCTURE AFABB OPTIONAL*" RELATION_TABLE_OLD STRUCTURE AAFAB OPTIONAL*" PSTEXT_TABLE STRUCTURE NPTXB OPTIONAL*" PSTEXT_TABLE_OLD STRUCTURE ANPTX OPTIONAL*" MILESTONE_TABLE STRUCTURE MLSTB OPTIONAL*" MILESTONE_TABLE_OLD STRUCTURE AMLST OPTIONAL*" PLANNED_ORDER_TABLE STRUCTURE PLAF*" STATUS_TABLE STRUCTURE JEST*" STATUS_TABLE_OLD STRUCTURE JEST*" OPERATION_RELATIONS STRUCTURE PRE_DEC*" OPERATION_RELATIONS_OLD STRUCTURE PRE_DEC*" OPERATION_TABLE_OLD_AFVU STRUCTURE AAFVU*" DOCLINK_TABLE STRUCTURE AFDLD*" DOCLINK_TABLE_OLD STRUCTURE AFDLD*"---------------------------------------------------------------------- CHECK sy-tcode = 'CO02'. CONSTANTS:c_h TYPE string VALUE '抬头'. CONSTANTS:c_r TYPE string VALUE '工艺'. CONSTANTS:c_c TYPE string VALUE '组件'. CONSTANTS:c_s TYPE string VALUE '订单状态'. DATA:lt_log TYPE TABLE OF zppt_gdbg_log, ls_log TYPE zppt_gdbg_log, ls_log_temp TYPE zppt_gdbg_log. DATA:lv_tname TYPE zppt_gdbg_zd-tabname, lv_tname_old TYPE zppt_gdbg_zd-tabname. "IP和HOST DATA: lv_iporg TYPE msxxlist-hostadr, lv_ipdec TYPE char16, lv_host TYPE char18. DATA:lv_arbpl TYPE arbpl, lv_arbpl_old TYPE arbpl. DATA:lv_delete TYPE c, lv_seq TYPE zppt_gdbg_log-seqno. FIELD-SYMBOLS: TYPE any, TYPE any. SELECT SINGLE MAX( seqno ) FROM zppt_gdbg_log INTO lv_seq WHERE aufnr = header_table-aufnr. "生产订单变更日期监控字段 SELECT tabname,"表名 fieldname,"字段 ddtext"名称 FROM zppt_gdbg_zd INTO TABLE @DATA(lt_field).** Get user IP,hostname CALL FUNCTION 'TH_USER_INFO' " Get user IP,hostname EXPORTING client = sy-mandt user = sy-uname IMPORTING hostaddr = lv_iporg terminal = lv_host EXCEPTIONS OTHERS = 1.**"Conv.IP addr to format 'xxx.xxx.xxx.xxx' CALL FUNCTION 'GWY_IPADR2STRING' "Conv.IP addr EXPORTING ipadr = lv_iporg IMPORTING string = lv_ipdec. READ TABLE header_table INDEX 1. READ TABLE header_table_old INDEX 1. READ TABLE position_table INDEX 1. READ TABLE position_table_old INDEX 1. ls_log_temp-mandt = sy-mandt. ls_log_temp-aenam = sy-uname. ls_log_temp-laeda = sy-datum. ls_log_temp-times = sy-uzeit. ls_log_temp-tcode = sy-tcode. ls_log_temp-host = lv_host. ls_log_temp-ip = lv_ipdec. ls_log_temp-aufnr = header_table-aufnr.*1)生产订单抬头更改记录字段 LOOP AT lt_field INTO DATA(ls_field) WHERE tabname = 'HEAD'. ASSIGN COMPONENT ls_field-fieldname OF STRUCTURE header_table TO . IF sy-subrc EQ 0. ASSIGN COMPONENT ls_field-fieldname OF STRUCTURE header_table_old TO . IF sy-subrc EQ 0 AND <> . ls_log = ls_log_temp. lv_seq = lv_seq + 1. ls_log-seqno = lv_seq. ls_log-object = c_h. ls_log-chnid = 'U'. ls_log-field = ls_field-ddtext. ls_log-value_old = . ls_log-value_new = . APPEND ls_log TO lt_log. CLEAR ls_log. ENDIF. ENDIF. CLEAR:ls_field. ENDLOOP. LOOP AT lt_field INTO ls_field WHERE tabname = 'POSI'. ASSIGN COMPONENT ls_field-fieldname OF STRUCTURE position_table TO . IF sy-subrc EQ 0. ASSIGN COMPONENT ls_field-fieldname OF STRUCTURE position_table_old TO . IF sy-subrc EQ 0 AND <> . ls_log = ls_log_temp. lv_seq = lv_seq + 1. ls_log-seqno = lv_seq. ls_log-object = c_h. ls_log-chnid = 'U'. ls_log-field = ls_field-ddtext. ls_log-value_old = . ls_log-value_new = . APPEND ls_log TO lt_log. CLEAR ls_log. ENDIF. ENDIF. CLEAR:ls_field. ENDLOOP.*-组件*2)生产订单组件更改记录字段* 删除组件时也需要记录以上内容 LOOP AT component_table WHERE vbkz EQ 'U' OR vbkz EQ 'I' OR vbkz EQ 'D'. CASE component_table-vbkz. WHEN 'I'. LOOP AT lt_field INTO ls_field WHERE tabname = 'COMP'. ASSIGN COMPONENT ls_field-fieldname OF STRUCTURE component_table TO . IF sy-subrc EQ 0 AND IS NOT INITIAL. ls_log = ls_log_temp. lv_seq = lv_seq + 1. ls_log-seqno = lv_seq. ls_log-object = c_c. ls_log-chnid = 'I'. ls_log-field = ls_field-ddtext. ls_log-matnr = component_table-matnr. ls_log-value_new = . APPEND ls_log TO lt_log. CLEAR ls_log. ENDIF. CLEAR:ls_field. ENDLOOP. WHEN 'D'. CLEAR component_table_old. READ TABLE component_table_old WITH KEY rsnum = component_table-rsnum rspos = component_table-rspos. LOOP AT lt_field INTO ls_field WHERE tabname = 'COMP'. ASSIGN COMPONENT ls_field-fieldname OF STRUCTURE component_table_old TO . IF sy-subrc EQ 0 AND IS NOT INITIAL. ls_log = ls_log_temp. lv_seq = lv_seq + 1. ls_log-seqno = lv_seq. ls_log-object = c_c. ls_log-chnid = 'D'. ls_log-field = ls_field-ddtext. ls_log-matnr = component_table_old-matnr. ls_log-value_old = . APPEND ls_log TO lt_log. CLEAR ls_log. ENDIF. CLEAR:ls_field. ENDLOOP. WHEN 'U'. CLEAR component_table_old. READ TABLE component_table_old WITH KEY rsnum = component_table-rsnum...