Forum Discussion

Richard_Mayo's avatar
Richard_Mayo
New Contributor III
10 months ago

Pass in parameters to a public function

Morning All,

I'm working on a new solution to avoid having many, many separate confirmation rules with their own code which is almost identical in each case, and instead move to using a public function so that the similar code is recycled. Seems like a sensible idea!

I've got a basic prototype roughly working. So I've created a public function in Finance Business Rules which I am then calling from inside the confirmation rule code.

ie. the first code snippet is the public function and the second code snippet is the confirmation rule code calling it.

So far, so good and I've proved that the public function is indeed running when I run the confirmation rule (the error log message appears as expected) so I'm pleased so far!

What I now want to do is pass in some parameters from each confirmation rule, ie. the only thing that will be different in most cases is which accounts are being checked. So here is where I'm stuck. Within the code that calls the public function I want to be able to put in some variables/account details. I'm thinking I need to use some sort of namevaluepairs code that can be used in the public function but I haven't managed to get this part working.

Does anyone know what the correct syntax is to pass variables from the calling code to the public function? And then how I would access them in the public function?

Thanks in advance!

Richard

Public function that needs to receive some account details from the calling code:

Namespace OneStream.BusinessRule.Finance.UE_Shared_Conf_Rules_A
	
	Public Class MainClass
			
		Public Function SecondFunction(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As FinanceRulesApi, ByVal args As FinanceRulesArgs) As Object

			Try
				
				Dim IntegerReturn As Integer = 1234567
				Return IntegerReturn
				
			Catch ex As Exception
				
				Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
				
			End Try
			
		End Function		
		
	End Class
	
End Namespace

Calling code (inside confirmation rule code) that I want to put some account details in to pass to the public function:

Dim SharedRule As New OneStream.BusinessRule.Finance.UE_Shared_Conf_Rules_A.MainClass
brapi.ErrorLog.LogMessage(si,"ShareRule Return is: "& SharedRule.SecondFunction(si,globals,api,args).tostring)

 

  • Hi,

    just add the parameter in whichever form you need to the function and pass it on like that. E.g. by adding myParameterDictionary  as an object.

    Public Function SecondFunction(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As FinanceRulesApi, ByVal args As FinanceRulesArgs, ByVal myParameterDictionary As Object) As Object

    You then call this function like that:

    SharedRule.SecondFunction(si,globals,api,args,myParameterDictionary)

    If you do not get it to work right away, maybe try passing on a "ByVal mySingleStringParameter as String" first and write that into the error log. 

  • Richard_Mayo Business Rules are Namespaces.  Namespaces contain Classes.  Classes contain Methods (functions and subs).  all of this lends itself well for your Object Oriented Programming (OOP) goal here of Code Reuse.

    Code reuse is a central design philosophy of proper OOP coding. 

    Here is a sample way to use this design format to create parameterized, reusable Confirmation Rule logic.  Doing it this way can significantly reduce development time and maintenance effort by reducing code complexity and repetition.

    Here is a very simple use of a Finance rule to containerize a set of parameterized Confirmation Rule functions:

    Namespace OneStream.BusinessRule.Finance.ConfirmationRules
    	Public Class CubeDataValidations
    		Public Function ValidateCubeDataMonthly(si As SessionInfo, api As FinanceRulesApi, args As FinanceRulesArgs, accountName As String) As (result As String, message As String)
    		    Try
    		        If accountName.Equals("SomeAccount", StringComparison.CurrentCultureIgnoreCase) Then  
    		            Return ("Pass", "Validation succeeded")
    		        Else
    		            Return ("Warning", "Account name does not match 'SomeAccount'")
    		        End If
    		    Catch ex As Exception
    		        ErrorHandler.LogWrite(si, New XFException(si, ex))
    		        Return ("Fail", "An error occurred during validation")
    		    End Try
    		End Function
    	End Class
    End Namespace
    

    This code is then consumed repetitively in Confirmation Rules:

     

  • Hi Richard_Mayo  you got it!.

    The return type of ValidateCubeDataMonthly is called a "Tuple".  A tuple is a nice way to return a few things in one neat package when referencing a custom object at both ends of the code isn't feasible.

      In your new case you've created a tuple consisting of a string result, a string message, and a boolean value for passFail.
    It looks like this:

     

    (result As String, message As String, passfail as boolean)

     

    and it is assigned/returned like this:

     

    Dim result as String = "this is the result"
    Dim message as String = "This is the message"
    Dim isPass as Boolean = False 'this validation failed
    
    Return (result, message, isPass)
    

     

    Make sure you update the method signature of your function to use the new tuple:

     

    Public Function ValidateCubeDataMonthly(si As SessionInfo, api As FinanceRulesApi, args As FinanceRulesArgs, accountName As String) As (result As String, message As String, passfail as Boolean)

     

    Then in your calling code, in the confirmation rule, assign and consume the new tuple:

    Dim validationResult as (result As String, message As String, passfail As Boolean)
    
    validatinResult = cubeData.ValidateCubeDataMonthly(si, api, args, "SomeAccountName")
    
    

     

     


     

  • RobbSalzmann's avatar
    RobbSalzmann
    Valued Contributor II

    Richard_Mayo Business Rules are Namespaces.  Namespaces contain Classes.  Classes contain Methods (functions and subs).  all of this lends itself well for your Object Oriented Programming (OOP) goal here of Code Reuse.

    Code reuse is a central design philosophy of proper OOP coding. 

    Here is a sample way to use this design format to create parameterized, reusable Confirmation Rule logic.  Doing it this way can significantly reduce development time and maintenance effort by reducing code complexity and repetition.

    Here is a very simple use of a Finance rule to containerize a set of parameterized Confirmation Rule functions:

    Namespace OneStream.BusinessRule.Finance.ConfirmationRules
    	Public Class CubeDataValidations
    		Public Function ValidateCubeDataMonthly(si As SessionInfo, api As FinanceRulesApi, args As FinanceRulesArgs, accountName As String) As (result As String, message As String)
    		    Try
    		        If accountName.Equals("SomeAccount", StringComparison.CurrentCultureIgnoreCase) Then  
    		            Return ("Pass", "Validation succeeded")
    		        Else
    		            Return ("Warning", "Account name does not match 'SomeAccount'")
    		        End If
    		    Catch ex As Exception
    		        ErrorHandler.LogWrite(si, New XFException(si, ex))
    		        Return ("Fail", "An error occurred during validation")
    		    End Try
    		End Function
    	End Class
    End Namespace
    

    This code is then consumed repetitively in Confirmation Rules:

     

    • Richard_Mayo's avatar
      Richard_Mayo
      New Contributor III

      Hi Robb,

      This is awesome, thanks so much for sharing the code, that is super useful!

      And yes I'm looking forward to getting this working to cut down on the maintenance I currently have.

      Just one thing - to set the green/red status of the confirmation rule, presumably you could extend your code and have more than 2 things being sent back? eg:

      Public Function ValidateCubeDataMonthly(si As SessionInfo, api As FinanceRulesApi, args As FinanceRulesArgs, accountName As String) As (result As String, message As String, passfail as boolean)

      Then I would use the additional "passfail" that is sent back to set the confirmation rule status.

      Not urgent as I'll have a play around with this, just checking I'm on the right lines.

      Thanks again,

      Richard

      • RobbSalzmann's avatar
        RobbSalzmann
        Valued Contributor II

        Hi Richard_Mayo  you got it!.

        The return type of ValidateCubeDataMonthly is called a "Tuple".  A tuple is a nice way to return a few things in one neat package when referencing a custom object at both ends of the code isn't feasible.

          In your new case you've created a tuple consisting of a string result, a string message, and a boolean value for passFail.
        It looks like this:

         

        (result As String, message As String, passfail as boolean)

         

        and it is assigned/returned like this:

         

        Dim result as String = "this is the result"
        Dim message as String = "This is the message"
        Dim isPass as Boolean = False 'this validation failed
        
        Return (result, message, isPass)
        

         

        Make sure you update the method signature of your function to use the new tuple:

         

        Public Function ValidateCubeDataMonthly(si As SessionInfo, api As FinanceRulesApi, args As FinanceRulesArgs, accountName As String) As (result As String, message As String, passfail as Boolean)

         

        Then in your calling code, in the confirmation rule, assign and consume the new tuple:

        Dim validationResult as (result As String, message As String, passfail As Boolean)
        
        validatinResult = cubeData.ValidateCubeDataMonthly(si, api, args, "SomeAccountName")
        
        

         

         


         

  • Henning's avatar
    Henning
    Valued Contributor II

    Hi,

    just add the parameter in whichever form you need to the function and pass it on like that. E.g. by adding myParameterDictionary  as an object.

    Public Function SecondFunction(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As FinanceRulesApi, ByVal args As FinanceRulesArgs, ByVal myParameterDictionary As Object) As Object

    You then call this function like that:

    SharedRule.SecondFunction(si,globals,api,args,myParameterDictionary)

    If you do not get it to work right away, maybe try passing on a "ByVal mySingleStringParameter as String" first and write that into the error log. 

    • Richard_Mayo's avatar
      Richard_Mayo
      New Contributor III

      Hi there,

      Thanks so much for this! And apologies for the slow response. I got that working, the syntax is actually a bit simpler than I first thought so thanks for explaining it!

      Regards,
      Richard