Skip to main content
OneStream Employee
October 25, 2021
Solved

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

  • October 25, 2021
  • 2 replies
  • 0 views

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

Best answer by ChristianW

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

 

2 replies

ChristianWOneStream EmployeeAuthorAnswer
OneStream Employee
October 25, 2021

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

 

OneStream Employee
October 25, 2021

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
Contributor
January 3, 2023

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