10-25-2021 06:11 AM - last edited on 05-02-2023 10:24 AM by JackLacava
If I like to migrate a HFM rules file, is there an equivalent to the HS.con function?
Solved! Go to Solution.
10-25-2021 07:51 AM
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
10-25-2021 07:51 AM
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
10-25-2021 08:00 AM
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
10-25-2021 08:10 AM - edited 10-25-2021 08:16 AM
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
11-06-2022 05:17 AM
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
11-07-2022 09:25 AM
No, set databuffer is always overrideing the result, only setcell has the accumulate option.
But this is not a problem, if you start with an allready filled databuffer as a target databuffer, instead of an empty one, you obviously accumulate the result when writing back.
You can fill the target databuffer using the api.Data.GetDataBufferUsingFormula functions.
11-22-2022 10:00 AM
Great Post as always! I have a question, what if my target includes C#Elimination It seems like the code below does not set the C# to Elimination
For Each scriptDimType As DimType In DimType.GetRightHandDimTypes()
Dim memberName As String = targetScript.MemberNames(scriptDimType.Name)
BRApi.ErrorLog.LogMessage(si, $"x: script dime type: {scriptDimType.Name} member name: {memberName} ")
'Test if the dimension exists in the target script
If memberName <> "" Then
'If it exists override the source definition
BRApi.ErrorLog.LogMessage(si, $"v: {api.Pov.Entity.Name} {memberName} ")
targetCellPk.Item(scriptdimtype.Id) = api.Members.GetMemberId(scriptDimType.Id, memberName)
End If
Next
12-25-2022 07:45 AM
Thank you Oscar
Consolidation isn‘t a databuffer dim, it is a dataunit dimension. The consolidation is controlled by the pov of the calculation.
But you have to be careful with the origin dimension, an elimination only works, if the origin is elimination as well.
cheers
Christian
01-03-2023 09:36 AM
Thank You Chrsitian! Still analyzing how best to handle the special treatment (calculation) of these Equity Accounts, but your comment is right on point!