环境: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,要记得感谢赵彦军大神的艰苦付出哦!