Use this reference guide to learn about the syntax and semantics of advanced formula steps in SAP Analytics Cloud data actions. It's meant for administrators with an understanding of planning processes and models within SAP Analytics Cloud. You don't need previous scripting experience, though. Advanced formula steps use their own scripting language, which is similar to formulas in SAP Analytics Cloud models. If you write SQL script, you'll also recognize some instructions.
Introduction to Advanced Formulas
Advanced formula steps in data actions give you a lot more flexibility to run calculations on planning model data. The calculation results are stored in the base cells of the model, which means that you can run calculations and copy data across different sets of filters. Similar syntax is available when creating calculated accounts and measures, but most of that syntax is function-based. Planning with advanced formulas requires more procedural functionality, so it exists as a separate language.
Notation Convention
This reference uses syntax notation very similar to Backus-Naur Form (BNF), a notation technique used to define programming languages.
Symbols
This reference guide uses the following symbols to show the relationships between syntax terms.
Symbol
Description
< >
Angle brackets surround the name of a syntactic element.
::=
The definition operator defines the element that appears to its left.
[]
Square brackets indicate optional elements in a formula. You can choose whether to specify or omit optional elements in your script.
{}
Braces group elements in a formula. Repeating elements (zero or more elements) can be specified within brace symbols.
|
The alternative operator indicates that the portion of the formula following the bar is an alternative to the portion preceding it.
[...]
An ellipsis with square brackets around it indicates optional repetition of the preceding element or grouped elements. For example, if you can specify one or more columns for an option and must separate them by commas, this is expressed as: <column_name> [,...]. An example of grouped elements that don't need a comma separator looks like this: { <column_name> <data_type> } [...]
Syntax Term Representations
Throughout this reference guide, each syntax term is defined using one of the following representations:
This option specifies how to deal with unbooked source data. Unbooked data refers to cells with empty values.
Turn it on to treat unbooked source cells as 0 value. In this case, unbooked cells can be included in data to copy and change target value to 0.
If turned off (the default setting), only booked data will be copied. Unbooked data in the calculation results will be ignored and won't change target values.
If this configuration is turned on, all calculations consider the sign value of debit accounts (expense or asset) or credit accounts (income or liability and equity), as shown in the model's fact table. When it's set to off (the default setting), RESULTLOOKUP calculations return account values with automatic sign switching applied to INC and LEQ accounts. In this case, account values will usually be positive numbers.
This configuration governs the hierarchy of one or more dimensions you will be working on in a script. For any dimension that you don't include, the default hierarchy of the dimension will be used instead. This configuration can also be used to govern the hierarchy of a linked model. When specifying the hierarchy of a dimension in a linked model, you can either use CONFIG.HIERARCHY outside a MODEL statement or HIERARCHY inside one.
This configuration expands the calculation scope to include members that aren't in the hierarchy for one or more dimensions. This configuration can also be used to include not in hierarchy member of a linked model. When specifying the dimension in a linked model, you can either use CONFIG.HIERARCHY.INCLUDE MEMBERS NOT IN HIERARCHY outside a MODEL statement or HIERARCHY.INCLUDE MEMBERS NOT IN HIERARCHY inside one.
MODEL < linked_model >
HIERARCHY.INCLUDE_MEMBERS_NOT_IN_HIERARCHY {<dimension>}[,...]
ENDMODEL
Member Selector Functions
Member selector functions help set the overall scope of your step or return members of a dimension that match certain criteria.
MEMBERSET
Use this statement to define the overall dimension member scope.
MEMBERSET statements let you pick which members to include or exclude in your advanced formulas step.
MEMBERSET [d/PRODUCT].[p/FACTOR] = 100 TO %numberParameter%
BASEMEMBER
This function sets the scope to all base members of one or more specific parent members. Base members refer to the leaf members without any child members in a given hierarchy.
MODEL [HR]
MEMBERSET [d/Account_HR] = BASEMEMBER([d/Account_HR].[h/parentId],"Salary_Month_Total" )
ENDMODEL
ELIMMEMBER
This function returns the names of the elimination members below the first common parent of two companies that did inter-company trading.
In the case above, the inter-company transaction data between Korea and China will be eliminated after copying to Elimination Asia, which is the elimination member under their common parent, Asia. For the inter-company transaction data between Korea and France, the value will be copied to Elimination World under their first common parent, World. Using ELIMMEMBER, you can get Elimination Asia as the elimination member of Korea and China and Elimination World as the elimination member of Korea and France.
Use this function to define a leaf member for each aggregated dimension. This leaf member will receive any values that are written to the dimension using the DATA function.
In effect, it works like the Aggregate To option for copy steps and cross-model copy steps in a data action.
To aggregate dimensions of a linked model, define AGGREGATE_DIMENSIONS functions inside a MODEL statement.
You can also use MEMBERSET functions within a MODEL statement to filter the aggregated dimensions. The MODEL statement can also be used to define a linked model scope.
These statements let you define variables in your script. A variable is a named data object that refers to a number or virtual dimension member.
VARIABLEMEMBER
You can define this virtual member to store intermediate calculated values that can be reused elsewhere, whenever necessary, to avoid calculating the value repeatedly.
The virtual variable member will be stored independently and cannot be added to a dimension like a real dimension member. After defining a variable member for a certain dimension, you can use the variable member to store values for that specific dimension only.
Syntax
VARIABLEMEMBER #VariableMemberName OF <measures/dimension>
This function lets you write values and create records based on the scope. By default, DATA functions overwrite existing values in the target scope with specific values, or with data filtered by the RESULTLOOKUP function.
This function lets you to write values and create records based on the scope. If there are existing values in the target scope, the new values are appended to them.
These expressions include functions for reading data within the default model or from a different model, and for carrying forward values over multiple time periods.
RESULTLOOKUP
This function returns a data set of corresponding, specified dimension values filtered by the formula.
The LINK function is used to copy or read data from a different model than the default model in the data action. You can only write data to the default model, so LINK functions can't be defined in DATA functions to write data to the linked model.
LINK functions support classic account models and models with measures (with or without an account dimension) as either the source or target model. You can copy across any of these different model types.
After the linked model scope is defined, the LINK function can be used in a way to offer more functionality and flexibility to cross-model data actions.
The linked mode scope, which can also be called source model scope, determines the dimension members that will be inherited by the dimension filters in the LINK function and other functions like IF and FOREACH. Note that only missing dimensions can be used in the linked model scope defined by MODEL…ENDMODEL, but not all missing dimensions need to be defined in it. If you don't define a missing dimension this way, all its members will be used by the dimension filters in other functions such as LINK. In the LINK function itself, you don't need to select one member for a missing dimension in the function, which means they can be omitted in the LINK function.
Syntax
LINK (<linked_model>,<linked_version>,<linked_member>{,...},[<shared_member>,...])
Syntax Elements
<linked_model> ::= Linked <MODEL>
<linked_version> ::= {<version_dim>=<leaf_member>}
<linked_member> ::= <linked_dimension>= {<leaf_member> | <dimension>.<property>}
<linked_dimension> ::= Local <measures/dimension> of linked MODEL
<shared_member> ::= <shared_dimension>= {<leaf_member> | <dimension>.<property> | <date_scope_function>}
<shared_dimension> ::= Public <dimension> that exists in both the linked and default MODEL.
<date_scope_function> ::= [ PERIOD () | NEXT() | PREVIOUS () | FIRST () | PREYEARLAST () ]
MODEL [Sales]
ENDMODEL
@Volume = ATTRIBUTE([Sales].[d/Product_Item].[p/ProductUnit], "ACAC")
CARRYFORWARD
This business function allows users to carry forward values to the opening amount of new periods. This is a very common way for business users to manage the cash flow of balance sheet statement accounts.
The carry forward function only changes the opening values and closing values (or an alternative target member, if you define one).
This function returns the time period or a date that deducts a specified offset value (a signed integer) of a certain granularity from the current date dimension, a dimension attribute of date format, or a fixed date.
This function returns the number of days in a calendar month taken from a specific date, date dimension, or dimension property. The number returned is an integer.
Syntax
DAYSINMONTH(<date>)
Syntax Elements
<date> ::= <fixed_date> | <date_parameter_single_leaf> | [<linked_model>.]<date_dim> | [<linked_model>.]<dimension>.<date_property> | TODAY()
<date_parameter_single_leaf> ::= <parameter_single_leaf> of <date_dim>
<date_property> ::= <property> with date format
This function returns number of days in a calendar year. The year is a 4-digit number taken from a specific date, date dimension, or dimension property.
Syntax
DAYSINYEAR(<date>)
Syntax Elements
<date> ::= <fixed_date> | <date_parameter_single_leaf> | [<linked_model>.]<date_dim> | [<linked_model>.]<dimension>.<date_property> | TODAY()
<date_parameter_single_leaf> ::= <parameter_single_leaf> of <date_dim>
<date_property> ::= <property> with date format
This function calculates how many days between the start and end date overlap the given period, and then divides the overlapping days by the total number of days in the period.
Syntax
DATERATIO(<start_date>,<end_date>,[<date>])
Syntax Elements
<start_date> ::= <fixed_date> | [<linked_model>.]<dimension>.<date_property> | TODAY()
<end_date> ::= <fixed_date> | [<linked_model>.]<dimension>.<date_property> | TODAY()
<date> ::= <fixed_date> | <date_parameter_single_leaf> | <date_dim> | <dimension>.<date_property> | TODAY()
<date_parameter_single_leaf> ::= <parameter_single_leaf> of <date_dim>
<date_property> ::= <property> with date format
MODEL [BOM]
ENDMODEL
FOREACH [BOM].[d/Product_BOM]
//Statement...
ENDFOR
FOREACH.BOOKED
This function repeats a group of statements for each booked combination of dimension members in a specified scope of one or more dimensions. Compared to FOREACH, this function can improve performance by avoiding unnecessary repetitions on unbooked members.
INTEGER @counter
INTEGER @endValue
@endValue = %Input_End_Number%
FOR @counter = 1 TO @endValue
DATA() = RESULTLOOKUP() * 0.5
ENDFOR
BREAK
To stop the loop based on specific conditions, you can add BREAK to a FOREACH or FOREACH.BOOKED loop. When the condition is met, the remaining calculations in the loop are skipped.
These keywords let you set conditions on a group of statements so that they only run in specific cases.
IF ELSEIF ELSE
IF statements, combined with ELSEIF and ELSE statements, let you conditionally run a group of statements depending on the value of an expression. By combining conditions using OR or AND operators, you can create complex conditions.
Limitations
Measure filters with OR operators are not supported.
When you include a measure filter and a non-measure filter, ELSEIF clauses aren't supported.
For RESULTLOOKUP() functions in a model with measures, a measure needs to be included in the RESULTLOOKUP() function.
Syntax
IF <condition> {[<and_or> <condition>]} THEN
<Statement>
[...]
[ELSEIF <condition> {[<and_or> <condition>]}]
<Statement>
[...]
[ELSE]
<Statement>
[...]
ENDIF
This function lets you specify a number and an integer. It returns a number that has the number of decimal places specified by the integer, and that is as large as possible without being greater than the entered number. The integer is optional and defaults to 0 if you don't specify it.
This function lets you specify a number and an integer. It returns a number that has the number of decimal places specified by the integer, and that is as small as possible without being smaller than the entered number. The integer is optional and defaults to 0 if you don't specify it.
This function returns the floating-point number of a given number. (Note that the FLOAT keyword can also be used to define a variable with a floating-point data type.)