Code
Easily changing option values on a field without breaking a sweat
by admin on dec.16, 2009, under Code
How many times have we built a table with option fields and then – six months later – had to insert option values between the existing option values?
After we insert a new option value, we have to find all code using the options and change the option references, because – as you know – it is the integer value of the option that gets compiled into the object and not the Option::Value part of the field.
Damn.. what can we do to avoid that?
The answer is pretty simple: Start using functions to return the values of the individual option values.
Let’s say we have a simple table with a option field with three values:
Option1, Option50 and Option100
Now, create three functions on the table, called:
GetOption1, GetOption50 and GetOption100
Set each function to return an integer. We will be using these functions to return the value of a specific option.
Now we are ready to use these new functions in our code:
It is important to use the GetOption-functions everytime and everywhere you would normally use the option value reference (the “incorrect” code).
Now comes the part that would usually make us sweat.
Some person says that he wants a new option value – called Option20 – and he wants it to be placed between Option1 and Option50 (can’t argue with that
))
As the nice guys we are, we say “ok, I will create your option for you”, knowing we have to go through days of code to find all the places we used Option50 and Option100, because their integer-value have now changed!
Well… that is no problem anymore
You’ve got the Option-functions to do the work.
Let’s insert the option value:
Now let us take a look at our table functions for the option field:
As we knew it would happen. The Option20-value is now taking the place of what used to be Option50’s integer value.
Well, that is ok, because we only need to update the code here in the table. And nowhere else !
Update your functions to look like this:
Now, let’s have a look at the code where we used the function:
Notice how the function-call has not been changed (obviously). But the Option-value reference has been changed, just as in our function, and this would have been the case perhaps hundreds of places around the system.
I have started to create return-functions for option values everytime I create a new option field and/or add or update values to it.
It is a relief only having to change the code one place
Indexing a char in a string
by admin on dec.04, 2009, under Code
After working with Dynamics NAV (Navision) in five years, I can still be surprised by the small details.
I just did a new discovery that is even documented in the C/SIDE help
I regularly use the COPYSTR function to extract substrings of a string. Even if it was only a single character that I wanted to substring.
When copying the charachter in position 5 … instead of using:
mySubString := COPYSTR(myFullString , 5, 1);
We can use:
mySubString := myFullString[5];
The result is the same, except from the latter where we actually extract a “char” datatype instead of a text string.
There can be circumstances where you have to FORMAT the char. For example if you want to MESSAGE it.
MESSAGE(myFullString[5]);
This won’t work because the MESSAGE function will only display the text datatype and not the char datatype.
This will work:
MESSAGE(FORMAT(myFullString[5]));
No matter if we assigned mySubstring to the char index [5] or return value of the COPYSTR this (below) will of course work.
There is an implicit datatype conversion from char to text when assigning mySubstring.
mySubString := myFullString[5];
MESSAGE(mySubstring);
Determining your session environment in Dynamics NAV – Citrix vs. local
by admin on nov.28, 2009, under Code
Today I ran into a scenario where I wanted some specific code to be run when the client was started on a Citrix server and some other code to be run when the client was started on a desktop.
To determine where the client is started, we can use an automation of the subtybe Windows Scipting Host Object Model to access the Windows Environment variables.
Those of you that were around ind the good old DOS days surely know a great deal about the environment variables. We are interested in the environment variable called SESSIONNAME, which on Citrix has a value something like “ICA……..” and locally has the value “CONSOLE”.
So by requesting the content of SESSIONNAME we can determine if the client is being executed on the Citrix server.
Here’s how:
1. Create an automation variable, with the subtype: ‘Windows Script Host Object Model’.WshShell
And the code:
Notice that we have to name the environment variable by using the prefix and suffix percent character (%).
Of course this is useful for many other things to, if you want to know something about the current client session.
You can get a full list of environment variables by opening a command prompt and typing
“set”
A lot of useful information exists in the environment variables. For example the name of the Program Files folder etc.
Logging Code Coverage to file in Dynamics NAV
by admin on nov.27, 2009, under Code
This entry will be about the CODECOVERAGE feature of Dynamics NAV.
This is done in version 5.0 SP1 but works in most newer versions.
I will not cover the normal use of Code Coverage. And by normal use I mean the scenario where you (the dynamics nav developer) manually start and stop the Code Coverage and view the code. I am sure most of you know how to handle that.
I recently found an new feature which I hadn’t really thought of before. And it became very useful indeed.
- The option to start Dynamics NAV with CODECOVERAGE enabled.
- The option to tell Dynamics NAV to log all CODECOVERAGE to a file.
- The option to start and stop the CODECOVERAGE from code.
In a problem solving situation where you cannot reproduce an error presented to you by a user, the combination of features 2 and 3 turned out to be a great tool.
Why?
Because it gives me the precise code that was executed at the time the error occured at the user’s computer, and I didn’t even have to be present.
He can send me the log file, and I can open it in my own Dynamics NAV client (which is also done using option 2 above).
Here is what you do:
1. Change the user’s shortcut, so that the client will always log CODECOVERAGE to file, when started. This is done by adding:
COVERAGEFILENAME=c:\somefilename.txt
…to your program shortcut.
Like this:

Now the client knows that whenever CODECOVERAGE is started – manually or by code – it must log to that file.
If you suspect something weird is going on in…say… the Sales Order Form, you can start Code Coverage in OnInit trigger:
CODECOVERAGELOG(TRUE);
..and stop it in the Onclose trigger:
CODECOVERAGELOG(FALSE);
Always running the form with Code Coverage enabled like this will of course have some impact on the performance for that user, but when hunting a problem it can be very useful.