Oracle Essbase入门系列(三)

数据库计算

Essbase中单元格的数据可以是外部输入或计算而得,单元格因而分为输入单元格和计算单元格。计算单元格的计算方法可以通过大纲中维度成员的合并计算符和公式脚本定义,此称为大纲计算定义。

例1张大明家在上海市区和浦东各有一套房,1月5日时张大明收到市区房子的水费和电费账单,然后缴付;张大明的妻子王翠花同时也收到并缴付了浦东房子的账单。两地的水电单价和用量均不一样。

在HomeFinancial应用程序中,对应的单元格录入数据如下表的数据。表中,灰底的单元格是输入单元格,其中的数据是手工录入;而公共事业费,作为父级成员应由其子代成员作合并计算,所以对应表中黑底的单元格就是计算单元格。

Essbase中子代成员合并到父级成员的计算可以通过合并计算符设置。在维库编辑HomeFinancial应用程序。选中维度结构中任何非1代成员,都有一项【Consolidation】属性,这就是合并计算符。双击此属性进行编辑,如下图,在下拉列表中有7种合并计算符供选择,下表列出了这些计算符的含义。创建成员时,默认的合并计算符是加法“+”。

在例1中,公共事业费需要按如下公式进行合并:

公共事业费 = 电单价 × 电用量 + 水单价 × 水用量

那么是否将公共事业费子成员的合并计算符改成下图设置就够了呢?图中成员名称后是合并计算符。

此思路是对的,但做法在Essbase中行不通。原因是Essbase中同级成员并非按数学中先乘除后加减的顺序计算,而是单纯按照成员排序顺序计算。如果按图中那样,公共事业费的计算就变成了:

公共事业费 = (电单价 × 电用量 + 水单价) × 水用量

要纠正这个错误有两种方法。其一是在维度结构上做文章,按下图重新设计维度结构,得到正确的计算顺序如下:

第二种方法是使用成员公式。通过成员公式可以编写脚本定义计算,成员公式会覆盖子代成员的合并计算。而且Essbase提供了丰富的计算函数和完善的脚本语法,在成员公式中能实现各种复杂的计算。

在维度结构中选择公共事业费成员,修改它的【Member Formula(BSO)】属性,在公式编辑器中输入脚本:

= "水单价" * "水用量" + "电单价" * "电用量";

如果要编写复杂的脚本,推荐使用EAS Console。EAS Console中的公式编辑器更强大,可以提示计算函数和运算符,可以帮助验证脚本语法。Essbase的计算函数和语法可参看官方手册。

有了成员公式,子代成员的合并计算符就没有意义了。出于严谨性考虑,可以将子代成员的合并计算符设为“~”,即子成员不参与合并计算。

回到例1最初的那个表格,横轴和纵轴分别是两个维度,仔细观察表中的计算单元格,会发现存在两个疑问。

第一个疑问,表中两个维度,代表了两种计算方向,这两种方向的计算结果是不一致的。具体来说,最右下角的单元格,代表的是整个家庭公共事业费的合计。如按箭头方向①,即沿Account维度计算,根据成员公式,结果是584.5;反之,按箭头方向②,即沿Home维度计算,根据合并计算符,结果是300.5。

显然第二种计算方向是正确的,那么如何让Essbase按我们希望的方式计算呢?答案是控制Essbase的计算顺序。就是要先计算Account维度,得到表中最下面一行单元格的数据,然后计算Home维度,得到表中最右边一列单元格的数据。后计算的结果会覆盖前面计算的结果,即是说会以300.5作为右下角单元格的最终计算结果。Essbase根据如下条件判断维度间的计算顺序。

  • 如果大纲中同时包含Account和Time两种类型的维度,且Account维中使用到成员公式,计算顺序为:
    1. Account维度
    2. Time维度
    3. 密集维度,根据在大纲中排序计算
    4. 稀疏维度,根据在大纲中排序计算
  • 其他情况下,计算顺序为:
    1. 密集维度,根据在大纲中排序计算
    2. 稀疏维度,根据在大纲中排序计算

因此,维度的存储类型和在大纲中的排序是控制计算顺序的两个重要手段。如HomeFinancial按照Account > Year > Home > Scenario的顺序计算,这样就能保证产生正确的计算结果。如果不清楚数据的计算顺序,可以在执行计算命令后,从Essbase的日志文件中查看。

此外,若要改变维度中个别成员的计算顺序。比如需要公共事业费在Home维度后计算,即需要表格右下角单元格的计算结果是584.5。那么可以启用公共事业费的【Two Pass Calculation】属性。此属性表明成员需要二次计算,Essbase会在按正常顺序计算一遍后,再用公共事业费的成员公式对相关单元格进行第二次计算。

第二个疑问,是电单价和水单价。按Home维度上的计算方法,使用加分“+”做合并计算,计算结果在父级成员上是无意义的。我们已经将电单价和水单价的合并计算符置为“~”,使之不在Account维度上进行合并计算,那么如何让它们不在其他维度上进行合并呢?实际上,这里想要说明的是合并计算符“~”与“^”的区别,因为这两个计算符常让人困惑和混淆。这个例子中,要让电单价和水单价在Home、Year、Scenario上都不执行合并计算,需要将合并计算符设成“^”,如下图。

改成“^”后,电单价和水单价相关单元格在计算过程中不会产生任何合并计算值。只有使用公式脚本或输入值才能向这些单元格写入数据。

除了记录日常收支流水外,我们还要为HomeFinancial加入计算现余额的功能。因此在Account维度的现金流层次下加入了4个成员。

  • 期初现金:某一时期开始的现金量;
  • 净收入:总收入减总支出;
  • 调整:当发现收支跟现金余额对不上时,用于调整;
  • 期末现金:某一时期最后的现金量;

例2:下表记录的是张大明在2013年Q1季度的现金流。

在1月1日时张大明有现金500000元,整个1月份他花了10000元,赚了30000元,则净收入有20000元。1月31日结束时他应该有现金520000元,但由于漏记,或者银行交易产生的手续费,张大明发现实际的金额是519980元,于是补录了20元的调整项。所以有如下等式:

净收入 = 收入 – 支出

期末现金 = 期初现金 + 净收入 + 调整

要在Essbase中实现净收入和期末现金的计算,可以使用成员公式。在维库中编辑净收入的成员公式属性,输入脚本:

= "收入" - "支出";

编辑期末现金的成员公式属性,输入脚本:

= "期初现金" + "净收入" + "调整";

到1月结束时张大明所拥有的现金,同时也就是2月最初所拥有的现金。于是又有如下等式:

期初现金 = 上期的期末现金

将期初现金的成员公式修改为:

IF(NOT @ISMBR("1月1日"))
    "期初现金"[email protected]("期末现金",1);
ENDIF;

此脚本要求我们在1月1日输入期初现金,之后每一时期的期初现金都等于上一时期的期末现金。

定义了3个成员的公式后,接着要讨论一下这3个成员的计算顺序问题。前面我们使用例1来说明维度间的计算顺序,即同一类型的维度,计算顺序是由它们在大纲中的排序顺序决定的。这一规则也同样适用于同一维度中成员间的计算顺序。在同一维度的成员间,Essbase按照由低级到高级,由前到后的顺序计算。所以现金流这部分成员的计算顺序如下图。

下表用箭头标示了单元格的计算路径。

按照这样的计算路径,期初现金的成员公式会引用到晚于它计算的期末现金,从而产生错误的计算结果。例如当计算2月的期初现金时,1月的期末现金还未计算,结果得到空值。

将引用成员置于被引用成员之前,造成计算顺序错误的现象称为“前置引用”。要解决此问题,方法是让期末现金和期初现金一起计算,修改期初现金的公式脚本为:

IF(NOT @ISMBR("1月1日"))
    "期初现金"[email protected]("期末现金",1);
ENDIF;
"净收入" = "收入" - "支出";
"期末现金" = "期初现金" + "净收入" + "调整";

然后移除净收入和期末现金的成员公式。依此计算公式,当1月期初现金计算时,1月的净收入和期末现金同时被计算。那么在计算2月期初现金时,就可以得到正确的计算结果。

接着计算2月和3月的现金流。在Q1季度,期初现金应该是1月的期初现金,期末现金应该是3月份的期末现金,净收入和调整是3个月的合计。同理,整个2013年,期初现金是Q1的期初现金,期末现金是Q4的期末现金,净收入和调整是4个季度的合计。

可见,期初现金和期末现金在Year维度上采用了一种特殊的合并方式——分别取第一个子成员值和最后一个子成员值。在现实应用场景中,常常会碰到与时间相关的计算,如同比、环比、累计等。Essbase提供了大量有关Time类型维的计算函数和方法。本例中,除了使用成员公式,可以使用时间平衡(Time Balance)计算实现期初和期末计算。时间平衡计算要求数据库中必须含有Time类型维度,且仅能用在Account类型维度上使用。时间平衡计算不会影响Time类型外其他维度的合并方式。时间平衡有3种计算,含义如下表。

在维库中,将期初现金的【Time Balance】属性设为First;将期末现金的【Time Balance】属性设为Last。

时间平衡计算还有一个属性【Skip Value】,此属性控制是否要忽略空值Missing或零值。比如现金流是从2月开始,1月的期初现金是空值。如果期初现金的【Skip Value】属性是None,不忽略空值和零值,则Q1的期初现金会是1月的空值;如果是Missing,则计算Q1的期初现金时会忽略1月的空值,取2月的值。

在有了大纲计算后,每次录入和修改数据,Essbase是不会自动按合并计算符和成员公式进行计算的。必须执行计算命令,Essbase才会计算相关单元格。计算命令可写在计算脚本中,计算脚本可精确控制计算范围和顺序,还可覆盖大纲计算。可以为数据库创建多个计算脚本,执行不同的计算脚本以实现不同的计算。每个数据库都有一个默认计算脚本。

在EAS Console中,右击HomeFinancial下的y2013数据库,菜单中选择【设置】>【默认计算】。可看到在默认计算脚本中,使用了CALC ALL语句计算整个数据库,根据需要我们可以修改默认计算脚本。要创建新的计算脚本,在y2013数据库的右键菜单中选【创建】>【计算脚本】。

执行计算脚本的途径有多种,如通过MaxL Shell,Smart View,EAS Console等。要在EAS Console中执行计算脚本,通过右键菜单选【执行计算】,然后选需要执行的脚本。

时间: 2024-10-11 11:02:03

Oracle Essbase入门系列(三)的相关文章

Oracle Essbase入门系列(二)

本篇开始会一个三口之家的家庭财务数据库为例,讲述Essbase的功能和开发.为了说明EPM应用程序的管理和开发过程,会绕一些弯路,不使用EAS,而尽量用EPMA. 创建应用程序 首先登陆到Workspace,在左上角菜单中选择[导航]>[管理]>[应用程序库]. 应用程序库是EPMA的一部分,通过它可以管理EPM和Essbase应用程序.打开应用程序库后,在Workspace菜单中选[文件]>[新建]>[应用程序],接着会出现应用程序创建向导. 在应用程序创建向导的第一步,选择应用

Oracle Essbase入门系列(四)

成员存储类型 除了大纲计算,维度成员的另一项重要属性是存储类型,存储类型决定维度成员相关单元格的物理存储方式.在维库中编辑成员的[Data Storage]属性,下拉菜单中可选的5种,再加上Shared成员,一共6种存储类型. Store:储存数据.当一个单元格所有成员的存储类型都是Store时,单元格的数据会物理存储.前面说明输入单元格和计算单元格时,似乎存在这样的印象——非0级和带有成员公式的单元格都是不可输入的,必须由子代成员合并或公式计算得到.其实不然,决定单元格是否“可输入”是由存储类

oracle学习入门系列之二 数据库基础知识

oracle学习入门系列之二 数据库基础知识 本篇蛤蟆要梳理下那些被淡忘的数据库基础知识,也许根本就没被人记住过.不管是哪种情况,该记住的必须记住,记不住就把他记下来吧. 首先问几个问题如下: 数据库基础知识是什么? 好吧,蛤蟆直接吐后而不亡,看目录开始吧. 本人邮箱:[email protected] 微信公众号:HopToad 欢迎各界交流 1      基本概念 概念就是概念,大伙对这些名词不要死磕,但是对定义一定要理解,理解方能领悟,领悟方能运用自如后创新. 1.1      数据 数据

oracle学习入门系列之一 数据库发展与历史

oracle学习入门系列之一 数据库发展与历史 这个oracle学习入门系列是根据本人工作中的一些笔记.项目进行回忆.整理.一方面是自己知识积累,便于技能提升:另一方面是和小伙伴们共进退互通有无,做一个爱分享的好公民.当然最后也夹杂着自己的一个小心愿,改掉自己重理不重文的臭毛病.想想读书考试的时候,当时如果语文英语多个几分,现在可能就不会落到如此...(咳咳~~),做IT也挺好.那就这样开场白切入吧. 既然学习数据库,就不能不抛几个问题了. 1.        为什么需要数据库,什么是数据库 2

oracle学习入门系列之五 内存结构、数据库结构、进程

oracle学习入门系列之五 内存结构.数据库结构.进程 上篇蛤蟆简单描述了oracle公司的数据库产品.其他产品及oracle软件的一些特点.干货虽有但是真心是比较少的,这篇开始就是以干货为主,其中夹杂一些扯淡的事情了.蛤蟆一直也在想如何能生动的通过这干巴巴的文字来描述着世界级的软件,太理论大家都看不下去,太实践又缺乏深度.想想自己上大学那会,老师的讲课,无不枯燥乏味啊,满满的兴趣尽是消耗殆尽.所以不能仿效之,我们得走自己特色的路.以最易懂的形式.比喻等手段描述深奥的计算机知识.走起~ 开篇问

Xen入门系列三【Xen 管理工具 xm】

xm命令是管理Xen的最基本的工具,可以通过xm --help 来获得帮助. 1. 列出所有正在运行的虚拟操作系统 # xm list PS[1]:可缩写为 xm li2. 启动虚拟机 # 通过配置文件启动虚拟机 # xm create <ConfigFile> # 通过虚拟机名称启动虚拟机,虚拟机必需已存在 xm list 中 # xm start <DomainName> 参数说明: ConfigFile:虚拟机配置文件 DomainName: 虚拟机名称 PS[2]:很多教程

RxJava入门系列三,响应式编程

RxJava入门系列三,响应式编程 在RxJava入门系列一,我向你介绍了RxJava的基础架构.RxJava入门系列二,我向你展示了RxJava提供的多种牛逼操作符.但是你可能仍然没能劝服自己使用RxJava,这一篇博客里我将向你展示RxJava提供的其他优势,没准了解了这些优势,你就真的想去使用RxJava了. 异常处理 直到目前为止,我都没有去介绍onComplete()和onError()方法.这两个方法是用来停止Observable继续发出事件并告知观察者为什么停止(是正常的停止还是因

oracle学习入门系列之六 模式

oracle学习入门系列之六 模式 上篇咱们学习记录了ORACLE数据库中的数据库结构.内存结构和进程等,篇幅 蛤蟆感觉偏多了.这次要休整下,每次笔记不宜太多,不然与书籍有何区别.我们要保证的是每次做记录都能所有收获所有提升. 上次中我们从总体上把握了下ORACLE系统结构,这次开始我们将涉及到ORACLE数据库的具体方方面面了.本次就从模式对象入手. 老规矩,先来两个问题: a)        什么事模式 b)       为什么需要 搞清楚这两个问题即可. 本人邮箱:[email prote

C语言快速入门系列(三)

C语言快速入门系列(三) 结构化的程序设计 -----------------------------------转载请注明出处:coder-pig 本节引言: 在前面的学习中,我们对C语言的基本语法进行了了解,可以暂时理解成我们学了单词; 现在要做得就是学语法,也就是算法;就是构成一个一个基本的程序! 在这一节中我们要学习的是C语言中的输入输出,以及程序的三种结构(顺序,选择,循环结构) 本节学习路线图: 正文: 1.字符输入/输出函数 2.格式输入/输出函数 跟前面的单个字符的输入输出不同,