场景:现在存在一段时间的订单销售数据,我们需要根据日期查看不同时间段内的订单笔数的同比环比值
功能实现点:
1:同比环比实现
2:用户体验
3:实现效果
效果1:用户默认不用选择任何条件进入报表页面,默认显示从当前时间向前推一个月的数据
效果2:实现按照日期显示该天、该天前一天、该天后一天、去年该天的订单笔数
效果3:用户重新选择任意时间段,实现该时间段内该天、该天前一天、该天后一天、去年该天的订单笔数
下面就从报表开发来说一下具体的实现步骤:
【1】:模型开发与设计-建模过程不再阐述
1.1:这里主要是开发一个雪花模型,由于时间有限,就创建一个维度和一个度量,结构如下
【2】:报表开发与设计
2.1:创建提示页面1-目的是为了给报表运行中必要的参数赋初始值
拖入一个提示页面,结构如下图所示
html1处代码为:
<div style="display:none">
//隐藏提示页面中的对象
sbdate1,sedate1为日期提示控件,参数名为sbdate,sedate,名称为sbdate1,sedate1
bdate1,edate1为值提示控件,参数名为bdate,edate,名称为bdate1,edate1,值来自查询1,使用值都为[日]
html2处代码为:
<script>
//得到昨天时间并格式化
function getyesterday()
{
var dtToday = new Date();
var dtYesterday = new Date( dtToday - 86400000 );
var strYesterday = [dtYesterday.getUTCFullYear(), dtYesterday.getMonth()+1, dtYesterday.getDate()].join("-");
return strYesterday;
}
//得到上一个月的昨天并格式化
function getyesterdaybeforeamonth()
{
var dtToday = new Date();
var dtYesterday = new Date( dtToday - 86400000 );
dtYesterday.setMonth(dtYesterday.getMonth()-1);
var stryesterdaybeforeamonth= [dtYesterday.getUTCFullYear(), dtYesterday.getMonth()+1, dtYesterday.getDate()].join("-");
return stryesterdaybeforeamonth;
}
//得到日期提示的值并返回
function getsdate()
{
var sbdate=getFormWarpRequest().txtDatesbdate1.value;
var sedate=getFormWarpRequest().txtDatesedate1.value;
var returnstr=sbdate+'_'+sedate;
return returnstr;
}
//执行查询
function doquery(datastr)
{
//alert('来了');
//alert(datastr);
//接收日期提示来的值
var strarray= new Array();
strarray=datastr.split("_");
var bdatestr=strarray[0];
var edatestr=strarray[1];
//接收2012-5-10这样的截取后的年月日
var barray=new Array();
var earray=new Array();
barray=bdatestr.split("-");
earray=edatestr.split("-");
//需要转换的格式:[订单数据分析].[日期维度].[日期维度].[日]->[all].[2013].[201310].[20131019]
//处理已经从日期提示获取到的日期值的格式
var givebdate='[订单数据分析].[日期维度].[日期维度].[日]->[all].' + '['+barray[0]+'].' + '['+barray[0]+addzero(barray[1])+'].' + '['+barray[0]+addzero(barray[1])+addzero(barray[2])+']';
var giveedate='[订单数据分析].[日期维度].[日期维度].[日]->[all].' + '['+earray[0]+'].' + '['+earray[0]+addzero(earray[1])+'].' + '['+earray[0]+addzero(earray[1])+addzero(earray[2])+']';
//alert(givebdate);
//alert(giveedate);
//为值提示赋值
var form=getFormWarpRequest();
var mylist1=form._oLstChoicesbdate1;//粗体部分为提示页面中值提示的名称,而不是参数名称。
var mylist2= form._oLstChoicesedate1;//粗体部分为提示页面中值提示的名称,而不是参数名称。
//alert(mylist1.length);
//alert(mylist2.length);
//给开始日期的值提示赋值
for(var i=0;i<mylist1.length;i++)
{
if(mylist1[i].value==givebdate)
{
mylist1[i].selected="true";
}
}
//给结束日期的值提示赋值
for(var i=0;i<mylist2.length;i++)
{
if(mylist2[i].value==giveedate)
{
mylist2[i].selected="true";
}
}
//提交form
promptButtonFinish();
}
//转换格式2014-3-9为2014-03-09
function addzero(str)
{
var returnstr;
if(str>0&&str<10)
{
returnstr=0+str;
}
else
{
returnstr=str;
}
return returnstr;
}
//初始化页面的方法
function init()
{
pickerControlsbdate1.setValue( getyesterdaybeforeamonth());//给开始日期赋值
doquery(getsdate());//提交查询
}
</script>
<body onload="init()">
</body>
</div>
2.2:进入报表页面1,拖一个交叉表,在查询1中新建如下数据项
对应表达式分别为:
当前时间
currentMember([订单数据分析].[日期维度].[日期维度])
前一个时间
prevMember ([当前时间])
后一个时间
nextMember ([当前时间])
去年当前时间
parallelPeriod ([订单数据分析].[日期维度].[日期维度].[年],1,[当前时间])
环比前一个时间
value (tuple ([前一个时间],[订单笔数]))
环比后一个时间
value (tuple ([后一个时间],[订单笔数]))
同比去年当前时间
value (tuple ([去年当前时间],[订单笔数]))
日期
except (lastPeriods (-9000,[订单数据分析].[日期维度].[日期维度].[日]->?bdate?),lastPeriods (-9000,nextMember ([订单数据分析].[日期维度].[日期维度].[日]->?edate?)))
过滤
total([订单笔数] for [日期])
从图上可以看出,需要把过滤>0放入明细过滤器中,不显示无订单笔数的日期数据.
2.3设计报表页面,在交叉表拖入结构如下,使用查询为查询1
sbdate,sedate为日期提示控件,参数名为sbdate,sedate,名称为sbdate,sedate
bdate,edate为值提示控件,参数名为bdate,edate,名称为bdate,edate,值来自查询1,使用值都为[日]
html1出代码为:
<div class="clsPromptComponent" pt="btn">
<script>
//得到来自日期提示的值并返回
function getsdate()
{
var sbdate=getFormWarpRequest().txtDatesbdate.value;
var sedate=getFormWarpRequest().txtDatesedate.value;
var returnstr=sbdate+'_'+sedate;
return returnstr;
}
//执行查询,主查询
function doquery(datastr)
{
//alert('来了');
//alert(datastr);
//接收日期提示来的值
var strarray= new Array();
strarray=datastr.split("_");
var bdatestr=strarray[0];
var edatestr=strarray[1];
//接收2012-5-10这样的截取后的年月日
var barray=new Array();
var earray=new Array();
barray=bdatestr.split("-");
earray=edatestr.split("-");
//需要转换的格式:[订单数据分析].[日期维度].[日期维度].[日]->[all].[2013].[201310].[20131019]
//处理已经从日期提示获取到的日期值的格式
var givebdate='[订单数据分析].[日期维度].[日期维度].[日]->[all].' + '['+barray[0]+'].' + '['+barray[0]+addzero(barray[1])+'].' + '['+barray[0]+addzero(barray[1])+addzero(barray[2])+']';
var giveedate='[订单数据分析].[日期维度].[日期维度].[日]->[all].' + '['+earray[0]+'].' + '['+earray[0]+addzero(earray[1])+'].' + '['+earray[0]+addzero(earray[1])+addzero(earray[2])+']';
//alert(givebdate);
//alert(giveedate);
//为值提示赋值
var form=getFormWarpRequest();
var mylist1=form._oLstChoicesbdate;//粗体部分为提示页面中值提示的名称,而不是参数名称。
var mylist2= form._oLstChoicesedate;//粗体部分为提示页面中值提示的名称,而不是参数名称。
//alert(mylist1.length);
//alert(mylist2.length);
//给开始日期的值提示赋值
for(var i=0;i<mylist1.length;i++)
{
if(mylist1[i].value==givebdate)
{
mylist1[i].selected="true";
}
}
//给结束日期的值提示赋值
for(var i=0;i<mylist2.length;i++)
{
if(mylist2[i].value==giveedate)
{
mylist2[i].selected="true";
}
}
//提交form
promptButtonFinish();
}
//处理2014-3-9 格式为2014-03-09
function addzero(str)
{
var returnstr;
if(str>0&&str<10)
{
returnstr=0+str;
}
else
{
returnstr=str;
}
return returnstr;
}
//自写button按钮,样式可以拖一个自带按钮然后借鉴
</script>
<button type="button" name="tijiao" id="tijiao" class="bp" onmouseover="this.className = 'bp bph'" onmouseout="this.className = 'bp'" onclick="doquery(getsdate())" style="padding-left:10px;padding-right:10px;">查询</button>
<body onload="">
</body>
</div>
html2处代码为
<div style="display:none">
html3处代码为
</div>
PS:html1为主要代码,html2与3的作用技术用一个层放入值提示,但是不显示。
【3】:查看效果
3.1:用户第一次运行报表
3.2:选择从2013-01-01开始
通过3.1和3.2可以看出数据显示正确
【4】:要点难点解析
3.1:没有过滤为什么可以实现显示所选时间段的值?同比环比公式需要注意的是什么
答:主要在于日期数据项的设计,里面用传参的方式实现了时间段的显示和同比环比
except (lastPeriods (-9000,[订单数据分析].[日期维度].[日期维度].[日]->?bdate?),lastPeriods (-9000,nextMember ([订单数据分析].[日期维度].[日期维度].[日]->?edate?)))
3.2:为什么要在提示页面即使用日期提示又使用值提示?同理为什么在报表页面即使用日期提示又使用值提示?
答:
第一问:由于之前已经写好了为日期提示赋值的代码,所以先给日期提示赋值,其实提示页面可以直接给值提示赋初始值,也可以不用日期提示,这里时间有限直接拿之前日期提示赋初始值的代码来用。
第二问:由于日期字段的特殊性,类似MemberUnique类型的格式'[订单数据分析].[日期维度].[日期维度].[日]->'必须用值提示的格式给’日期‘数据项传参,但是由于日这个层次的维度较多,选择不便,所以在用户选择方便使用日期提示选择,然后再点击查询的时候触犯onclick时间把日期提示的值赋给值提示,然后用值提示给'日期'数据项里面的参数传参,换一种思路解决日期提示参数格式不符合’日期‘传参的问题。
3.3:同比环比通用公式
可以通用的公式
currentMember([订单数据分析].[日期维度].[日期维度])
prevMember ([当前时间])
nextMember ([当前时间])
value (tuple ([前一个时间],[订单笔数]))
value (tuple ([后一个时间],[订单笔数]))
value (tuple ([去年当前时间],[订单笔数]))
可以举一反三扩展的公式
parallelPeriod ([订单数据分析].[日期维度].[日期维度].[年],1,[当前时间])
通过上面的公式我们也可以向前一季度,前一月,前一周的同一天修改
except (lastPeriods (-9000,[订单数据分析].[日期维度].[日期维度].[日]->?bdate?),lastPeriods (-9000,nextMember ([订单数据分析].[日期维度].[日期维度].[日]->?edate?)))
通过上面的公式我们也可以根据[年]、[季度]、[月]等来作为同比环比的粒度。
文终于此 2014-5-21