Files
gh-secondsky-sap-skills-ski…/references/analytics-designer-planning.md
2025-11-30 08:55:30 +08:00

24 KiB

SAP Analytics Cloud - Analytics Designer Planning Reference

Source: SAP Analytics Designer Planning Documentation (Planning.pdf) Last Updated: 2025-11-23


Table of Contents

  1. Overview
  2. Getting the Planning Object
  3. Enabling and Disabling Planning
  4. Refreshing Data
  5. User Input and Data Entry
  6. Planning Versions
  7. Version Management Operations
  8. Version Copying
  9. Data Locking
  10. Planning Events
  11. Members on the Fly
  12. Planning Categories

Overview

Analytics Designer reuses the Planning features of SAP Analytics Cloud and leverages capabilities through flexible scripting for customizing applications according to user requirements. Planning Data Models, Allocations, Data Action Triggers, and all Planning features can be integrated into applications.

What Analytics Designer CAN Do

  • Integrate Planning Data Models
  • Trigger Allocations via scripting
  • Execute Data Actions
  • Manage Versions programmatically
  • Control Data Locking via API
  • Create/Update/Delete dimension members dynamically

What Analytics Designer CANNOT Do

  • Use Input Tasks
  • Planning scripting for models based on BPC Write-Back

Getting the Planning Object

Access planning functionality through the Table widget's getPlanning() method.

Syntax

Table.getPlanning(): Planning | undefined

Return Value

  • Returns Planning object if the table has a planning model assigned
  • Returns undefined if no planning model is assigned

Example

var planning = Table_1.getPlanning();
if (planning) {
    console.log("Planning model is assigned");
} else {
    console.log("No planning model assigned to this table");
}

Enabling and Disabling Planning

Planning can be enabled/disabled both at design time and runtime.

Design Time Configuration

In the Table's Builder panel, under Properties section:

  • Planning enabled: Checkbox to enable planning capabilities
  • Mass Data Entry as default: Optional setting for bulk data entry

Runtime Scripting

Enable/Disable Planning

setEnabled(boolean): void

Use Case: Disable planning based on business rules (e.g., no budget changes in Q4).

// Disable planning if current date is in Q4
var currentMonth = new Date().getMonth() + 1;
if (currentMonth >= 10) {
    Table_Budget.getPlanning().setEnabled(false);
    Application.showMessage("Budget changes are locked in Q4");
}

Check Planning Status

isEnabled(): boolean

Example:

var planning = Table_1.getPlanning();
if (planning && planning.isEnabled()) {
    // Proceed with planning operations
    performPlanningUpdate();
} else {
    Application.showMessage("Planning is not enabled");
}

Unbooked Data Configuration

In the Table's Builder panel, configure Unbooked Data per dimension to show dimension members without existing data. Useful when:

  • Planning model has no booked data yet
  • End users need to see available members for planning

Refreshing Data

The refreshData() method refreshes all data models and widgets in the application.

Syntax

Application.refreshData(): void

When to Use

  • After data model updates via Live Connectivity
  • When background process finishes updating master data
  • After application is reopened
  • After external data changes

Example

// Refresh button onClick event
function onRefreshClick() {
    Application.showBusyIndicator();
    Application.refreshData();
    Application.hideBusyIndicator();
    Application.showMessage("Data refreshed successfully");
}

User Input and Data Entry

Setting User Input

Update cell values programmatically using setUserInput().

setUserInput(selectedData: Selection, value: String): boolean

Parameters

Parameter Type Description
selectedData Selection Cell selection from table
value String Value to set (max 17 characters)

Return Value

  • true: Value was set successfully
  • false: Value could not be set (locked cell, invalid value)

Value Format Rules

Format Type Example Description
Raw Value "1234.567" Direct numeric value (uses user's formatting settings)
Scale Factor "*0.5" Multiply current value by factor
Scale Factor "*2" Double the current value

Scaling Examples (Million Scale)

Input Raw Value Formatted Display
"12345678" 12345678 "12.35"
"123456789" 123456789 "123.46"
"*0.5" of 123456789 61728394.5 "61.73"

Constraints

  • Maximum value length: 17 characters
  • If value is scaled: less than 7 digits
  • Can be performed from widget events or table events

Data Validation Behavior

Scenario API Return User Feedback
Invalid value false Error/warning message shown
Same value planned twice true Value is set
Cell is locked false Warning message shown

Example: Custom Input Form

// Save Data button onClick
function onSaveData() {
    var selection = Table_1.getSelections()[0];
    var newValue = InputField_Value.getValue();

    if (!selection) {
        Application.showMessage("Please select a cell first");
        return;
    }

    var success = Table_1.getPlanning().setUserInput(selection, newValue);

    if (success) {
        Table_1.getPlanning().submitData();
        Application.showMessage("Value saved successfully");
    } else {
        Application.showMessage("Failed to save value - check if cell is locked");
    }
}

Submitting Data

Submit all pending changes to the planning model.

submitData(): boolean

Important: Always call submitData() after setUserInput() to persist changes.

// Submit all changes
Table_1.getPlanning().submitData();

Planning Versions

SAP Analytics Cloud supports two types of planning versions: Private and Public.

Private Versions

Private versions are only visible to the user who created them and other SAP Analytics Cloud solutions cannot see this data.

Get All Private Versions

getPrivateVersions(): [Array of Planning Private Versions] | empty array

Get Specific Private Version

getPrivateVersion(versionId: String): Planning Private Version | undefined

Get Owner ID

Returns the user ID of the user who created the private version.

getOwnerID(): String

Public Versions

Public versions are visible to all users and all solutions of SAP Analytics Cloud.

Get All Public Versions

getPublicVersions(): [Array of Planning Public Versions] | empty array

Get Specific Public Version

getPublicVersion(versionId: String): Planning Public Version | undefined

Version Common Methods

Both version types support:

// Get internal ID (for getData() calls)
getId(): String

// Get display ID (for UI dropdowns/texts)
getDisplayId(): String

// Delete version (all versions except 'Actual' can be deleted)
deleteVersion(): boolean

Example: List All Versions

function listAllVersions() {
    var planning = Table_1.getPlanning();

    console.log("=== Private Versions ===");
    var privateVersions = planning.getPrivateVersions();
    for (var i = 0; i < privateVersions.length; i++) {
        var pv = privateVersions[i];
        console.log(pv.getId() + " - Owner: " + pv.getOwnerID());
    }

    console.log("=== Public Versions ===");
    var publicVersions = planning.getPublicVersions();
    for (var j = 0; j < publicVersions.length; j++) {
        var pub = publicVersions[j];
        console.log(pub.getId() + " (" + pub.getDisplayId() + ")");
    }
}

Version Management Operations

Automatic Save Behavior

Any change in data in any type of version is automatically saved. Even if the browser is closed unexpectedly, data will still be present when the application is reopened by the same user who changed the data.

Publishing and Reverting

To make private data visible to other users, publish the public version.

Check for Unpublished Changes (Dirty Check)

isDirty(): boolean

Visual Indicator: Dirty versions show an asterisk (*) after the version name.

// Check before showing publish dialog
var version = Table_1.getPlanning().getPublicVersion("Forecast");
if (version.isDirty()) {
    // Show publish option
    Button_Publish.setEnabled(true);
} else {
    Application.showMessage("No changes to publish");
}

Revert Changes

Discard all data changes.

revert(): boolean

Publish Changes

Make changes visible to other users.

publish(): boolean

Success/Failure Messages

After executing publish() or revert():

Scenario Message
Success "Version has been published successfully"
No Changes "You can't publish or revert version 'X' because you have not modified it"

Publishing Private Versions

Private versions have two publishing options:

Option 1: Publish to Original Source

publish(): boolean

Option 2: Publish As New Public Version

publishAs(newVersionName: String, versionCategory: PlanningCategory): boolean

Parameters:

  • newVersionName: Name for the new public version
  • versionCategory: Category for the new version (see Planning Categories)

Example: Version Publish Dialog in Popup

// Useful when planning table is in a popup
// (toolbar is in background Canvas)

function onPublishButtonClick() {
    var planning = Table_1.getPlanning();
    var privateVersion = planning.getPrivateVersion();

    if (!privateVersion) {
        Application.showMessage("No private version available");
        return;
    }

    if (!privateVersion.isDirty()) {
        Application.showMessage("No changes to publish");
        return;
    }

    Application.showBusyIndicator();

    var success = privateVersion.publish();

    Application.hideBusyIndicator();

    if (success) {
        Application.showMessage("Published successfully");
        Popup_Planning.close();
    } else {
        Application.showMessage("Publish failed");
    }
}

Publish and Leave Dialog

SAP Analytics Cloud reminds users to publish data changes before leaving the application.

To disable this dialog:

  1. Go to Canvas Styling panel at design time
  2. Under Planning Settings
  3. Deselect "Remind of publishing all data changes before leaving"

Version Copying

Create copies of versions using the copy() method.

Syntax

copy(newVersionName: string, planningCopyOption: PlanningCopyOption, versionCategory?: PlanningCategory): boolean

PlanningCopyOptions Enumeration

Option Description
PlanningCopyOptions.NoData Create a new empty version
PlanningCopyOptions.AllData Copy all data from the source version
PlanningCopyOptions.PlanningArea Copy only planning area data from source

Example: Copy Version

function copyActualToBudget() {
    var planning = Table_1.getPlanning();
    var actualVersion = planning.getPublicVersion("Actual");

    if (actualVersion) {
        var success = actualVersion.copy(
            "Budget_2025",
            PlanningCopyOptions.AllData,
            PlanningCategory.Budget
        );

        if (success) {
            Application.showMessage("Budget version created");
            Application.refreshData();
        }
    }
}

Data Locking

The Data Locking script API allows checking and setting lock states even if the table isn't planning-enabled.

Data Locking API Methods

// Get data locking object
Table.getPlanning().getDataLocking()

// Get lock state for selection
Table.getPlanning().getDataLocking().getState(selection)

// Set lock state for selection
Table.getPlanning().getDataLocking().setState(selection, state)

Checking Data Locking Enabled

var planning = Table_1.getPlanning();
var dataLocking = planning.getDataLocking();

if (dataLocking) {
    console.log("Data locking is enabled on this model");
} else {
    console.log("Data locking is not enabled");
}

Note: You can also verify data locking in SAP Analytics Cloud Model Preferences.

Getting Lock State

getState(selection): DataLockingState | undefined

Returns: One of the DataLockingState values or undefined if state cannot be determined.

DataLockingState Enumeration

State Description
DataLockingState.Open Data can be edited by anyone
DataLockingState.Restricted Only owner can edit
DataLockingState.Locked No edits allowed by anyone
DataLockingState.Mixed Selection contains multiple lock states

Undefined Return Conditions

getState() returns undefined when:

  • Selection is invalid
  • Cell referenced by selection isn't found
  • Cell is in unknown state
  • Cell was created using "Add Calculation" at runtime

Example: Get Lock State

var selection = Table_1.getSelections()[0];
var dataLocking = Table_1.getPlanning().getDataLocking();

var lockState = dataLocking.getState(selection);

switch (lockState) {
    case DataLockingState.Open:
        console.log("Cell is open for editing");
        break;
    case DataLockingState.Restricted:
        console.log("Only owner can edit");
        break;
    case DataLockingState.Locked:
        console.log("Cell is fully locked");
        break;
    case DataLockingState.Mixed:
        console.log("Selection has mixed lock states");
        break;
    default:
        console.log("Lock state unknown");
}

Setting Lock State

setState(selection, state): boolean

Returns: true if successful, false otherwise.

Restrictions

  • Cannot set on private versions: Error message: "You can only set data locks on public versions. Please use a public version and try again."
  • Cannot set Mixed state: Error message: "You can't set the state with the value 'mixed'. Please specify either 'open', 'restricted' or 'locked' as value."
  • Multiple cell selection: Lock state is applied to first selection only

Valid States to Set

  • DataLockingState.Open
  • DataLockingState.Restricted
  • DataLockingState.Locked

Example: Set Lock State

var selection = Table_1.getSelections()[0];
var dataLocking = Table_1.getPlanning().getDataLocking();

var success = dataLocking.setState(selection, DataLockingState.Locked);

if (success) {
    Application.showMessage("Data locked successfully");
} else {
    Application.showMessage("Failed to lock data");
}

Show Locks Option

If Show Locks option is activated for the table, lock icons update automatically after getState() or setState() completes.

Important Notes

  • Disabling data locking on a model deletes all locks
  • Re-enabling data locking resets all members to default locking state
  • Same behavior if default locking state or driving dimensions are changed

Planning Events

Two planning-related widgets provide onBeforeExecute events.

BpcPlanningSequence Widget

onBeforeExecute(): boolean

Called when user clicks the BPC planning sequence trigger.

Return Value Behavior
true or no value BPC planning sequence executes
false BPC planning sequence is ignored

DataActionTrigger Widget

onBeforeExecute(): boolean

Called when user clicks the data action trigger.

Return Value Behavior
true or no value Data action executes
false Data action is ignored

Example: Conditional Data Action Execution

// DataActionTrigger onBeforeExecute event
function onBeforeExecuteDataAction() {
    // Check if user has confirmed
    if (!userConfirmed) {
        Application.showMessage("Please confirm before executing");
        return false; // Prevent execution
    }

    // Check data locks
    var selection = Table_1.getSelections()[0];
    var lockState = Table_1.getPlanning().getDataLocking().getState(selection);

    if (lockState === DataLockingState.Locked) {
        Application.showMessage("Cannot execute - data is locked");
        return false; // Prevent execution
    }

    return true; // Allow execution
}

Members on the Fly

The PlanningModel script API allows adding, updating, retrieving, and deleting dimension members dynamically.

Create Members

PlanningModel_1.createMembers(dimensionId, memberData)

Example:

PlanningModel_1.createMembers("LOCATION", {
    id: "BERLIN",
    description: "Berlin"
});

Note: Creating multiple members with same ID results in an error.

Update Members

PlanningModel_1.updateMembers(dimensionId, memberData)

Example (adding data locking owner):

PlanningModel_1.updateMembers("LOCATION", {
    id: "BERLIN",
    dataLockingOwners: [{
        id: "ADMIN",
        type: UserType.User
    }]
});

Get Single Member

var member = PlanningModel_1.getMember(dimensionId, memberId);
console.log(member.description);

Get Multiple Members (with Pagination)

var members = PlanningModel_1.getMembers(dimensionId, options);

Example (get members 5-12):

var members = PlanningModel_1.getMembers("LOCATION", {
    offset: "4",  // 0-indexed, so 4 = 5th member
    limit: "8"    // Return 8 members
});

Member Property Access Rights

Certain member properties require specific rights/access on the dimension:

Property Required Right/Access
dataLockingOwner Data Locking Ownership
responsible Responsible
readers Data Access Control
writers Data Access Control

Important Notes

Dimension Type Restriction

Members can only be added to dimensions of type "Generic". Adding members to these types is NOT supported:

  • Account
  • Version
  • Time
  • Organization

Refresh After Changes

After adding, updating, or deleting members, call refresh:

DataSource.refreshData()
// or
Application.refreshData()

This is required for charts/tables to reflect modified members in subsequent calls to:

  • DataSource.getPlanning().getState()
  • DataSource.getPlanning().setState()
  • DataSource.getData()
  • Planning.setUserInput()

Large Model Considerations

After adding members to very large models (millions of members), not all members may display immediately after refresh due to asynchronous background operations. Repeat the refresh after a short delay.

Custom Property Naming

When adding custom properties to planning members, use a prefix to avoid name conflicts with existing properties.

Complete Member Management Example

// Create new cost center
function createCostCenter(id, description, region) {
    Application.showBusyIndicator();

    try {
        PlanningModel_1.createMembers("CostCenter", {
            id: id,
            description: description,
            properties: {
                "CUSTOM_Region": region,
                "CUSTOM_Status": "Active"
            },
            dataLockingOwners: [{
                id: Application.getUserInfo().userId,
                type: UserType.User
            }]
        });

        // Refresh to see new member
        Application.refreshData();

        Application.showMessage("Cost center created: " + id);
    } catch (e) {
        Application.showMessage("Error: " + e.message);
    } finally {
        Application.hideBusyIndicator();
    }
}

Planning Categories

Version categories classify versions in planning models.

PlanningCategory Enumeration

Category Description
PlanningCategory.Actual Historical/actual data (auto-created, cannot be deleted)
PlanningCategory.Planning General planning version
PlanningCategory.Budget Budget version
PlanningCategory.Forecast Forecast version
PlanningCategory.RollingForecast Rolling forecast version

Usage in Version Operations

// Create new version with specific category
privateVersion.publishAs("Forecast_Q4", PlanningCategory.Forecast);

// Copy with category
sourceVersion.copy("Budget_2025", PlanningCopyOptions.AllData, PlanningCategory.Budget);

Quick Reference Cheat Sheet

// === PLANNING OBJECT ===
var planning = Table_1.getPlanning();  // Returns Planning | undefined
planning.isEnabled();                   // Check if planning enabled
planning.setEnabled(true);              // Enable/disable planning

// === DATA ENTRY ===
planning.setUserInput(selection, "100");    // Set absolute value
planning.setUserInput(selection, "*1.1");   // Increase by 10%
planning.submitData();                       // Submit changes

// === REFRESH ===
Application.refreshData();  // Refresh all data sources

// === VERSIONS ===
planning.getPublicVersions();                    // All public versions
planning.getPublicVersion("Budget");             // Specific public version
planning.getPrivateVersions();                   // User's private versions
planning.getPrivateVersion("MyDraft");           // Specific private version

// === VERSION OPERATIONS ===
version.getId();              // Internal ID
version.getDisplayId();       // Display ID
version.isDirty();            // Has unsaved changes?
version.publish();            // Publish to source
version.publishAs("NewVer", PlanningCategory.Budget);  // Publish as new
version.revert();             // Discard changes
version.deleteVersion();      // Delete version
version.copy("Copy", PlanningCopyOptions.AllData);     // Copy version

// === DATA LOCKING ===
var locking = planning.getDataLocking();
locking.getState(selection);  // Open, Restricted, Locked, Mixed
locking.setState(selection, DataLockingState.Locked);

// === MEMBERS ON THE FLY ===
PlanningModel_1.createMembers("Dim", {id: "X", description: "Y"});
PlanningModel_1.updateMembers("Dim", {id: "X", description: "Z"});
PlanningModel_1.getMember("Dim", "X");
PlanningModel_1.getMembers("Dim", {offset: "0", limit: "100"});

// === ENUMERATIONS ===
// DataLockingState: Open, Restricted, Locked, Mixed
// PlanningCopyOptions: NoData, AllData, PlanningArea
// PlanningCategory: Actual, Planning, Budget, Forecast, RollingForecast
// UserType: User

Documentation Links: