1, 变更文档简介
一般来说,SAP标准程序会将凭证,业务数据的创建,删除和修改的历史都会被保存到表cdpos和cdhdr中,详细可以参见文章
查看更改历史(cdpos和cdhdr)报表-RSSCD1TS
下面通过一个例子介绍一下如何记录自定义表的修改历史。
2, SCDO创建表更文档对象
注意:CDPOS和CDHDR是否更新和技术设置中的log data change无关,log data change作用请参见
通过TCode SCDO为表ZZZ_SALESSTAT创建变更文档对象(change document object),输入object名字zztest然后点击创建按钮,
勾上checkbox,输入text,然后点击红宝马按钮生成change document object,
点击Generate 按钮生成相关对象,
在下一屏幕中可以看到自动生成的include程序,update的函数ZZTEST_WRITE_DOCUMENT,这个函数就是将来在程序里调用更新CDHDR和CDPOS表的FM,还有一个结构YZZZ_SALESSTAT,
自动生成的更新函数ZZTEST_WRITE_DOCUMENT的输入参数中,有部分会影响CDHDR表,剩余的UPD_ICDTXT_ZZTEST和UPD_ZZZ_SALESSTAT是控制CDPOS的,这个可以通过associated type 看出来。
3, 例子程序
创建一个例子程序,用来测试表数据插入,删除,修改时调用update的函数ZZTEST_WRITE_DOCUMENT更新CDHDR和CDPOS表。
程序选择画面,有一个字段,用来表示操作类型,
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
INCLUDE fzztestcdt."SCDO中自动生成的include INCLUDE fzztestcdc."SCDO中自动生成的include PARAMETERS p_type TYPE c. *----------------------------------------------------------------------* * INITIALIZATION *----------------------------------------------------------------------* INITIALIZATION. *----------------------------------------------------------------------* * AT SELECTION-SCREEN *----------------------------------------------------------------------* AT SELECTION-SCREEN. *----------------------------------------------------------------------* * START-OF-SELECTION *----------------------------------------------------------------------* START-OF-SELECTION. CASE p_type. WHEN 'I'. * 插入 PERFORM salesstat_insert. WHEN 'U'. * 修改 PERFORM salesstat_update. WHEN 'D'. * 删除 PERFORM salesstat_delete. ENDCASE. *----------------------------------------------------------------------- * END-OF-SELECTION *----------------------------------------------------------------------- END-OF-SELECTION. FORM salesstat_insert . DATA:li_salesstat TYPE STANDARD TABLE OF zzz_salesstat, ls_salesstat TYPE zzz_salesstat, ls_xzzz_salesstat TYPE yzzz_salesstat. REFRESH:li_salesstat. CLEAR:ls_salesstat. * 插入两条数据 ls_salesstat-vkorg = '1500'. ls_salesstat-kunnr = '20004'. ls_salesstat-matnr = '050-0501-99'. ls_salesstat-kwmeng = 10. ls_salesstat-vrkme = 'PCS'. APPEND ls_salesstat TO li_salesstat. MOVE-CORRESPONDING ls_salesstat TO ls_xzzz_salesstat. ls_xzzz_salesstat-kz = 'I'. APPEND ls_xzzz_salesstat TO xzzz_salesstat. ls_salesstat-vkorg = '1501'. ls_salesstat-kunnr = '20004'. ls_salesstat-matnr = '050-0501-99'. ls_salesstat-kwmeng = 11. ls_salesstat-vrkme = 'PCS'. APPEND ls_salesstat TO li_salesstat. MOVE-CORRESPONDING ls_salesstat TO ls_xzzz_salesstat. ls_xzzz_salesstat-kz = 'I'. APPEND ls_xzzz_salesstat TO xzzz_salesstat. IF li_salesstat[] IS NOT INITIAL. * 插入数据 MODIFY zzz_salesstat FROM TABLE li_salesstat[]. * 用表KEY键组成ObjectID objectid = ls_salesstat-vkorg && ls_salesstat-kunnr && ls_salesstat-matnr. . CALL FUNCTION 'ZZTEST_WRITE_DOCUMENT' EXPORTING objectid = objectid tcode = sy-tcode utime = sy-uzeit udate = sy-datum username = sy-uname object_change_indicator = 'I' "cdoc_upd_object upd_zzz_salesstat = 'I' TABLES icdtxt_zztest = icdtxt_zztest xzzz_salesstat = xzzz_salesstat[]. "新值 COMMIT WORK. MESSAGE 'Insertion is over' TYPE 'S'. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& Form SALESSTAT_DELETE *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM salesstat_delete . DATA:li_salesstat TYPE STANDARD TABLE OF zzz_salesstat, ls_salesstat TYPE zzz_salesstat, ls_yzzz_salesstat TYPE yzzz_salesstat. REFRESH:li_salesstat. CLEAR:ls_salesstat. * 取一条数据 SELECT SINGLE * INTO ls_salesstat FROM zzz_salesstat. IF sy-subrc = 0. MOVE-CORRESPONDING ls_salesstat TO ls_yzzz_salesstat. ls_yzzz_salesstat-kz = 'D'. "删除标识 APPEND ls_yzzz_salesstat TO yzzz_salesstat. * 删除数据 DELETE zzz_salesstat FROM ls_salesstat. * 用表KEY键组成ObjectID objectid = ls_salesstat-vkorg && ls_salesstat-kunnr && ls_salesstat-matnr. CALL FUNCTION 'ZZTEST_WRITE_DOCUMENT' EXPORTING objectid = objectid tcode = sy-tcode utime = sy-uzeit udate = sy-datum username = sy-uname object_change_indicator = 'D' "删除标识 upd_zzz_salesstat = 'D' "删除标识 TABLES icdtxt_zztest = icdtxt_zztest yzzz_salesstat = yzzz_salesstat[]. "旧值 ,删除场合下不需要输入新值 . COMMIT WORK. MESSAGE 'Deletion is over' TYPE 'S'. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& Form SALESSTAT_UPDATE *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM salesstat_update . DATA:li_salesstat TYPE STANDARD TABLE OF zzz_salesstat, li_yzzz TYPE STANDARD TABLE OF yzzz_salesstat, li_xzzz TYPE STANDARD TABLE OF yzzz_salesstat, ls_salesstat TYPE zzz_salesstat, ls_xzzz_salesstat TYPE yzzz_salesstat, ls_yzzz_salesstat TYPE yzzz_salesstat. REFRESH:li_salesstat. CLEAR:ls_salesstat. * 取一条数据 SELECT SINGLE * INTO ls_salesstat FROM zzz_salesstat. IF sy-subrc = 0. * 旧值 MOVE-CORRESPONDING ls_salesstat TO ls_yzzz_salesstat. ls_yzzz_salesstat-kz = 'U'. APPEND ls_yzzz_salesstat TO li_yzzz. * 新值,修改两个字段 ls_salesstat-kwmeng = ls_salesstat-kwmeng + 1. IF ls_salesstat-vrkme = 'PCS'. CLEAR:ls_salesstat-vrkme. ELSE. ls_salesstat-vrkme = 'PCS'. ENDIF. APPEND ls_salesstat TO li_salesstat. MOVE-CORRESPONDING ls_salesstat TO ls_xzzz_salesstat. ls_xzzz_salesstat-kz = 'U'. APPEND ls_xzzz_salesstat TO li_xzzz. * 插入数据 MODIFY zzz_salesstat FROM TABLE li_salesstat[]. * 用表KEY键组成ObjectID objectid = ls_salesstat-vkorg && ls_salesstat-kunnr && ls_salesstat-matnr. . CALL FUNCTION 'ZZTEST_WRITE_DOCUMENT' EXPORTING objectid = objectid tcode = sy-tcode utime = sy-uzeit udate = sy-datum username = sy-uname " object_change_indicator = 'U' "cdoc_upd_object upd_zzz_salesstat = 'U' TABLES icdtxt_zztest = icdtxt_zztest xzzz_salesstat = li_xzzz "新值 yzzz_salesstat = li_yzzz. "旧值 . COMMIT WORK. MESSAGE 'Modification is over' TYPE 'S'. ENDIF. ENDFORM. |
4, 测试
数据插入,
查看CDHDR和CDPOS表,发现新增加的数据插入修改记录
在CDPOS中能看到两条插入记录,
数据删除,
查看CDHDR和CDPOS表,发现新增加的数据删除修改记录
数据修改,例子程序中抽取了一条数据,然后将数量字段kwmeng加1,并且修改了单位字段vrkme,
然后查看CDHDR和CDPOS表,发现新增加的数据修改记录,
有一点很奇怪,修改了两个字段CDPOS中只记录了一个字段vrkme的修改历史,没有记录kwmeng字段的。
具体原因请移步,[问题解决]CDPOS表中缺失字段修改历史。
以上。
发表评论