Changing Dictionary Context when using Passthrough Dexterity sanScript Part 2

David Meego - Click for blog homepageThis is the second in a series of posts which are are designed to help Dexterity developers as well as VBA and Visual Studio Developers to understand how to work with passthrough Dexterity sanScript.  The main focus of this series is to understand how to change the Dictionary Context that the code executes in.

If you have not read the first post, please do so now to get the background for this post.

Disclaimer: The method of calling passthrough sanScript from VBA is not supported by Microsoft.  However as it is such a useful technique, you will see it used may times on this blog. 

The methods used here show the script examples using VBA. The concept can easily transferred over to VB.Net and C# in Visual Studio.

The first script example uses the same Dexterity sanScript code to display the Product ID and Name for the dictionary context.  This shows the standard method of calling sanScript from VBA using the ExecuteSanscript method in the Dynamics.Application object.  The context for this script is controlled by the CurrentProductID property. 

Note: The double quotes in the sanScript code have to be doubled up to ensure the double quote character is included in the vba string variable.

VBA Code Example showing simple passthrough Dexterity sanScript

     'Dim CompilerApp As New Dynamics.Application
    Dim CompilerApp As Object
    Dim CompilerMessage As String
    Dim CompilerError As Integer
    Dim CompilerCommand As String
    
    ' Create link without having reference marked
    Set CompilerApp = CreateObject("Dynamics.Application")
    
    CompilerCommand = ""
    CompilerCommand = CompilerCommand & "warning ""Product Context is "" " & vbCrLf
    CompilerCommand = CompilerCommand & "    + str(Runtime_GetCurrentProductID()) + "": "" " & vbCrLf
    CompilerCommand = CompilerCommand & "    + Launch_GetProdName(Runtime_GetCurrentProductID()); " & vbCrLf
    
    ' Execute SanScript
    CompilerApp.CurrentProductID = 1493 ' SmartList
    'CompilerApp.CurrentProduct = CompilerApp.CurrentProduct & "!Modified"
    CompilerError = CompilerApp.ExecuteSanscript(CompilerCommand, CompilerMessage)
    If CompilerError <> 0 Then
        MsgBox CompilerMessage
    End If

Note: The code using late binding to the Dynamics.Appliction object.  This avoids the need to create a reference to the Continuum Integration Library.  Also note the commented out line which can be used to change the context to allow the passthrough code to work with the modified version of a window.

The second example uses Dexterity's execute() function to change the context from the context defined at the VBA level to another context.  This method can be used when there are issues getting the VBA context selection to work.  The double quotes have to be double up again for the extra level of nesting.

VBA Code Example using passthrough sanScript to change Dictionary Context

     'Dim CompilerApp As New Dynamics.Application
    Dim CompilerApp As Object
    Dim CompilerMessage As String
    Dim CompilerError As Integer
    Dim CompilerCommand As String

    ' Create link without having reference marked
    Set CompilerApp = CreateObject("Dynamics.Application")
    
    CompilerCommand = ""
    CompilerCommand = CompilerCommand & "local text code; " & vbCrLf
    CompilerCommand = CompilerCommand & "local string compiler_error; " & vbCrLf
    CompilerCommand = CompilerCommand & "local integer context; " & vbCrLf

    CompilerCommand = CompilerCommand & "{Build the pass-through sanScript code.} " & vbCrLf
    CompilerCommand = CompilerCommand & "context = 1493; { SmartList } " & vbCrLf
    CompilerCommand = CompilerCommand & "clear code; " & vbCrLf
    CompilerCommand = CompilerCommand & "code = code + ""warning """"Product Context is """" "" + char(13); " & vbCrLf
    CompilerCommand = CompilerCommand & "code = code + ""    + str(Runtime_GetCurrentProductID()) + """": """" "" + char(13); " & vbCrLf
    CompilerCommand = CompilerCommand & "code = code + ""    + Launch_GetProdName(Runtime_GetCurrentProductID()); ""  + char(13); " & vbCrLf
    
    CompilerCommand = CompilerCommand & "{Execute the code. Pass the House_Data table as a parameter.} " & vbCrLf
    CompilerCommand = CompilerCommand & "if execute(context, code, compiler_error {, Parameters }) <> 0 then " & vbCrLf
    CompilerCommand = CompilerCommand & "    {A compiler error occurred. Display the error.} " & vbCrLf
    CompilerCommand = CompilerCommand & "    error compiler_error; " & vbCrLf
    CompilerCommand = CompilerCommand & "end if; " & vbCrLf
    
    ' Execute SanScript
    CompilerApp.CurrentProductID = 0 ' DYNAMICS
    'CompilerApp.CurrentProduct = CompilerApp.CurrentProduct & "!Modified"
    CompilerError = CompilerApp.ExecuteSanscript(CompilerCommand, CompilerMessage)
    If CompilerError <> 0 Then
        MsgBox CompilerMessage
    End If

Following on from the previous post, this next script is just to create the Dexterity sanScript code in a text file.  You can use any method you wish to write the code and place it into a text file. 

VBA Code Example to write sanScript code to text file

     Dim CompilerCommand As String

    CompilerCommand = ""
    CompilerCommand = CompilerCommand & "warning ""Product Context is "" " & vbCrLf
    CompilerCommand = CompilerCommand & "    + str(Runtime_GetCurrentProductID()) + "": "" " & vbCrLf
    CompilerCommand = CompilerCommand & "    + Launch_GetProdName(Runtime_GetCurrentProductID()); " & vbCrLf

    ' Write code to file
    Open CurDir() + "\SCRIPT.TXT" For Output As 1
    Print #1, CompilerCommand
    Close #1

This final example uses passthrough Dexterity sanScript to read the previously created text file and execute the code in the specified context.

VBA Code Example to read text file and execute it in a specified Dictionary Context

     'Dim CompilerApp As New Dynamics.Application
    Dim CompilerApp As Object
    Dim CompilerMessage As String
    Dim CompilerError As Integer
    Dim CompilerCommand As String

    ' Create link without having reference marked
    Set CompilerApp = CreateObject("Dynamics.Application")
    
    CompilerCommand = ""
    CompilerCommand = CompilerCommand & "local text code; " & vbCrLf
    CompilerCommand = CompilerCommand & "local string compiler_error; " & vbCrLf
    CompilerCommand = CompilerCommand & "local integer context; " & vbCrLf
    
    CompilerCommand = CompilerCommand & "local string l_Pathname; " & vbCrLf
    CompilerCommand = CompilerCommand & "local integer l_File_ID; " & vbCrLf
    
    CompilerCommand = CompilerCommand & "l_Pathname = Path_MakeNative(Path_GetForApp(PATH_DATAFOLDER)) + ""SCRIPT.TXT""; " & vbCrLf

    CompilerCommand = CompilerCommand & "{Read the pass-through sanScript code from file.} " & vbCrLf
    CompilerCommand = CompilerCommand & "context = 1493; { SmartList } " & vbCrLf
    CompilerCommand = CompilerCommand & "clear code; " & vbCrLf
    CompilerCommand = CompilerCommand & "l_File_ID = TextFile_Open(Path_MakeGeneric(l_Pathname), 0, 1); " & vbCrLf
    CompilerCommand = CompilerCommand & "TextFile_ReadText(l_File_ID, 32767, code); " & vbCrLf
    CompilerCommand = CompilerCommand & "TextFile_Close(l_File_ID); " & vbCrLf
    
    CompilerCommand = CompilerCommand & "{Execute the code. Pass the House_Data table as a parameter.} " & vbCrLf
    CompilerCommand = CompilerCommand & "if execute(context, code, compiler_error {, Parameters }) <> 0 then " & vbCrLf
    CompilerCommand = CompilerCommand & "    {A compiler error occurred. Display the error.} " & vbCrLf
    CompilerCommand = CompilerCommand & "    error compiler_error; " & vbCrLf
    CompilerCommand = CompilerCommand & "end if; " & vbCrLf

    ' Execute SanScript
    CompilerApp.CurrentProductID = 0 ' DYNAMICS
    'CompilerApp.CurrentProduct = CompilerApp.CurrentProduct & "!Modified"
    CompilerError = CompilerApp.ExecuteSanscript(CompilerCommand, CompilerMessage)
    If CompilerError <> 0 Then
        MsgBox CompilerMessage
    End If

Using this two stage method of writing to a text file and then reading the file and executing the code has the advantage that the code is a little simpler to write because we don't have the quadruple double quotes that the second example on this post has.

Note: Please see the previous post for a discussion of generic and native pathnames. 

Please let me know if these techniques are useful to you.  

David

// Copyright © Microsoft Corporation. All Rights Reserved.
// This code released under the terms of the
// Microsoft Public License (MS-PL, https://opensource.org/licenses/ms-pl.html.)