Changing Dictionary Context when using Passthrough Dexterity sanScript Part 1

David Meego - Click for blog homepageThis is the first 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.

When Dexterity code is executed it runs in the context of a specific dictionary.  If the code needs to access resources, such as tables and forms, which exist in a particular dictionary, then the passthrough code needs to be executed in the context of that dictionary.

Dexterity has the execute() function which can be used to execute code stored in a string (255 character limit) or a text (32767 character limit) field.  The function has an optional first parameter which can be used to specify the Dictionary or Product ID of the Dexterity dictionary to use as the context.  You can obtain these ID values from the Dynamics.set launch file. Examples are 0 for Dynamics and 1493 for SmartList.

To explain the concepts,  we will start simple and build up to more complex examples.  The first script is just standard code which will display the Product ID and Name for the context that the code is executed in.  If you use the Support Debugging Tool's Runtime Execute window, you can change context and execute the code to see how it works. 

Simple Code Example running current Dictionary Context

 warning "Product Context is " 
    + str(Runtime_GetCurrentProductID()) + ": " 
    + Launch_GetProdName(Runtime_GetCurrentProductID());

The second example shows how the same code can be built into a text field and then executed in the context of a specified dictionary using the execute() function.

NOTE: Each level of nesting requires the double quotes to be doubled up.  Add the carriage returns (ASCII value 13) is optional but makes the code more readable if it is displayed to the screen using a warning statement.

Code Example using passthrough sanScript to change Dictionary Context

 local text code;
local string compiler_error;
local integer context;

{Build the pass-through sanScript code.}
context = 1493; { SmartList }
clear code;
code = code + "warning ""Product Context is "" " + char(13);
code = code + "    + str(Runtime_GetCurrentProductID()) + "": "" " + char(13);
code = code + "    + Launch_GetProdName(Runtime_GetCurrentProductID()); "  + char(13);

{Execute the code. Pass the House_Data table as a parameter.}
if execute(context, code, compiler_error {, Parameters }) <> 0 then
    {A compiler error occurred. Display the error.}
    error compiler_error;
end if;

The third script is optional.  It is being used to write a text file containing the same script as shown in the first example.  This is in preparation for the final example.  You could always use Notepad to write the code.... or write the code in Dexterity and cut & paste to Notepad. 

Code Example to write sanScript code to text file

 local text code;

local string l_Pathname;
local integer l_File_ID;

l_Pathname = Path_MakeNative(Path_GetForApp(PATH_DATAFOLDER)) + "SCRIPT.TXT";

{Build the pass-through sanScript code.}
clear code;
code = code + "warning ""Product Context is "" " + char(13) + char(10);
code = code + "    + str(Runtime_GetCurrentProductID()) + "": "" " + char(13) + char(10);
code = code + "    + Launch_GetProdName(Runtime_GetCurrentProductID()); "  + char(13) + char(10);

{ Write code to file }
l_File_ID = TextFile_Open(Path_MakeGeneric(l_Pathname), 0, 0);
TextFile_WriteText(l_File_ID, code);
TextFile_Close(l_File_ID);

The fourth and final example shows how Dexterity code can be used to read a text file and then execute the context of that text file in the context of the specified dictionary.

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

 local text code;
local string compiler_error;
local integer context;

local string l_Pathname;
local integer l_File_ID;

l_Pathname = Path_MakeNative(Path_GetForApp(PATH_DATAFOLDER)) + "SCRIPT.TXT";

context = 1493; { SmartList }
clear code;

{ Read code from file }
l_File_ID = TextFile_Open(Path_MakeGeneric(l_Pathname), 0, 1);
TextFile_ReadText(l_File_ID, 32767, code);
TextFile_Close(l_File_ID);

{Execute the code. Pass the House_Data table as a parameter.}
if execute(context, code, compiler_error {, Parameters }) <> 0 then
    {A compiler error occurred. Display the error.}
    error compiler_error;
end if;

Note: The TextFile_Open() function requires the path to the text file to be provided in generic pathname format.  You can use the Path_MakeGeneric() and Path_MakeNative() functions to swap between generic and native path formats. Generic pathnames are a format that works for Mac and PC and are a legacy from when Dexterity was supported on both platforms.

  • Native Pathname             C:\Program Files\Microsoft Dynamics\GP\Data
  • Generic Pathname          :C:Program Files/Microsoft Dynamics/GP/Data

The rule for generic pathnames is that they have the drive surrounded by colons, no root slash and use forward slash instead of backslash.  If you look at the paths in the Dynamics.set launch file, you will see generic pathnames in use.

For more information working with multiple dictionaries, see Cross Dictionary Dexterity Development.

Stay tuned for the next post where we see how these concepts work from VBA (Link will be available on Wednesday).

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.)