IBM Cognos 最佳实践: 在 Report Studio Prompt 中使用相对时间类别

文档性质:技巧或技术;产品:IBM Cognos BI;关注领域:报表

本指南将演示如何在 Report Studio Prompt 中使用 Transformer 相对时间类别的方法。该指南介绍如何创建默认值为相对时间类别的提示,同时允许用户使用任何其他时间类别。本文所显示的方法没有使用任何 Java 脚本。

Marc Reed, 首席顾问, IBM

Marc Reed 是 UK Cognos BI 团队的首席顾问。他从事 Cognos BI 软件开发工作已经 10 多年时间了。在这段时间里,他曾经为许多客户(各个行业)的众多项目提供帮助,范围涉及故障排除到大型企业应用部署。这么多年来,Marc 开发过许多最佳实践方法,并且将它们共享给了许多 BI 开发者和咨询师。



2012 年 4 月 16 日

免费下载:IBM® Cognos® Express V9.5 或者 Cognos® 8 Business Intelligence Developer Edition V8.4 试用版
下载更多的 IBM 软件试用版,并加入 IBM 软件下载与技术交流群组,参与在线交流。

简介

目的

本指南将演示在 Report Studio Prompt 中使用 Transformer 的相对时间类别的方法。该指南介绍如何创建默认值为相对时间类别的提示,同时允许用户使用任何其他时间类别。本文所显示的方法没有使用任何 Java 脚本。

适用性

本指南适用于 IBM Cognos Report Studio 8 及其更高版本。

例外条款

本技术仅适用于拥有相对时间类别的 OLAP 源。


场景

用户能够在通过 Analysis Studio 或 Query Studio 创建自编写报表时使用相对时间类别。专业的报表创作者常常希望在他们在 Report Studio 内创建的报表中提供类似的功能,使用户能够为任何选定的时间类别或一种相对时间类别运行报表。

通过提供对相对时间类别的访问能力,用户交将拥有使用专业编写报表的更好体验:

  • 当计划报表时。
    例如,无需考虑月更改而时常更改提示答案。
  • 当运行报表时。
    可将提示默认设置为相对时间类别,例如默认为当前月。

本文演示的技术展示了如何在不使用 Java 脚本的情况下提供此功能。该技术将使用一种典型的 powercube,其中包含当前月相对时间类别。尽管该技术演示了当前月,但也可适用于任何相对时间类别或相同提示中的多个相对时间类别。

此处展示了两种技术。第一种是一个简单的报表,其中使用相对时间来过滤或切片报表。在第二种技术中,在报表中结合使用了相对时间类别和其他相对时间函数。


使用相对时间类别来切片或过滤

本节介绍如何提供一个提示,允许用户过滤当前月或时间维度中的任何其他月份。

在整个示例中,我们将使用基于 Great Outdoor Sales 多维数据集的 Great Outdoors Sales(多维数据集)示例包。

图 1:Great Outdoors Sales(多维数据集)元数据树
图 1:Great Outdoors Sales(多维数据集)元数据树

在此多维数据集的时间维度内,我们可以看到:

  • 有一个具有 Month 级别的 Years 层次结构。
  • 有一个 Current Month 层次结构 。它拥有一个包含子元素 2007/Jul 的 Current Month 成员。该层次结构具有一个 Current Month 级别和另一个 Month 级别。

以下是要求我们生成的一个示例报表:

图 2:IBM Cognos 示例交叉表报表
图 2:IBM Cognos 示例交叉表报表

报表包含:

  • Revenue 度量指标。
  • Product Line 行。
  • Retailer type 列。

该报表作者想要为用户提供为任何选定的月份运行报表的能力,并且还想允许用户选择当前月。我们将生成此报表。

首先,我们生成基本的交叉表。

  1. 将 Great Outdoor Sales powercube 用作一个包打开 Report Studio。
  2. 创建一个新的交叉表报表。
  3. 将 revenue 拖到交叉表的 measures 区域。
  4. 将 Product Line 级别从 Products 维度拖到行上。
  5. 将 Retailer type 级别从 Retailers 维度拖到列上。

报表应该是这样:

图 3:Report Studio 中的 IBM cognos 示例报表
图 3:Report Studio 中的 IBM cognos 示例报表

现在我们将在报表中添加提示,以允许用户对一个月进行过滤。我们将此提示添加到报表页本身上,以提供一个更加动态的报表。

  1. 删除包含页标题文本的块 (Block)。
  2. 将 Value 提示从 Insertable Objects 工具箱中拖到页眉。将会启动 Value 提示的提示向导。
  3. 将 Create a new parameter 更改为 ChosenMonth,如图 4 所示。
    图 4:提示向导:参数
    图 4:提示向导:参数
  4. 按下 Next
  5. 取消选择 “Create a paramterized filter”。我们将在后面创建自己的切片器。
  6. 按下 Next

将 Create new query 的 name 更改为 “Prompt month”。

最好的做法是标记我们的提示查询,以便以下报表开发人员可轻松区分数据查询和提示查询。

Value to use 中,我们将使用来自 Years 维度的 Years 层次结构的 Month Level。

图 5:使用 Name 和 Values 来使用所填充的值的提示向导
图 5:使用 Name 和 Values 来使用所填充的值的提示向导

提示向导完成后,您的交叉表报表现在应该在报表页眉中显示 value 提示,如图 6 所示。

图 6:Report Studio 中具有 Value 提示的示例报表
图 6:Report Studio 中具有 Value 提示的示例报表

我们可以在页眉中看到新的 value 提示。我们将通过自动提交提示,使报表更加动态。然后将添加当前月作为提示的静态成员。

  1. 在 Value 提示的属性上,将 Auto-Submit 属性从 No 更改为 Yes。
    图 7:auto-submit 设置为 Yes 的 Value 提示属性
    图 7:auto-submit 设置为 Yes 的 Value 提示属性
  2. 在提示的 Static Choices 属性上,添加以下值:
    显示值 “Current Month”。
    使用值 “[great_outdoors_sales_en].[Years].[Current Month].[Current Month]->:[PC].[@MEMBER].[Current Month]”。这是当前月相对时间类别的 MUN(成员唯一名称)。
    图 8:Value 提示属性:静态选择
    图 8:Value 提示属性:静态选择
  3. 设置提示的 Default Selection 属性。
    图 9:Value 提示属性:默认选择
    图 9:Value 提示属性:默认选择
    我们想要把报表默认设置为当前月,所以我们再次使用了上面第 2 步中使用的当前月相对时间类别的 MUN。

我们现在需要按所选的月份值对我们的主要数据查询进行切片。

在 Query 1 中,在切片器窗格添加一个 Slicer Member Set,表达式编辑器将打开。通常,您会使用一个与下列相似的切片器定义:

[great_outdoors_sales_en].[Years].[Years].[Month]-> ?ChosenMonth?

但是,我们不打算使用此语法。此语法假设知道我们想要的过滤级别。我们希望报表能够在两种不同级别上进行过滤。尽管对于正常月份,我们希望在级别 [great_outdoors_sales_en].[Years].[Years].[Month] 上进行过滤,对于相对时间过滤器,我们希望在级别 [great_outdoors_sales_en].[Years].[Current Month].[Current Month] 上进行过滤。显然,传统的过滤器语法不允许这么做。

因此,我们将使用一个宏。在表达式编辑器中,键入:

#prompt( 'ChosenMonth', 'MUN', '[great_outdoors_sales_en].[Years].
[Current Month].[Current Month]->:[PC].[@MEMBER].[Current Month]' ) #
  • ChosenMonth 是该参数的名称。
  • MUN 是提示的数据类型。
  • [great_outdoors_sales_en].[Years].[Current Month].[Current Month]->:[PC].[@MEMBER].[Current Month] 是提示的默认值的 MUN (成员唯一名称)。对于我们的报表,这是当前月相对时间类别的 MUN。
图 10:切片器成员表达式编辑器和表达式
图 10:切片器成员表达式编辑器和表达式

当我们首次运行报表时,会看到提示默认设置为 “Current Month”。我们现在可以使用更改为任何其他月份或 Current Month 的提示,如图 11 中所示:

图 11:Cognos Report Studio Report Viewer
图 11:Cognos Report Studio Report Viewer

提示相对时间成员或普通成员和使用相对时间函数

当报表作者想要切片或过滤一个月份时,就可用前面演示的技术。而当报表作者需要在所选月份上执行其他相对时间功能时,就无法使用该技术。

例如,让我们想想下面的交叉表报表,它拥有一个 Revenue 行以及两个分别为所选月份和上一个月的列。

这里,用户想要选择一个月份并显示上一个月。这是一个典型的月环比比较报表,也是一种常见需求。如果在这里重复第一种技术,我们将发现它并不适用。为什么?为了计算 “PreviousMonth”,使用 PrevMember 函数:

prevMember( [ChosenMonth] )

如果用户已从级别成员 [great_outdoors_sales_en].[Years].[Years].[Month] 中选择了一个提示答案,此函数将生效,但如果用户已选择成员 [great_outdoors_sales_en].[Years].[Current Month].[Current Month]->:[PC].[@MEMBER].[Current Month],此函数将不生效。相对时间成员没有上一个成员,所以该函数将不会返回想要的输出。

使用相对月份提示创建这种类型的报表稍微复杂一点。

首先要解决问题是如何将 Current Month 成员转换为 [great_outdoors_sales_en].[Years].[Years].[Month] 级别的成员,以便使相对时间函数生效。

如果检查时间维度,我们可以看到 Current Month 成员有一个子月份。在 Great Outdoors Sales(多维数据集)包中,我们可以看到 Current Month 成员含有一个子月份 2007/Jul。在 Current Month 成员上使用维度函数 FirstChild ,会向我们返回 2007/Jul 成员。

但是,这个成员与 Months 级别中的 2007/Jul 成员并不是同一个。让我们对比一下两个 MUN,可以发现:

第一个是来自 Current Month 层次结构的 2007/Jul:

[great_outdoors_sales_en].[Years].[CurrentMonth].[Month]->:[PC].[@MEMBER].[20070701-20070731]

现在这个来自 Years 层次结构的 2007/Jul:

[great_outdoors_sales_en].[Years].[Years].[Month]->:[PC].[@MEMBER].[20070701-20070731]

我们也可以在时间维度中看到,Current Month 下的 2007/Jul 没有同级成员,所以 PrevMember 函数不会返回想要的结果。

有一个很方便的维度函数,它可以使我们轻松地返回一个成员在不同层次结构中的相应成员,这个就是 linkMember 函数。

linkmember(firstchild([great_outdoors_sales_en].[Years].
[Current Month].[Current Month]->:[PC].[@MEMBER].[Current Month] ) ,
 [great_outdoors_sales_en].[Years].[Years].[Month] )

将 PrevMember 和 LinkMember 函数链接到一起,我们可以将相对 Current Month 成员转换为一个真实月份,然后再执行我们的相对时间函数。

从第一个示例中,我们的提示返回了 Current Month 成员或来自月份级别的一个成员。前面创建的函数将不适用于来自月份级别的成员,原因在 FirstChild 上。

这些函数仅适用于 Current Month 成员。如果我们在来自提示的任何其他值(也就是来自 Month 级别的值)上尝试并执行这些函数,那么我们不会获得想要的结果,原因在 FirstLevel 函数上。

我们将使用 If-then-else 来确定我们的用户是否选择了 Current Month。如果选择了 Current Month,我们将调用基于 linkMember 的函数。如果没有选择 Current Month,我们将使用用户已选择的月份。If 语句将如下所示:

if (chosenMonth = 'Current Month')
then ( linkmember based function)
else (chosenMonth)

但是,这个 If 语句有问题。来自 If 语句的两个结果都必须来自相同的层次结构。乍看起来,这个 If 语句确实是这样的。其实不然。如果用户选择 Current Month,链接成员是来自 Years 层次结构的成员,而 chosenMonth 是来自 Current Month 层次结构的成员。我们通过不让提示返回成员来解决此问题!

首先将所有这些部分放至一个示例报表中。

  1. 在 Report Studio 中创建一个基于 Great Outdoors Sales(多维数据集)的新交叉表报表。我们将首先构建提示。
  2. 删除包含页眉的标题文本的块 (Block)。
  3. 将 Value 提示从 Insertable Objects 工具箱中拖到页眉中。会启动 Value 提示的提示向导。创建一个名为 “ChosenMonthEx2” 的新参数。
    图 12:提示向导:创建一个新参数
    图 12:提示向导:创建一个新参数
    按下 Next
  4. 取消选择 “Create a paramterized filter”,并单击 next
  5. 选择 “Create a new query”。将查询命名为 “Prompt Month Ex2”。
    图 13:提示向导:创建新查询
    图 13:提示向导:创建新查询
    单击 Finish。现在将进一步细化提示查询。
  6. 从 Query Explorer 中,访问 Prompt Month Ex2 查询,在查询数据项中添加一个数据项。表达式定义使用:
    caption ([great_outdoors_sales_en].[Years].[Years].[Month] )

    将数据项命名为 Month Caption。
  7. 在查询数据项中添加另一个数据项。表达式定义使用:
    roleValue ('_memberUniqueName', [great_outdoors_sales_en].[Years].[Years].[Month] )

    将数据项命名为 Month MUN。

返回至报表页面以完成 Value 提示的定义。选择 Value 提示。

  1. Use value 中,选择 “Month MUN”。
  2. Display value 中,选择 “Month Caption”。
  3. Auto-Submit 属性设置为 “Yes”。
  4. 输入 Static Choices
    图 14:Value 提示属性:静态选择框
    图 14:Value 提示属性:静态选择框
    输入一个静态选择 “Current”。
  5. 输入默认选择 “Current”。
    图 15:Value 提示属性:默认选择框
    图 15:Value 提示属性:默认选择框

我们现在将在 Query 中操作,而不是直接在交叉表上操作。进入交叉表所基于的查询中。

  1. 将 Revenue 度量值添加到查询中。
  2. 将一个数据项添加到查询中。表达式定义为:
    linkmember(  firstchild(  [great_outdoors_sales_en].[Years].
    [Current Month].[Current Month]->:[PC].[@MEMBER].[Current Month] ),
    [great_outdoors_sales_en].[Years].[Years].[Month])
  3. 数据项将称为 “Current Month as Real Month”。这为我们提供 Current Month 的一个数据项作为 Years 层次结构的成员。
  4. 将另一个数据项添加到查询中。该数据项名为 “ChosenMonth”。该数据项的表达式定义为:
    if ( ?ChosenMonthEx2?= 'Current'  ) 
     then (  [Current Month as Real Month] )
     else (   #substitute('Current',
     '[great_outdoors_sales_en].[Years].[Years].[Month]->:
         [PC].[@MEMBER].[20040101-20040131]', 
     prompt( 'ChosenMonthEx2','token','Current') ) # )

    看起来像是一个复杂的语句,值得解释一下子句的 Else 部分。我们再次使用了 IBM Cognos 宏语法。ChosenMonth 提示将返回一个字符串。
    如果字符串为 “Current”,那么替换函数会将该字符串替换为
    '[great_outdoors_sales_en].[Years].[Years].[Month]->:
     [PC].[@MEMBER].[20040101-20040131]'

    这只是来自 Year 层次结构的 Months 级别的一个成员。但是,我们知道,如果 ChosenMonth 为 “Current Month”,则使用了 If 子句的第一部分,所以从不会实际使用该成员。
    如果 ChosenMonthEx2 提示不是 “Current”,那么该宏将简单地返回提示,这恰好是所选月份的 MUN。
    这个复杂的宏可确保无论用户作何选择(Current 还是真实的月份),都会返回 Year 层次结构的 Month 级别的成员。我们现在有一个 If 条件,它始终返回相同层次结构级别的成员。
  5. 将另一个数据项添加到查询中。该数据项名为 PreviousMonth。该数据项的表达式定义为:
    prevMember([ChosenMonth])

返回到交叉表页面。

从 Insertable data items 选项卡:

  1. 将 Revenue 数据项拖到行上。
  2. 将 ChosenMonth 数据项拖到列上。
  3. 将 PreviousMonth 数据项拖到 ChosenMonth 旁边的列上。

如果现在运行报表,我们可以看到,它将提示默认设置为 Current Month。报表上的交叉表向我们显示了所选月份 2007/Jul 和 Previous Month。如果我们从提示中选择另一个月份,报表仍然有效。


下载

描述名字大小
本文的示例脚本RelativeTimeInPrompts.zip245KB

参考资料

学习

获得产品和技术

讨论

  • 参与 developerWorks 博客 并加入 developerWorks 中文社区,developerWorks 社区是一个面向全球 IT 专业人员,可以提供博客、书签、wiki、群组、联系、共享和协作等社区功能的专业社交网络社区。

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Information Management
ArticleID=810311
ArticleTitle=IBM Cognos 最佳实践: 在 Report Studio Prompt 中使用相对时间类别
publish-date=04162012