Forum Discussion

ChristianW's avatar
ChristianW
Valued Contributor
4 years ago

Is there an equivalent to the the HS.con function?

If I like to migrate a HFM rules file, is there an equivalent to the HS.con function?

  • Yes, there is, it is called setCell and it is a method of the databuffer class. It doesn't use a string as input, so it is a little different to use

    resultDataBuffer.SetCell(si As SessionInfo, cell as DataCell, accumulateIfCellAlreadyEsists as boolean)
    
    or
    
    resultDataBuffer.SetCell(si As SessionInfo, cell as DataBufferCell, accumulateIfCellAlreadyEsists as boolean) 

    The Onestream help is giving a similar example like this one for the whole process.

    'Copy all "U2#Input:U3#Input" numbers for this dataUnit to the UD2 none Members and the UD3 member with the name "Target Member Name".
    Dim destinationInfo As ExpressionDestinationInfo = api.Data.GetExpressionDestinationInfo("")
    Dim sourceDataBuffer As DataBuffer = api.Data.GetDataBuffer(DataApiScriptMethodType.Calculate, "U2#Input:U3#Input", destinationInfo)
    If Not sourceDataBuffer Is Nothing Then
        Dim resultDataBuffer As DataBuffer = New DataBuffer()
        For Each cell As DataBufferCell In sourceDataBuffer.DataBufferCells.Values
           If (Not cell.CellStatus.IsNoData) Then
              cell.DataBufferCellPk.UD2Id = DimConstants.None
              cell.DataBufferCellPk.UD3Id = api.Members.GetMemberId(dimtypeid.UD3, "Target Member Name")
              resultDataBuffer.SetCell(si, cell)
           End If
        Next
        api.Data.SetDataBuffer(resultDataBuffer, destinationInfo, True)
    End If

     

  • ChristianW's avatar
    ChristianW
    Valued Contributor

    Yes, there is, it is called setCell and it is a method of the databuffer class. It doesn't use a string as input, so it is a little different to use

    resultDataBuffer.SetCell(si As SessionInfo, cell as DataCell, accumulateIfCellAlreadyEsists as boolean)
    
    or
    
    resultDataBuffer.SetCell(si As SessionInfo, cell as DataBufferCell, accumulateIfCellAlreadyEsists as boolean) 

    The Onestream help is giving a similar example like this one for the whole process.

    'Copy all "U2#Input:U3#Input" numbers for this dataUnit to the UD2 none Members and the UD3 member with the name "Target Member Name".
    Dim destinationInfo As ExpressionDestinationInfo = api.Data.GetExpressionDestinationInfo("")
    Dim sourceDataBuffer As DataBuffer = api.Data.GetDataBuffer(DataApiScriptMethodType.Calculate, "U2#Input:U3#Input", destinationInfo)
    If Not sourceDataBuffer Is Nothing Then
        Dim resultDataBuffer As DataBuffer = New DataBuffer()
        For Each cell As DataBufferCell In sourceDataBuffer.DataBufferCells.Values
           If (Not cell.CellStatus.IsNoData) Then
              cell.DataBufferCellPk.UD2Id = DimConstants.None
              cell.DataBufferCellPk.UD3Id = api.Members.GetMemberId(dimtypeid.UD3, "Target Member Name")
              resultDataBuffer.SetCell(si, cell)
           End If
        Next
        api.Data.SetDataBuffer(resultDataBuffer, destinationInfo, True)
    End If

     

    • ChristianW's avatar
      ChristianW
      Valued Contributor

      I personally try to avoid working with strings, so I use something like the following function

       

       

      Public Sub Book (ByRef oSourceCell As DataBufferCell, ByVal targetDataBuffer As DataBuffer, Optional ByVal iAccount As Integer = DimConstants.All, Optional ByVal iFlow As Integer = DimConstants.All, Optional ByVal iIC As Integer = DimConstants.All, Optional ByVal iOrigin As Integer = DimConstants.All, Optional ByVal iUD1 As Integer = DimConstants.All, Optional ByVal iUD2 As Integer = DimConstants.All, Optional ByVal iUD3 As Integer = DimConstants.All, Optional ByVal iUD4 As Integer = DimConstants.All, Optional ByVal iUD5 As Integer = DimConstants.All, Optional ByVal iUD6 As Integer = DimConstants.All, Optional ByVal iUD7 As Integer = DimConstants.All, Optional ByVal iUD8 As Integer = DimConstants.All, Optional ByVal dFactor As Decimal = 1) 
      	Try		
      		Dim oTargetCell As New DataBufferCell(oSourceCell)
      					
      		With oTargetCell.DataBufferCellPk
      						
      			If Not iAccount = DimConstants.All Then .AccountId = iAccount
      			If Not iFlow = DimConstants.All Then .FlowId = iFlow
      			If Not iIC = DimConstants.All Then .ICId = iIC
      			If Not iOrigin = DimConstants.All Then .OriginId = iOrigin
      			If Not iUD1 = DimConstants.All Then .UD1Id = iUD1
      			If Not iUD2 = DimConstants.All Then .UD2Id = iUD2
      			If Not iUD3 = DimConstants.All Then .UD3Id = iUD3
      			If Not iUD4 = DimConstants.All Then .UD4Id = iUD4
      			If Not iUD5 = DimConstants.All Then .UD5Id = iUD5
      			If Not iUD6 = DimConstants.All Then .UD6Id = iUD6
      			If Not iUD7 = DimConstants.All Then .UD7Id = iUD7
      			If Not iUD8 = DimConstants.All Then .UD8Id = iUD8
      							
      		End With
      
      		dFactor = dFactor * GetFactor(oSourceCell.DataBufferCellPk, oTargetCell.DataBufferCellPk)
      		oTargetCell.CellAmount = dFactor * oSourceCell.CellAmount
      					
      		targetDataBuffer.SetCell(api.SI, oTargetCell, True)
      			
      	Catch ex As Exception
      			
      		Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
      	End Try
      
      End Sub

       

       

      • Marcello's avatar
        Marcello
        Contributor

        Hi Christian,

        is there a way to accumulate values in the destination intersection using the function api.Data.SetDataBuffer(resultDataBuffer, destinationInfo, True)

         

        I have some BR where I need to cumulate values on a certain element but when I use the SetDataBuffer the rules saves only the last value of the sourceDataBuffer

         

        Thanks in advance for the help.

        Marcello

    • ChristianW's avatar
      ChristianW
      Valued Contributor

      If you like to simplify the process, I would suggest, a sub-procedure to mimic the HS.con function

      Public Sub Book(ByVal sourceCell As dataBufferCell, ByVal targetDataBuffer As DataBuffer, ByVal target As String, ByVal factor As Decimal)			
      	Try
      		'Create a DataBufferCellPk object for the target initialize it with the DataBufferCellPk of the source
      		Dim targetCellPk 	As New DataBufferCellPk(sourceCell.DataBufferCellPk) 
      		'Create a MemberScriptBuilder object for the target inizialize it with the target string
      		Dim targetScript 	As New MemberScriptBuilder(target)
      				
      		'Loop all databuffer dimensions -> GetRightHandDimTypes
      		For Each scriptDimType As DimType In DimType.GetRightHandDimTypes()
      			Dim memberName As String = targetScript.MemberNames(scriptDimType.Name)
      			'Test if the dimension exists in the target script
      			If memberName <> "" Then 
      				'If it exists override the source definition 
      				targetCellPk.Item(scriptdimtype.Id) = api.Members.GetMemberId(scriptDimType.Id, memberName)
      			End If	
      		Next
      				
      		'Adjust the factor based On AccountType And Flow settings
      		factor = factor * GetFactor(sourceCell.DataBufferCellPk, targetCellPk)
      		Dim cellAmount As Decimal = factor * sourceCell.CellAmount
      
      		'Creat a target cell as DataBufferCell using the targetcellPK, the cellAmount and the sourcecell's status
      		Dim targetCell 	    As New DataBufferCell(targetCellPk, cellAmount, sourcecell.CellStatus)
      				
      		'Write it to the targetDataBuffer
      		targetDataBuffer.SetCell(si, targetCell, True)
      
      	Catch ex As Exception
      				
      		Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
      	End Try
      		
      End Sub
      
      Private Function GetFactor (ByRef sourcecellPK As DataBufferCellPk, ByRef targetcellPK As DataBufferCellPk) As Decimal
      	Dim factor As Decimal = 1
      				
      	'If both accounttypes not share the same sign (are both positive or both negative) multiply with -1
      	If Not ((api.account.GetAccountType(targetcellPk.AccountId).IsAccountTypePositive = api.account.GetAccountType(sourcecellPK.AccountId).IsAccountTypePositive)) Then
      		factor = factor*-1
      	End If
      	'If both flows not have the same switch sign setting multiply with -1
      	If api.flow.SwitchSign(targetcellPk.flowid) Xor api.flow.SwitchSign(sourceCellPk.flowId) Then
      		factor = factor*-1
      	End If
      	'Return the adjusted factor.
      	Return factor			
      End Function
  • Oscar's avatar
    Oscar
    Contributor

    Thank You Chrsitian! Still analyzing how best to handle the special treatment (calculation) of these Equity Accounts, but your comment is right on point!