abap-标准程序调试例二之CO46

来源:互联网 发布:top已备案域名出售 编辑:程序博客网 时间:2024/05/21 10:38

原文: http://gnolux-blog.appspot.com/2010/06/30/abap_10063003.html

今天搞了一天的调试跟踪,头晕眼花了,晚上清醒一点记录一下过程。

业务背景:
集团有公司代码1000和2000,1000下的销售订单都生成对2000的采购申请(现状是订单的每行都会产生一个采购申请),1000的计划人员,将多张采购申请合并创建一张对2000的公司间采购订单.2000根据采购订单跑物料需求和生产计划。
现在使用 CO46 查看,某张销售订单的需求时出现的问题: 理论上每一个销售单行对应到一个采购单的行,但现在是每行都对应到相应采购单的所有行了。表面上看应该是关联逻辑有误,每个订单行只和采购单号关联了,没有和采购单行对应。
没有找到相应的后台配置,决定跟踪此程序,找出它的设计逻辑,再想办法处理。

TCODE: CO46,进入选择屏,并填写好必要查询条件,  /H 进入abap调试状态.

.................................................这里是漫长的 F8,F6及断点组合,略.......考的是耐心、细心加眼力..............................

找到 对 ebkn 和 ekkn 的读操作,就是采购申请和采购订单,两者取数逻辑是类似的,看下图是取采购订单的代码

 


cm61x是一个结构变量,再前面的调试中记得它是装入了当前订单的所有行项的,从这里可以看出再找相应采购单行时逻辑应该是正确的,分别用了订单+行号两个键来取数,这样的话感觉可能只是显示部份的问题了,先保留这种想法,继续跟踪下去.

发现最终取得的数据装在如下图所示的内表里,基本可以确定,取数没问题,是显示部份的问题.


(以 00001 开头的是 销售订单, 460 开头的是采购订单,从上图可以看出之间的对应关系通过 extra 字段可以确定)
假设后面的显示部份,如果是用 extra 这个字段去不断找下层数据(构造 tree 结点)应该就不会有问题.

下面我们去找 alv_tree 相关的代码,我设 了 call   和 create 两个语句断点,分别针对 bapi 和 类的方式使用 alv tree 的代码.
最终跟终到如下图代码,是创建 tree 和显示的地方



找到添加结点的地方,调用了 IO_ADD_LINE FORM , 在 IO_BUILD_HIERARCHY FORM  里面 , 
IO_ADD_LINE 会传出一个参数 lf_nxtrs 内表,而这个内表的数据来源,是之前添加的结点的字段 NCTPS 的值(见前面第二张内表数据图),并不是 extra 字段,NCTPS 在此时只是一个采购单编号,而不含行号。
看下面 loop 里的代码, 最终 NCTPS 的值会给到 lf_delnr 并作为参数传到  io_add_children Form 里,在这里就可以看出,后面取子结点应该会有问题了,取出是采购单的所有行。(问题点 1)

下图是添加了结点过程,通过 if_rsnum 查找内表(前面图二 内表数据), lf_rsnum 的值就是传下来的采购单号,
后续代码会将这个采购单号的所有行都作为结点,添加到当前对应订单行的结点下。如果此时有采购单的行号过滤就不会错了。(问题点 2)


另外此 Form 里有递归调用,以处理更深层的结点.

通过上面的跟踪基本可以知道,有两个地方有问题,最后修改如下:

在调用 io_add_children 前将对应的子结点的行项找到并传到到参数  lf_delps 。

 

在  io_add_children Form 里添加根据带进来的行项参数过滤掉不需要的行。

 

最后完成了修改,并满足了需求,皆大欢喜,就是苦了我的眼睛了。 :)

 

参考: abap-标准程序调试一例 

        sap-通过调试突破client的锁定修改系统数据

        abap-如何更好的给代码添加硬断点 break-point

 

 

原创粉丝点击