Recent Content
Data Processing and Performance - A comprehensive guide of tables, and design
Overview To maintain well performing application, one must understand how the underlying database works and more importantly its limitations. Understanding how a system works, allows designers and administrators to create reliable, stable, and optimal performing applications. This white paper is intended to guide the design of those optimal data processing strategies for the OneStream platform. First, this document will provide a detailed look at the data structures used by the stage engine as well as those used by the in-memory financial analytic engine, providing a deep understanding of how the OneStream stage engine functions in relation to the in-memory financial analytic engine. The relationship between stage engine data structures and finance engine data structures will be discussed in detail. Understanding how data is stored and manipulated by these engines will help consultants build OneStream applications that are optimized for high-volume data processing. Second, the workflow engine configuration will be examined in detail throughout the document since it acts as the controller / orchestrated of most tasks in the system. The workflow engine is the primary tool used to configure data processing sequences and performance characteristics in an OneStream application. The are many different workflow structures and settings that specifically relate to data processing and these settings will be discussed in relation to the processing engine that they impact. Finally, this document will define best practices and logical data processing limits. This will include suggestions on how to create workflow structures and settings for specific data processing workloads. With respect to data defining processing limits, this document will help define practical / logical data processing limits in relation to hard/physical data processing limits and will provide a detailed explanation of the suggested logical limits. This is an important topic because in many situations the physical data processing limit will accept/tolerate that amount of data that is being processed, but the same data may be able to be processed in a much more efficient manner by adhering to logical limits and building the appropriate workflow structures to partition data. These concepts are particularly important because they enable efficient storage, potential parallel processing and high-performance reporting/consumption when properly implemented. Conclusion Large Data Units can create problems for loading, calculating, consolidating, and reporting data. This really is a limitation of what the hardware and networks can support. Your design needs to consider this. But from this paper, I hope you can take away some options to relieve some of the pressure points that could appear.Dashboard: XFBR String
Business rules written and used as Parameters that return a specific value based on the defined inputs. This Business Rule can be applied to any Dashboard or Cube View property where a Parameter is used. Imports System Imports System.Data Imports System.Data.Common Imports System.IO Imports System.Collections.Generic Imports System.Globalization Imports System.Linq Imports Microsoft.VisualBasic Imports System.Windows.Forms Imports OneStream.Shared.Common Imports OneStream.Shared.Wcf Imports OneStream.Shared.Engine Imports OneStream.Shared.Database Imports OneStream.Stage.Engine Imports OneStream.Stage.Database Imports OneStream.Finance.Engine Imports OneStream.Finance.Database Namespace OneStream.BusinessRule.DashboardStringFunction.XFBRStringExamples Public Class MainClass Public Function Main(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As Object, ByVal args As DashboardStringFunctionArgs) As Object '------------------------------------------------------------------------------------------------------------ 'Reference Code: GetCalcStatus ' 'Usage: This shows different examples of BRString usage in Cube Views and Dashboards ' 'GetCalcStatus ' Parameter Example: ' BRString(XFBRStringExamples, GetCalcStatus, ParamCube = GolfStream, ' ParamEntity = [Houston Heights], ParamParent = Houston, ' ParamCons = USD, ParamScenario = Actual, ParamPeriod = 2011M1) ' 'GetUserIsAdmin ' Parameter Example: BRString(XFBRStringExamples, GetUserIsAdmin) ' 'EntityDesc ' Parameter Example: BRString(XFBRStringExamples, EntityDesc, ParamEntity=[|!MyEntity!|]) ' 'Created By: OneStream 'Date Created: 12-18-2017 '------------------------------------------------------------------------------------------------------------ Try Select Case args.FunctionName Case Is = "GetCalcStatus" 'Get the Passed in parameters Dim paramCubeValue As String = args.NameValuePairs("ParamCube") Dim paramEntityValue As String = args.NameValuePairs("ParamEntity") Dim paramParentValue As String = args.NameValuePairs("ParamParent") Dim paramConsValue As String = args.NameValuePairs("ParamCons") Dim paramScenarioValue As String = args.NameValuePairs("ParamScenario") Dim paramPeriodValue As String = args.NameValuePairs("ParamPeriod") Return BRApi.Finance.Data.GetCalcStatus(si, _ paramCubeValue, paramEntityValue, paramParentValue, _ paramConsValue, paramScenarioValue, paramPeriodValue) Case Is = "GetUserIsAdmin" 'Check to see if the user is an administrator ' (Can be used to hide objects that are administrator only) Return BRApi.Security.Authorization.IsUserInAdminGroup(si) Case Is = "EntityDesc" 'Get the Passed in parameter Dim myEntity As String = args.NameValuePairs("ParamEntity") Dim myEntityDesc As String = BRApi.Finance.Metadata.GetMember( _ si, 0, myEntity).Member.Description Return myEntityDesc End Select Return Nothing Catch ex As Exception Throw ErrorHandler.LogWrite(si, New XFException(si, ex)) End Try End Function End Class End Namespace3.6KViews2likes0CommentsCan you give an example of the best way to sum a row from a cube view? For example, if I add two rows to a cube view, one with a selection of members, how do I make the second row a custom sum of the first? I know one way to do it, but I don’t love it, I would love to see what else you guys recommend.
Clarification – this is referring to using Cube View Row/Column math when members expansions are in use. Answer No “elegant” ways to address this currently – options are: Avoid using member filters (i.e., break the source rows down to more detail) Replicate the member filter in a GetDataCell function on the total row Create a CV Helper function to return the same thing Enhancement Status: There have been numerous enhancement requests to allow CV Row/Column math to work against member expansions, as well as suppressed rows/columns. These have all been approved by Development and should be in one of the upcoming quarterly releases in 2020. Source: Office Hours 2020-03-26 Partner Enablement2.6KViews1like1CommentDashboard: Get or Set Literal Parameter
Literal Parameters are, effectively, application-wide variables that can be used to drive Dashboards and Cube Views. Their values can be set or retrieved in code as shown below. From version 7.3 onwards, they are contained in a Workspace. That means that the relevant calls now require the ID of the Workspace where the Parameter is located. Note that the ID of Default Workspace is an empty Guid. Note: Literal Parameters are effectively shared between all users; which means that, if a Dashboard Action triggered by "User1" modifies a Literal Parameter value, "User2" will also receive the changed value in any Dashboards they are using (at the first refresh). OneStream Version 7.3+ Dim parameterName As String = "MyParameterName" ' if Parameter lives in Dashboards under "System" tab, set this to True Dim isSystemLevel as Boolean = False ' retrieve workspace ID. If it's Default Workspace, you can just use Guid.Empty instead Dim workspaceID As Guid = BRApi.Dashboards.Workspaces.GetWorkspaceIDFromName( _ si, isSystemLevel, workspaceName) ' --- Set literal parameter value Dim newValue As String = "New Literal Value" BRApi.Dashboards.Parameters.SetLiteralParameterValue( _ si, isSystemLevel, workspaceID, parameterName, newValue) ' --- Retrieve literal parameter value Dim pValue as String = BRApi.Dashboards.Parameters.GetLiteralParameterValue( _ si, isSystemLevel, workspaceID, parameterName) OneStream Version 7.2 and below Dim parameterName As String = "MyParameterName" ' if Parameter lives in Dashboards under "System" tab, set this to True Dim isSystemLevel as Boolean = False ' --- Set literal parameter value Dim newValue As String = "New Literal Value" BRApi.Dashboards.Parameters.SetLiteralParameterValue( _ si, isSystemLevel, parameterName, newValue) ' --- Retrieve literal parameter value Dim pValue as String = BRApi.Dashboards.Parameters.GetLiteralParameterValue( _ si, isSystemLevel, parameterName)Cube Dimension Assignment
Summary The following details offer a quick snapshot of this article’s core content and primary focus to ensure that it is most relevant to your needs. What: Cube dimension assignment When: Early build Why: Enable future flexibility How: Assign dimensions to specific Scenario Types and change “(Use Default)” to the Root dimension Overview To enable future flexibility, it is foundationally critical to properly configure the cube dimension assignments prior to loading data. Once data has been loaded to a cube, the assignments for the (Default) Scenario Type are locked in. The Root dimension assignments in the above image can be updated on the (Default) Scenario Type in the future, but any Scenario Types that have data and are set to “(Use Default)” like the image below, cannot be changed. This means that if not configured properly, the entire cube must abide by the updates to the (Default) Scenario Type. If the cube dimensions are configured properly, additional dimensions can be added to specific Scenario Types in the future. The example use case illustrated in this guide is adding a customer dimension in Budget to expand the annual planning capabilities. This guide provides example configurations to illustrate the recommended approach and common misconfigurations. Recommendation When a cube is created, dimension assignments on specific Scenario Types are set to “(Use Default)” on the Cube Dimensions tab. To properly configure an application for extensibility and enable data model flexibility/expansion in the future, these settings should be updated for the active Scenario Types within each cube. (Default) Scenario Type: Assign the Data Unit dimensions of entity and scenario. Leave all non-Data Unit dimensions as Root. For all active Scenario Types: Entity and scenario will remain as “(Use Default).” All non-Data Unit dimensions should be assigned a specific dimension. Select Root for all unused dimensions. “(Use Default)” should not remain for any dimension. Leave inactive Scenario Types as-is until ready to be activated. Use Case & Examples Use Case: A client with a live OneStream application wants to enable a customer dimension in Budget to expand their annual revenue planning capabilities and include their top customers. Data has already been loaded to Actual and a prior year Budget. Configuration #1: Recommended Configuration The recommended configuration of cube dimension assignments will enable the application to take full advantage of extensibility. This configuration will allow the addition of new dimensions to specific Scenario Types in the future and eliminate the need to “stub out” unused dimensions for future use. To configure properly, the Data Unit dimensions (entity and scenario) will be assigned to the (Default) Scenario Type, and all remaining active dimensions will be assigned to their respective active Scenario Types. Any inactive dimensions should be set to "Root” instead of “(Use Default)”. Recommended initial assignment is as follows: (Default) Actual Budget After the Actual and Budget Scenario Types both have data in them, we are still able to change our UD4 Dimension assignment in the Budget Scenario Type to include our new summary customer dimension. **Be aware that once you hit save, the new UD4 assignment will be locked in, and you will be unable to change it if there is data in that cube and Scenario Type combination. Changing from a Root dimension is a one-time change that cannot be reverted if there is data in this cube and Scenario Type combination. ** After adding the new dimension to the Budget Scenario Type, one will see the history in UD4#None, and the new dimension members active for input in subsequent budget cycles. Since it was assigned to the specific Scenario Type and not (Default), you will notice that this new UD4 dimension is invalid for the Actual Scenario Type. This configuration will also allow the future addition of UD5 and UD6 dimensions by following these same steps. Configuration #2: Improper Assignment to the (Default) Scenario Type A common error is to assign all dimensions to the (Default) Scenario Type and only use the Scenario Type-specific tabs for those that differ. This configuration will work and will also allow you to add additional dimensions in the future but is much less flexible. Additional dimensions in this setup must be assigned to the (Default) Scenario Type and will therefore apply to all active scenarios. In the example below, all active dimensions have been assigned to the (Default) Scenario Type and a different Account dimension has been assigned to the Budget Scenario Type to enable the use of extensibility. The remaining non-Data Unit dimensions have been left as (Use Default) for both the Actual and Budget Scenario Types: (Default) Actual Budget In this setup, attempting to assign our new customer dimension to UD4 on the Budget Scenario Type: Will display this error: Due to the use of (Use Default) on the active Scenario Types, they are now locked into whatever the (Default) Scenario Type has set for these dimensions and they cannot be updated. To add our new customer dimension, one is forced to assign it to the (Default) Scenario Type: When assigning to the (Default) Scenario Type, you will notice that it works for Budget as required (same as the recommended configuration), but it is now active for the Actual Scenario Type as well which was not the desired result. With this configuration, existing business rules and member formulas will need to be validated throughout the application to ensure the right intersections are specified. This additional dimension contains valid intersections in all Scenario Types; therefore, rules need to be more explicit in their filtering and writing of data. If written improperly or too open, this new dimension may cause a performance impact or zeros and other bad data being calculated in these new intersections. Configuration #3: Improper Assignment of (Use Default) Another erroneous configuration is to assign all dimensions to their respective Scenario Type but leave unused dimensions as (Use Default). This configuration will also work and will allow you to add additional dimensions in the future, but also is not as flexible as the recommended setup. Additional dimensions in this setup must be assigned to the (Default) Scenario Type and will therefore apply to all active scenarios. In the example below, all active dimensions have been assigned to their respective Scenario Types. The remaining inactive dimensions have been left as (Use Default) for both the Actual and Budget Scenario Types: (Default) Actual Budget In this setup, attempting to assign our new customer dimension to UD4 on the Budget Scenario Type will result in the same error as configuration #2 above: Again, forcing the assignment to the (Default) Scenario Type which will apply to all active Scenario Types with the setting of (Use Default) for UD4. This assignment will also work for Budget, but as with configuration #2 above, you will notice that it is now active for the Actual Scenario Type as well which was not the desired result. As with configuration #2 above, existing business rules and member formulas should be validated throughout the application to ensure the right intersections are specified. Additional no input rules may be necessary to limit input to these intersections in Scenario Types that do not apply. Considerations The recommended configuration for cube dimension assignment eliminates the need to “stub out” unused dimensions for future use. If unused dimensions are assigned to “Root” on their respective Scenario Types, they can be changed in the future. One should not create a placeholder dimension for those that are unused (UD4, UD5, and UD6 in our example above) as this will only limit future flexibility. If additional dimensions are not configured properly, you can only update from Root to a specific dimension once. If you accidentally save an incorrect dimension update, you’re locked into that change. Plan and make sure these settings are properly updated before saving the changes. Despite adding flexibility for the future, configuring the cube dimensions in this way still does not allow you to change active dimensions with data. Conclusion As you can see from the examples above, non-Data Unit dimensions should be assigned to the cube by Scenario Type with (Use Default) changed to the Root dimension for those that are inactive at setup. Assigning non-Data Unit dimensions to the (Default) Scenario Type and leaving (Use Default) on the specific Scenario Types will limit the benefits and flexibility provided by extensibility. Improper setup will force the entire cube to conform to future updates to the (Default) Scenario Type. Conversely, assigning non-Data Unit cube dimensions to specific Scenario Types and utilizing the Root dimensions instead of (Use Default) will open additional growth opportunities for the application. This recommended configuration is also more flexible than “stubbing out” dimensions for future use as you do not have to consider the potential pitfalls related to that design.2.4KViews14likes0CommentsQuestion: Is there a way to report the total of a group of members based on a text attribute with multiple dimensions in a row?
Question (cont) The example below is for an operating expense that I want to be filtered using a text property of “HP” (a specific business line). I thought the following would work, but it is still pulling in the total company business line, not just a total of the “HP” UD3 members. A#Marketing:U1#TotalBU:U2#Top:U3#CustomerGroup_0002.Base.Where(Text1 contains HP):Name(Market) I don’t need an expansion of the customers (UD3) but a total of the relevant members. Answer Using CVR Math in a cubeview row will not work in this situation. CVR Math Example A Dashboard XFBR String will be needed to aggregate the members with the Text property to produce a total. XFBR Example Source: Office Hours 2021-02-04 - Partner Enablement2.3KViews4likes0CommentsExtender: Auto Create Member
This snippet will create a new Account member, including setting some properties that can vary by Scenario Type and/or Time. Note: SaveMemberInfo does not create entries in Audit tables, which means the Audit Metadata report will not contain anything related to this operation. For this reason, we do not recommend to use this snippet outside of implementation activities or in production environments. 'Create a new MemberInfo object with its child objects. Dim objMemberPk As New MemberPk(DimType.Account.Id, DimConstants.Unknown) 'Update Dim Name accordingly Dim objDim As OneStream.Shared.Wcf.Dim = BRApi.Finance.Dim.GetDim(si, "<Dimension Name>") 'Create New Member Dim objMember As New Member(objMemberPk, _ "<New Member Name>", "<Member Description>", objDim.DimPk.DimId) 'Create VaryingMemberProperties object Dim objProperties As New VaryingMemberProperties( _ objMemberPk.DimTypeId, objMemberPk.MemberId, DimConstants.Unknown) 'Create new member info object for new member Dim objMemberInfo As New MemberInfo( _ objMember, objProperties, Nothing, objDim, DimConstants.Unknown) 'Modify some member properties. Account dimension, in this example. Dim accountProperties As AccountVMProperties = objMemberInfo.GetAccountProperties() accountProperties.AccountType.SetStoredValue(AccountType.Revenue.Id) accountProperties.Text1.SetStoredValue( _ ScenarioType.Unknown.Id, DimConstants.Unknown, "MyNewText1Value") 'Save the member and its properties. Dim isNew As TriStateBool = TriStateBool.TrueValue BRApi.Finance.MemberAdmin.SaveMemberInfo(si, objMemberInfo, True, True, False, isNew)Question: Are there any learning materials to help when setting up a new application (in addition to the training materials)? As a new partner, we're spending some time to build an application to understand the interdependencies but is there anything which defines what order things need to be set up?
Answer Attached is a sample project plan showing the typical build activities and the ordering of such. Source: Office Hours 2020-01-17 Partner Enablement2.2KViews0likes0Comments