Files
gh-secondsky-sap-skills-ski…/references/api-data-operations.md
2025-11-30 08:55:33 +08:00

527 lines
14 KiB
Markdown

# SAC Data Operations API Reference
Comprehensive guide for working with data sources, filters, hierarchies, and members in SAP Analytics Cloud scripting.
---
## Table of Contents
1. [Data Sources Overview](#data-sources-overview)
2. [Range and Exclude Filters](#range-and-exclude-filters)
3. [Getting Dimension Filters](#getting-dimension-filters)
4. [Dimension Properties](#dimension-properties)
5. [Hierarchies](#hierarchies)
6. [Getting Members](#getting-members)
7. [DataSource Information](#datasource-information)
8. [Pattern-Based Functions](#pattern-based-functions)
---
## Data Sources Overview
Data sources are accessed through data-bound widgets:
```javascript
var ds = Chart_1.getDataSource();
var ds = Table_1.getDataSource();
```
### Key Method Categories
| Category | Methods |
|----------|---------|
| Filters | `setDimensionFilter()`, `removeDimensionFilter()`, `getDimensionFilters()` |
| Members | `getMembers()`, `getMember()` |
| Dimensions | `getDimensions()`, `getDimensionProperties()` |
| Hierarchies | `setHierarchy()`, `setHierarchyLevel()`, `expandNode()`, `collapseNode()` |
| Data | `getData()`, `getResultSet()`, `refreshData()` |
| Variables | `getVariables()`, `setVariableValue()` |
---
## Range and Exclude Filters
The `DataSource.setDimensionFilter()` method supports both range filters and exclude filters.
### Exclude Filters
Filter out specific members from the drill-down.
**Single Value Include**:
```javascript
// Keep only employee ID 230 in drill-down
DS_1.setDimensionFilter("EMPLOYEE_ID", {value: "230"});
```
**Single Value Exclude**:
```javascript
// Remove employee ID 230 from drill-down
DS_1.setDimensionFilter("EMPLOYEE_ID", {value: "230", exclude: true});
```
**Multiple Values Include**:
```javascript
// Keep employees 230 and 240 in drill-down
DS_1.setDimensionFilter("EMPLOYEE_ID", {values: ["230", "240"]});
```
**Multiple Values Exclude**:
```javascript
// Remove employees 230 and 240 from drill-down
DS_1.setDimensionFilter("EMPLOYEE_ID", {values: ["230", "240"], exclude: true});
```
### Range Filters
Filter ranges of members in the drill-down.
**Important Limitations**:
- Range filters can **only be applied to numeric dimensions**
- A time dimension is **not** a numeric dimension
- SAP BW does **not** support numeric dimensions
**Between Range**:
```javascript
// Keep employees with IDs between 230 and 240
DS_1.setDimensionFilter("EMPLOYEE_ID", {from: "230", to: "240"});
```
**Less Than**:
```javascript
// Keep employees with IDs less than 230
DS_1.setDimensionFilter("EMPLOYEE_ID", {less: "230"});
```
**Less Than or Equal**:
```javascript
// Keep employees with IDs less than or equal to 230
DS_1.setDimensionFilter("EMPLOYEE_ID", {lessOrEqual: "230"});
```
**Greater Than or Equal**:
```javascript
// Keep employees with IDs greater than or equal to 230
DS_1.setDimensionFilter("EMPLOYEE_ID", {greaterOrEqual: "230"});
```
**Greater Than**:
```javascript
// Keep employees with IDs greater than 230
DS_1.setDimensionFilter("EMPLOYEE_ID", {greater: "230"});
```
**Multiple Range Filters**:
```javascript
// Keep employees with IDs less than 230 OR greater than 240
DS_1.setDimensionFilter("EMPLOYEE_ID", [{less: "230"}, {greater: "240"}]);
```
---
## Getting Dimension Filters
Retrieve current filter values with `getDimensionFilters()`.
### Method Signature
```javascript
getDimensionFilters(dimension: string | DimensionInfo): FilterValue[]
```
### Basic Usage
```javascript
var values = Table_1.getDataSource().getDimensionFilters("COUNTRY");
```
### Working with Filter Types
Filter values can be `SingleFilterValue`, `MultipleFilterValue`, or `RangeFilterValue`. Use the `type` property to determine which:
```javascript
var value = Table_1.getDataSource().getDimensionFilters("COUNTRY")[0];
switch (value.type) {
case FilterValueType.Single:
var singleValue = cast(Type.SingleFilterValue, value);
console.log(singleValue.value);
break;
case FilterValueType.Multiple:
var multipleValue = cast(Type.MultipleFilterValue, value);
console.log(multipleValue.values); // Array of values
break;
case FilterValueType.Range:
var rangeValue = cast(Type.RangeFilterValue, value);
console.log(rangeValue.from);
console.log(rangeValue.to);
// Also available: less, lessOrEqual, greater, greaterOrEqual
break;
default:
break;
}
```
### Limitations
- Time range filters are **not** currently returned
- SAP BW may have valid filters not supported by SAP Analytics Cloud
---
## Dimension Properties
Retrieve dimension properties of a data source.
### Method Signature
```javascript
getDimensionProperties(dimension: string | DimensionInfo): DimensionPropertyInfo[]
```
### Usage
```javascript
var properties = Table_1.getDataSource().getDimensionProperties("Location");
for (var i = 0; i < properties.length; i++) {
console.log("Property: " + properties[i].id);
console.log("Description: " + properties[i].description);
}
```
---
## Hierarchies
Set hierarchy levels and expand/collapse nodes.
**Note**: Currently supported only by data sources of **Table** and **Chart** widgets.
### Set Hierarchy Level
```javascript
DataSource.setHierarchyLevel(dimension: string|DimensionInfo, level?: integer): void
DataSource.getHierarchyLevel(dimension: string|DimensionInfo): integer
```
**Chart Example**:
```javascript
var ds = Chart_1.getDataSource();
ds.setHierarchy("Location_4nm2e04531", "State_47acc246_4m5x6u3k6s");
ds.setHierarchyLevel("Location_4nm2e04531", 2);
```
**Table Example**:
```javascript
var ds = Table_1.getDataSource();
ds.setHierarchy("Location_4nm2e04531", "State_47acc246_4m5x6u3k6s");
ds.setHierarchyLevel("Location_4nm2e04531", 2);
```
### Expand/Collapse Hierarchy Nodes
```javascript
DataSource.expandNode(dimension: string|DimensionInfo, selection: Selection): void
DataSource.collapseNode(dimension: string|DimensionInfo, selection: Selection): void
```
**Expand Single Node (Chart)**:
```javascript
// Chart with Location in category axis, hierarchy level 1
// Expand California node
Chart_1.getDataSource().expandNode("Location_4nm2e04531", {
"Location_4nm2e04531": "[Location_4nm2e04531].[State_47acc246_4m5x6u3k6s].&[SA1]",
"@MeasureDimension": "[Account_BestRunJ_sold].[parentId].&[Discount]"
});
```
**Expand All Nodes with Specific Value (Chart)**:
```javascript
// Chart with Location and Product in category axis
// Expand all Alcohol nodes
Chart_1.getDataSource().expandNode("Product_3e315003an", {
"Product_3e315003an": "[Product_3e315003an].[Product_Catego_3o3x5e06y2].&[PC4]",
"@MeasureDimension": "[Account_BestRunJ_sold].[parentId].&[Discount]"
});
```
**Expand Specific Node (Table)**:
```javascript
// Table with Location and Product in rows
// Expand California + Alcohol node
Table_1.getDataSource().expandNode("Location_4nm2e04531", {
"Product_3e315003an": "[Product_3e315003an].[Product_Catego_3o3x5e06y2].&[PC4]",
"Location_4nm2e04531": "[Location_4nm2e04531].[State_47acc246_4m5x6u3k6s].&[SA1]",
"@MeasureDimension": "[Account_BestRunJ_sold].[parentId].&[Discount]"
});
```
---
## Getting Members
### Get Single Member
```javascript
DataSource.getMember(
dimension: string | DimensionInfo,
memberId: string,
hierarchy?: string | HierarchyInfo
): MemberInfo
```
**Flat Hierarchy**:
```javascript
// With flat presentation hierarchy
Table_1.getDataSource().getMember("Location_4nm2e04531", "CT1");
// Returns: {id: 'CT1', description: 'Los Angeles', dimensionId: 'Location_4nm2e04531', displayId: 'CT1'}
```
**With Specific Hierarchy**:
```javascript
// With State hierarchy active
Table_1.getDataSource().getMember(
"Location_4nm2e04531",
"[Location_4nm2e04531].[State_47acc246_4m5x6u3k6s].&[CT1]"
);
// Returns: {id: '[Location_4nm2e04531].[State_47acc246_4m5x6u3k6s].&[CT1]', description: 'Los Angeles', ...}
```
**Important**: Member ID format depends on the active hierarchy:
- Flat hierarchy: `"CT1"`
- Actual hierarchy: `"[Location_4nm2e04531].[State_47acc246_4m5x6u3k6s].&[CT1]"`
### Get Multiple Members
```javascript
DataSource.getMembers(
dimension: string | DimensionInfo,
options?: integer | MembersOptions
): MemberInfo[]
```
**Basic Usage (Limit Count)**:
```javascript
// Get first 3 members
Table_1.getDataSource().getMembers("Location_4nm2e04531", 3);
// Returns array of 3 MemberInfo objects
```
**With Options Object**:
```javascript
Table_1.getDataSource().getMembers("Location_4nm2e04531", {limit: 3});
```
### MembersOptions
```javascript
{
// Type of members: MemberAccessMode.MasterData (default) or MemberAccessMode.BookedValues
accessMode: MemberAccessMode,
// Hierarchy ID (default: currently active hierarchy)
hierarchyId: string,
// Maximum number of returned members (default: 200)
limit: integer
}
```
**With Hierarchy**:
```javascript
Table_1.getDataSource().getMembers("Location_4nm2e04531", {
limit: 2,
hierarchyId: "State_47acc246_4m5x6u3k6s"
});
```
**Master Data vs Booked Values**:
```javascript
// Master Data (all possible members)
Table_1.getDataSource().getMembers("Location_4nm2e04531", {
accessMode: MemberAccessMode.MasterData
});
// Returns all members including states
// Booked Values (only members with data)
Table_1.getDataSource().getMembers("Location_4nm2e04531", {
accessMode: MemberAccessMode.BookedValues
});
// Returns only members that have actual data
```
**Tip**: To find booked values:
1. Create table with dimension
2. Set desired hierarchy
3. Open ... menu → Deselect "Unbooked Values"
4. Table shows only booked values
---
## DataSource Information
Get metadata about a data source.
### Method Signature
```javascript
DataSource.getInfo(): DataSourceInfo
```
### DataSourceInfo Properties
```javascript
class DataSourceInfo {
modelName: string,
modelId: string,
modelDescription: string,
sourceName: string, // SAP BW only
sourceDescription: string, // SAP BW only
sourceLastChangedBy: string, // SAP BW only
sourceLastRefreshedAt: Date // SAP BW only
}
```
**Note**: `sourceName`, `sourceDescription`, `sourceLastChangedBy`, and `sourceLastRefreshedAt` are only supported for SAP BW models. For other models they return `undefined`.
### Usage Example
```javascript
var dsInfo = Table_1.getDataSource().getInfo();
console.log("Model name: " + dsInfo.modelName);
console.log("Model ID: " + dsInfo.modelId);
console.log("Model description: " + dsInfo.modelDescription);
console.log("Source name: " + dsInfo.sourceName);
console.log("Source description: " + dsInfo.sourceDescription);
console.log("Source last changed by: " + dsInfo.sourceLastChangedBy);
var strLastRefresh = "undefined";
if (dsInfo.sourceLastRefreshedAt !== undefined) {
strLastRefresh = dsInfo.sourceLastRefreshedAt.toISOString();
}
console.log("Source last refreshed at: " + strLastRefresh);
```
**SAP BW Output**:
```
Model name: HAL_TEST_Scenario_Query
Model ID: t.H:C9gjfpmu5ntxaf3dbfwtyl5wab
Model description: Sample scenario query
Source name: TEST_SCENARIO_QUERY
Source description: Test Query Scenario
Source last changed by: SYSTEM
Source last refreshed at: 2021-09-23T22:00:00.000Z
```
**SAP HANA Output**:
```
Model name: BestRunJuice_SampleModel
Model ID: t.2.CMRCZ9NPY3VAER9AO6PT80G12:...
Model description: Sample Model
Source name: undefined
Source description: undefined
Source last changed by: undefined
Source last refreshed at: undefined
```
---
## Pattern-Based Functions
Create string transformation functions using input/output examples instead of code.
### Adding Pattern-Based Function
1. In Outline, add a **ScriptObject**
2. Choose **...** → **Add Pattern Based Function**
3. Define function name and description
### Creating the Pattern
1. Click **+** next to "Create Pattern"
2. Define **Training Example**: Input → Output mapping
- Example: `john.doe@sap.com``John Doe`
3. Click **Create** to generate pattern via machine learning
4. Add more examples if ambiguous (up to 3)
5. Click **+** next to "Verify Pattern" to test
6. Click **Done** when complete
### Using in Scripts
```javascript
var fullName = ScriptObject_1.myPatternBasedFunction("joe.doe@sap.com");
// Returns: "Joe Doe"
```
### Example: Date Transformation
Transform dates from `MM.DD.YYYY` to `DD.MM.YY`:
**Training Examples**:
- Input: `10.11.2011` → Output: `11.10.11`
- Input: `09.05.2020` → Output: `05.09.20` (needed for disambiguation)
### Example: String Extraction
Transform appointment text to structured format:
**Input**: `John Doe has an appointment on 06.07.20 at 3:00pm.`
**Output**: `Name: John Doe, Date: 06.07.20, Time: 3:00pm`
### Troubleshooting
- If pattern defaults to returning input, add more training examples
- Click **Reset** to undo changes and restore last working pattern
- Maximum 3 training examples supported
---
## Best Practices
### Filter Performance
```javascript
// GOOD: Pause refresh before multiple filters
var ds = Table_1.getDataSource();
ds.setRefreshPaused(true);
ds.setDimensionFilter("Year", "2024");
ds.setDimensionFilter("Region", "EMEA");
ds.setDimensionFilter("Product", "Widget");
ds.setRefreshPaused(false); // Single backend call
// BAD: Each filter triggers refresh
ds.setDimensionFilter("Year", "2024"); // Refresh
ds.setDimensionFilter("Region", "EMEA"); // Refresh
ds.setDimensionFilter("Product", "Widget"); // Refresh
```
### Member Retrieval
```javascript
// GOOD: Use getResultSet() when possible (no backend trip)
var resultSet = Chart_1.getDataSource().getResultSet();
// EXPENSIVE: getMembers() always hits backend
var members = Chart_1.getDataSource().getMembers("Dimension");
// GOOD: Specify limit to reduce data transfer
var members = ds.getMembers("Dimension", {limit: 50});
// GOOD: Use BookedValues when you only need data with values
var members = ds.getMembers("Dimension", {
accessMode: MemberAccessMode.BookedValues
});
```
---
**Source**: SAP Analytics Designer Development Guide - Chapter 4: Scripting in Analytics Designer
**Last Updated**: 2025-11-23