You must have heard. Codeunit 1 is a goner! And if you have not heard it – you must have read about it. Because it has been on Microsoft Docks for a while, and also there was a blog that Microsoft spent on it.
Well, before I managed to find these description, I was working on my own overview ;-). So let me share it – I do believe that I look at it from another angle.
Where are my events?
If we want to extend codeunit 1, we have been subscribing to events. And if not – you should have ;-). So, first question would be – where are the events that we were subscribing to??
Well, I made my own overview of all the published events in codeunit 1, and the mapping to the new event in the table below:
OnCheckPreconditionsPerCompany | Codeunit<Data Upgrade Mgt.>.PROCEDURE<OnCheckPreconditionsPerCompany> |
OnCheckPreconditionsPerDatabase | Codeunit<Data Upgrade Mgt.>.PROCEDURE<OnCheckPreconditionsPerDatabase> |
OnInstallAppPerCompany | NOT AVAILABLE ANYMORE |
OnInstallAppPerDatabase | NOT AVAILABLE ANYMORE |
OnUpgradePerCompany | Codeunit<Data Upgrade Mgt.>.PROCEDURE<OnUpgradePerCompany> |
OnUpgradePerDatabase | Codeunit<Data Upgrade Mgt.>.PROCEDURE<OnUpgradePerDatabase> |
OnValidateUpgradePerCompany | Codeunit<Data Upgrade Mgt.>.PROCEDURE<OnValidateUpgradePerCompany> |
OnValidateUpgradePerDatabase | Codeunit<Data Upgrade Mgt.>.PROCEDURE<OnValidateUpgradePerDatabase> |
OnAfterAutoFormatTranslate | Codeunit<AutoFormatManagement>.PROCEDURE<OnAfterAutoFormatTranslate> |
OnAfterCaptionClassTranslate | Codeunit<CaptionManagement>.PROCEDURE<OnAfterCaptionClassTranslate> |
OnAfterCompanyClose | Codeunit<LogInManagement>.PROCEDURE<OnAfterCompanyClose> |
OnAfterCompanyOpen | Codeunit<LogInManagement>.PROCEDURE<OnAfterCompanyOpen> |
OnAfterFindPrinter | Codeunit<ReportManagement>.PROCEDURE<OnAfterGetPrinterName> |
OnAfterGetApplicationVersion | Codeunit<Application System Constants>.PROCEDURE<OnAfterGetApplicationVersion> |
OnAfterGetDatabaseTableTriggerSetup | Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterGetDatabaseTableTriggerSetup> |
OnAfterGetDefaultRoleCenter | Codeunit<Conf./Personalization Mgt.>.PROCEDURE<OnAfterGetDefaultRoleCenter> |
OnAfterGetGlobalTableTriggerMask | Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterGetGlobalTableTriggerMask> |
OnAfterGetSystemIndicator | Table<Company Information>.PROCEDURE<OnAfterGetSystemIndicator> |
OnAfterHasCustomLayout | Codeunit<ReportManagement>.PROCEDURE<OnAfterHasCustomLayout> |
OnAfterMakeCodeFilter | NOT AVAILABLE ANYMORE |
OnAfterMakeDateFilter | Codeunit<TextManagement>.PROCEDURE<OnAfterMakeDateFilter> |
OnAfterMakeDateText | NOT AVAILABLE ANYMORE |
OnAfterMakeDateTimeFilter | Codeunit<TextManagement>.PROCEDURE<OnAfterMakeDateTimeFilter> |
OnAfterMakeText | NOT AVAILABLE ANYMORE |
OnAfterMakeTextFilter | Codeunit<TextManagement>.PROCEDURE<OnAfterMakeTextFilter> |
OnAfterMakeTimeFilter | Codeunit<TextManagement>.PROCEDURE<OnAfterMakeTimeFilter> |
OnAfterMakeTimeText | NOT AVAILABLE ANYMORE |
OnAfterOnDatabaseDelete | Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnDatabaseDelete> |
OnAfterOnDatabaseInsert | Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnDatabaseInsert> |
OnAfterOnDatabaseModify | Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnDatabaseModify> |
OnAfterOnDatabaseRename | Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnDatabaseRename> |
OnAfterOnGlobalDelete | Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnGlobalDelete> |
OnAfterOnGlobalInsert | Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnGlobalInsert> |
OnAfterOnGlobalModify | Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnGlobalModify> |
OnAfterOnGlobalRename | Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnGlobalRename> |
OnAfterReportGetCustomRdlc | Table<Custom Report Layout>.PROCEDURE<OnAfterReportGetCustomRdlc> |
OnBeforeCompanyClose | Codeunit<LogInManagement>.PROCEDURE<OnBeforeCompanyClose> |
OnBeforeCompanyOpen | Codeunit<LogInManagement>.PROCEDURE<OnBeforeCompanyOpen> |
OnBeforeOnDatabaseDelete | Codeunit<GlobalTriggerManagement>.PROCEDURE<OnBeforeOnDatabaseDelete> |
OnBeforeOnDatabaseInsert | Codeunit<GlobalTriggerManagement>.PROCEDURE<OnBeforeOnDatabaseInsert> |
OnBeforeOnDatabaseModify | Codeunit<GlobalTriggerManagement>.PROCEDURE<OnBeforeOnDatabaseModify> |
OnBeforeOnDatabaseRename | Codeunit<GlobalTriggerManagement>.PROCEDURE<OnBeforeOnDatabaseRename> |
OnBeforeOpenSettings | Codeunit<Conf./Personalization Mgt.>.PROCEDURE<OnBeforeOpenSettings> |
OnEditInExcel | Codeunit<ODataUtility>.PROCEDURE<OnEditInExcel> |
OnRoleCenterOpen | Codeunit<Conf./Personalization Mgt.>.PROCEDURE<OnRoleCenterOpen> |
I indicated in red the ones that need a bit attention, as either they are not available, or are renamed.. .
Are there new events as well?
Yes! And quite many of them. I just don’t know how I can give you a complete overview of all the events “that could have been in codeunit 1, but are now spread over multiple codeunits.. “. So, let me just give you a few tips of where you could find such “generic” or “platform wide” or “…” events.
In my opinion, the below codeunits have these kind of events that I think are very interesting in a application-wide-context:
- LogInManagement
- ReportManagement
- Application System Constants
- Conf./Personalization Mgt.
- TextManagement
- AutoFormatManagement
- CaptionManagement
- GlobalTriggerManagement
- SaaS Log In Management
- Company Information
- Custom Report Layout
- ODataUtility
- Data Upgrade Mgt.
So. Just to help you … I created another list with events which I think are quite interesting for you. In bold, you see the ones that didn’t exist in Codeunit 1.
- Codeunit<LogInManagement>.PROCEDURE<OnAfterCompanyClose>
- Codeunit<LogInManagement>.PROCEDURE<OnAfterCompanyOpen>
- Codeunit<LogInManagement>.PROCEDURE<OnAfterLogInEnd>
- Codeunit<LogInManagement>.PROCEDURE<OnAfterLogInStart>
- Codeunit<LogInManagement>.PROCEDURE<OnBeforeCompanyClose>
- Codeunit<LogInManagement>.PROCEDURE<OnBeforeCompanyOpen>
- Codeunit<ReportManagement>.PROCEDURE<OnAfterGetPaperTrayForReport>
- Codeunit<ReportManagement>.PROCEDURE<OnAfterGetPrinterName>
- Codeunit<ReportManagement>.PROCEDURE<OnAfterHasCustomLayout>
- Codeunit<ReportManagement>.PROCEDURE<OnAfterSubstituteReport>
- Codeunit<Application System Constants>.PROCEDURE<OnAfterGetApplicationVersion>
- Codeunit<Conf./Personalization Mgt.>.PROCEDURE<OnAfterCopyProfile>
- Codeunit<Conf./Personalization Mgt.>.PROCEDURE<OnAfterGetDefaultRoleCenter>
- Codeunit<Conf./Personalization Mgt.>.PROCEDURE<OnBeforeOpenSettings>
- Codeunit<Conf./Personalization Mgt.>.PROCEDURE<OnGetBuiltInRoleCenterFilter>
- Codeunit<Conf./Personalization Mgt.>.PROCEDURE<OnInitializeProfiles>
- Codeunit<Conf./Personalization Mgt.>.PROCEDURE<OnProfileChanged>
- Codeunit<Conf./Personalization Mgt.>.PROCEDURE<OnRoleCenterOpen>
- Codeunit<TextManagement>.PROCEDURE<OnAfterMakeDateFilter>
- Codeunit<TextManagement>.PROCEDURE<OnAfterMakeDateTimeFilter>
- Codeunit<TextManagement>.PROCEDURE<OnAfterMakeTextFilter>
- Codeunit<TextManagement>.PROCEDURE<OnAfterMakeTimeFilter>
- Codeunit<TextManagement>.PROCEDURE<OnBeforeMakeTextFilter>
- Codeunit<AutoFormatManagement>.PROCEDURE<OnAfterAutoFormatTranslate>
- Codeunit<CaptionManagement>.PROCEDURE<OnAfterCaptionClassTranslate>
- Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterGetDatabaseTableTriggerSetup>
- Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterGetGlobalTableTriggerMask>
- Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnDatabaseDelete>
- Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnDatabaseInsert>
- Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnDatabaseModify>
- Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnDatabaseRename>
- Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnGlobalDelete>
- Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnGlobalInsert>
- Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnGlobalModify>
- Codeunit<GlobalTriggerManagement>.PROCEDURE<OnAfterOnGlobalRename>
- Codeunit<GlobalTriggerManagement>.PROCEDURE<OnBeforeOnDatabaseDelete>
- Codeunit<GlobalTriggerManagement>.PROCEDURE<OnBeforeOnDatabaseInsert>
- Codeunit<GlobalTriggerManagement>.PROCEDURE<OnBeforeOnDatabaseModify>
- Codeunit<GlobalTriggerManagement>.PROCEDURE<OnBeforeOnDatabaseRename>
- Codeunit<SaaS Log In Management>.PROCEDURE<OnSuppressApprovalForTrial>
- Table<Company Information>.PROCEDURE<OnAfterGetSystemIndicator>
- Table<Custom Report Layout>.PROCEDURE<OnAfterReportGetCustomRdlc>
- Codeunit<ODataUtility>.PROCEDURE<OnEditInExcel>
- Codeunit<Data Upgrade Mgt.>.PROCEDURE<OnCheckPreconditionsPerCompany>
- Codeunit<Data Upgrade Mgt.>.PROCEDURE<OnCheckPreconditionsPerDatabase>
- Codeunit<Data Upgrade Mgt.>.PROCEDURE<OnIsUpgradeInProgress>
- Codeunit<Data Upgrade Mgt.>.PROCEDURE<OnUpgradePerCompany>
- Codeunit<Data Upgrade Mgt.>.PROCEDURE<OnUpgradePerDatabase>
- Codeunit<Data Upgrade Mgt.>.PROCEDURE<OnValidateUpgradePerCompany>
- Codeunit<Data Upgrade Mgt.>.PROCEDURE<OnValidateUpgradePerDatabase>
But that’s not all…
If you look for example into Codeunit “LoginManagement”, you’ll see that it subscribes to an event called “OnCompanyClose”, which is an event in codeunit “2000000003”.
I wasn’t able to export that codeunit (with powershell, nor with the classic client) – and even found a few more like those codeunits. In classic environment, this is what I saw:
So all these codeunits end with “Triggers” – which means in VSCode, we are able to access them with Intellisense like:
Here is an overview of all the events in these “system trigger codeunits”:
Company Triggers | OnCompanyClose |
Company Triggers | OnCompanyOpen |
Debugger Triggers | OnDebuggerBreak |
Extension Triggers | OnInstallAppPerCompany |
Extension Triggers | OnInstallAppPerDatabase |
Global Triggers | GetDatabaseTableTriggerSetup |
Global Triggers | GetGlobalTableTriggerMask |
Global Triggers | OnDatabaseDelete |
Global Triggers | OnDatabaseDelete |
Global Triggers | OnDatabaseInsert |
Global Triggers | OnDatabaseModify |
Global Triggers | OnDatabaseRename |
Global Triggers | OnGlobalDelete |
Global Triggers | OnGlobalInsert |
Global Triggers | OnGlobalModify |
Global Triggers | OnGlobalRename |
Upgrade Triggers | OnCheckPreconditionsPerCompany |
Upgrade Triggers | OnCheckPreconditionsPerDatabase |
Upgrade Triggers | OnUpgradePerCompany |
Upgrade Triggers | OnUpgradePerDatabase |
Upgrade Triggers | OnValidateUpgradePerCompany |
Upgrade Triggers | OnValidateUpgradePerDatabase |
Version Triggers | GetApplicationBuild |
Version Triggers | GetApplicationVersion |
Version Triggers | GetReleaseVersion |
Reporting Triggers | GetPaperTrayForReport |
Reporting Triggers | GetPrinterName |
Reporting Triggers | HasCustomLayout |
Reporting Triggers | MergeDocument |
Reporting Triggers | ReportGetCustomRdlc |
Reporting Triggers | ScheduleReport |
Reporting Triggers | SubstituteReport |
UI Helper Triggers | AutoFormatTranslate |
UI Helper Triggers | CaptionClassTranslate |
UI Helper Triggers | GetApplicationLanguage |
UI Helper Triggers | GetCueStyle |
UI Helper Triggers | GetDefaultRoundingPrecision |
UI Helper Triggers | GetSystemIndicator |
Filter Helper Triggers | MakeCodeFilter |
Filter Helper Triggers | MakeDateFilter |
Filter Helper Triggers | MakeDateTimeFilter |
Filter Helper Triggers | MakeIntFilter |
Filter Helper Triggers | MakeTextFilter |
Filter Helper Triggers | MakeTimeFilter |
System Action Triggers | CustomizeChart |
System Action Triggers | GetDefaultRoleCenterID |
System Action Triggers | InvokeExtensionInstallation |
System Action Triggers | OnEditInExcel |
System Action Triggers | OpenContactMSSales |
System Action Triggers | OpenDebugger |
System Action Triggers | OpenSettings |
I’m not sure in how to use all of them – but it is a great help to simply look into the code of Busines Central, as most (if not all) of these events exist because Microsoft needed them. You can figure out how to use them, and in many cases, you’ll find what are the actual events you should use as a developer.
Enjoy!
9 comments
Skip to comment form
you can c&p the System codeunits to peek into it. Just stand on an object you have Access (Luke cu 50000)
Author
Thanks, but I’m not sure what you mean…
I would like an event that triggers on each error a users gets. Including user name and business application stack trace. That would give so much info on the users experience. IF users need training, if a part of the application is to difficult, …
Author
Absolutely.
Now, I’ve seen something like that in the “Admin center” they are creating for CSP-partners for SaaS implementations. Let’s see if we can get this for OnPrem…
What Stephan meant:
Go to Object Designer, Codeunit 2000000002 “Global Triggers” (as an example). Select that line and copy into clipboard.
Then go to any existing 50000..99999 object in the object designer and “Paste” the object from your clipboard.
Ignore the error, assign a new number and a new name.
Now you can check the code inside the codeunit you just “created”.
@Thomas
… at least this works up to the December build …
For those, who wonder why the new trigger codeunits in the range 2000000001 to 2000000010 are the only objects not readable with a developer license… – they might simply have missed them.
There is an article published under official upgrade documentation. We have presented this at Directions – you have missed the great session ;-).
https://docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/upgrade/transition-from-codeunit1
There is also a replacement COD1 that you can use for upgrade. We do not recommend to use this one in production, since it is not maintained. We support the code only foar upgrade.
Author
Thank, Nikola! Great additional info!
Author
And in my defence, that link is on the very beginning of my blogpost :p