#BCALHelp

It’s the week of NAVTechDays, the biggest Business Central Community event of the year and I thought it would be good to spend a few moments on the state of our community.

Business Central is taking off. According to Microsoft there are more than 4000 paying tenants and the average number of users per tentant is 10+ which is the sweetspot where Navision used to be strong.

I can also see it in my daily work, especially at ForNAV, where almost all of the support cases and pre-sales activities now involve onboarding new Business Central Partners. Especially from North America the uptake from Great Plains partners is great and it’s nice to see the entousiasm.

I’ve said it before and I’ll say it again. Business Central is by far the best ERP in the cloud and with no doubt the most flexible and easy to enhance. If you just forget for a moment that it used to be Navision and forget about the failed marketing it’s so easy to fall in love with the product once again.

Microsoft is much more quiet or less noisy. Working hard on improving the product and realising the vast amount of changes nessesairy to put dots on I’s and crosses on T’s.

The people who are new to the product need help getting started and Twitter is a nice medium to shout out for help.

For that reason Microsoft started the hashtag #BCALHelp and encourages the community to subscibe to the hastag and help their peers.

I think being the underdog, quietly working on being the best without bragging has been a position that was always good for Navision and it’s good for Business Central. Our customers are small entrepeneurs working hard and not as sensible for loud marketing as the big fortune 500.

Let’s be humble and be the best in our game. Take it slow and steady and make the best with what we have.

I’m sure that with that, NAVTechDays will soon be BCTechDays with the same pride and dignity as before serving the same great communities of Navision and Great Plains combined.

See you all in Antwerp!

Working with dates in AL vs. C/AL

It’s friday afternoon and I’m goofing around a bit with the ForNAV AL Converter. I ran into something I want to share.

AL seems to be more strickt in hardcoded dates than C/AL.

Example

Constant value '99993112D' is outside the range for a Date. The syntax for defining Date format is yyyymmddD, where D is a mandatory letter. For example, 20180325D, read as the 25th of March, 2018.

This should be 99991231D but C/Side exports it using your regional settings.

Fortunately we can fix this in C/Side by changing the code to

DMY2DATE(31,12,9999)

I only have to replace 42 instances for the project/partner I’m currently working on. Thank god it’s friday afternoon. 😉

Mapping Codeunit 10201 “Transfer Custom Fields” to Events (NA Only)

By Steve Krisjanovs

Below is a list of all COD10201 external functions and where I believe their event equivalents live in. There were three functions in the list below that had me stumped so a second set of eyes would be helpful.

I do still believe that BC’s out of the box COD10201 should still have been modified by MS to indicate that all of these external functions are dead.

The problem I encountered, was because nothing has changed with this codeunit from NAV to BC (the codeunit exists, but all objects that used to call this codeunit no longer do that in BC), the NAV merge tools merged/upgraded our legacy modified cod10201 without any issues since it couldn’t find any conflicts. This could have been an avoidable scenario e.g. if the BC functions in this codeunit threw a runtime error at the beginning of each function call (e.g. “Depricated! Use {event pub object type} {event pub object ID}.{event pub name}”) our merge tools would have caught the conflict and I could have investigated much sooner in my merge/upgrade efforts.

  • [External] GenJnlLineTOGenLedgEntry(VAR GenJnlLine : Record “Gen. Journal Line”;VAR GenLedgEntry : Record “G/L Entry”)
    • maps to COD12.OnAfterInitGLEntry
  • [External] GenJnlLineTOTaxEntry(VAR GenJnlLine : Record “Gen. Journal Line”;VAR TaxEntry : Record “VAT Entry”)
    • maps to COD12.OnBeforeInsertVATEntry
  • [External] GenJnlLineTOCustLedgEntry(VAR GenJnlLine : Record “Gen. Journal Line”;VAR CustLedgEntry : Record “Cust. Ledger Entry”)
    • maps to COD12.OnAfterInitCustLedgEntry
  • [External] GenJnlLineTOVendLedgEntry(VAR GenJnlLine : Record “Gen. Journal Line”;VAR VendLedgEntry : Record “Vendor Ledger Entry”)
    • maps to COD12.OnAfterInitVendLedgEntry
  • [External] GenJnlLineTOBankAccLedgEntry(VAR GenJnlLine : Record “Gen. Journal Line”;VAR BankAccLedgEntry : Record “Bank Account Ledger Entry”)
    • maps to COD12.OnPostBankAccOnBeforeBankAccLedgEntryInsert
  • [External] BankAccLedgEntryTOChkLedgEntry(VAR BankAccLedgEntry : Record “Bank Account Ledger Entry”;VAR CheckLedgEntry : Record “Check Ledger Entry”)
    • maps to COD12.OnPostBankAccOnBeforeCheckLedgEntryInsert
  • [External] VendLedgEntryTOCVLedgEntryBuf(VAR VendLedgEntry : Record “Vendor Ledger Entry”;VAR CVLedgEntryBuf : Record “CV Ledger Entry Buffer”)
    • maps to TAB382.OnAfterCopyFromVendLedgerEntry
  • [External] CVLedgEntryBufTOVendLedgEntry(VAR CVLedgEntryBuf : Record “CV Ledger Entry Buffer”;VAR VendLedgEntry : Record “Vendor Ledger Entry”)
    • maps to TAB25.OnAfterCopyVendLedgerEntryFromCVLedgEntryBuffer
  • [External] CustLedgEntryTOCVLedgEntryBuf(VAR CustLedgEntry : Record “Cust. Ledger Entry”;VAR CVLedgEntryBuf : Record “CV Ledger Entry Buffer”)
    • maps to TAB21.OnAfterCopyCustLedgerEntryFromCVLedgEntryBuffer
  • [External] CVLedgEntryBufTOCustLedgEntry(VAR CVLedgEntryBuf : Record “CV Ledger Entry Buffer”;VAR CustLedgEntry : Record “Cust. Ledger Entry”)
    • couldn’t identify a suitable event mapping
  • [External] ItemJnlLineTOItemLedgEntry(VAR ItemJnlLine : Record “Item Journal Line”;VAR ItemLedgEntry : Record “Item Ledger Entry”)
    • COD22.OnAfterInitItemLedgEntry
  • [External] ItemJnlLineTOPhysInvtLedgEntry(VAR ItemJnlLine : Record “Item Journal Line”;VAR PhysInvtLedgEntry : Record “Phys. Inventory Ledger Entry”)
    • maps to COD22.OnBeforeInsertPhysInvtLedgEntry
  • [External] ItemJnlLineTOValueEntry(VAR ItemJnlLine : Record “Item Journal Line”;VAR ValueEntry : Record “Value Entry”)
    • maps to COD22.OnAfterInitValueEntry
  • [External] JobJnlLineTOResJnlLine(VAR JobJnlLine : Record “Job Journal Line”;VAR ResJnlLine : Record “Res. Journal Line”)
    • maps to TAB207.OnAfterCopyResJnlLineFromJobJnlLine
  • [External] JobJnlLineTOItemJnlLine(VAR JobJnlLine : Record “Job Journal Line”;VAR ItemJnlLine : Record “Item Journal Line”)
    • maps to TAB83.OnAfterCopyItemJnlLineFromJobJnlLine
  • [External] JobJnlLineTOGenJnlLine(VAR JobJnlLine : Record “Job Journal Line”;VAR GenJnlLine : Record “Gen. Journal Line”)
    • couldn’t identify a suitable event mapping
  • [External] JobJnlLineTOJobLedgEntry(VAR JobJnlLine : Record “Job Journal Line”;VAR JobLedgEntry : Record “Job Ledger Entry”)
    • legacy NAV called from this from COD1012.CreateJobLedgEntry(…) but there doesn’t appears to be any suitable event pub in BC
  • [External] ResJnlLineTOResLedgEntry(VAR ResJnlLine : Record “Res. Journal Line”;VAR ResLedgEntry : Record “Res. Ledger Entry”)
    • maps to COD212.OnBeforeResLedgEntryInsert

AppSource; Prefix, Suffix & Intellisense

This article was triggered by a discussion on Yammer yesterday that I felt went a bit sideways.

Business Central is a first class cloud citizen and it beats born in the cloud solutions easily but fact remains that it’s based on Navision, an ERP solution with a 30-some year legacy.

Part of that legacy is a requirement for unique names in the objects, also in the cloud.

Microsoft is working hard to remove this requirement hence it’s a temporary fix but the result is that every app on AppSource needs a three letter prefix or suffix.

You can register your TLA with Microsoft and when this is done nobody else can use it.

With Per-Tenant extensions you don’t need prefixing and I would actually recommend against it since there may be a fair change you’ll use one that is used by one of the apps.

At ForNAV I am primary responsible for the App we have on AppSource and we Prefix everything with ForNAV, hence we reserved “FOR” as a prefix.

I am probably a little autistic and I like stuff that looks clean, so my C/Side looks like this:

Had I suffixed everything it would have been so ugly to look at.

What about Intellisense?

If you watch my YouTube video’s or if you attended one of my classes you’ll have heard me say I recommend suffixing so this sticks into peoples heads.

However this is on a totally different topic. This recommendation is for people who are so stubborn that they want to cling on to Hungarian notation. This will affect Intellisense.

With an AppSource solution I would recommend (and use this myself) to leave our your Registered TLA of your variables all together.

Here is an example:

As a sidenote, Intellisense in Visual Studio Code works smarter than just the first characters, it would actually do a smart search and also suggest results that contain the characters even with small typos. It’s one of the things that make VSCode better than C/Side. (One of the few things though 😊).

Tip #64 | Show License Information in Business Central

With the retirement of C/Side we have a challenge we did not have before regarding the license.

We used to be able to see the license information from C/Side, upload the license and quickly create a new page that displays permissions.

With Business Central this is no longer possible and we now need PowerShell to upload a license.

On my GitHub you can find a repo you can clone to display the license information.

Challenge

I would also like to be able to change the license from this page. I hope one of my readers can put this in and do a pull request.

It will require DotNET but that’s fine, this extension is targeted for OnPrem anyway.

Enjoy!

Tip #63 | Export Warnings & Errors from Visual Studio Code

If I get asked the same question twice I am already tempted to blog about it. This one exceeds this number and is long overdue.

It looks like the whole world is now converting from C/AL to AL and running into challenges with that.

Right now I am analysing several databases and one thing you need after elliminating low hanging fruit and removing errors that crash the compiler is to find common errors and count them.

An Excel Pivot Table is perfect for that.

Normally Visual Studio Code is not nice in exporting errors and warnings. You can try to copy/paste them but the work to clean up is hard.

With the magic AL runner by Tobias Fenster it is prepared for you. You can download it here.

You can copy and paste this into Excel and use Data -> Text to Columns to use the | as a separator.

The only thing that you’ll miss is the object ID and type. You can add these with adding two columns using the formula like

=LEFT(C5;FIND(“.”;C5)-1)

After that you’ll spend several hours. or often days in C/Side fixing errors you could have fixed a long long time ago.

Enjoy!

Business Central & Nintendo

WARNING!! Personal opinion here!

Inspiration to write down idea’s are everywhere. Next week my youngest son has his birthday and we went out this evening with the train to the big city of Deventer to buy him (us) a Nintendo Switch.

I’ve been loyal to Nintendo since the 1980ies and bought many of their consoles. I’m also loyal to Mario and have most of the games.

When the Nintendo WII came out there was the option of buying NES games for 5 dollar and I bought Mario I and III. Again, because I already purchased them 20 or so years earlier.

Now what does this have to do with Business Central? It made me reflect to a talk I had a few hours earlier while driving back home in the car with some former collegueas. They wanted to pick my brains about upgrading customers from old Navision to Business Central. In this case one was on 3.70 and the other on 2009 classic.

With Navision upgrading was easy. It required common sense and discipline. Two qualities every Navision developer should have. Back in the days I did many upgrades fixed price for less than 5k.

60% of all Navision installations are on classic, or that is what my former collegues told me. The hold of upgrading because of the gap with RTC and something called a financial crisis that forces many people from sitting on their (flat) wallet for half a decade or more.

They wanted to know how to analyse if the customizations can be ported to Business Central. The idea was to install Business Central On Prem and keep running on the same version again for a decade or more.

I told them that this was a horrible idea and it should not be advised to customers. Nobody should want to run Business Central On Prem with a support window of only 6 monhts.

That’s right. Business Central only get’s cumulative updates for 6 months. After that you are on your own and if you want to do stuff like backporting a fix from a higher version it means making your own base app.

That’s horrible.

Business Central on AL Only has just officially become a cloud only solution because no SMB is qualified to install and maintain it on premises and upgrade every 6 months.

Because the Extension model in Business Central with AL is based on taking a dependency on metadata from Microsoft it’s very fragile for changes done my Microsoft.

A lot of things that are technically possible should be avoided with per-tenant extensions because you will be forced to refactor your changes every 6 months. Very, very expensive.

Business Central is a high volume product that should be perrsonalised with apps from AppSource. An AppSource app is only interesting from an economics perspective with one hundred paying customers or more as it requires a dedicated team focussing on high quality, automated testing and an intuitive user interface.

The partners who do not accept this and keep modifying Business Central with complex per-tenant extensions are a danger for our ecosystem.

If you require a complex module for your company, use a different platform like power platform or other Microsoft options. As long as you stick to Azure, MSFT does not care.

The days of easy upgrades with Navision are over. Welcome to the days of Nintendo where we have to constantly buy new consoles to use the new toys.