# 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