In the past few months, I have been extremely busy, even if there was a vacation period in Poland, and I wanted to spend more time out of the keyboard. But looking for many lines of code (mostly not mine) I have seen that there are some rules/patterns/tips/good practices (name it as you like) that are nice to remind for all Business Central Developers.
Never ever do hardcode things in AL
Let’s start with something I hope I would never need to write but here we are.
It was a little scary to see hardcoded values like dimension codes, payment terms, or even salesperson codes. At all costs, do not do it! That is the first potential place where your helpdesk or you will have work in the future.
And if you think:
“ye but this is just a PTE we can change it quickly”
this is the worst excuse you can use. When I see hardcoded values that is for me a red flag taking over the extension support.
Making things as fields in the setup is not a big cost for developers but can help during testing, migration, and later daily operation. Remember if it can be hardcoded it most likely can be moved to setup as well.
… even the error messages
That is another one in the same category. Always use labels – do not hardcode them.
“Why? We use only one language so no big deal.”
Yes, it is. First of all, you never know if the text would require translation or not. But what is more important such errors are not visible in telemetry so it is hard to do any analysis if users see those errors or not.
Try to avoid code on the pages
This is related to field properties such as MinValue, BlankZero, etc. Those are the best examples (from many) which should be directly on a table not on the page. But, what is even more important try to avoid field triggers on pages – or in other words: think if the better place is to put it in the table not a page.
Why it is important?
I will give you an example. Someone added new fields on the Sales Order page and when validating the field Sell-to Customer No. those new fields were populated. However that worked only from the page. If I tried to develop a feature to automatically create order the code was skipped – despite using validate in all fields.
What solution the company did give us?
“You can call our function to populate the fields after validation. We also use it.”
But that is not a good way of handling that. Why? First of all, it gives more complexity and potential issues. AppSource extensions should work out of the box thinking ahead to what customers can have already installed or would like to install in the future. My PTE code was not working but any other will also not work out of the box in such a case – which gives more time for investigations, calls with unhappy customers, finding workarounds, etc.
Second, if we have a dependency on their app, it means we need to get runtime packages otherwise our builds will stop, and we become more dependent on what they are doing- in the future, they would obsolete the code we would need to make changes as well. That would be easy to avoid if someone had not added the code on the page in the first place.
Use triggers in the proper places
I know that you can add codeunits and create onAfterValidate, onAfterInsert (or other) triggers for tables, and other triggers for pages. But for me (maybe it is just my esthetic approach) is much cleaner to add the code in proper places – page extensions or table extensions.
This can be much easier to find.
However, there is also one additional aspect to this – especially for the tables. I have seen many cases where developers forget to check if the trigger is run or if the table is temporary.
Of course, there are moments when adding code in codeunits for such triggers is necessary but think if this is the case when you develop it – I did not count many of such moments.
Keep the code simple
Lately, I have seen the code where someone was doing SetRange or SetFilter only on Primary Key and then has been running if FindFirst then… Moreover, before that, the Reset on local variable has been run.
Of course that would work but I always have the question: Why was it needed? Is there a hidden reason? I spent a few minutes to figure out if there was something wrong that a simple code could not be used (Get).
So my final advice for today: Keep the code simple. Write the code that everyone can understand right away, do not overcomplicate functions if not needed, and keep naming conventions for variables.
It would be helpful not only to your colleagues but in a while also to yourself.