需求:一个现有量查询界面,需要按照不同维度查询:输入了物料,显示物料在各个子库下的现有量;不输物料,输入子库,则显示所有物料在这个子库下的现有量,以物料子库的维度查询;不输入物料和子库,直接查询某库存组织该物料的现有量;
分析:由于查询维度不同,分别为明细维度,按子库汇总维度,按组织汇总维度,因此同一段视图逻辑不能满足需求;
解决方式:
1.采用UNION ALL方式,联合多段试图,并加上一个字段作为分类,如QUERY_TYPE分别为DETAIL,SUBINV,TOTAL分别对应不同维度查询,根据查询条件指定不同的QUERY_TYPE;在PRE-QUERY的后边加入以下代码来选择执行的查询:
IF :ITEM_LINE_BLK.ITEM_NUMBER IS NOT NULL THEN :ITEM_LINE_BLK.QUERY_TYPE := 'DETAIL'; ELSIF :ITEM_LINE_BLK.SUBINVENTORY_CODE IS NOT NULL THEN :ITEM_LINE_BLK.QUERY_TYPE := 'SUBINV'; ELSE :ITEM_LINE_BLK.QUERY_TYPE := 'TOTAL'; END IF;
然而,这种方式并太好用,因为SQL执行查询的时候并不是首先按照该条件去执行筛选,而是先执行主SQL的查询逻辑,最后才进行了外部条件的筛选,物料数据量较大,这样查询就比较慢了;
2.采用多视图的方式,即把多段逻辑的视图分开,根据查询条件选择不同的视图进行查询;
在PRE-QUERY中添加如下代码进行动态选择试图:
IF :ITEM_LINE_BLK.ITEM_NUMBER IS NOT NULL THEN --设置块的查询视图 set_block_property('ITEM_LINE_BLK',QUERY_DATA_SOURCE_NAME,'XXIVFA01_ITEM_AVAILABLE_V'); ELSIF :ITEM_LINE_BLK.SUBINVENTORY_CODE IS NOT NULL THEN set_block_property('ITEM_LINE_BLK',QUERY_DATA_SOURCE_NAME,'XXIVFA01_ITEM_AVAILABLE1_V'); ELSE set_block_property('ITEM_LINE_BLK',QUERY_DATA_SOURCE_NAME,'XXIVFA01_ITEM_AVAILABLE2_V'); END IF;
该方式比第一种方式快些;
使用了这种按照不同维度进行查询的情况,会出现一个新的错误,即ORDER_BY1-3三个排序块的使用会影响上述操作;ORDERBY块查询的时候会记录上次的查询条件,同时会执行PRE_QUERY中的查询条件,由于查询块和主数据块都可以进行查询,因此不能使用G_Query_Find参数来区分;根据排序ITEM可能执行的触发器WHEN-MOUSE-UP去查找代码,发现会APPFLDR.PLL中会进行判断,判断是不是需要执行排序操作,在这个过程中会维护一个全局变量,来判断是否为排序模式:但是这个全局变量开始是不存在的,因此直接使用会报错,应该在PRE-FORM或WHEN-NEW-FORM-INSTANCE中进行初始化为'N':
copy('N', 'global.appfldr_sort_mode');
然后在点击ITEM进行排序的时候,会把该变量改为Y,然后再进行操作;因此就可以根据该变量来判断是否需要重新设置查询视图;
PRE-QUERY代码如下:
IF NVL(:global.appfldr_sort_mode,'N') <> 'Y' THEN IF :ITEM_LINE_BLK.ITEM_NUMBER IS NOT NULL THEN --设置块的查询视图 set_block_property('ITEM_LINE_BLK',QUERY_DATA_SOURCE_NAME,'XXIVFA01_ITEM_AVAILABLE_V'); ELSIF :ITEM_LINE_BLK.SUBINVENTORY_CODE IS NOT NULL THEN set_block_property('ITEM_LINE_BLK',QUERY_DATA_SOURCE_NAME,'XXIVFA01_ITEM_AVAILABLE1_V'); ELSE set_block_property('ITEM_LINE_BLK',QUERY_DATA_SOURCE_NAME,'XXIVFA01_ITEM_AVAILABLE2_V'); END IF; END IF;
以上方式,可以在排序模式中,避免再次重新设置查询视图!