I had responded with some information on the thread, but when I tried to implement the suggestions I made, I found that it was not actually possible and that other methods would be needed.
The Extender product is a very clever tool created by my friend Andrew Brown from eOne Solutions, it allows Microsoft Dynamics GP windows to be “extended” with additional custom fields. These fields are entered using additional Extender windows and are stored in a series of tables in SQL Server. Each custom field is stored as a single record in one of a series of SQL tables depending on its datatype. The idea behind the product is to allow customisation of Dynamics GP without needing any coding. That said, the Extender Enterprise product does allow you to add custom logic with scripts.
While Extender itself is very flexible, it can be difficult to customise, or modify the windows. The methods that you would use for a standard window will not work.
The issue is that Extender windows as they are seen by the user don’t really exist. The Extender windows that the user sees are dynamically created using a series of hidden template windows. For each type of Extender window or form, there are 10 template windows. The reason for the multiple windows is so that you can open more than one Extender window of each type at a time, Extender just uses the next available window. This is similar to how Dynamics GP has five Note windows which are dynamically used.
Each of these windows has one field of each datatype for each line on the window. When the window is opened by Extender, it reads the setup definition then hides and shows the fields as required to display the correct window. It populates the read-only string fields to display the prompts and also renames the window title. Finally, it resizes the window to remove the extra white space.
Disclaimer: There may be other steps and the order might differ. I don’t have the source code, so this is just my understanding…. but you get the idea. 🙂
So, how can I modify a window that is dynamically created from one of the template windows? For our example, I want to disable the delete button on an Extender window, but only when that window is being used as a specified Extender window (based on the Window Extender ID).
Below are some of the usual tools which can be used and details of their limitations:
|Modifier||As the Extender windows are hidden from the Security subsystem, it is not possible to tell Dynamics GP to open a modified version of the window instead of the original.||Even if it could work, you would need to modify all 10 windows of the same type and any change would affect all Extender windows of the same type as there is no scripting.|
|Field Level Security||As the Extender windows are hidden from the Security subsystem, they cannot be selected from the Field Level Security Resource Explorer.||Even if you could select the window, you would need to modify all 10 windows of the same type and any change would affect all Extender windows of the same type as there is no scripting.|
|Rockton Software’s Conditional Field Level Security||As the Extender windows are hidden from the Security subsystem, they cannot be selected from the Field Level Security Resource Explorer.||Even if you could select the window, you would need to modify all 10 windows of the same type. With the conditional scripting it would be possible to check which Extender ID and make the customisation dynamic, but Field Level Security prevents us even selecting the window.|
|Visual Basic for Applications||It would be possible to use VBA scripting to read the Extender ID and create a dynamic customisation.||This customisation would have to be repeated for each of the 10 windows and then be deployed to every workstation in your system.|
The Simpler Solution
Just use GP Power Tools.
Using the Resource Information window in Form mode with the show currently selected window option enabled, I clicked on the Delete Button on the example Extender window that I created. It identified the field as ‘Delete Button’ of window ‘User Defined Window’ of form PT_UD_Window_1.
Using the Runtime Execute window, I used the Names button to lookup other fields on the PT_UD_Window_1. To display the form on the GP Power Tools Resource Explorer, I ticked the Hidden Forms checkbox. I located the ‘PT Window ID’ field which holds the Extender Window ID.
warning 'PT Window ID' of window 'User Defined Window' of form 'PT_UD_Window_1';
The above code was executed in the context of the Extender Dictionary and confirmed that the field contained the value I was expecting for the open Extender window.
Using the Automatic Debugger Mode Setup window, I created an Automatic Starting, Non-Logging Trigger on the Window Activate Focus event of the window ‘User Defined Window’ of form PT_UD_Window_1 with the following script:
out boolean OUT_Condition; OUT_Condition = false; if isopen(form PT_UD_Window_1) then case 'PT Window ID' of window 'User Defined Window' of form 'PT_UD_Window_1' in ["TEST ITEM 2"] disable 'Delete Button' of window 'User Defined Window' of form 'PT_UD_Window_1'; OUT_Condition = true; else end case; end if;
Where “TEST ITEM 2” in the case statement is the Extender Window ID for the window on which I want to disable the Delete Button. If desired, more windows can be added into a list separated by a comma.
Using the Window Activate (window gains focus) event is a little lazy but it avoids having to identify the actual script after which our code should run.
The final step, is to duplicate (using the Duplicate Button) and modify the Triggers for the other 9 windows. It is easiest to copy the script into a Notepad.exe window before modifying the form name on the Resource tab, so it can be pasted back.
Deployment of the customisation is simple… it is already done. The triggers will automatically start working on all workstation on which GP Power Tools is installed. No need to do anything more.
The example GP Power Tools settings file for the 10 windows can be downloaded from here.
Hope you find this helpful.
This article was originally posted on http://www.winthropdc.com/blog.