First Look at Menus for Visual Studio Tools

September 25, 2008

My friend David Musgrave has been busy lately. He has brought to us great products like Named Printers, Advanced Security, SnapShot, and Support Debugging Tool. He has done it again with the release of Menus for Visual Studio Tools (MVST).

For those of you not familiar with MVST, it’s a Dexterity-based product that exposes an API to Visual Studio developers for them to add their own menu items to the Microsoft Dynamics GP interface, providing even more transparent integrating products and customizations. If you may recall, there was no (out of the box) way to go about this with standard Visual Studio Tools functionality, which forced VS developers to create their own Dexterity customization to add their own menus. Of course, every developer has a different approach to writing code and coming up with an integrating solution — IF they happen to know Dexterity, which wasn’t always the case.

As a participant in the of the beta testing phase I played with some of the tool’s features and suggested a few changes to the documentation based on my experiences. David also incorporated tons of error handling routines and made it a virtually unbreakable product. Some of the feature I most enjoy are:

1) The relative ease of incorporation into already existing projects and easy call of APIs. The product registration in VS is straight forward and the naming convention is very logical.

2) The ability to add menus items to any existing Dynamics GP menu with the option to display conditional meny items, toggling them on or off according to application events.

3) The abundance in error handling and clearness of the errors.

David has released a stub on his blog with more information on the tool. The product is currently compatible with version 10.0 of Microsoft Dynamics GP and can be downloaded via CustomerSource and PartnerSource at:

CustomerSource – Menus for Visual Studio Tools for Microsoft Dynamics GP 10.0

PartnerSource – Menus for Visual Studio Tools for Microsoft Dynamics GP 10.0

FINAL NOTE: I was able to compile my code with Visual Studio 2005 and Visual Studio 2008, however, you will need the latest VST service pack to compile on VS2008.

Until next post!

MG.-
Mariano Gomez, MIS, MVP, MCP, PMP
Maximum Global Business, LLC
http://www.maximumglobalbusiness.com/


Microsoft Dynamics GP 11.0 Previewed at GPUG Summit

September 23, 2008

The GPUG Summit 2008 is in full swing and the keynote speech delivered by Jeff Young, product unit manager for Microsoft Business Solutions came with a surprising presentation of Microsoft Dynamics GP 11.0. While the preview was very limited, it focused on the extended workflow capabilities for Office 14 and improved Sharepoint integration. 2009 has been targeted as the release for GP 11.0, however no specific quarter has been identified for it’s release.

Microsoft execs promissed a better preview at Convergence 2009. More information at MSDynamicsWorld.com.

Until next post!

MG.-
Mariano Gomez, MIS, MVP, MCP, PMP
Maximum Global Business, LLC
http://www.maximumglobalbusiness.com/


Best practices for labeling customized windows with Modifier and VBA in Microsoft Dynamics GP

September 20, 2008

Ever walked into a site where customizations to the Dynamics GP system seem to be endless? Are you confused as a consultant by what was done in what tool? This one may seem as a no brainer, but it is one of the biggest issues I face when I go to a customer’s site, especially when I am not the first to walk in there.

In addition, many of my customers also ask about windows with titles enclosed by periods, i.e., “.Customer Maintenance.“, or preceded by one period, i.e., “.Customer Maintenance“, or suffixed by one period, i.e., “Customer Maintenance.“, of course, for the trained and qualified eye, all created with Modifier and/or VBA, and/or both. The question is often, why is it that we have these two periods around the window name? Can’t we change it to something more visually appealing and truly indicative of existing customizations?The honest truth is, unless you have a much trained eye, these periods can escape you very easily and can make users very confused as to what they are seeing on the screen.

In fact, as part of my Dynamics GP list of best practices, I do recommend customers to make the following subtle changes to the titles of modified and VBA-customized Dynamics GP windows, as follows:

1) If the window includes only changes done with Modifier — one period at the beginning of the window title — change the title to MOD: Window Name.

NOTE: the period cannot be removed under Modifier, hence once security is granted; the window title will appear as .MOD: Window Name. The period is not completely gone, but still the impact of having the word “MOD” in the title is already a big change from just the period.

2) If the window includes only changes done with Visual Basic for Applications — a period at the end of the window title — change the title to VBA: Window Name

3) If the window includes changes done with Modifier and Visual Basic for Applications, change the title to MVBA: Window Name.

Modifier Only Changes

1) Open Modifier and perform all necessary changes to your window. Before save, change the Object Title property to MOD: Customer Maintenance as shown below.

2) Save all your changes and return to Microsoft Dynamics GP

3) Grant security to the modified window.

4) Open the window to view the title. As shown below, it is easier to identify changes done with Modifier this way.

Visual Basic for Applications (VBA) Only Changes

1) Open un-modified window; add to Visual Basic (CTRL+F11 on your keyboard)

2) Add all fields required for the customization you are planning

3) Change the Caption property as shown below to reflect VBA: Customer Maintenance.

4) When window is displayed by GP, title is now preceded by the word VBA.

Modifier with Visual Basic for Applications (VBA) changes

1) Follow steps 1 and 2 as indicated in the above scenario

2) Change the Caption property to include MVBA: Customer Maintenance

3) When the window is displayed by GP, title is now preceded by the word MVBA

Trivial? Maybe. However, these simple techniques for identifying customizations done with Modifier and further enhanced with VBA, have saved me from many redundant and sometimes unnecessary questions and comments, including “some developer did not pay attention when they were typing the window title”, ehem!

Until next post!

MG.-
Mariano Gomez, MIS, MVP, MCP, PMP
Maximum Global Business, LLC
http://www.maximumglobalbusiness.com/


Currency Formatting in Analysis Cubes for Excel

September 18, 2008

Fellow bloggers Dwight Specht a Mark Polino tackle the formatting of currency fields being pulled into Excel from Analysis Services. Dwight and Mark provide detail steps on how to overcome this issue, but fundamentally on how to get rid of it forever. Please stop by DynamicAccounting.net to read this very interesting article.

Until next post!

MG.-
Mariano Gomez, MIS, MVP, MCP, PMP
Maximum Global Business, LLC
http://www.maximumglobalbusiness.com/


New Dynamics GP bloggers on the block: Welcome Dynamics GP Land!

September 17, 2008

It is always good to see fellow consultants willing to share their knowledge and experience. Christina Phillips (The Knaster Technology Group) and Steve Endow (Precipio Services) have become a part of the select list of Dynamics GP bloggers who have decided to share their collective knowledge on their new site: Dynamics GP Land.

Visit Christina’s and Steve’s site and drop them a note of support for their efforts. They will sure appreciate your insight.

Until next post!

MG.-
Mariano Gomez, MIS, MVP, MCP, PMP
Maximum Global Business, LLC
http://www.maximumglobalbusiness.com


New Article on MSDynamicsWorld: "Dynamics GP Inventory BOM/Assembly Transaction Entry" by Frank Hamelly

September 17, 2008

Well, it’s gotta be the Southern air that produces so many great GP consultants, writers, MVPs, and the alikes! Fellow MVP, Frank Hamelly decided to break his “pen’s silence” and explores BOM and Assembly Transactions for companies requiring minimum manufacturing functionality without getting into the complexities of a full blown product. You can find Frank’s first article on MSDynamicsWorld.com.

Until next post!

MG.-
Mariano Gomez, MIS, MVP, MCP, PMP
Maximum Global Business, LLC.
http://www.maximumglobalbusiness.com/


How to display existing record notes on an existing Dynamics GP window with Modifer and VBA

September 10, 2008


The following post started out as many of my other posts — with a question on the Dynamics GP newsgroup: how to display record notes for items on the Item Inquiry window. When I first thought of this question, it was immediately apparent that a few SQL calls in VBA to read the notes table and return the text to some VBA form, and bit of old fashioned “hide” and “show” of fields could get the job done, but then I thought, what if I could make this code act and behave just like that of standard Microsoft Dynamics GP windows with record level notes? That is, the buttons had to look and feel just like standard GP windows, then when you click on the buttons, they had to open the standard GP notes windows, and even better, what if you could attach new notes a la Dynamics GP from those same inquiry windows too.

Code History

On my first iteration, I used the new VBA UserInfo object to create an ADO connection to the company database to retrieve the Note Index from the Record Notes Master table (SY03900). Since I had constructed the notes buttons with Modifier, all I had to do was use the BeforeUserChanged events on these buttons to toggle the correct note button if there was a note present by forming a pass-thru sanScript command string with the traditional code used in pass versions of Dynamics GP to open the notes window. This method presented a problem: the traditional sanScript code behind the notes buttons is quite extensive and impractical for the purposes of delivering an elegant customization.

Click here to download package file of my first version.

There is also another known method to retrieve record notes that uses the Dynamics GP built-in NoteObj object-based approach. This method also presented another challenge as it requires defining a local variable in Modifier which could be setup as the NoteObj data type. Since the NoteObj data type is defined as a global resource in the dictionary, it cannot be used with fields created with Modifier, effectively putting this method out of reach.

The method I decided to use came about in a late night IM conversation with David Musgrave, who pointed out that before the NoteObj object-based approach was created, there were two globals procedures created to manage record notes: Note_Button and Check_For_Record_Note. I liked this approach because it meant less lines of code, I could focus solely on pass-thru sanScript — eliminating my initial use of SQL calls — and in turn I could also make use of a local variable in Modifier to set the value returned by the Note_Button Dexterity global procedure, and once again call the Check_For_Record_Note proc to manage the toggle of the record note buttons.

Implementation

1) With the Item Inquiry window open (Inquiry > Inventory > Item), press CTRL+F10 to open Modifier.

2) Set the drop-down on the Toolbox to Local Fields, and create 3 local variables as follow:

a) for the first variable — ‘(L) Item Note Show Hide’, click New to open the Local Field Definition window. Complete the information as shown below and click Ok when finished:

b) for the second variable — ‘(L) RecordNoteAbsent’, click New to open the Local Field Definition window. Complete the information as shown below and click Ok (twice) when finished:

c) for the third variable — ‘(L) RecordNotePresent’, click New to open the Local Field Definition window. Complete the information as shown below and click Ok (twice) when finished:

3) Drag the recently created fields to the window layout as shown below.

NOTE: The above illustration is provided only as a reference. Keep the record note buttons contiguous, but DO NOT STACK yet. You can return to Modifier when indicated to stack them.

Change the Visual Appearance property of the record note buttons to 2D Border. Change the Back Color Visual property to Bright Green.

4) Save the newly modified window and return to GP. Grant security to the modified Item Inquiry window.

5) Open the Item Inquiry window and verify that you can see the newly added record note buttons.

6) Add the Item Inquiry window to Visual Basic. Press CTRL+F11 on your keyboard.

7) Press SHIFT+F11 on your keyboard and add the following fields to Visual Basic: ‘Item Number’, the two record note buttons, and the ‘(L) Item Note Show Hide Field’.

NOTE: At this point, return to Modifier to stack the record note buttons and change the Visible Visual property of the ‘(L) Item Note Show Hide’ field to False. Save the changes and return to GP. Open the Item Inquiry window to verify layout, then press ALT+F11 on your keyboard to open the Visual Basic editor.

8) Locate the ItemInquiry (Window) object under the Microsoft_Dynamics_GP project in the Project Explorer window. Double-click to open the Code Editor window.

9) Copy and Paste the following code to the Code Editor


' ------------------------------------------------------------------------------------------------------------
' NOTE RECORDS DEMO - Item Inquiry Window
' Created by: Mariano M. Gomez Bent, MVP, MCP
' Maximum Global Business, LLC.
' http://www.maximumglobalbusiness.com
' Updated by: David Musgrave
' ------------------------------------------------------------------------------------------------------------

Private Sub Window_BeforeOpen(OpenVisible As Boolean)
Call ItemNoteShowHide_AfterUserChanged
End Sub

Private Sub ItemNumber_Changed()
Call ItemNoteShowHide_AfterUserChanged
End Sub

Private Sub RecordNoteAbsent_BeforeUserChanged(KeepFocus As Boolean, CancelLogic As Boolean)
' Dim CompilerApp As New Dynamics.Application
Dim CompilerApp As Object
Dim NoteIndex As Long

Set CompilerApp = CreateObject("Dynamics.Application")

If Not ItemNumber.Empty Then
NoteIndex = CompilerApp.GetDataValue("'Note Index' of table IV_Item_MSTR of form IV_Item_Inquiry")
Else
NoteIndex = 0
End If

Call Note_Button(NoteIndex, ItemNumber)
End Sub

Private Sub RecordNotePresent_BeforeUserChanged(KeepFocus As Boolean, CancelLogic As Boolean)
'Run the note absent script
Call RecordNoteAbsent_BeforeUserChanged(KeepFocus, CancelLogic)
End Sub

Private Sub ItemNoteShowHide_AfterUserChanged()
' Dim CompilerApp As New Dynamics.Application
Dim CompilerApp As Object
Dim NoteIndex As Long

Set CompilerApp = CreateObject("Dynamics.Application")

If Not ItemNumber.Empty Then
NoteIndex = CompilerApp.GetDataValue("'Note Index' of table IV_Item_MSTR of form IV_Item_Inquiry")
Else
NoteIndex = 0
End If

Call RecordNoteShowHide(NoteIndex)
End Sub


Private Sub RecordNoteShowHide(IN_NoteIndex As Long)
' Dim CompilerApp As New Dynamics.Application
Dim CompilerApp As Object
Dim CompilerMsg As String
Dim CompilerError As Integer
Dim CompilerCmd As String

Dim l_result As Integer

CompilerCmd = ""
CompilerCmd = CompilerCmd & "call Check_For_Record_Note,"
CompilerCmd = CompilerCmd & Str(IN_NoteIndex) & ","
CompilerCmd = CompilerCmd & " '(L) Item Note Show Hide' of window IV_Item_Inquiry of form IV_Item_Inquiry;"
CompilerCmd = CompilerCmd & "if '(L) Item Note Show Hide' of window IV_Item_Inquiry of form IV_Item_Inquiry = 1 then"
CompilerCmd = CompilerCmd & " hide '(L) RecordNoteAbsent' of window IV_Item_Inquiry of form IV_Item_Inquiry;"
CompilerCmd = CompilerCmd & " show '(L) RecordNotePresent' of window IV_Item_Inquiry of form IV_Item_Inquiry;"
CompilerCmd = CompilerCmd & "else"
CompilerCmd = CompilerCmd & " show '(L) RecordNoteAbsent' of window IV_Item_Inquiry of form IV_Item_Inquiry;"
CompilerCmd = CompilerCmd & " hide '(L) RecordNotePresent' of window IV_Item_Inquiry of form IV_Item_Inquiry;"
CompilerCmd = CompilerCmd & "end if;"

Set CompilerApp = CreateObject("Dynamics.Application")
CompilerApp.CurrentProductID = 0 ' DYNAMICS
CompilerApp.CurrentProduct = CompilerApp.CurrentProduct & "!Modified"
CompilerError = CompilerApp.ExecuteSanscript(CompilerCmd, CompilerMsg)

If CompilerError 0 Then
l_result = MsgBox(CompilerMsg, vbOKOnly, "Dexterity Compiler")
End If
End Sub

Private Sub Note_Button(IN_Note_Index As Long, IN_Item_Number)
' Dim CompilerApp As New Dynamics.Application
Dim CompilerApp As Object
Dim CompilerMsg As String
Dim CompilerError As Integer
Dim CompilerCmd As String

Dim l_result As Integer

' Pass-through sanScript code to be compiled by the

CompilerCmd = ""
CompilerCmd = CompilerCmd & "call Note_Button,"
CompilerCmd = CompilerCmd & """" & IN_Item_Number & ""","
CompilerCmd = CompilerCmd & " """", {form display name}"
CompilerCmd = CompilerCmd & " true, {record note button}"
CompilerCmd = CompilerCmd & " 20010, {An item number must be entered before you can add a note.}"
CompilerCmd = CompilerCmd & Str(IN_Note_Index) & ","
CompilerCmd = CompilerCmd & " 'Item Number' of window IV_Item_Inquiry of form IV_Item_Inquiry, {field with the record note}"
CompilerCmd = CompilerCmd & " table IV_Item_MSTR, {file with the record note}"
CompilerCmd = CompilerCmd & " '(L) Item Note Show Hide' of window IV_Item_Inquiry of form IV_Item_Inquiry;"

Set CompilerApp = CreateObject("Dynamics.Application")
CompilerApp.CurrentProductID = 0 ' DYNAMICS
CompilerApp.CurrentProduct = CompilerApp.CurrentProduct & "!Modified"
CompilerError = CompilerApp.ExecuteSanscript(CompilerCmd, CompilerMsg)

If CompilerError 0 Then
l_result = MsgBox(CompilerMsg, vbOKOnly, "Dexterity Compiler")
End If
End Sub

WARNING: This customization uses a method of executing Dexterity SanScript code from VBA which is unsupported by Microsoft.

10) Compile and save the code. Close the Visual Basic Editor. Return to GP and test by opening the inquiry window, selecting an item with the lookup, using the browse buttons to go through the items, and finally, adding a note to an item.

Techniques Used

The above implementation uses the Dynamics Continuum Integration Library to execute pass-through sanScript in the context of the modified form. In addition, it uses calls to standard Microsoft Dynamics GP global procedures designed to manage record notes. An important aspect for this customization is portability. To avoid using referenced objects, I implemented calls to the Continuum library by instantiating the object with the CreateObject method, rather than the standard VBA “Dim New As Object”.

Downloads

You can download the package file for the above code with the links below:

Click here for Dynamics GP v10

Click here for Dynamics GP v9

Click here for Dynamics GP v8

VBA can prove an invaluable tool when implementing customizations and can help reduce the the maintenance headaches involved with workarounds.

Please drop a note describing your experience with this customization or any comments you may have. If there is something you want to see posted on this site please let me know as well.

My thanks go out to David Musgrave for pushing me in researching the techniques and pointing out some of the coding techniques required for this customization. He has more to say about the implementation of this customization at:

http://blogs.msdn.com/developingfordynamicsgp/archive/2008/09/11/adding-record-notes-to-a-window-example.aspx

Be sure to check his site for more fun customizations and articles.

Until next post!

MG.-
Mariano Gomez, MVP, MCP
Maximum Global Business, LLC
http://www.maximumglobalbusiness.com/

Please note that the customization being provided in this communication cannot be considered to be an official hotfix or service pack for any reported issue, and hence you take all responsibility for its implementation and ongoing support as well as future upgrades. Although it has been unit tested, it is strongly recommended that it also be tested by both you and your Microsoft Dynamics GP partner in a suitable test environments, before being released into a production environment.


Microsoft Dynamics GP 9.0 Service Pack 4 Now Available for Download!

September 9, 2008

Microsoft has just released Service Pack 4 for Dynamics GP 9.0. These service packs are for English speaking installations of Release 9.0. Translated service packs release approximately 30-60 days following the English speaking releases.

Accoding to the release notes, Service Pack 4 will be the final release for Dynamics GP 9.0

Service Pack 4 for Microsoft Dynamics GP 9.0 can be downloaded here. For all Microsoft Dynamics GP 9.0 Service Packs, visit the Service Pack download page here.

Until next post!

MG.-
Mariano Gomez, MVP, MCP
Maximum Global Business, LLC
http://www.maximumglobalbusiness.com/


David Musgrave on "Welcome to Dynamics!" VBA Customization

September 9, 2008

David Musgrave knocks it over the wall with this fun, yet powerful customization that shows the endless possiblities of Dynamics GP’s Visual Basic for Applications. For those of you who are not quite familiar with the first four or five releases of GP, upon launching the application, a WAV file would play the now famous words in a sassy voice “Welcome to Dynamics!”.

In David’s script, the PlaySound method found in the Windows Winmm.dll library allows a user to play a sound file. If the flag parameter is switch from 1 to 0, the method will pause while it plays the sound allowing the screen to refresh. By setting the flag parameter to 1, the sound is played immediately forcing VBA not to wait for the screen refresh.

As usual, in his article David provides the code, wave file, package file, and step by step instructions for you to recreate this customization and have fun.

Until next post!

MG.-
Mariano Gomez, MIS, MVP, MCP, PMP
Maximum Global Business, LLC
http://www.maximumglobalbusiness.com/


Using pass-through sanScript in VBA to return a file path to a Dynamics GP Modified form field

September 7, 2008

If you read my previous article on “Using the Win32 Common Dialog Box API to return a file path to a Dynamics GP Modified form field“, you are now familiar with the technique and the beaty of it. Now Let’s take a look at how you would replace Common Dialog Box with pass-through sanScript by creating a reference to the Dynamics Continuum Integration Library object file.

NOTE: this method of calling pass-through sanScript is not supported by Microsoft.

Replace the previous script in step 6 with the following:


Private Sub PBFile_BeforeUserChanged(KeepFocus As Boolean, CancelLogic As Boolean)
Dim CompilerApp As Object
Dim CompilerMsg As String
Dim CompilerErr As Integer
Dim CompilerCmd As String

Dim winMessage As String
Dim lpstrTitle As String
Dim sFilter As String
Dim l_path As String

Set CompilerApp = CreateObject("Dynamics.Application")

' add quote character as part of the filter -- Chr(34)
lpstrTitle = Chr(34) & "Select File" & Chr(34)
sFilter = Chr(34) & "All Files(*.*)*.*" & Chr(34)

CompilerCmd = ""
CompilerCmd = CompilerCmd & "local string filePath;" & vbCrLf
CompilerCmd = CompilerCmd & "local boolean l_result;" & vbCrLf
CompilerCmd = CompilerCmd & "l_result = getfile(" & lpstrTitle & ", 1, filePath, " & sFilter & ");" & vbCrLf
CompilerCmd = CompilerCmd & "if l_result then" & vbCrLf
CompilerCmd = CompilerCmd & " '(L) sFilePath' of window POP_PO_Entry of form POP_PO_Entry = Path_MakeNative(filePath);" & vbCrLf
CompilerCmd = CompilerCmd & "end if;"

CompilerApp.CurrentProductID = 0 ' DYNAMICS
CompilerApp.CurrentProduct = CompilerApp.CurrentProduct & "!Modified"
CompilerError = CompilerApp.ExecuteSanscript(CompilerCmd, CompilerMsg)

If CompilerError 0 Then
MsgBox (CompilerMsg)
End If
End Sub

The Dexterity getfile() function creates a dialog box that allows the user to select a file. It returns a boolean value indicating whether the user clicked OK or Cancel in the dialog box. If the user clicks OK or Open, the file name and path will be returned to the variable named in the path parameter, in this case the filePath variable.

The files displayed in the dialog can be filtered so that only certain types of files are displayed. You can use a predefined filter, or create your own filter. See the Dexterity help file for more information on getfile.

The real trick is to get the code to execute in the context of the modified form and not the original form. To achieve this, we add the extension “!Modified” to our form as indicated in this code snippet:


CompilerApp.CurrentProductID = 0 ' DYNAMICS
CompilerApp.CurrentProduct = CompilerApp.CurrentProduct & "!Modified"

VBA is a very powerful tool, but more so when used with Dexterity. Please send your comments in and let me know what you are working on and what you would like to see posted on my site.

Download Package File Here. You will need to grant security to the modified form first.

Until next post!

MG.-
Mariano Gomez, MIS, MVP, MCP, PMP
Maximum Global Business, LLC.
http://www.maximumglobalbusiness.com/