It’s new years eve 2014. A good moment to quickly remember a great year before spending some time with wife and kids counting down until midnight.
2014 was my first full WordPress year. I wrote about 50 new articles and brought forward another 40 from my old blog. The blog was viewed about 43.000 times.
For me 2014 was about Design Patterns. Co-funded by Microsoft I recorded about 25 videos about Design Patterns which are almost all on YouTube now. In January I will go to Microsoft to discuss how to move forward. There is a nice PartnerSource page scheduled around the patterns.
2014 was also the first full year for 2013 R2 to be up and running. With the new asynchronous object metadata it was quite a challenge in the early builds.
I started exploring C#, Visual Studio, TFS and GIT this year. I already shared some of my learnings, and I plan on continue the series next year. Some great topics are ready to be published in my head.
This fall was all about traveling and evangelising the Design Patterns. I’ve visited six events in 10 weeks across the globe. From San Diego to Poznan, from St. Louis to Bali and from Seattle to Antwerp. Talking about Design Patterns at each large NAV Conference.
It was the year where I’ve updated my book for 2013(R2) and Design Patterns. The receipt was amazing this time. Thanks to everyone who helped me, purchased the book or spread the word!
At home things have changed too. All four kids go to school now which makes a big difference. I work from home for 80% of my time allowing me to be more flexible and spend more time with the community.
2015 will be an interesting year. It will be the year when Design Patterns grow up to be complete. I am working on a train-the-trainer program with MCT’s and training partners around the world to teach people both experienced and new. The first trainings are scheduled for March in Atlanta (US) and Toronto (CA). They will be hosted by local MCT’s. I am working on a training program in Europe and an online program.
Next year will also be important for Microsoft. As new online ERP packages come up very quickly it is going to be interesting to see if a large company such as Microsoft is quick enough to adopt to changes and stay ahead.
Happy 2015 everyone. May it all be in good health and happy coding!
With Repeatability being the big “buzzword” in the NAV community for 2014 I thought it would be nice to close the year with a blog around this topic.
There is no doubt in my mind that after a decade, Microsoft is still searching for positioning with its dynamics products, but it seems to me that we are getting closer to an answer. Or maybe not.
Funny thing is that (part of) the positioning of the answer is actually repeated too.
Microsoft Marketing is trying to position Dynamics NAV in a “highly” repeatable volume market, preferably in a cloud environment.
Here, only the last part is new. The rest is not.
Software has always been repeatable, also before the cloud. When I went to school we exchanged games using floppy disks. This was highly repeatable software.
Until very recently it was very common to buy boxed software at retail stores, also bookkeeping software. This was also highly repeatable software.
Some Dynamics NAV partners have been selling their vertical product to hundreds of customers for many, many years. Even before Microsoft acquired Navision. This was (highly) repeatable software.
So why is it such a buzzword all of the sudden?
Even though Microsoft, and Navision before them, have always pushed their partners to go vertical and high volume, the software is and was extremely suitable as a customisable erp package for the upper segment of the SMB market.
This is a very lucrative market for resellers. It includes selling a huge amount of consultancy hours and many years or even decades of after care and upgrades or reimplementation.
Regardless of arguments that this is successful for some partners and customers or not, consultancy does not bring any money on the table for Microsoft, since they only sell licenses. (In the early days, Navision also charged a percentage of the consultancy).
The Cloud as Accelerator
So Microsoft have been trying this model for years, but only few partners picked it up. So now with the cloud they are giving it a “second try”.
Using private and public clouds allow partners to distribute software much faster than the traditional boxing and shipping. It also allows them to adapt to changes much quicker.
Although Marketing people want us to believe otherwise, there are more challenges than we can count going to a repeatable cloud model. Partners that have been selling consultancy services for two decades do not have the business model required to be repeatable. For these partners it is easier to start a new business with new people rather than changing their existing companies.
And why would they? The fact that Microsoft asks partners to go cloud and repeatable does not mean that there is no business in the upper SMB market. NAV is still as suitable for this market as it has ever been and there is still a lot of money to be made there.
Another big challenge that we face with Dynamics NAV going to the cloud being repeatable is the completeness and user friendliness of the product.
Being targeted at larger companies for many years, NAV has never been a very user-friendly product out of the box. Nor is the base product complete for any market, not even small businesses.
This means that the initial investment to build a cloud product is relatively high. And although NAV is very customisable, the User Interface is not. There are a lot of limitations in the UI, especially the web variant, that partners cannot work their way around. To be highly repeatable you need a Facebook like or app-like interface.
Together with the fact that cloud products pop-up like crazy at the moment, one even more user-friendly than the other, it’s going to be hard for NAV to enter that market.
Next year(s) will be very important for Microsoft to see how succesful they can be in the highly repeatable cloud.
My personal opinion, keys are in making the user interface more intuitive and changeable for partners and make the base product more feature rich.
That off course and moving to Visual Studio and TFS. But that’s a no-brainer. The current development environment is completely unuseful for building repeatable software.
Encapsulation is one of the four corner stones of object oriented programming and it is about componentizing your software, it’s basics go back even to the 1970ies. In this article we will investigate how we can introduce this concept in Dynamics NAV.
Elements of encapsulation
Encapsulation is about creating small reusable components grouping features that belong together.
A very important rule here is to be as local as possible. The intention of being local is to prevent the wrongly use of features.
Within Encapsulation a programming language typically allows override, just in case it is required and the programmers know what they are doing and why.
Encapsulation is tightly related to the Object-Method-Property model that we discussed in the first video of this series of implementation patterns.
If we take some keywords from this list, we need to define Small, Usable, Local, Hide and Override.
Microsoft Dynamics NAV.
A small reusable element can be a Codeunit. Within the Codeunit we can have functions that can be global and local. Global functions can be accessed always when we declare the Codeunit as a variable. Local functions can only be accessed from the object itself, thus the Codeunit. This allows us to be as local as possible and implement encapsulation.
In Microsoft Dynamics NAV2015 functions are local by default. This is to encourage encapsulation.
Let’s take an example. We could create a Codeunit for VAT and SalesTax calculation. This Codeunit has one global function that is called CalculateVATAndTAX which takes an argument table as a parameter. The business logic will be in local functions that are only accessible from within the Codeunit.
With this example we have creates a small but usable component of features that belong together and business logic that is as local as possible. Hence we have implemented encapsulation in Microsoft Dynamics NAV.
In the Application
Unfortunately I have to admit that encapsulation is not implemented throughout the product. There are reasons for that which I will explain in another episode of the series. But it exist. A very good example is Inventory Profile Offsetting. This Codeunit has a global function that takes an Item, some setup and other parameters and then start a logical order of functions. These functions are local.
The goal of using local functions is to avoid the wrongly use of them. This way the designer makes a clear intention of which functions you can call, and which functions should never be called from outside the object. This is one of the fundamental basics of encapsulation.
Mapped to C#
If we take this learning and go back to the first pattern of this series, Class, Method, Property we can now expand this with Public and Private, these are the keywords for Global and Local functions in C#.
Natural Language Programming
We can also relate this to the second pattern, natural language programming where we separate readable code from nerdy code. The readable code are the local functions and the nerdy code is the C/AL code in these functions.
We are starting to get a completer picture here, and this is why I’ve put these articles in this specific order.
Now we discussed Small, Usable, Local and Hide. We have not discussed Override. There is a good reason for that.
Most programming languages have built in mechanisms for overriding. C++ uses friend and C# and other languages have reflection.
C/AL does not have anything built in that allows this. If we want to override, we have to hack into the source code and change the behavior. This is the reason NAV is open source.
However there is another implementation pattern that allows override, which is the façade pattern. This pattern is based on decoupling and should be implemented if there is a clear expectation of overriding being required. In Dynamics NAV it requires extra coding, objects and it makes the of the business logic intention less clear.
Global & Local
So does this mean that with encapsulation each Codeunit should have one global and multiple local functions? No. There are a number of patterns that require more than one global function in a Codeunit such as implementing API’s, management codeunits such as journal management and the Model View-View Model pattern. This often relates back to reusing global variables in memory state or keeping software features together in one class, which relates back to one of the fundamental basics of encapsulation.
Be as Local as possible
We can however create one clear statement: “Be as Local as Possible.”. Which is enforced by Dynamics NAV 2015.
So when we look at the key elements of encapsulation we can say that one of the corner stones of object oriented programming can be implemented in Microsoft Dynamics NAV and helps us to clearly structure our code and emphasizing the clear intention of the designer.
This Blog Article was brought forward from my old blog
As I described in my previous post, we will get report design guidlines.
One of these guidlines is to use itterated background changes in list reports. This looks realy cool, just like listplaces in the RTC. But how do you implement this. Wel, it is extremely easy.
This is a property that every contol has in RDLC and you can populate it with a name or hexnumber representing the color
In most RDLC properties you can write expressions. This is a very easy language which is unfortunately different from C/AL. For example the IF/ELSE statement is IIF(Condition, Yesresult, Noresult). But still easy to learn.
Built In Report variables
One thing I advice everyone to learn is that RDLC has built in variables that you can use, similar to CurrReport.PAGENO in the classic designer, but TONS and TONS more.
One of them is RowNumber.
If you combine this you can create an expression like this:
Nothing) mod 2, “LightGrey”, “White”)
The result is making reports easily look like this:
This Blog Article was brought forward from my old blog
One of the “Real life” tips I showed at NavTechDays is how to use the classic debugger smartly.
What I see people do many times is turn on the debugger with Breakpoints on Triggers
This means that the debug process wil break on each trigger it finds, meaning form & table triggers, functions and objects.
Even if you step through this process with F5, debugging a posting process like Sales wil take forever as there are hundreds of triggers that you will pass.
So what is the alternative.
The alternative is to place your own Breakpoints; this can be done in two ways
1. Via the Object Desiger
If your license allows you to edit C/AL code you can use this icon to go to the code of each object.
If you do this you’ll enter the C/AL Editor that shows the code behind the application. But if you look closer there is a hidden “column” in this editor.
If you use the “Show Column” feature you’ll see that this column even has a name: Breakpoint Column
If you select a line of code and hit F9 you’ll see that a “Red Dot” appears in the column, meaning there is a breakpoint for the debugger.
Whenever you start the debugger now without the “Break on triggers” option, you’ll see that the debugger will stop at this point, allowing you to go directly to the “suspected” piece of code.
But wait, there is more.
2. Via the debugger
You cannot just put breakpoints in the C/AL code via the object designer, you can also set them in the debugger directly, while debugging.
This allows you to set a new breakpoint somewhere down the line. This avoids the issue of stepping into all the functions and losing time.
Be Careful: This only works in the active object! You cannot step back into the previous object and add a breakpoint there.
The great feature about these breakpoints is that the debugger and code editor remember each others breakpoints. So if you place a breakpoint in the debugger, the red dot wil appear in the C/AL editor. This is done using the system table Breakpoint that is not visible in the Object Designer but is from the Report/Form/Page designer.
So remember using this smartly and save a lot of time in your debugging processes.
What does the open “red dot” mean?
Was one of the questions on NavTechDays, and I have to admin that I did not knew. But fortunately Lars Hammer of Microsoft was in the room and he knew. (And he should).
This allows you to temporarily disable a breakpoint without throwing it completely away. So you can quickly reenable it.
Another great feature about the debugger is the possibilty to roll-back a transaction that you are debugging. This is often useful when you have a scenario that requires a long time to setup and you don’t want to backup and restore databases just to have the same scenario while finetuning your code.
Remember this when you need to fiddle with your code and you want to see the step-by-step results.
In Dynamics NAV you are likely to step into a loop of objects if you debug a complex process. Sometimes you hit an error somewhere in a tree and you want to see where this code was executed from. This is where you can use the Call Stack.
In this example, Codeunit 80 was called from codeunit 81 and before that from Form 42. You can double click on an object and see which line of code caused the execution of that object. This you can then use to stop the debug process, go to the object and place your breakpoint there. Remember: you cannot add breakpoints in the debugger in a tree of objects.
Sometimes you would like to see the data that your process creates without actually committing the transaction so you can roll-back and change your code. With the SQL Server option you can do that since NAV is using the ReadUncommitted isolation level. This allows users to see data in the database that is not committed yet.
NOTE: with the introduction of buffered inserts you might not see the inserted data since that is buffered to either a find command on that table or the commit of the transaction. If you do want to see the uncoommitted data and you know where to go, then put in a simple FIND statement on a copy variable of the record object.
This Blog Article was brought forward from my old blog
UPDATE 2014 : In current versions with DotNet interop you would probably want to use that instead.
As many of you know there is a lenght limitation of text variables in Microsoft Dynamics NAV.
One of the real-life problems you can encounter due to this is when doing interfacing, especially when reading EDI files.
EDI files are often very long and without Cariage Return Line Feeds.
Solutions are using a dataport with a delimiter such as ‘+’ instead of NewLine or asking the EDI vendor to implement CRLF’s.
If both are not possible, for example if you want to read the EDI files though a NAS you have to use a codeunit with File variable.
Using the File variable with long textlines with result in overflow errors.
The solution to work around this is using a stream variable. This is how:
i := 1;
EDIFile.TEXTMODE(FALSE); EDIFile.OPEN(NewFileName); EDIFile.CREATEINSTREAM(EDIInStream); WHILE NOT EDIInStream.EOS DO BEGIN EDIProcBufferTemp.”Entry No.” := i; i := i + 1; EDIInStream.READTEXT(EDIProcBufferTemp.”EDI Text”, 250); EDIProcBufferTemp.INSERT; END;
WHILE NOT Finished DO BEGIN IF STRPOS(EDIText, ‘+’) = 0 THEN BEGIN EDIProcBufferTemp.DELETE; IF EDIProcBufferTemp.FINDFIRST THEN EDIText := EDIText + EDIProcBufferTemp.”EDI Text” ELSE Finished := TRUE; END; IF STRPOS(EDIText, ‘+’) <> 0 THEN BEGIN EDITag := COPYSTR(EDIText, 1, STRPOS(EDIText, ‘+’) – 1); EDIText := COPYSTR(EDIText, STRPOS(EDIText, ‘+’) + 1, 1000); SplitInfo(EDITag); END ELSE SplitInfo(EDIText); //* Last Tag END;
In this example I move the contents of the textfile to a InSteam variable. The Insteam variable supports the ReadText method that allows us to read the content in smaller chunks.
Then I move the lines into a buffer table for easier processing. (I love working with buffer tables, they make cleaner coding).
Since breaking the file into 250 characters might actualy split some of the EDI tags, I re-connect the lines into a larger text varible. I can easily merge two 250 character lines into one 1000 character variable.
Remember to also process the last tag when there are no more delimiters.
Here you are, good luck.
If you want to learn more about interfacing you can read chapter 9 of my book which is dedicated to this subject.
This Blog Article was brought forward from my old blog
Ok, it has been a while since I blogged. One of the reasons for that was that we bought another house and moved last month. This has a huge impact on a family with young children and my wife is pregnant. Right now we are settled and everything is starting to be on its place.
Another reason is, I have to be honest, that after finishing the book my mind was not exactly on writing at all. The book has been publised now for quite a while and I had many nice reactions. I even signed a couple of books which feels very special.
Enough about me, what is this blog entry about. A tip, yes. Number 29 already. There has been a lot of talk about the changes that RDLC reporting brings to Dynamics NAV. A lot of good things, new possibilities, but also a new learning curve for developers. Also for me.
A while ago I was fiddling with formatting in RDLC. The syntax for formatting is different compared to the classic report designer. For example a decimal number can be formatted as #.##000. The format is saved in the Format propery of each field.
Since Dynamics NAV (Navision) can have dynamic decimal formatting depending on the Currency code this format is by default brought over in the DataSet, for example in the Sales Invoice (Report 206, my favorite) you have Sales_Invoice_Line__Line_Amount_Format.Value representing the format for the Line Amount field.
However, for many Navision end-users formatting is not such rocket science. They have formatting which is always the same.
Good news for these scenario’s is that RDLC has some formatting shorcuts that can be easily implemented.
Here is a list:
C or c
D or d
E or e
F or f
G or g
N or n
P or p
R or r
X or x
How easy can you have it…
So if you want a DateTime field to be Time formatted you just enter t in the format property. If you enter P0 your percentage will be formatted as 80%. How cool is that.
Formatting Dates is just as easy. The following table lists common .NET Framework date formatting strings.
Full date/time (short time)
Full date/time (long time)
General date/time (short time)
General date/time (long time)
M or m
R or r
Y or y
So did I find this out myself? No… I used google. (not Bing, sorry Microsoft).