BIEE中修正Union结果集传参公式错误问题

浏览: 4011

环境:BIEE11.1.1.7...

背景:

工作中经常会碰到在报表中使用union结果集拼接分析的情况,有时候又需要导航到明细报表页。这个时候从汇总往明细页传参是最头疼的问题。如果拼接的值固定,还可以在设置导航连接时候使用条件,若值不固定,是某些维度信息,这个时候往往达不到期望的效果。

PS:以下实例是工作中赵彦军大神研究出来的。我这里借花献佛,供大家参考。


栗子奉上:

假设需要展示这样的一个汇总表,点击度量指标导航到明细报表,明细报表根据导航的维度信息,展示不同的明细数据。

地区 销售额

union

产品 销售额

例如展示是这样:

广州 销售额A

深圳 销售额B

union

冰箱 销售额C

电视 销售额D

若点击广州,则明细报表展示的是广州对应的明细信息,若点击冰箱,则期望展示的是冰箱的明细信息。

可往往事与愿违,BIEE中,点击广州或者深圳则明细数据显示正常。点击冰箱或者电视则明细无数据。


若调换union次序呢?

冰箱 销售额C

电视 销售额D

union

广州 销售额A

深圳 销售额B

则点击冰箱或者电视则明细数据显示正常。点击广州或者深圳则明细无数据。


究其原因,还是BIEE的内部机制作怪。在BIEE中,默认为union的列都是同一列,具有相同的列公式,所以在参数传递的时候,把第一个union的列作为要传递的参数列。但现实和理想还是有点点小差距,所以要么默默忍受,要么奋起反抗~


那么,上大招了。(真实实例哦

假设有这样一个仪表盘page页,需要导航到明细报表。

提示器:

年份、月份

报表展示:

地区 运输类别("Trans"."Type") 指标

union

地区 运输方式("Trans"."Mode") 指标


若选择了年份:2014,月份:12,点击 地区:中国,运输方式:By Air 这一行的指标导航到明细报表,那么过程如何呢?


这里插点不是题外的题外话:(关于BIEE导航的过程或者说步骤)

1、点击导航交互列

2、获取这一列对应的行记录对象

3、获取当前dashboard当前page页的提示器对象及状态

4、将步骤3的提示器相关及第2步骤中的行记录中的非度量列,根据模型生成JS参数对象继续传递

5、经过一系列内部处理,最终传递给目标报表,目标报表根据预先定义的过滤器提示来确认是否接受参数并过滤数据


对应上面的过程,那么自然可以看出在第4步的时候会组合参数对象传递给目标报表使用。如果我们在参数传递的第4步修改因错误传递的列公式为正确的列公式即可满足要求。

例如由原来的参数对象(年份:2014,月份:12,地区:中国,运输类别:By Air 

修改为新的参数对象(年份:2014,月份:12,点击 地区:中国,运输方式:By Air 


那么其中有几个关键点值得思考:

1、必须定位到传参的过程或者方法

2、在传递到目标报表之前,修改错误参数公式为正确的参数公式

3、修改后的代码,不能影响原生功能。


针对以上几个关键点,使用万能的F12,跟踪分析JS代码,定位到下面的方法会生成JS参数对象:

obiaf.ExecuteAction.prototype.runClientScript=function(a){.......}

那么接下来就是改造过程了。

添加辅助列(列公式为'T1'、'T2',以此类推),用来标识结果集(PS:有小伙伴没有研究成功,我在这里加点详细的描述)

地区 'T1' 运输类别("Trans"."Type") 指标

union

地区 'T2' 运输方式("Trans"."Mode") 指标


在需要传参的仪表盘,新增静态文本,覆盖函数定义,修改之(代码见下述);


<script src="res/b_Mozilla/tp/jq/jquery-1.6.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
var intv=setInterval(function(){
if(typeof(obiaf) != 'undefined'){
obiaf.ExecuteAction.prototype.runClientScript=function(a){
var j=(typeof(a)=="function"?a:obiaf.Action.getFunctionPointer(a));
if(typeof(j) !="function"){
var h=this.resourceManager.getResource(obiaf.ActionBase.resourceFile,"kmsgActionInvalidFunction").getString();
var k=this.resourceManager.getResource(obiaf.ActionBase.resourceFile,"kmsgActionInvalidFunctionMessage").getString(a);
this.displayMessage(h,k,obips.MessageDialog.TITLE_IMAGE_ERROR);
return
}
var g=new Array();
var b=new Array();
for(var e=0;e<this.paramsEditorModel.ParameterDocuments.length;++e){
var c=this.paramsEditorModel.ParameterDocuments[e];
g[c.name]=c.getFirstValue();
var f=new Object();
var d=c.doesFirstValueHaveDisplayValue();
if(d){
f.codeValue=true;
}else{
f.codeValue=false;
}
b[c.name]=f;
}
if(this.bNavOpenNewWindowOption){
g.bNavOpenNewWindowOption=this.bNavOpenNewWindowOption;
}
//gp为我们新定义对象,用于修改传参公式
var gp=new Array();
for(var it in g){
//这里的g["'T1'"]是指列公式为'T1'的列,'T2'是列值,代表是第2个结果集,如果超过2个。新增if判定语句
if(g["'T1'"]=='T2' && it=="\"Trans Mode\".\"Trans Type\""){
gp["\"Trans Mode\".\"Trans Mode\""=g[it];]
}else{
gp[it]=g[it];
}
}
j.call(this.ctx,gp,b);
};
clearInterval(intv);
}
},50);
});
</script>


如果有TX发现函数代码有错误的地方,请指正。

也感谢一直看到这里的TX。是不是蠢蠢欲动了呀。那就工作中用起来吧!

要记得万能的F12,要记得感谢赵彦军大神的艰苦付出哦!

推荐 5
本文由 百分百 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

6 个评论

对我帮助挺大,之前也遇到过类似问题。
辛苦了,大师们。
辛苦辛苦
JS看起来很厉害呀,辛苦
新增了辅助列说明和代码说明,还有不懂的私信我
M_T

M_T 回复 百分百

额 这个不就是我的实例嘛。。。

要回复文章请先登录注册