1实现行属性的目录树展开功能。
1.1在LIST报表中的现实
1.拖入6个字段,并且对产品系列、产品类型分组,如下图:
2.添加产品系列、产品类型的页眉
3.拆分产品系列、产品类型的单元格
4.将产品系列、和产品类型的汇总拖到产品名称处
5.删除产品系列,产品类型
6.打开列表的锁
7.按住CTRL,拖动数量、单位成本、单价到产品类型,产品系列的页眉处
8.在report page中插入HTML控件,然后拷贝如下代码进去,下面代码主要是定义了两个函数,一个用于目录树的展开与缩进,另一个用于页面初始化时隐藏一些数据,下面代码只支持到2层目录,更详细的含义可参考的在交叉表中实现目录树功能的注释。
代码如下:
function ExpandCollapse( el )
{
var tr = el.parentElement.parentElement;
var tbl = tr.parentElement.parentElement;
var sDisplay = ( el.src.indexOf( "minus" ) == -1 ) ? "" : "none";
var sDisplayReverse = ( el.src.indexOf( "minus" ) == -1 ) ? "none" : "";
el.src = "../pat/images/PropertyGroup_" + ( el.src.indexOf( "minus" ) == -1 ? "minus" : "plus" ) + ".gif";
for ( var i = tr.rowIndex + 1; i < tbl.rows.length; i++ )
{
var trCurrent = tbl.rows( i );
if ( trCurrent.cells( 0 ).firstChild && trCurrent.cells( 0 ).getElementsByTagName( "IMG" ).length )
{
if ( tr.cells(0).style.paddingLeft =="" && trCurrent.cells(0).style.paddingLeft =="20px" )
{
if (el.src.indexOf( "minus" ) == -1 )
{
trCurrent.cells(0).getElementsByTagName("IMG").item(0).src = "../pat/images/PropertyGroup_plus.gif";
}
}
else {
break;
}
}
if ( tr.cells(0).style.paddingLeft =="" && trCurrent.cells(0).style.paddingLeft =="40px" && el.src.indexOf( "minus" ) >0 )
{
trCurrent.style.display = sDisplayReverse;
}
else {
trCurrent.style.display = sDisplay;
}
}
}
function StartHidden(el)
{
var tbl=el.parentElement.parentElement.parentElement.parentElement;
for (var i = 0; i < tbl.rows.length; i++)
{
var trCurrent = tbl.rows(i);
if (trCurrent.cells(0).style.paddingLeft.indexOf("px") > -1)
{
trCurrent.style.display = "none";
}
}
}
9.拖入两个HTML项目插入到产品系列与产品类型单元格前面,修改成查询项目,并修改表达式
产品系列中HTML控件代码如下:
''+ [gosales_goretailers].[产品].[产品系列] + ''
产品类型中HTML控件代码如下:
''+ [gosales_goretailers].[产品].[产品类型] + ''
10.删除掉产品系列和产品类型
11.设置产品类型的填充为左侧20,设置产品名称的填充为左侧40
12.增加列表页脚(注意,这里的HTML控件一定要放入表页脚里面,否则不能实现隐藏数据的功能),并拷贝HTML代码,删除掉列表页脚几个字
代码如下:
13.选择列表,并设置列表每页行数为9999(这样就不用再翻页了)
14.这样一个树状报表就做好了,剩下就是调整颜色,样式的工作了
1.2交叉表实现
在交叉表中现实目录树有两种方法,第一种主要技术是通过UNION等方法首先实现类似分组的功能,然后再利用HTML代码实现,第二种的主要技术是建立在一定的前提下,前提是:在制作报表前已对数据模型进行了特殊的设计。下面介绍第二种方法。
1,在报表中插入的数据如下图所示:
界面中分别插入了三个HTML控件,与在LIST表中位置一样。由于在交叉表中不能对数据进行分组,所以不能采用在LIST表中的实现方法,但是原理是一样的。主要不同之前要对数据模型进行设计。
paddingLeft 属性设置元素的左内边距。
padding 属性定义元素边框与元素内容之间的空间。
1、页头中的HTML代码如下:
/*纵向折叠*/
function ExpandCollapse1( el )
{
if ( el.src.indexOf( "blank" ) >0 ) return;
var tr = el.parentElement.parentElement;
var tbl = tr.parentElement;
/*判断加减号*/
el.src = "../pat/images/PropertyGroup_" + ( el.src.indexOf( "minus" ) == -1 ? "minus" : "plus" ) + ".gif";
/*判断层次*/
/*每一个最外层的if实现一级目录的展开与缩进*/
if(tr.cells(0).style.paddingLeft =="20px")
{
/*”20px“表示是第一级目录。*/
/*循环读取并判断表中每一条记录。*/
for ( var i = tr.rowIndex + 1; i < tbl.rows.length; i++ )
{
var trCurrent=tbl.rows(i);
if(trCurrent.cells(0).style.paddingLeft =="20px")
/*如果是当前目录则退出循环不作处理*/
{break;}
if ( el.src.indexOf( "minus" ) >0 )
/*判断是否图标为“-”号,如果是则有可能是其已经展开了的子目录,但现还不能确定是否是其子目录,有可能是同一级的已展开了的目录*/
if(trCurrent.cells(0).style.paddingLeft =="40px" )
/*判断是否为当前目录的子目录。若是则展开,因为”minus“标记表明已经由”plus“转变过来。即点击了”+“号。*/
{
/*表示可以显示*/
trCurrent.style.display = "";
/*并将”-“号图标变为”+“号以表明目录已展开,方便下次判断*/
trCurrent.cells(0).getElementsByTagName("IMG").item(0).src = "../pat/images/PropertyGroup_plus.gif";
}
/*以下if语句实现展开后缩进*/
if ( el.src.indexOf( "plus" ) >0 )
if((trCurrent.cells(0).style.paddingLeft =="40px" )
||(trCurrent.cells(0).style.paddingLeft =="60px" )
||(trCurrent.cells(0).style.paddingLeft =="80px" ))
{
/*隐藏当前目录下的行记录。*/
trCurrent.style.display = "none";
}
}
}
/*以下模块功能和上面差不多。*/
if(tr.cells(0).style.paddingLeft =="40px")
{
for ( var i = tr.rowIndex + 1; i < tbl.rows.length; i++ )
{
var trCurrent=tbl.rows(i);
if(trCurrent.cells(0).style.paddingLeft =="40px")
{break;}
if ( el.src.indexOf( "minus" ) >0 )
if(trCurrent.cells(0).style.paddingLeft =="60px" )
{
trCurrent.style.display = "";
trCurrent.cells(0).getElementsByTagName("IMG").item(0).src = "../pat/images/PropertyGroup_plus.gif";
}
if ( el.src.indexOf( "plus" ) >0 )
if((trCurrent.cells(0).style.paddingLeft =="60px" )
||(trCurrent.cells(0).style.paddingLeft =="80px" ))
{trCurrent.style.display = "none";}
}
}
if(tr.cells(0).style.paddingLeft =="60px")
{
for ( var i = tr.rowIndex + 1; i < tbl.rows.length; i++ )
{
var trCurrent=tbl.rows(i);
if(trCurrent.cells(0).style.paddingLeft =="60px")
{break;}
if ( el.src.indexOf( "minus" ) >0 )
if(trCurrent.cells(0).style.paddingLeft =="80px" )
{
trCurrent.style.display = "";
}
if ( el.src.indexOf( "plus" ) >0 )
if(trCurrent.cells(0).style.paddingLeft =="80px" )
{trCurrent.style.display = "none";}
}
}
}
/*该函数实现初始化页面时隐藏一些记录。*/
function StartHidden(el)
{
var tbl=el.previousSibling;
var trCurrent2=tbl.rows(0);
var subnum;
var i,j,jj;
/*判断层次,*/
/*若要显示总数,则消除下面这条语句的注释。*/
/*trCurrent2.cells(trCurrent2.cells.length-1).children(0).innerText="合计";*/
for(var j=1;j if((trCurrent2.cells(j).children(0).innerText.indexOf(" ")==0) &&(trCurrent2.cells(j).children(0).innerText.indexOf(" ")!=0)){ trCurrent2.cells(j).style.paddingTop="10px"; continue; } if((trCurrent2.cells(j).children(0).innerText.indexOf(" ")==0) &&(trCurrent2.cells(j).children(0).innerText.indexOf(" ")!=0)){ trCurrent2.cells(j).style.paddingTop="20px"; continue; } } /*纵向折叠*/ /*若要显示总数,则消除下面这条语句的注释。*/ var trCurrent1; /*tbl.rows(1).cells(0).children(1).innerText="合计";*/ tbl.rows(1).cells(0).getElementsByTagName("IMG").item(0).src = "../pat/images/blank.gif"; /*从表中第二条记录开始判断子目录是否展开了,若展开了则隐藏。第一条为合计汇总。*/ for ( i = 2; i < tbl.rows.length; i++ ){ trCurrent1=tbl.rows(i); if((trCurrent1.cells(0).children(1).innerText.indexOf(" ")==0) &&(trCurrent1.cells(0).children(1).innerText.indexOf(" ")!=0)){ trCurrent1.cells(0).style.paddingLeft ="20px"; /*trCurrent1.style.display = "none";*/ continue; } if((trCurrent1.cells(0).children(1).innerText.indexOf(" ")==0) &&(trCurrent1.cells(0).children(1).innerText.indexOf(" ")!=0)){ trCurrent1.cells(0).style.paddingLeft ="40px"; trCurrent1.style.display = "none"; continue; } if((trCurrent1.cells(0).children(1).innerText.indexOf(" ")==0) &&(trCurrent1.cells(0).children(1).innerText.indexOf(" ")!=0)){ trCurrent1.cells(0).style.paddingLeft ="60px"; trCurrent1.style.display = "none"; } if((trCurrent1.cells(0).children(1).innerText.indexOf(" ")==0) &&(trCurrent1.cells(0).children(1).innerText.indexOf(" ")!=0)){ trCurrent1.cells(0).style.paddingLeft ="80px"; trCurrent1.style.display = "none"; trCurrent1.cells(0).getElementsByTagName("IMG").item(0).src = "../pat/images/blank.gif"; } } } 2,表中(即中间)的HTML代码如下: '' 2、最后的HTML代码如下: 2报表开发技巧整理 2.1树形列表 要点:首先通过对数据项进行分组实现将各层次的数据项放在同一列中,子层被嵌套在父层中,然后对各层都设置一个标记以区别于其它层的数据,这里通过在数据项前面的缩进距离作为标记,然后利用在页面中嵌入脚本代码控件数据的展开显示和隐藏,其实当报表刚打开时,报表的所有数据包括父级与子级的数据都显示出来,只不过是通过代码将其隐藏而已,当用户单击展开目录按钮时代码通过一个循环语句显示出某一级别的数据,而其中一个终止循环的条件就是判定某一行的前面缩进的距离,而缩进目录的原理也是类似。(具体制作过程可参考上面) 2.2树形交叉表 要点:由于在交叉表中不能像LIST表中一样实现分组,所以要通过利用层次各级数据项建立一种数据联接关系,目的是将父级与子级目录的内容通过嵌套显示出来,效果其实与分组一样,所以可以在数据模型定义的时候对数据的格式进行特殊处理,例如不同层次的数据前面可以插入不同长度的空格,以识别其它层次,那么这样在代码处理方面就可以类似在列表中一样操作。其实当报表刚打开时,报表的所有数据包括父级与子级的数据显示出来,只不过是通过代码将其隐藏而已,另外,在各子级目录的开始可通过设置不同空格的长度而让代码识别内容所在的级别。当用户单击展开目录按钮时代码通过一个循环语句显示出某一级别的数据,而其中一个终止循环的条件就是判定某一行的前面缩进的距离,而缩进目录的原理也是类似。(具体制作过程可参考上面) 2.3科目层次选择 特点:科目层次选择 功能:选择科目层次,然后下面自动出现该科目的所有成员列表框供选择 分摊表,科目按层次显示 1、下拉框选择显示的层次,保存在参数 p_level 中(使用静态成员,如1、 2、3……) 2、在“条件资源管理器”中定义条件变量,读取的是参数 p_level 3、对于多个科目层次,使用多个列表框,每个列表框设置其生成变量(Render Variable),对应条件变量中的具体值(即选择该值则生成该列表框) 4、层次选择下拉框要自动提交;列表框要cascade到 p_level 5、Query中使用科目时,需要通过case来控制显示的层,如: CASE ?科目层次? WHEN '1' THEN caption([erpfdb].[CCB_COGNOS_FTACCT_DV1].[CCB_COGNOS_FTACCT_DV].[ACCT1_DESC]) WHEN '2' THEN caption([erpfdb].[CCB_COGNOS_FTACCT_DV1].[CCB_COGNOS_FTACCT_DV].[ACCT2_DESC]) WHEN '3' THEN caption([erpfdb].[CCB_COGNOS_FTACCT_DV1].[CCB_COGNOS_FTACCT_DV].[ACCT3_DESC]) END 6、而Query中的条件,则需要给每个供选择的层次的科目都添加条件,条件使用“可选(optional)”即可 2.4多列树状折叠 特点:多列折叠 示例报表:分摊表3 要点: 第一列只在所在行有效,所以从如图中所示,“行政条线”跟“产品合计”在同一行上,所以“行政条线”对象的表示方法为“rows(i).cells(0)”,即属于第0个cell,而“产品合计”则属于第1个cell(“rows(i).cells(1)”); 下来一行,“行政条线”列就不起效了,所以“默认2”就属于第1列了,表示为“rows(i+1).cells(0)”。 在js脚本上使用的技巧是将“行政条线”列退格5px,然后进行判断 if(trCurrent1.cells(0).style.paddingLeft=="5px"){ /*如果是“行政条线”列*/ trCurrent1.cells(1).getElementsByTagName("IMG").item(0).src = "../pat/images/blank.gif"; } /*取cells(1)对象*/ else{ if((trCurrent1.cells(0).children(1).innerText.indexOf(" ")==0) /*否则取cells(0)对象*/ …… 其他跟上述折叠报表技巧类似 2.5全部展开、折叠功能 效果如下图:报表上添加了“全部展开”按钮,点击可以将所有折叠的项都展开; 1、修改原来的js代码: /*纵向折叠*/ var tbl; function allWrap(el) { if(el.value=="全部展开"){ for ( i = 2; i < tbl.rows.length; i++ ){ tbl.rows(i).style.display = ""; if(tbl.rows(i).cells(0).style.paddingLeft !="80px") tbl.rows(i).cells(0).getElementsByTagName("IMG").item(0).src = "../pat/images/PropertyGroup_minus.gif"; } el.value="全部折叠"; return; } if(el.value=="全部折叠"){ for ( i = 2; i < tbl.rows.length; i++ ){ if(tbl.rows(i).cells(0).style.paddingLeft !="20px") tbl.rows(i).style.display = "none"; if(tbl.rows(i).cells(0).style.paddingLeft !="80px") tbl.rows(i).cells(0).getElementsByTagName("IMG").item(0).src = "../pat/images/PropertyGroup_plus.gif"; } el.value="全部展开"; } } function ExpandCollapse1( el ) { if ( el.src.indexOf( "blank" ) >0 ) return; var tr = el.parentElement.parentElement; /*var tbl = tr.parentElement;*/ /*判断加减号*/ el.src = "../pat/images/PropertyGroup_" + ( el.src.indexOf( "minus" ) == -1 ? "minus" : "plus" ) + ".gif"; /*判断层次*/ if(tr.cells(0).style.paddingLeft =="20px") { for ( var i = tr.rowIndex + 1; i < tbl.rows.length; i++ ) { var trCurrent=tbl.rows(i); if(trCurrent.cells(0).style.paddingLeft =="20px") {break;} if ( el.src.indexOf( "minus" ) >0 ) if(trCurrent.cells(0).style.paddingLeft =="40px" ) { trCurrent.style.display = ""; trCurrent.cells(0).getElementsByTagName("IMG").item(0).src = "../pat/images/PropertyGroup_plus.gif"; } if ( el.src.indexOf( "plus" ) >0 ) if((trCurrent.cells(0).style.paddingLeft =="40px" ) ||(trCurrent.cells(0).style.paddingLeft =="60px" ) ||(trCurrent.cells(0).style.paddingLeft =="80px" )) {trCurrent.style.display = "none";} } } if(tr.cells(0).style.paddingLeft =="40px") { for ( var i = tr.rowIndex + 1; i < tbl.rows.length; i++ ) { var trCurrent=tbl.rows(i); if(trCurrent.cells(0).style.paddingLeft =="40px") {break;} if ( el.src.indexOf( "minus" ) >0 ) if(trCurrent.cells(0).style.paddingLeft =="60px" ) { trCurrent.style.display = ""; trCurrent.cells(0).getElementsByTagName("IMG").item(0).src = "../pat/images/PropertyGroup_plus.gif"; } if ( el.src.indexOf( "plus" ) >0 ) if((trCurrent.cells(0).style.paddingLeft =="60px" ) ||(trCurrent.cells(0).style.paddingLeft =="80px" )) {trCurrent.style.display = "none";} } } if(tr.cells(0).style.paddingLeft =="60px") { for ( var i = tr.rowIndex + 1; i < tbl.rows.length; i++ ) { var trCurrent=tbl.rows(i); if(trCurrent.cells(0).style.paddingLeft =="60px") {break;} if ( el.src.indexOf( "minus" ) >0 ) if(trCurrent.cells(0).style.paddingLeft =="80px" ) { trCurrent.style.display = ""; } if ( el.src.indexOf( "plus" ) >0 ) if(trCurrent.cells(0).style.paddingLeft =="80px" ) {trCurrent.style.display = "none";} } } } function StartHidden(el) { /*var*/ tbl=el.previousSibling; var trCurrent2=tbl.rows(0); var subnum; var i,j,jj; Cognos报表—知识整理 一、提示页自动加载 1、功能需求背景 华中电网概况报表首页需要有日期参数,但是每次进入首页时出现日期选择框影响美观,所以为其增加提示页面,但根据要求不能增加提示页面,所以设计出提示页面自动加载。通俗的讲就比如:出现提示页面,电脑自动点击确定进入主页面…… 2、功能实现方法 步骤1: 新建提示页面,新页面中内容包括:onload项目、完成按钮、日期提示框以及针对提示框的html项目。如下图1 图1 步骤2: Onload项目中函数:详见图1 cognos报表知识整理
二、进入页面后自动刷新一次 1、功能需求背景 电网概况报表电厂容量分析主页面中,需要自动根据日期刷新一次页面(具体原因参见三、特殊的日期过滤) 2、功能实现方法 步骤1: Onload项目加载函数,如图2 图2 步骤2: Js中函数新加一行代码,如图3 图3
3、可参考报表 电网概况报表>>1.电厂容量分析 三、特殊的日期过滤 1、功能需求背景 电网概况中发电情况包括水、火、风三种发电方式,在数据库中体现即为水(火、风)电机组管理(参数)表。根据用户要求,需要对全网水(火、风)当年新投机组容量等进行数据统计, 2、设计思想 1)将水、火、风机组管理表分别对应查询中取相同数据项,为U联做准备。 2)在三个查询中新建“投运年”数据项,取得机组投运年份。表达式:substr(【投运日期】,1,4) 3)将三个查询进行U联,给U联后的查询设置过滤条件,如图4 图4 3、出现问题分析 根据2、设计思想中进行操作,报表验证报错,不能对substr进行集操作,经查询得知,dm 数据库不支持在两层(原层和U联层)查询中同时使用substr。 4、新的解决方法 思路如下图:
1COGNOS的使用 1.1模型定义 1,打开Frame Manager程序,如下图: 2,新建一个项目,建完后,打开该项目,如下图:
3,在界面左边中选择“Packages”,然后单击右键新建一个包。按照提示一步步做,其中有一步是从数据库的表选所要用到的表,打勾为选用。 4,点击”Diagram”显示表,但表之间还没有建立联接关系,通过建立各表关系后如下图
5,然后将该包发布,点击右键该包选择“Publish Package”将其发布。 1.2模型的物理和逻辑定义 1,模型定义的规范:将模型分为2个部分,分别为物理层和逻辑层,物理层为从数据源引入表的物理定义和连接关系,逻辑层为业务视角下的逻辑定义。 2,物理层的建立:根据数据分析,设计模型中需创建的物理表,以便尽可能的提高查询语句的运行效率(比较理想的结构是星形结构,一个中间表和多个物理维表)。 在根名字空间(和数据源同名)下,建立一个名为物理层的目录,在物理层文件夹下执行Run Metedate Wizard将数据源中相关的物理表引入这个目录,然后将这些表建立连接关系,建议不要有Orphan表。如下图:
3,逻辑层的定义:在根名字空间下,建立一个名为逻辑层的目录,在逻辑层文件夹下生成Query Subject,Query Subject的字段都是根据业务逻辑从物理层从引入,建议字段名都为中文。逻辑层中的表为事实表和维表的结构,在事实表中包含维度的编码值和指标的值,维表中包括每个维度上编码值和其名称的对应关系。也可以根据需要建立Regular Dimension(3.4说明),在逻辑层中不要建立逻辑表之间的关系。如下图:
Cognos 8开发之Cube V1.0
知识成果简要信息表
第一章 Cognos简介 1.概述 Cognos展现的报表基于统一的元数据模型。统一的元数据模型为应用提供了统一、一致的视图。用户可以在浏览器中自定义报表,格式灵活,元素丰富,而且可以通过Query Studio进行即席的开放式查询。Cognos还具有独特的穿透钻取(roll up和drill down)、切片(slice)和切块(dice)、以及旋转(pivot)等功能,使分析人员、管理人员或执行人员能够从多角度对信息进行快速、一致、交互地存取,从而获得对数据的更深入了解,有效地将各种相关的信息关联起来,使用户在分析汇总数据的同时能够深入到自己感兴趣的细节数据中,以便更全面地了解情况,做出正确决策。 Cognos强大的报表制作和展示功能能够制作/展示任何形式的报表,其纯粹的Web界面使用方式又使得部署成本和管理成本降到最低。同时Cognos还可以同数据挖掘工具、统计分析工具配合使用,增强决策分析功能。进行合作,推动以AIX 技术为中心的创新,同时开发、测试和使用各种用于支持AIX 操作系统的新应用和中间件。 2 . Cognos 8 的功能组件介绍: Cognos 8 的功能组件分为服务器端和客户端两部分,服务器端是基于SOA构架的Cognos 8服务,以Web Service的方式接受和处理用户请求;客户端程序是开发人员使用,用于构建CUBE 和Cognos 8元数据的工具,它们分别是:TransFormer 和FrameWork。用户制作、浏览报表和业务分析都是基于浏览器的,不需要安装插件或客户端,在浏览器端,用户可以访问以下组件:Report Studio 、Query Studio 、Analysis Studio。同时用户也可以基于Cognos提供的SDK开发应用直接访问Cognos 8 服务。 Cognos 8产品结构图:
1实现行属性的目录树展开功能。 1.1在LIST报表中的现实 1.拖入6个字段,并且对产品系列、产品类型分组,如下图: 2.添加产品系列、产品类型的页眉
3.拆分产品系列、产品类型的单元格 4.将产品系列、和产品类型的汇总拖到产品名称处
5.删除产品系列,产品类型 6.打开列表的锁
7.按住CTRL,拖动数量、单位成本、单价到产品类型,产品系列的页眉处 8.在report page中插入HTML控件,然后拷贝如下代码进去,下面代码主要是定义了两个函数,一个用于目录树的展开与缩进,另一个用于页面初始化时隐藏一些数据,下面代码只支持到2层目录,更详细的含义可参考的在交叉表中实现目录树功能的注释。 代码如下: 8.拖入一个HTML项目插入到运营商单元格前面,修改成数据项,并修改表达式 运营商中HTML控件代码如下: ''+ [orc82].[D_OPERATIONROLES].[运营商所在地] + '' 9.删除掉运营商所在地 10.设置运营商的填充为左侧20 11.增加图片 增加树形的图片,空白图片到cognos相应的图片目录 12. 增加列表页脚 (注意,这里的HTML控件一定要放入表页脚里面,否则不能实现隐藏数据的功能),并拷贝HTML代码,删除掉列表页脚几个字 代码如下: