I had a great time attending the Dynamics SL User Group in San Antonio this week! Thanks to everyone who worked to hard to make it an informative and fun event!!!
In an interactive session with SL developer legend, Tom Malia, he mentioned a gotcha while upgrading VBA customization code to version 2015. Tom said he had been frustrated and searched the internet to no avail for help with the issue. I ran into the same thing earlier myself and thought, at the time, that I would blog about it. Sometimes, though, I feel that writing about crazy little things that take too much time is boring and not particularly helpful to many people. Maybe so. But on the other hand I have often been grateful for a post someone else wrote when they got stuck.
You will notice this issue when you upgrade a fully functioning VBA customization with code for the Update1 control to Dynamics SL 2015. In other words, the customization works without any errors on version 2011. If you open the customization and try to save it you will get System Message 20217 “The VBA code could not be compiled for execution. The project was successfully saved to the database.” Most likely none of the code in your customization will run, so you may well get other errors as a result. For example, if you have a control on a form that uses a buffer you declared with a VBA_SetAddr statement, you will see System Message 10051 “Setaddr() has not been called for <YourBufferName>. Error in property of control Form1.<CustomControlName>. A setaddr call should be made in Form1_Load event of Basic Script Language macro code.”… and so forth. What, you ask? Basic Script Language isn’t installed and there are no Basic Script Language customizations associated with the screen. Perhaps there were not even any for version 2011. Now, both of these errors can occur for other reasons, which I why I italicized fully functioning.
The problem is that a signature changed for the methods associated with the control named Update1 by default, whose name is never changed in the standard Dynamics SL screens. The method used to have a signature for its event handlers like this:
Sub Update1_OnUpdate(Level As Integer, RetVal As Integer)
Sub Update1_OnUpdate(level%, insertflg%, retval%)
Sub Update1_OnUpdate(ByVal Level As Integer, ByVal InsertFlg As Integer, ByRef RetVal As Integer)
Chances are that you have never written the line of code that broke. You just let the VBA Developer Environment create it. It created the handler without ByVal on the initial parameters. Thus it’s about the last place you might expect to look for an error.
The documentation for this has not been updated… not in the help (it just has “(level%…)”, or in the PDF documentation. The compiler doesn’t give you a clue that this is what’s wrong. You can export the customization and import it without creating an event log. It’s easy to just overlook the ByVal, even if you let the IDE recreate the method. ByRef is the default for VBA, unless ByVal is specified. Now ByVal is required for all but the RetVal parameter on all the Update1 events (OnCancel, OnDelete, OnInsert, OnUpdate), and it’s not documented. Simply adding this keyword (to all but the last parameter; some have three parameters) resolves the issue.
One suggestion Tom made was to export all the customizations and merge them into a single text file. Then it is possible to fix all the Update1 handlers with a single “Replace All” command. Thanks, Tom, for refreshing my memory about something that will doubtlessly come up again, and motivating me to write about it.
(Posted from 30,000 feet. 🙂 )