Sei sulla pagina 1di 12

Adding an Advanced Formulas Action

Follow this guide to use Advanced Formulas.

In this guide, you’ll learn how to:

 Define a scope

 Define a condition for calculation

 Calculation and Data generation

What is Advanced formulas?

Advanced Formulas performs calculations with only base-level cells that don’t any account
formulas defined.

Advanced Formulas syntax is basically designed to be aligned with SAC account dimension
formula and Calculation node. Therefore, the basic understanding of the SAC account dimension
formula will also be helpful for creating Advanced Formulas.

Basically, the Advanced formulas consists of three parts. One is a scope definition. Second one is a
condition to apply various calculation with various condition. Third one is calculation and
calculated data generation.

Define a scope

Usually, users don't want to perform Planning Script against entire SAC model, there must be
a way to handle scope of an SAC model before calculation.

Using MEMBERSET, a user can define the calculation scope. See MEMBERSET

For an instance,

If a user wants to do calculation (Copy 2017 January Sales number into 2018 January Sales plan
with 5% increase), user should define the scope like below.
MEMBERSET [d/ACCOUNT]=”Sales”
MEMBERSET [d/TIME]="201801“
Data([d/CATEGORY]="Plan") = ResultLookup([d/TIME]=Previous(12), [d/CATEGORY]="Actual") * 1.05

Define a condition for calculation

After definition of calculation scope, there could be conditions to apply different calculation in
an Advanced Formulas.

Using IF function, a user can give filter for calculation. There are three kind of conditions which
are possible, member names, attribute values and cell values. See IF

For an instance,

In case some P&L account members which are about balance sheet calculation, there should be
a condition to filter out not balance sheet calculation related to account members.

IF [d/ACCOUNT].[p/BS_CALC]="YES" THEN
Data([d/ACCOUNT]=[d/ACCOUNT].[p/BSACCOUNT], [d/FLOW]="BSCALC") = ResultLookup()
ENDIF

Calculation and Data generation

DATA([d/ACCOUNT]=“Revenue”)=RESULTLOOKUP([d/ACCOUNT]=“Price”, [d/FACTORY]=“#”) *
RESULTLOOKUP([d/ACCOUNT]=“Quantity”)

Right side of equal operator:

It is very similar with Account formula. The cells in current scope will do calculation with this
expression.

DATA([d/ACCOUNT]=“Revenue”)=RESULTLOOKUP([d/ACCOUNT]=“Price”, [d/FACTORY]=“#”) *
RESULTLOOKUP([d/ACCOUNT]=“Quantity”)

Left side of equal operator:

The Data in left side of equal operator is the opposite function of the ResultLookup because it
is setting values not getting. The Data has the same grammar as ResultLookup. The Data can
set value(s) on current scope and it can re-direct calculation result to different cell(s) by
parameter of Data function. If Data function redirects current scope to different one and # of
cell is smaller than current scope, aggregation will happen.

Creating Your First Advanced Formulas

Configuration in Help
Member Selector Functions in help

Add the example below into MEMBERSET for Time dimension

Add the example below into MEMBERSET


MEMBERSET [d/TIME] =”201701” TO “201712”

MEMBERSET [d/FLOW] = (“F_TEMP”, “F_NONE”)


Left value(from) or right value(TO) could be omitted.

MEMBERSET [d/CURRENCY] = [d/ENTITY].[p/CURRENCY]


MEMBERSET [d/TIME] = TO NEXT(12)

MEMBERSET [d/TIME] = PREVIOUS(12) TO

Time functions in help

Data([d/CATEGORY] ="PLAN", [d/TIME] = NEXT(12)) = ResultLookup([d/CATEGORY] ="ACTUAL") *


1.05
Data([d/CATEGORY] ="PLAN") = ResultLookup([d/CATEGORY] ="ACTUAL", [d/TIME] =
PREVIOUS(12)) * 1.05

RESULTLOOKUP([d/S_ACCOUNT]= “Volume”, [d/TIME] = FIRST())

- It returns cell value of First month from current year.

RESULTLOOKUP([d/S_ACCOUNT]= “Volume”, [d/TIME] = PREYEARLAST())

- It returns cell value of last month from previous year.

IF

-- This case is referring other dimension's attribute.

IF ResultLookup([d/ACCOUNT] ="Quantity", [d/PLANT] =[d/PRODUCT].[p/PLANT]) > 0 THEN

--This case is referring own attribute.

IF ResultLookup([d/ACCOUNT] ="Quantity", [d/PLANT] =[d/PLANT].[p/LinkedPLANT]) > 0 THEN

-- IF with BASEMEMBER

IF [d/FLOW] = (BASEMEMBER([d/FLOW].[h/Hierarchy] ,"F_TOTAL" )) THEN

ENDIF

IF [d/ACCOUNT]=”PRICE” THEN

IF RESULTLOOKUP([d/ACCOUNT]=” PRICE”)>0 THEN

ENDIF

ENDIF
Loop

Use cases
There are two use cases at least with the LOOP instruction (FOREACH). Only the two cases are
recommended to use FOREACH Otherwise, it is not recommended.

1. Time sequential calculation such as Carry-Forward.

It will execute content of the Loop period sequentially.

Example,

MEMBERSET [d/TIME] ="201801" TO "201812"

FOREACH [d/TIME]

Data([d/FLOW] ="OPENING") = ResultLookup([d/TIME] =PREVIOUS(1))

Data([d/FLOW] ="DELTA") = ResultLookup() - ResultLookup([d/TIME] =PREVIOUS(1))

ENDFOR
The result of each iteration should work as data source in next iteration. For example,
calculation result of "201801" should be integrated with data source before "201802"
calculation so that "201802" calculation could refer "201801" calculation result.

2. Calculation with specific member combination of dimensions.

MEMBERSET [d/PLANT] =("PLT01", "PLT02")

MEMBERSET [d/TIME] = "201801" TO "201812"

FLOAT TOTREV

IF ResultLookup([d/ACCOUNT] ="Price", [d/AUDIT] ="#") > 0 THEN

FOREACH [d/PLANT], [d/TIME]

TOTREV= 0 // to aggregate quantity by plant & product and use aggregated value for following calculations

IF [d/ACCOUNT] = "REVENUE" THEN

FOREACH // it will scan all records in the scope. So, user should filter out improper record explicitly. If no "revenue" filter, TOTREV will be wrong
because not revenue record will be calculated together.

TOTREV = TOTREV + ResultLookup() // all products per each PLANT

ENDFOR

ENDIF

Data([d/ACCOUNT] ="COGS", [d/AUDIT] ="COSTALLOC") =

ResultLookup([d/ACCOUNT]="PLTCOST",[d/AUDIT]="#",[d/PRODUCT]="#")*
ResultLookup([d/ACCOUNT] ="REVENUE") / TOTREV

Data([d/ACCOUNT] ="PLTCOST", [d/AUDIT] ="#", [d/PRODUCT] ="#") = 0 // because all Plant Cost is allocated

ENDFOR

ENDIF

[d/PLANT] has two members and [d/TIME] has twelve members in the scope tables. Then, there
are twenty-four combination possible for iteration. There are 5 scope tables because of 5
dimensions in the model. For the "FOREACH [d/PLANT], [d/TIME]" loop, PLANT and TIME scope
tables will be touched. In first iteration, two scope tables will be modified to have only one
member for proceeding content of the loop like ("PLT01" and "201801"). In second iteration, the
scope tables will have ("PLT01", "201802"). Then the script in the loop will have only scope tables
for proceeding consistently.

Comparison the result between FOREACH and only IF.

MEMBERSET TIME = ("201701", "201702", "201703")

IF [d/ACCOUNT] ="REVENUE" THEN

IF [d/PRODUCT] ="16GB" THEN

Data([d/CATEGORY] ="PLAN") = ResultLookup([d/CATEGORY] ="ACTUAL", [d/TIME] = PREVIOUS(1)) * 1.05

ENDIF

Original data Result


after
Advance
d
Formula
s

The values will be calculated just previous value with * 1.05. it doesn’t give any
influence to next calculation and value.??

MEMBERSET TIME = ("201701", "201702", "201703")

FOREACH [d/TIME]

IF [d/ACCOUNT] ="REVENUE" THEN

IF [d/PRODUCT] ="16GB" THEN

Data([d/CATEGORY] ="PLAN") = ResultLookup([d/CATEGORY] ="ACTUAL", [d/TIME] = PREVIOUS(1)) * 1.05

ENDIF

END

ENDFOR

Original data Result


after
Advance
d
Formula
s

The result of each iteration should work as data source in next iteration.
DATA

NOTE - Data generation with zero value

Zero and EMPTY are different technically in the analytic cube. EMPTY (unbooked in Orca) means
there is no record in the cell. Zero means summation of records with same POV is zero.

Data = 0

This syntax makes invalidating the current records in the calculation scope. It means setting the
cells of the scope to zero in case there are records in the calculation scope. And the cells will stay
as EMPTY in case there is no record in PDC.

Example,

Data([d/ACCOUNT] ="Price", [d/PLANT] ="#", [d/AUDIT] ="NONE", [d/PRODUCT] ="16GB",


[d/TIME] ="201701") = 0

Based on the calculation, Price of “16GB” product at "201701" with [d/Plant] (#), [d/AUDIT] (None)
will be set as zero . It will generate a below record in case there is a record already and overwrite
cell value with zero whatever the cell value was.

ACCOUNT PLANT AUDIT PRODUCT TIME SIGNEDDATA

PRICE # None 16GB 201701 0

Lookup and Reference Functions in help

Resultlookup- examples
Data([d/ACCOUNT] ="REVENUE", [d/CATEGORY] ="PLAN", [d/TIME] ="201801") =
ResultLookup([d/ACCOUNT] ="REVENUE", [d/CATEGORY] ="ACTUAL", [d/TIME]="201701") * 1.05

This one is to initialize “201801” plan data with 201701 with 5% increase. If there is no filter on
the other dimensions. All REVENUE records of “201701” will be copied to “201801” with 5%
increase.

Data([d/ACCOUNT] ="REVENUE", [d/PLANT] ="PLT01", [d/AUDIT] ="None", [d/PRODUCT] ="16GB", [d/TIME]


="201801") =

ResultLookup([d/ACCOUNT]="Quantity", [d/PLANT] ="PLT01", [d/AUDIT] ="None", [d/PRODUCT]="16GB",


[d/TIME] ="201801") *
ResultLookup([d/ACCOUNT] ="Price", [d/PLANT]="#", [d/AUDIT]="None", [d/PRODUCT] ="16GB", [d/TIME]
="201801")

Note - If ResultLookup has fully qualified POV with fixed members like this example, the scope won't
influence ResultLookup(s).

MEMBERSET [d/PRODUCT] = (“16GB”, “32GB”, “64GB”)


MEMBERSET [d/TIME] = (“201701”, “201702”)

Data([d/ACCOUNT] ="Revenue") =
ResultLookup([d/ACCOUNT] ="Price", [d/PLANT] ="#", [d/AUDIT] ="None") * ResultLookup([d/ACCOUNT] ="Quantity")

The ResultLookup represents a set of values with [d/PRODUCT] and [d/TIME] combination with the defined
parameter calculation scope. Therefore, the Advanced Formulas gets the scope for [d/PRODUCT] (16GB,
32GB, 64GB) and [d/TIME] (201701, 201702) previously with the MEMBERSETs. Then,
ResultLookup([d/ACCOUNT] ="Price", [d/PLANT] ="#", [d/AUDIT] ="None") returns below records.

Mathematical functions
Mathematical and Conditional Operators
Master Data Functions in help

Potrebbero piacerti anche