29
April 2004

Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

Embed Size (px)

Citation preview

Page 1: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

April2004

Page 2: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block
Page 3: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

and the calculator language can be used to con-struct calculation scripts for block storage data-bases. However, this document addressesneither of these uses of the languages. It focus-es just on the member formulas define in theoutline.

Before beginning this document you shouldhave basic familiarity with the workings ofaggregate storage outlines in Essbase. SeeVolume IV of the Database Administrator’sGuide, which discusses all aspects of aggregatestorage.

The differences between aggregate storage out-lines and block storage outlines affect the writ-ing of member formulas in a number of waysbesides the language used:

• While a block storage outline allows formu-las to be attached to any member in theoutline, aggregate storage outlines requirethat formulas be attached only to membersin the dimension explicitly tagged asaccounts.

The Calc language cannot be used to writemember formulas for aggregate storage data-bases. To write formulas for aggregate storageoutlines requires the MDX language. The MDXlanguage and the Calc languages are bothdefined in the Technical Reference. The purposeof the current document is to provide supportfor rewriting Calc formulas in MDX for out-lines that have been migrated from block stor-age to aggregate storage.

This document provides an overview of thekey elements of the calculator and MDX lan-guages comparing and contrasting them, bothsyntactically and semantically, as appropriate.Function categories in either language areexplored in great detail with the intent ofenabling the reader to use this document toaccomplish the process of converting formulasfrom a block storage to an aggregate storageoutline or vice-versa. Since aggregate storageoutline formulas are always computed dynam-ically, they are comparable to dynamic formu-las in the block storage model. Note that theMDX language can be used to describe queriesfor both aggregate and block storage databases

Hyperion Essbase 7.1 introduces a new storage mechanism to per-

sist a multidimensional cube, called aggregate storage. An aggre-

gate storage database differs from a block storage database in a

number of ways. One primary difference relates to member formulas,

which are the focus of this document. To write formulas for block storage

outlines, Essbase provides a set of calculation functions and operators. For

the purpose of this document, this set of functions and operators and the

attendant syntax is referred to as the Calc language.

[ ]

Page 4: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

The fundamental element in both languages isa member in a dimension. A member whosename contains spaces or other special charac-ters is enclosed in double quotes in Calc,whereas MDX requires such names to beenclosed within square braces; for example:

[100-10] /* MDX */.

“100-10” /* Calc */

In Calc, a member that has shared counter-parts in the same dimension always refers tothe non-shared, tagged version of the member(relevant for the purpose of metadata func-tions). The concept of shared members doesnot exist in aggregate storage databases.

A collection of one member from one or moredimensions is referred to as a cross member inCalc. The same entity is referred to as a tuple inMDX, with the difference that a tuple is anordered collection of members. This differenceis particularly relevant in terms of the next fun-damental element of the languages, sets oftuples. Examples of a tuple and a cross memberare:

([100-10], East) /* MDX tuple */

“100-10”->East /* Calc */

A set is an ordered collection of zero, one, ormore tuples with the rule that the membersappear in the same dimensional order in eachtuple. Consequently operations such as thehead or tail of a set, current tuple, and nth tupleof a set are all meaningful. A set can containmore than one occurrence of the same tuple.

• The storage characteristics of a member andhence all its associated cells are defined in ablock storage outline through dynamiccalc (and store) attributes, and storedattributes. Such attributes do not exist inan aggregate storage outline. Upper levelmembers along an explicitly taggedaccounts dimension and members withformulas attached to them are always cal-culated dynamically in such a database.

• Built-in financial calculation functions withtime intelligence such as time-balance,time series and expense reporting are avail-able only in block storage outlines.

• In block storage outlines, calculation orderis dependent on the order in which mem-bers appear in the outline whereas formu-las are executed in order of theirdependencies in aggregate storage outlines.In addition, calculation order in the eventof ambiguity in the evaluation of a cell, andtwo-pass calculation tags are not requiredin an aggregate storage outline because for-mulas can only be attached to accountsdimension members, and all membersassociated with formulas are calculateddynamically at query time.

• The layout of block storage outlines and theseparation of dimensions into dense andsparse has an effect on the semantics ofcertain calculations, giving rise to conceptssuch as top-down calculation mode, celland block calculation mode, and create-blocks on equations. The simplicity of theaggregate storage outlines, which do notseparate dimensions into dense and sparse,makes such concepts obsolete.

[ ]

Page 5: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

ior. Notable examples are @SHIFT and its vari-ants. See @SHIFT in the Calc to MDXFunctions table for more information.

MDX supports set union, intersect andexcept operations. Calc supports the same setof operations on lists. The rigorous definitionof sets requires careful handling of duplicatetuples whereas such requirements must beexplicitly handled by application developers inCalc through the use of @REMOVE and@MERGE functions.

The MDX CrossJoin function returns thecross product of two sets, and includes pre-defined semantics on which set is iterated overfaster. The closest analog in Calc is the@RANGE function. However @RANGE oper-ates over a single member and set, unlikeCROSSJOIN, which can operate on two sets.

Both languages include procedural elements inthe form of IF-ELSEIF-ELSE constructs,although the syntax differs. MDX exposes thefunctionality in the form of a IIF constructwhen there is exactly one IF and one ELSE con-dition. Nested IF-ELSE-IF logic requires theuse of nested IIFs. Additionally, two flavors of aCASE-WHEN-THEN construct are also avail-able in MDX to be used where multiple IF,ELSE clauses are required. Calc has a single IF-ELSEIF-ELSE-ENDIF construct.

While methods (such as Children,Descendants etc) can be invoked syntacticallyas a function call in both languages, MDX,additionally allows an object-oriented invoca-tion style. For example:

Calc has no corresponding element, though alist comes close to representing a collection ofmembers or cross members. However, there isno rigor to how a list is composed (order ordimensionality requirements) and hence it isnot possible to identify the contents of a list byposition.

Calc sets can be constructed only by usingmetadata operations on outline members or byexplicit enumeration of members and crossmembers, referred to as explists. Calc sets donot necessarily subscribe to the definition rulesof an MDX set. MDX sets, on the other hand,can also be obtained through data-based oper-ations, referred to as filters.

An explicitly enumerated explist in the Calclanguage can be converted into an MDX set byensuring that each cross-member in the explisthas the same dimensionality (by substitutingany missing dimensions in the cross-memberby the root dimension member) and that theorder of enumeration of members within eachcross member is the same.

A cell is identified in both languages by atuple or a cross member that has representationfrom every dimension in the outline. When acell address is incompletely specified, both lan-guages use dimension level members alongdimensions that are not represented in a celladdress.

In MDX, the difference between a member,and a cell value indexed by a member, are veryclear. The MDX Value function is used if a cellvalue is desired in a particular context. In con-trast, most Calc functions implicitly assumethat the value of an expression is desired andthere is little control over the function behav-

[ ]

Page 6: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

functions in the Calc language. However, theability to extend the Calc language enablesalmost any expression that can be constructedin MDX to be achieved in Calc, although notefficiently. In particular, the ordering semanticsof sets is difficult to simulate in Calc. Customextensions to MDX will, however, be possible ina future release of Essbase.

The MDX functions that can be used to con-struct outline formulas can be categorizedbased on their return values, as follows:

• Member• Tuple• Set• Number• Dimension (root member of a dimension)• Layer (generation or level number/name)• String • Boolean.

Calc functions also have similar return typesand subscribe to the same categorization,except for return types tuple and set asdescribed earlier.

The functionality available in MDX andCalc is compared from the perspective of a userfamiliar with Calc and attempting a translationof outline formulas written for block storageoutlines to aggregate storage outlines.

Both languages support outline based opera-tions that return a single member, such asParent, Ancestor, Lead (Next) and Lag (Prior).Functions dealing with attribute dimensions,

Children(East) /* Valid in Calcand MDX */

East.Children /* Valid in MDXonly */

The assignment construct exists only inCalc. Thus in a block storage outline, a formu-la attached to a member A can influence thevalues of cells corresponding to a differentmember B. While the notion of indirect assign-ment is not relevant to dynamically calculatedmembers, the difference is worth mentioning.MDX formulas return a value only for cellsassociated with the member.

Calc exposes constructs such as SKIPMISS-ING, SKIPZERO, SKIPNONE and SKIPBOTHto control how zero and missing cell values in acube should be treated in certain functions,such as @AVGRANGE. While MDX does notdirectly support these elements, it is possible toachieve the same result using either the Filter,IIF, or CoalesceEmpty functions. Filter takes aset as input and produces an output set consist-ing of only those members that satisfy the filtercondition.

A dynamically calculated outline memberformula is evaluated at query time for every cellrequested in the query and associated with themember. Thus the context for the execution ofa formula is always a fully specified cell co-ordinate from the query. The precedence rulesand arithmetic rules involving missing and zerocells are identical between MDX and Calc.

The Calc language can be extended throughthe definition of user defined macros and javafunctions. The list of native functions availablein MDX is much higher and richer than the

[ ]

Page 7: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

storage outlines by the use of Accounts tagsTBFIRST and TBLAST.

To retrieve a cell value associated with amember, Calc has functions such as @MDPARENTVAL, @MDANCESTVAL and@MDSHIFT. All these functions take as input amember and return the value of a cross mem-ber consisting of parent/ancestor/shifted mem-ber along all dimensions (based on currentmember from each dimension) specified asarguments. To retrieve a cell value associatedwith a member in MDX, you explicitly con-struct a tuple with overriding parents/ancestorsof members then apply the Value function. Seethe description of @MDPARENTVAL in the“Calc to MDX Functions” table for an example.The function @XREF has a similar purposeexcept that the value fetched is from a cubeidentified explicitly as one of the functionarguments. MDX does not have the equivalentof an XREF function in this release.

Although the notion of a cross member existsin Calc, operations to isolate individual mem-bers of the cross member are not possible. Incontrast, MDX allows specific members to beisolated from a tuple by position using the Itemfunction.

A rich set of metadata functions that return aset of members based on hierarchical relation-ships in the outline are present in both lan-guages. In MDX, the resulting set subscribes toordering and dimensionality rules, whereas inCalc a set is merely a collection of (cross) mem-bers in Calc. Most metadata functions in Calchave a counterpart, directly or indirectly, in

namely, @ATTRIBUTEBVAL, @ATTRIBUTES-VAL and @ATTRIBUTEVAL exist only in Calc.MDX exposes attributes as properties. Thusmember properties can be used in place of thecorresponding Calc functions. See the descrip-tion of these functions in the “Calc to MDXFunctions” table for examples.

@SHIFT in Calc allows elements identifiedby relative positions in an input list to bereturned. Logically, @SHIFT, (@NEXT, and@PRIOR perform a metadata operation, name-ly, shifting in the right direction, based on thecurrent context of execution and the input set.The result for each of these functions is a cellvalue.

An important difference between the MDXand Calc languages is illustrated by the@SHIFT function. Calc implicitly assumes,based on the current context of execution, thatthe value of the shifted member is desired. Incontrast, MDX keeps the distinction betweenmembers (or sets) and cell values distinct.Thus, the variants of @SHIFT in MDX, name-ly, the Lead and Lag functions, return a mem-ber or a tuple. To obtain the cell value, the Valuefunction must be explicitly specified.

The Calc language allows the defaulting ofthe range input for functions to be the leaf levelmembers of an explicitly tagged time dimen-sion. This defaulting mechanism does not existin MDX.

MDX, additionally, has functions such as OpeningPeriod, ClosingPeriod andParallelPeriod, FirstChild, LastChild,FirstSibling, and LastSibling with no corre-sponding counterparts in Calc. Alternatively,time balance logic can be implemented in block

[ ]

Page 8: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

both languages. The :: Calc operator mapsto the MemberRange function in MDX.The : Calc operator maps to MemberRangewith an additional layer argument.@XRANGE is a multidimensional versionof the @RANGE function and creates aresult set by identifying the level of thearguments and pruning the result set toinclude only the argument members andthe list of members that are, in terms ofoutline order, between them.

@CURRMBRRANGE takes as input arange of members (set) and returns differ-ent subsets of the input set (with contigu-ous members) based on other argumentsand the relative position in the input set ofthe current member being calculated.While MDX can support certain variantsof this function through the use of the Lag,Lead, and RelMemberRange functions, notall Calc combinations can be readily trans-lated.

Most Calc functions that take a set asinput can also take an arbitrarily con-structed list of members or cross members,referred to as explists, as input. Such capa-bility makes Calc functions (such as@SUM, @MIN, @MAX. and so on) moreflexible than their counterparts in MDX.The explists need to be translated to MDXby fixing the dimensionality of the crossmembers as needed so they subscribe tothe rules of an MDX set.

MDX has a much richer repertoire of meta-data functions than Calc. To achieve function-ality in Calc, similar to that provided by theMDX metadata functions, may require proce-

MDX, with the exception of the @MATCHfunction, which returns members from adimension whose name conforms to a regularexpression pattern.

Functions that have a direct counterpart rec-ognizable simply by the same name in eitherlanguage are listed in the “Calc to MDXFunctions” table but are not described in anydetail in this document. Certain functionsrequire indirect translation as explained below.For a complete list of functions, both withdirect or indirect translation, see the “Calc toMDX Functions” table.

The versions of metadata functions withan i prefix (for example, @ICHILDREN)return the member on which a method isrequested along with the resulting mem-bers in the same set. In contrast, MDXrequires an additional union operation ofthe member with the result set of the oper-ation. See @ICHILDREN in the “Calc toMDX Functions” table.

The @LSIBLINGS and @RSIBLINGSfunctions must be translated indirectlyinto MDX. The following example shows aCalc function and its MDX equivalent:

@lsiblings(mbr) /* Calc */

MemberRange(FirstSibling(mbr),Lag(mbr, 1)) /* MDX */

The @RELATIVE function in Calc canbe replaced by the MDX Descendantsfunction.

The @XRANGE function is unique toCalc and is an extension of the range func-tions, : or :: operators that are available in

[ ]

Page 9: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

dural code in the form of custom defined func-tions. The following list describes the MDXmetadata functions.

The @DESCENDANTS function inCalc maps directly to Descendants inMDX. In addition, MDX has variants ofDescendants that enable optionally skip-ping members from one or more levels.

Operations on a set by using functionssuch as Distinct (duplicate removal), Head,Tail and Subset are available only in MDX.The Extract function operates on an inputset and a number of dimensions and cre-ates a resulting set that has members fromthose input dimensions only for each tuple.

Operations on two sets, using functionssuch as Union, Intersect, Except andCrossJoin are available only in MDX. Thecorresponding list processing functions inCalc do not compare in terms of function-ality.

Other sophisticated means of pruningan input set based on the value of an arbi-trarily complex numeric expression (anexpression that returns a double valuewhen evaluated for each member of theinput set) exist in MDX in the form ofTopCount and BottomCount functions.

The following Drill functions are available inMDX:

• DrilldownByLayer, (alternate name for theByLayer function)

• DrilldownMember

• DrillupByLayer

• DrillupMember performs ascendant ordescendant operations on one or moreinput members based on criteria specifiedby other parameters.

Complex procedural logic requiring outlinetraversals can be succinctly described using theMDX Generate function. This rich iterative setfunction applies a specified (member set)method on each element of the input set, andproduces an output set. When iterating throughthe elements of a set, the functionCurrentTuple, helps identify the element of theinput set currently being operated upon.

MDX has two kinds of set pruning func-tions. The Filter function uses a Boolean searchexpression to select input elements to appear inthe output. On the other hand, to pick a speci-fied count of members from an input set basedon the value of a numeric expression, MDXprovides the following functions:

• TopSum

• TopCount

• TopPercent

• BottomSum

• BottomCount

• BottomPercent.

TopPercent, for instance, returns the small-est possible subset of a set for which the totalresults of a numeric evaluation are at least agiven percentage. Elements in the result set arelisted from largest to smallest. This functionignores missing values. BottomSum, as anotherexample, returns the smallest possible subset ofa set for which the total results of a numericevaluation is at least a given sum.

Page 10: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

dimensionality), substituting for missingdimensions from the current calculation con-text and obtaining the cell values from thecube. Functions in the other variation, whichinclude @SUMRANGE, @MINRANGE,@MAXRANGE and @AVGRANGE, take asinput a member or a cross member and a range(collection of members from another dimen-sion) and perform the requested aggregationon cell values obtained by crossing the inputmember with each element of the range.

MDX rules for a set prohibit the first varia-tion directly. If every element of the arbitrarymember collection can be adjusted to subscribeto forming a set before being used as input tothe mathematical function, then the translationis possible.

Calc functions optionally take a SKIP argu-ment that specifies how to treat cell values thatare missing or zero. Such functionality does notexist in MDX but can be accomplished indi-rectly using Filter, IIF or CoalesceEmpty con-structs as demonstrated in the “Calc to MDXFunctions” table.

The Calc COUNT function returns thenumber of elements in an input set based onthe cell values of each element (and has anoptional SKIP argument). The MDX counter-part is NonEmptyCount.

Scalar statistical functions, such as @RANK,@STDDEV, @VARIANCE, @MEDIAN and@MODE, which return a single value, asopposed to vector statistical functions, areavailable only in Calc. Also, expense functionssuch as @VAR and @VARPER, which deter-mine the difference between two members bytaking into consideration any expense tags, arenot relevant in aggregate storage outlines.

Two functions, Order and Hierarchize canbe used to change the positions of elementswithin a set. Order sorts the members of a setin ascending or descending order based on thespecified value of a numeric expression to beapplied to each element of the set. Hierarchizereorders members within a set based on thehierarchical order of the members in the out-line.

While Calc assumes dynamic time series(DTS) members will be captured in the outlineand hence has no functions to deal with suchmembers, MDX has explicit support for timeseries calculations without referencing DTSmembers in the outline. Since aggregate storageoutlines cannot include DTS members, theability to execute DTS type calculations inMDX formulas is critical. The MDXPeriodsToDate function can be used to accom-plish similar functionality.

The appendix section contains examples ofDynamic Time series and Time balance func-tionality in MDX.

The MDX Count function returns the cardi-nality of an input set (the number of tuples).There is no analog to this function in Calc.

The set of numeric functions that accomplisharithmetic and statistical calculations is largerin Calc than in MDX. However, the MDX vari-ations, when they exist, tend to be richersemantically.

In Calc, the mathematical functions come intwo variations. In one variation, the functions,which include @SUM, @MIN, @MAX and@AVG, take as input an arbitrary collection ofmembers or cross members (without regard to

[ ]

Page 11: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

verts date strings to numbers that can then beused in calculation formulas.

While MDX does not support string manip-ulation functions in the current release, itenables querying properties such as membernames, aliases, and attributes. equality andinequality operators can also be used in expres-sions that accept string types. IIF can returnstring types.

In Calc, the most common Boolean functionsthat test for metadata outline relationships are:

@ISANCEST

@ISCHILD

@ISDESC

@ISGEN(LEV)

@ISSIBLING

@ISPARENT

@ISSAMEGEN(LEV)

ISUDA.

While some of these functions exist in MDXothers can be implemented through a combi-nation of metadata member-set functions, theset intersection operator, and the Is function,which returns TRUE if two members are iden-tical. For example:

@ISDESC(Member) /* Calc */

Count(Intersect({Member.Descendants},

{Member.dimension.CurrentMember}) = 1 --MDX

The MDX Dimension function returns the rootmember of the dimension to which an inputmember, level, or generation name belongs.Although Calc has no similar function, it ispossible to achieve the same result by request-ing the ancestor of the member at root level(generation 0).

Functions that return a generation or levelnumber given a member name as input aresimilar in both languages. Calc, additionallyenables generation and level numbers to beobtained based on current context (@CUR-GEN/LEV). The same result can be accom-plished in MDX by using Generation or Levelwith CurrentMember to identify the inputmember. For example:

Generation (CurrentMember(dimension)).

Calc has four functions that operate on stringdata types:

• @SUBSTRING

• @CONCATENATE

• @NAME

• @TODATE.

In conjunction with the @MEMBER func-tion the string functions can be used to selec-tively pick members from an outline.

The @SUBSTRING function returns a con-tiguous list of n characters from an inputstring. @CONCATENATE pastes together twoinput strings and the @NAME function con-verts input argument to a string. @Todate con-

[ ]

Page 12: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

Alternatively:

IsAncestor(Member, Member.dimen-sion.CurrentMember) --MDX

Calc also has i prefixed variations of all theabove functions (@ISICHILD, @ISIDESC, andso on) which include the specified member inthe test. The following examples show a CalcBoolean function and its equivalent in MDX:

@ISIDESC(member)/* Calc */

(Count(Intersect({Member.Descendants}, {Member}) = 1

OR

Is(Member, Member)) /* MDX */

Here is another way to write the same func-tionality in both languages:

@ISIDESC (member) /* Calc */

(Is (<member>, <member>.dimen-sion.CurrentMember)--MDX

OR

IsAncestor (<member>,<member>.dimension.CurrentMember))

The Calc IS* functions implicitly assumethat the check is for the current member alongthe same dimension as the argument to thefunction. MDX, in contrast, requires explicitspecification of the current member.

The Calc @ISMBR function takes as inputany arbitrary collection of members or crossmembers and enables membership testing. Thesame can be accomplished indirectly in MDXusing multiple Boolean constructs, Intersect,and Count functions. See the @ISMBR functionin the “Calc to MDX Functions” table.

Checking for missing cells can be accom-plished in MDX by using the IsEmpty function.For example:

(Value <> #MISSING) /* Calc */

IsEmpty (value_expression) --MDX

In Calc, @ISLEV is used to check for leaf-level members. In MDX, the IsLeaf function isused to check for leaf-level members. For example:

(@ISLEV(member) <> 0) /* Calc */

IsLeaf(member) --MDX

This section provides some general guidelinesas well as specific steps for translating Calc for-mulas to MDX.

Be certain that the application has beenredesigned to use an aggregate storage outline.In this regard, make certain that formulas donot reference any block-storage specific outlineconstructs, such as dynamic time series mem-bers, variance functions that rely on expensetagging, or functions that operate on sharedmembers (@RDESCENDANTS). Such con-structs are not valid in aggregate storage out-lines.

Remember that for an aggregate storage out-line, formulas can only be attached to an explic-itly tagged accounts dimension.

Rewrite each function in the formulasattached to an explicitly tagged accountsdimension for which a direct counterpart inMDX exists. See the Calc to MDX Functionstable for specific information and examples.

Page 13: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

Identify functions in the formulas attachedto an explicitly tagged accounts dimension forwhich an indirect rewrite is required using therules outlined in this document.

Understand the calculation order semanticsfor the formulas in the block storage outline.Organize the dependent formulas in the aggre-gate storage outline carefully to achieve thesame results as block storage.

If formulas reference custom-defined func-tions or macros consider rewriting them, if pos-sible, using other MDX functions.

For formulas attached to non-accountsdimensions, create template MDX queries to beexecuted at query-time. Formulas cannot becreated on non-accounts dimensions in aggre-gate storage outlines.

If an outline Calc formula in a block storageoutline involves assignment of values to a storedlevel 0 member, the translation involves twomembers in a corresponding aggregate storageoutline: one where the data is loaded andanother where the corresponding MDX formu-la can be attached. The current release ofEssbase considers members with formulasattached as implicitly ‘dynamic’. A dynamicmember cannot have data input to it. For example,

Net_Written_Car_Years = if(@ismbr(Coverage) or@ismbr(Bodily_Injury))

Net_Written_Car_Years->Bodily_Injury;

else

Net_Written_Car_Years;

This formula is translated into MDX using anadditional member, as follows. Note thatNet_Written_Car_Years_Input is usedto load input data.

Net_Written_Car_Years =

IIF (Is([Coverage].CurrentMember,[Coverage]) OR

Is ([Coverage].CurrentMember,[Bodily_Injury]),

(Net_Written_Car_Years_Input,Bodily_Injury),

(Net_Written_Car_Years_Input);

The Block Storage outline provides pre-definedtags in the form of TBFirst, TBLast and TBAvgfor automatic time balance functionality. Built-in time series members such as YTD, WTD etccan be associated with a specific generation of anamed time dimension to obtain time seriesfunctionality. Such tags are not available direct-ly in aggregate storage outlines. However, it ispossible to achieve similar functionalitythrough slightly different means. This sectionoutlines one such method of achieving bothtime balance and time series functionality usingthe sample/basic database when used in aggre-gate storage mode.

Recall that before you can use a time balance tagin an outline there must be an Accounts dimen-sion. Normally, the calculation of an upper-level member in the time dimension is based on

Page 14: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

either the outline hierarchy or any formula ifpresent on the member. However, if a memberin an accounts dimension is marked as TB First,then any upper level member in the timedimension is computed using the TBFirst tag.

For example, in sample/basic block storageoutline, data corresponding to member"Opening Inventory" (ignore the formula onopening inventory for the purpose of this dis-cussion and simply focus on the time-balancetag associated with the member) represents theinventory at the beginning of each month. Thequarterly value for "Opening Inventory" isequal to the Opening value for the first monthin that quarter. Thus, "Opening Inventory" istagged with TBFirst tag. Similarly, "EndingInventory" data represents the inventory at theend of each month. The quarterly value for"Ending Inventory" is equal to the ending valuefor the (last month in the) quarter. EndingInventory, is thus tagged with TB last. Thisfunctionality can be achieved in aggregate stor-age, for instance, through a combination ofUDAs and MDX outline formula as we willdemonstrate. Instead of using pre-defined tags,members of accounts dimension that requiretime-balance tags should be marked with UDAssuch as TBFirst and TBLast.

Thus, "Opening Inventory" would be associ-ated with a UDA called "TBFirst" and "EndingInventory" with the UDA "TBLast". Next,consider creating an additional dimensioncalled "Analytics" dimension which houses allformulas required for the outline and hence istagged as Accounts dimension in the AggregateStorage outline. Consider the presence of amember called "Actual" which is used to perform all dataloads. Additionally, consider a

member "TB" in this dimension that has the following formula attached to it to achievetime-balance functionality.

TB

CASEWHEN(IsUda([Measures].CurrentMember,"TBLast"))THEN (ClosingPeriod(Year.Levels(0), Actual))WHEN(IsUda([Measures].CurrentMember,"TBFirst")) THEN (OpeningPeriod(Year.Levels(0), Actual))

ELSE [Actual]END

Thus when cells at the intersection of themember "TB" from the Analytics dimensionand any other measure that is tagged with a"Time Balance" User Defined Attribute isretrieved, the time balance computation is per-formed dynamically at retrieval time.

Let us consider support for Quarter-to-Datefunctionality in Sample Basic outline. The func-tionality is obtained by enabling the Q-T-Dmember and associating it with the generationcontaining quarters, namely, generation num-ber 2, containing members Qtr1, Qtr2, Qtr3,and Qtr4. Retrieving Q-T-D member in aquery requires specification of a month (level 0member) as the latest member and results in thecalculation of monthly values up to the currentmonth in the quarter. Thus, Q-T-D(May)returns the quarter-to-date values by addingvalues for April and May.

Page 15: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

Let QTD be a member of the newly added"Analytics" dimension in Sample Basic outlinein Aggregate Storage mode. In keeping with therequirement that only level-0 members of timedimension can be specified as current timeperiod for Q-T-D, the QTD member intersec-tions with level-0 members of Year dimensionalone make sense.

The MDX formula required to be associatedwith the QTD member for sample/basic is givenbelow.

QTD

/* If the member from Yeardimension is at Level 0, then */CASE WHENIsLevel([Year].CurrentMember, 0)

/* Add all values from the firstsibling of the member to itself */

THEN Sum(Parent([Year].CurrentMember).FirstChild:[Year].CurrentMember,[Actual])

ELSE #Missing /* Meaningless to ask for QTDfor any other [Year].dimension member. */

END

Alternatively, the functionality representedby DTS member can also be expressed asSum(PeriodToDate (Year.Generations (n))where "n" is to be substituted by the generationnumber to which the DTS member applies.Thus for Q-T-D in the sample/basic database,the value of n=2

The following table lists all functions in theCalc language and their analogs in MDX (andvice versa). Where a direct analog doesn’t exist,transformation rules and examples are provided.

Page 16: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

@ABS

@ALLANCESTORS

@ALIAS

@ANCEST

@ANCESTORS

@ANCESTVAL

@ATTRIBUTE

@ATTRIBUTEBVAL

ABS

ANCESTOR

Not required

ANCESTOR with CURRENT-MEMBER as input.CROSSJOIN the result withthe optional third argumentto @ANCEST function

ANCESTOR

ANCESTOR with CURRENT-MEMBER as input.CROSSJOIN the result withthe optional third argumentto @ANCESTVAL function

ATTRIBUTE

[BaseDimension].CurrentMember.AttributeDimension

The MDX function returns ancestor ata particular generation. Call this func-tion repeatedly to get ancestors ateach generation and union the result-ing members. Same as @ANCES-TORS since shared members cannotappear in aggregate storage outlines.

In MDX, the argument to @ALIAS canbe passed as is to the outer function

@ancest(Product,2,Sales) /*Calc */Crossjoin ({Sales}, {Ancestor(Product.CurrentMember,Product.Generations (2))}) --MDX

@ancestval(Product,2,Sales) /* Calc */(Sales, Ancestor(

Product.CurrentMember,Product.Generations (2))).Value--MDX

See “MDX Properties” in theTechnical Reference for more infor-mation.@attributebval(Caffeinated) /* Calc */Product.CurrentMember.Caffeinated --MDX

CALC MDX REMARKS

Page 17: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

@ATTRIBUTESVAL

@ATTRIBUTEVAL

@AVG

[BaseDimension].CurrentMember.AttributeDimension

[BaseDimension].CurrentMember.AttributeDimension

If dimensionality of all ele-ments in the input set to@AVG is the same then useAvg. Translate SKIPNONE toINCLUDEEMPTYIf dimensionality of all ele-ments in the input set to@AVG is not the same, thenperform average by explicitlyadding the tuples and divid-ing by the set cardinality.

See “MDX Properties” in theTechnical Reference for more infor-mation.@attributesval(“Pkg Type”) /* Calc */Product.CurrentMember.[PkgType] --MDX

See “MDX Properties” in theTechnical Reference for more information.@attributeval(Ounces) /*Calc */Product.CurrentMember.Ounces--MDX

Note that the MDX Avg function skipsmissing cell values by default@avg(SKIPMISSING, @chil-dren(East)) /* Calc */Avg([East].Children)

If SKIPMISSING is replaced by SKIP-NONE, the translation changes toAvg([East].Children, Sales,INCLUDEEMPTY)

For SKIPZERO, the translation is:Avg([East].Children,IIF(Market.CurrentMember.Value=0,

Missing, IIF(Market.CurrentMember

= Missing, 0,

Market.CurrentMember.Value)))

For SKIPBOTH, the translation is:Avg([East].Children,IF(Market.CurrentMember=0,

#Missing,Market.CurrentMember.Value))

CALC MDX REMARKS

Page 18: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

@AVGRANGE

@CHILDREN

@CONCATENATE

@CORRELATION

@COUNT

CROSSJOIN(first argument,set created out of secondargument). Rest similar to@AVG when dimensionalityof all elements of the inputset is identical.

Children

-

-

Use Count if SKIPNONE.

Use NonEmptyCount ifSKIPMISSING.

For SKIPZERO, see theexample in the next column.

For SKIPBOTH use:Count(Filter(set,value <> 0 && value <>#MISSING))

@AVGRANGE (SKIPMISSING,Sales, @children(West)) /*Calc */AVG(CrossJoin({Sales},

{[West].Children)})--MDX

If SKIPMISSING is replaced by SKIP-NONE, the translation becomes:AVG({[West].Children)},Sales,INCLUDEEMPTY) --MDX

If SKIPZERO is used, then the trans-lation is:Avg([West].Children),IIF(Sales = 0, Missing,IIF(Sales = Missing, 0,Sales))) --MDX

No counterpart

No counterpart

@COUNT(SKIPMISSING, @RANGE(Sales,

Children(Product)))/* Calc */

NonEmptyCount(CrossJoin({Sales},{Product.Children})) --MDX

Note that Count counts empty cellsby default whereas NonEmptyCountdoes notFor SKIPNONE, the translation is:Count(CrossJoin(Sales,

Product.Children))--MDX

For SKIPZERO the translation is:NonEmptyCount(Product.Children,IIF(Sales=0, Missing,IIF(Sales = Missing, 0, sales)))/* MDX */

CALC MDX REMARKS

Page 19: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

@CURGEN@CURLEV

@CURRMBR

@CURRMBRRANGE

@DESCENDANTS

@EXP

@FACTORIAL

@GEN/@LEV

@GEN/LEVMBRS

@IALLANCESTORS

@IANCESTORS

@ICHILDREN

@IDESCENDANTS

@ILSIBLINGS

Generation(CurrentMember(dimension))

Level(CurrentMember(dimension))

CurrentMember

RelMemberRange

Descendants(member)

Exp

Factorial

Generation/Level

Layer.Members

Ancestors (note that aggre-gate storage outlines do nothave shared members)

Same as @IALLANCESTORSsince shared members arenot present in aggregatestorage outlines

Union(member, member.children)

Union(member,member.descendants)

Union(mbr,MemberRange(FirstSibling(mbr), Lag(mbr, 1)))

@CURGEN(year) /* Calc */Year.CurrentMember.Generation/* MDX */

@CurrMbrRange(Year, LEV, 0, -1, 1)/* Calc */

RelMemberRange(Year.CurrentMember, 1, 1, LEVEL)

@ILSIBLINGS(Florida) /* Calc */Union({Florida}, {MemberRange(Florida.FirstSibling,Florida.Lag(1)}) --MDX

CALC MDX REMARKS

Page 20: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

@INT

@ISACCTYPE

@ISANCEST

@ISCHILD

@ISDESC

@ISGEN

@ISIANCEST

@ISIBLINGS

@ISICHILD

Int

IsAccType

IsAncestor

IsChild

IIF (Count(Intersect(member.descendants,descendantmember)) = 1,TRUE, FALSE)

IsGeneration

IIF(Is(member,ancestormember)OR IsAnest(member, ances-tormember), TRUE, FALSE)

Union(member, member.siblings)

IIF(Is(member, childmember)ORIsChild(member, childmember),TRUE, FALSE)

@ISANCEST(California) /*Calc */IsAncestor(Market.CurrentMember,California) --MDX

@IsDesc(Market) /* Calc */IIF(Count(Intersect(

{Market.Descendants}, {Market.CurrentMember}))= 1,<true-part>, <false-part>)

/* MDX */

@ISGEN(Market, 2) /* Calc */IsGeneration(

Market.CurrentMember,2) --MDX

The i prefix is a simple equalitycheck. For example:@ISIANCEST(California) /*Calc */ IIF(IS(Market.CurrentMember, California) OR

IsAncestor(Market.CurrentMember,California), <true-part>, <false-part>)

--MDX

Returns a set that includes the specified member and its siblings.

@IsIChild(South) /* Calc */IIF(Is(Market.CurrentMember, South) OR

IsChild(Market.CurrentMember,South),<true-part>, <false-

part>) /* MDX */

CALC MDX REMARKS

Page 21: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

@ISIDESC

@ISIPARENT

@ISISIBLING

@ISLEV

@ISMBR

IIF(Is(member, descmember)ORIsDesc(member, descmember),TRUE, FALSE)

IIF(Is(member, parentmember)OR ISPARENT(member, parent-member), TRUE, FALSE)

IsSibling(member, sibling-member) OR Is(currentmember,siblingmember)

ISLEVEL

IIF (Count(Intersect(member-set, member)) = 1, TRUE,FALSE)

@IsIDesc(South) /* Calc */IIF (Is(Market.CurrentMember, South)ORCount(Intersect({[South].Descendants}, {Market.CurrentMember}))= 1)<true-part>, <false-part>)

/* MDX */

@IsIParent(Qtr1) /* Calc */IIF(Is(Time.CurrentMember, [Qtr1])

OR IsChild([Qtr1],Time.CurrentMember),<true-part>, <false-part>)

@ISISIBLING(Qtr2) /* Calc */IIF(Is(Time.CurrentMember,[Qtr2])

OR IsSibling([Qtr2], Time.CurrentMember),<true-part>, <false-part>

Calc allows a collection of members orcross members that do not subscribe tothe rules of an MDX set to appear as thesecond argument. This functionality can-not be easily replicated without enumerat-ing each element of the second set andtesting for intersection.

However if the second argument sub-scribes to MDX set rules then the transla-tion is easier as shown. For example:@ISMBR(“New York”: “New Hampshire”) /* Calc */

IIF (Count(Intersect({MemberRange([New York],

[New Hampshire])},{Market.CurrentMember})) = 1,<true-part>, <false-part>)/* MDX */

CALC MDX REMARKS

Page 22: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

@ISPARENT

@ISSAMEGEN/LEV

@ISSIBLING

@ISUDA

@LIST

@LN, @LOG/10

@L(R)SIBLINGS

@MATCH

@MAX

Use IsChild

IIF (member. generation() =CurrentMember(dimension).generation()), TRUE, FALSE)

IsSibling

IsUda

-

Ln, Log, Log10

Max

@ISPARENT(“New York”) /* Calc */ISCHILD(Market.CurrentMember,[New York]) --MDX

@ISSAMEGEN(West) /* Calc */IIF (

Ordinal(Market.CurrentMember.Generation) =Ordinal(West.Generation), <true-part>,<false-part>)/* MDX * /

If the memberset does not subscribeto MDX set rules, then explicit enu-meration is required. For rangelist useCrossJoin(member, set)

@LSiblings(Florida) /* Calc */MemberRange(Florida.FirstSibling,

Florida.Lag(1)) –MDX@Rsiblings(Florida) /* Calc */MemberRange(Florida.Lead (1),

Florida.LastSibling) –MDX

Use Max if argument list is a set.Otherwise rewrite logic using Caseconstructs by explicit enumeration ofthe argument list.@MAX(Jan:Mar) /* Calc */Max(MemberRange([Jan],[Mar])) --MDX

CALC MDX REMARKS

Page 23: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

@MAXRANGE

@MAXS

@MAXSRANGE

Max

Max

Max

@MAXRANGE(Sales,@Children(Qtr1))/* Calc */

Max(CrossJoin({Sales},{[Qtr1].Children})) /* MDX */or

Max([Qtr1].Children, Sales) --MDX

@MAXS (SKIPMISSING, Sales, @Children(Qtr1)) /* Calc */

Max(Filter(Children([Qtr1]),Sales <> Missing)) --MDX

For SKIPZERO the translation is:Max(Filter (Children([Qtr1]),Sales <> 0)) --MDX

For SKIPBOTH, the translation is:Max(Filter(Children([Qtr1]),

Sales <> 0 AND Sales <> Missing)) –MDX

@MAXSRANGE(SKIPMISSING,Sales, @Children(Qtr1)) /* Calc */Max(Filter (Children([Qtr1]),

Sales <> Missing)) --MDX

For SKIPZERO the translation is:Max(FILTER(Children([Qtr1]),

Sales <> 0)) --MDX

For SKIPBOTH the translation is:Max(Filter(Children([Qtr1]),Sales <> 0 AND Sales <> Missing))/* MDX */

CALC MDX REMARKS

Page 24: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

@MDANCESTVAL

@MDPARENTVAL

@MDSHIFT

See “Remarks” for@MDANCESTVAL butreplace Ancestor withParent.

See @NEXT and repeat thesame for each dimensionthat needs to be shifted.Cross join the results fromeach dimension and get thevalue of the final tuple. See“Remarks” for @MDANCESTVAL.

Find the ancestor along each dimen-sion, cross join the result with theancestor along the next dimensionand so on until all dimensions arecovered. Next cross join with thecross member if present. Finally, getthe value of the cell.

NOTE: Crossjoin requires that thetuples or sets of members for the twoarguments be from different dimen-sions, whereas Calc is flexible aboutthe same dimension appearing in thecross member. If the same dimensionappears in the cross member as well,then simply skip seeking the ancestoralong that dimension.

@MDANCESTVAL(2, Market, 2,Product, 2, Sales) /* Calc */(Sales,

Ancestor(Market.CurrentMember, 2),Ancestor(Product.CurrentMember, 2) ).Value/* MDX */

@MDPARENTVAL(2, Market, Product,Sales) /* Calc */(Sales, Market.CurrentMember.Parent,Product.CurrentMember.Parent).Value/* MDX */

CALC MDX REMARKS

Page 25: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

@MEDIAN

@MEMBER

@MERGE

@MIN

@MINRANGE

@MINS

@MINSRANGE

@MOD

@MODE

@NAME

-

-

Union(set1,set2)

Same rules as @MAX,except use Min instead ofMax.

Same rules as@MAXRANGE, except useMin instead of Max.

Same rules as @MAXS,except use Min instead ofMax.

Same rules as @MAXS-RANGE, except use Mininstead of Max.

Mod

-

-

Not available

Not needed in MDX

If the lists specified as inputs to@MERGE do not subscribe to therules of an MDX set, then the@MERGE function cannot be translat-ed. The following example assumesthat the lists doe subscribe to MDXset rules.

@Merge(@Children(East), @Children(West)) /* Calc */

{Union([East].Children, [West].Children)} --MDX

Not supported in MDX

Not needed in MDX

CALC MDX REMARKS

Page 26: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

@NEXT

@NEXTS

@PARENT

@PARENTVAL

@POWER

@Next(mbr,[n, range]) returnsthe nth cell value in therange from the suppliedmember. The functionreturns missing value if thesupplied member does notexist in the range. If range isnot specified, level 0 mem-bers of time are used.

MDX does not have anequivalent function for anarbitrary range. However ifthe range is restricted tomembers from a specificlevel or generation, thenusing NextMember (if n=1)or Lead/Lag will work asshown in the sample transla-tion. This is probably thecommon case.

No support

member.Parent

Value(Crossjoin(crossmem-ber, Parent(CurrentMember(dimension)))

Power

@Next(Cash) /* Calc */(NextMember([Year].CurrentMember,LEVEL), [Cash]).Value/* MDX */

Alternatively@Next(Cash, 2) /* Calc */CrossJoin(

Year.CurrentMember.Lead(2, LEVEL), Cash).Value/* MDX */

@PARENTVAL(Market, Sales) /* Calc */

([Sales], [Market].CurrentMember.Parent).Value

/* MDX */

CALC MDX REMARKS

Page 27: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

@PRIOR

@PRIORS

@RANGE

@RANK

@RELATIVE

@REMAINDER

@REMOVE

@ROUND

@SHIFT

@SIBLINGS

@STDEV/P/RANGE

Same as @Next

No support

CrossJoin(member, rangeset)

No support. This is a vectorfunction

REMAINDER

Except(set1, set2)

Round

See @PRIOR and @NEXT

Siblings

No support

@Prior(Cash) /* Calc */(PrevMember(Year.CurrentMember,LEVEL), [Cash]).Value /* MDX */

Alternatively@Prior(Cash, 2) /* Calc */

(Year.CurrentMember.Lag(2, LEVEL), [Cash]).Value/* MDX */

Calc automatically uses level 0 mem-bers of time dimension if a range isunspecified. That feature does notexist in MDX, so you must explicitlyinclude the range.@RANGE(Sales, @Children(East))

/* Calc */CrossJoin({Sales},{[East].Children}) /* MDX */

Translation will work only if set1 andset2 are true MDX sets.

Not supported

CALC MDX REMARKS

Page 28: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

[ ]

@SUBSTRING

@SUM

@SUMRANGE

@TODATE

@TRUNCATE

@UDA

@VAR/@VARPER

@VARIANCE/@VARIANCEP

@WITHATTR

@XREF

@XRANGE

No support

Sum

Sum(CrossJoin(member,rangeset))

ToDate

Truncate

Uda

Arg1 – Arg2

Not supported

WithAttr

No support.

No support

Convert each element of the explistto a tuple so collectively the tuplescan form a set.

An aggregate storage outline has noexpense tags. So variance functional-ity defaults to subtraction.

CALC MDX REMARKS

Page 29: Converting Calc Formulas to MDX, Hyperion Essbase Outlines, Block

, ..

Hyperion is the global leader in Business Performance

Management software. More than 9,000 customers – includ-

ing 91 of the FORTUNE 100 – rely on Hyperion software to

translate strategies into plans, monitor execution and provide

insight to improve financial and operational performance.

Hyperion combines the most complete set of interoperable

applications with the leading business intelligence platform to

support and create Business Performance Management

solutions. A network of more than 600 partners provides the

company’s innovative and specialized solutions and services.

Named one of the FORTUNE 100 Best Companies to

Work For 2004, Hyperion employs approximately 2,600

people in 20 countries. Distributors represent Hyperion in an

additional 25 countries. Headquartered in Sunnyvale,

California, Hyperion – together with recently acquired Brio

Software Inc. – generated combined annual revenues of $612

million for the 12 months ending June 30, 2003. Hyperion is

traded under the Nasdaq symbol HYSL. For more informa-

tion, please visit www. hyperion.com, www.hyperion.com/

contactus or call 800 286 8000 (U.S. only).

© 2004 Hyperion Solutions Corporation. All rights reserved. “Hyperion,” the Hyperion “H” logo, “Business Intelligence” and Hyperion’s product names are trademarks of Hyperion.References to other companies and their products use trademarks owned by the respective companies and are for reference purpose only. 4395_0604

,

. . . . . .

[ ]