Professional Documents
Culture Documents
Untitled
Untitled
Untitled
Dynamics 365 Business Central is a complete enterprise resource planning (ERP) software solution for mid-
sized organizations that is fast to implement, easy to configure, and simple to use. Right from the start,
simplicity has guided — and continues to guide — innovations in product design, development,
implementation, and usability. Users can customize and administrate their Business Central experience in the
product. Other tasks for administration and development require a more specialized profile, and in this
Development and Administration section, you can find more technical information, including information about
developing for Dynamics 365 Business Central using the AL Language extension and Visual Studio Code.
L IN K DESC RIP T IO N
Deployment of Dynamics 365 Business Central Describes the difference between making Business Central
available online and on-premises.
Administration of Business Central Online as an internal Learn about resources that are available to you as the
administrator system administrator, IT professional, or superuser of a
Business Central customer.
Administration of Business Central Online as a partner Learn about resources that are available to you as a Business
Central reselling partner.
The Business Central Administration Center Learn about the administration center and what you can do
there.
Technical Support for Dynamics 365 Business Central Learn about the tools that are available to you to help you
troubleshoot your customers' Business Central.
Administration of Business Central On-Premises Learn about resources that are available to you as the
system administrator, IT professional, or superuser of
Business Central on-premises.
Configuring the Help Experience Learn about your options for deploying Help for Business
Central.
L IN K DESC RIP T IO N
The SMB Opportunity for App Publishers Learn about the business opportunity for building your app
on top of Business Central.
Get Started with Building Apps Learn how to get started as a partner.
L IN K DESC RIP T IO N
Get Started as a Reseller of Business Central Online Landing page for readiness for resellers.
Business Functionality in Business Central Landing page for the core functionality in Business Central.
Enroll in the Cloud Solution Provider program Describes the different models for selling in the Cloud
Solution Provider (CSP) program so you can determine
which works best with your business.
NOTE
When you buy Business Central offers on behalf of your CSP customers, the CSP offer must be available in both your own
tenant's country and in your customer's tenant's country. For example, if your tenant is located in Slovakia and the
customer's tenant is in Germany, you will not be able to sell Dynamics 365 Business Central Premium to that customer,
because this offer is currently not available in Slovakia.
Similarly, if your tenant is located in Germany and the customer's tenant is in Slovakia, you will not be able to sell
Dynamics 365 Business Central Premium to that customer, because this offer is currently not available in Slovakia.
NOTE
The RSS feed returns a list of the 100 articles most recently updated. The list is sorted by date, but it can take up to a
week before the most recently updated articles make it to the list.
See also
Dynamics 365 Business Central Business Functionality Help
Dynamics 365 Business Central on Microsoft Learn
FAQ for Dynamics 365 Business Central Development and Administration
Resources for Help and Support for Dynamics 365 Business Central
The Lifecycle of Apps and Extensions
Maintenance of AppSource Apps and Per-Tenant Extensions
Microsoft Dynamics 365 Business Central on the Dynamics 365 blog
Dynamics 365 Business Central Partner Portal
Dynamics NAV Developer and ITPro Content
Dynamics 365 Product Licensing
Welcome to Business Central | Resources for
Partners
2/6/2023 • 3 minutes to read • Edit Online
Are you a Microsoft partner working with Business Central and looking for relevant resources? Find everything
you need in this article and remember to bookmark aka.ms/BCAll.
Stay up to date
Discover what's new for partners in the Business Central newsletter: aka.ms/BCNews
Watch the what’s new launch event sessions: aka.ms/BCLE
Join the office hours calls: aka.ms/BCOfficeHours
Find on-demand recordings of office hours calls: aka.ms/BCOfficeHoursRecordings
Go to market
Business Central homepage: dynamics.microsoft.com/business-central/overview/
Try Business Central for free (30-day trial): go.microsoft.com/fwlink/?LinkId=2143349&clcid=0x409
Business Central customer stories: aka.ms/BCCustomerStories
Discover useful resources for partners: aka.ms/BCPartnerPortal
Transact capability for Business Central Apps on Microsoft AppSource: aka.ms/BCAppTransact
Power Platform
Business Central and Power BI: aka.ms/BCPBI
Business Central and Power Automate: aka.ms/BCAutomate
Business Central and Power Apps: aka.ms/BCPApps
[Prototype] Low code sync of Business Central entities to Dataverse: aka.ms/bc2dataverse
Getting support
Managing technical support for customers: Manage Technical Support
Test network connectivity for Business Central: aka.ms/BCCP
Our mission is to empower every individual and every organization on the planet to achieve more. Particularly,
focusing on those 78 million small and mid-sized businesses (SMB) worldwide that passionately want more
resiliency in their tech intensity and their capability of transforming products and services to face the challenges
in the marketplace. To embrace the constant change and grow, every organization must have a business
application that breaks down the silos of data, processes, and workflow in their operations. This insight enables
employees to respond to daily challenges and opportunities with agility. Market research shows that the
business applications opportunity for software companies in the SMB space is predicted to be 51 billion dollars
by 2025. As a developer, you want to make sure you bet on the winning platform. The BizApps market growth in
this area is 17%; however Dynamics 365 platform growth is increasing at 47%!
Consultancy services
A large number of business users find it easy to buy consultancy services to research, deploy and manage apps.
Therefore, next to providing Apps, a publisher can also market consultancy services on Microsoft AppSource to
connect with buyers. The offered services could be assessments, briefings, workshops, proof of concepts, and
implementations. In general, the services are typically fixed in scope and duration. They're offered at a fixed price
or free, and have a defined outcome.
Here are a few examples of consultancy services provided by publishers:
Unified Commerce Readiness Intro: 1-Hr Assessment In this 1 hour assessment, LS Retail assesses how a
4-day engagement helps them with implementing their Unified Commerce Cloud solution based on
Microsoft Dynamics 365.
NAV-X Commission Mgt Gold 4-Hr Implementation In this 4 hour implementation workshop, NAV-X
supports the customers in implementing their commission management app.
Learn more about Consultancy Services.
See also
Get Started with Building Apps
Get Started with Building Apps
2/6/2023 • 8 minutes to read • Edit Online
Dynamics 365 Business Central is a business management solution that helps companies connect their services
and operations to streamline business processes, improve customer interactions and make better decisions.
With this modern business platform, you have the convenience to quickly tailor, extend, and build applications
so that they fit your specific needs with little to no code development.
Build a business app for a specific industry, process, or department such as HR, finance, marketing or
operations. Then, publish your app to the Microsoft commercial marketplace, where customers can find your
app, try it and get in touch with you. For more information, see What is the Microsoft commercial marketplace?.
Learn how you can become a Business Central app publisher in six steps in this article.
IMPORTANT
We currently advise new publishers to not request an RSP object range
IMPORTANT
We currently advise new publishers to request an app object range.
Currently, you can implement apps developed in both the RSP range and the app object range in Business
Central online and on-premises, as well as partner-hosted.
You can request an object range by downloading the object range request form here. After completion, send
them to your Regional Operational Center (ROC) for processing:
mbscon@microsoft.com if you're based in Europe, the Middle East, or Africa
mbsagree@microsoft.com if you're based in the Americas
mbslques@microsoft.com if you're based in the Asia Pacific region.
Downloading your development license file
After your Regional Operational Center has processed your Agreements and Object Range Request forms,
download your company's unique developer license from PartnerSource Business Center. Find it in the license
key configuration section under the developer tools section.
Register your unique prefix or suffix
In your extension, the name of each object must contain a prefix or suffix that is registered for your publisher
name. For more information about the use of affixes and the registration process, see Benefits and Guidelines
for using a Prefix or Suffix.
NOTE
If you have Microsoft 365, then your company most likely has Azure AD.
NOTE
To find out if your company has an Azure AD account, check with your system administrator.
2. Choose the settings icon in the top-right corner of the page, got to on account settings, and choose
user management .
3. Choose the grey ADD USERS button, and leave the default choice to Add existing users as-is. Now,
you can search for the user(s) that you want to add to Collaborate. To add them, you need to choose them
from the menu, and then choose the grey ADD SELECTED button.
4. You've successfully added your coworkers to Collaborate. Users can now sign in to Microsoft Collaborate
using the following link: aka.ms/Collaborate
Step 4 B: Getting access to the available builds and engagements
Once you've successfully registered on Microsoft Collaborate, Microsoft must assign you to the right programs,
and engagements before you can see the preview bits. Contact Dyn365BEP@microsoft.com and provide them
with information about the relevant users. the following table illustrates the type of information that you must
submit:
P UB L ISH ER DISP L AY W O RK A C C O UN T
NAME M P N ID F IRST N A M E L A ST N A M E EM A IL
After sending the email, expect a response from Microsoft within 1-2 business days.
See also
The SMB Opportunity for App Publishers
The Lifecycle of Apps and Extensions for Business Central
Update Lifecycle for AppSource Apps FAQ
Maintain AppSource Apps and Per-Tenant Extensions in Business Central Online
Microsoft Responsibilities for Apps on Business Central online
Customize Business Central
2/6/2023 • 2 minutes to read • Edit Online
Every business is unique. Dynamics 365 Business Central us ready to adapt to how customers work: their
streamlined processes, their terminology, and how their employees or departments connect and collaborate.
Whilst there may already be add-on apps available on AppSource that cover a customer’s need, we also have
the tools for you to build fully custom functionality or adapt what is already available out-of-the box.
How do I customize?
For most simple changes to the user interface, the browser-based Designer allows you to rapidly adjust the UI
for all users within the organization, without needing to write any code. Similar tools are available to customize
the UI for an individual user, or users of a specific role. Hide columns that aren't needed, drag-and-drop to
reposition FactBoxes, bookmark links to commonly used lists, or show data fields that were previously hidden:
these are all examples of simple changes that can be rolled out to an entire organization using Designer. For
more information, see Using Designer
With Visual Studio Code and the AL Language extension, you’re able to customize existing pages and tables by
creating page and table extensions, or you can add new tables and pages to implement entirely new
functionality. You can even write business logic in AL. For more information, see Get Started with AL.
You can start customizing in either Designer or in Visual Studio Code. If you start in Designer, the AL source code
generated by the Designer is downloadable, so you can continue developing in Visual Studio Code if needed. If
you start developing in Visual Studio Code, you'll initiate Designer directly from Visual Studio Code, to continue
customizing the UI with a more visual and real-time overview of your changes. When done using Designer you
synchronize changes back to Visual Studio code keeping all changes reflected in the AL source code.
The resulting AL code is compiled into an .app file, which can be deployed to production environments or other
sandbox environments for testing.
When you build an app or extension to Business Central and get that published to AppSource, it becomes an
app like so many others - the app itself can be updated, and the platform that it sits on, Business Central online
itself, will also get updated. But what happens after your app gets published?
When your app has passed all of our validations and has gone live to AppSource, customers can install your
extension and use it for their business. But you are expected to keep it compliant with the service and update it if
something changes.
The following sections describe the different upgrade scenarios that we have seen play out as we update
Business Central. For more information about your responsibility for keeping your app updated and the
resources that are available to you, see Maintain AppSource Apps and Per-Tenant Extensions.
Conclusions
You're responsible for your app. You own the process of updating the app and providing upgrade code if the
schema changes between versions of the app.
If a customer uninstalls your app, and then installs it again later, then when they install the app the second time,
they get the latest version from AppSource.
How Microsoft handles your app
When Microsoft upgrades a tenant with a service update, your app is tested against the new service version. If
the app breaks, Microsoft rolls back to the previous healthy state. Your customer never learns that anything was
about to break.
When a tenant uninstalls and reinstalls an extension via the Extension Management page or AppSource, there is
platform logic that determines whether an Install or an Upgrade must take place. We detect which version of the
extension the tenant previously had installed and perform the appropriate action. Therefore, the result of
manually uninstalling/installing the extension is the exact same as an automated upgrade.
Additionally, there will not be any data loss during uninstall, install, or upgrade actions. Data for extensions is
stored in its own tables in the tenant database. Before an extension gets installed, it first get synchronized on the
tenant database. This step is implicit and happens automatically when a tenant installs an extension. This
synchronization process creates the database tables for the extension. Once the extension is installed and the
tenant is using it, extension-specific data will get stored in these tables.
When an extensions gets uninstalled, these tables do not get removed. Therefore, when the extension gets
reinstalled (or upgraded), the data is still available. You do not need to worry about data loss for choosing the
uninstall/install route. However, do keep in mind that if any actions are being performed on the tenant while the
extension is uninstalled, the extension's events and such will not be firing, and your app may miss the creation of
new data. Try to perform the uninstall/install while the tenant is not online.
For more information, see When apps or PTEs cannot be updated by Microsoft.
See Also
Publishing and Installing an Extension
Retaining table data after publishing
Upgrading Extensions
Add your App to AppSource
Checklist for Submitting Your App
Upgrading AppSource Apps in Production
Maintain AppSource Apps and Per-Tenant Extensions
Update Lifecycle for Customizations of Business
Central Online
2/6/2023 • 2 minutes to read • Edit Online
When you create a tenant-specific customization, or an extension that is scoped to a single Business Central
environment (often referred to as per-tenant extensions), you must take the lifecycle of the extension into
consideration. For more information about the extension lifecycle and events that can cause incompatibilities
between the extension and base application, see The Lifecycle of Apps and Extensions for Business Central.
You are responsible for your extension. You own the process of updating the extension and providing upgrade
code if the schema changes between versions of the Business Central base application. When an update is
available for your Business Central environment, all extensions, both AppSource extensions and tenant
customizations, must be compatible with the next version of the base application before the update can be
installed on the environment. You are responsible for ensuring that your extensions are compatible with the
update version.
In this article, we describe the process for ensuring update compatibility for tenant customizations.
IMPORTANT
At least one email address must be specified as a notification recipient to receive the update notifications. If you do not
speciy an email address, you will not be notified of updates and other changes to the tenant.
The email notification provides information on the incompatible extension, detail on which properties must be
updated, and steps to bring the extension into compatibility.
See Also
Retaining table data after publishing
Upgrading Extensions
Updating Environments
Maintain AppSource Apps and Per-Tenant
Extensions in Business Central Online
2/6/2023 • 8 minutes to read • Edit Online
As a partner, keeping your apps and per-tenant extensions (PTEs) up to date is your responsibility. Business
Central is regularly updated with major and minor releases. These updates provide customers with a business
application that is always compliant, secure, and enriched with new platform and application functionality. Often
customers choose Business Central because of this promise of having an always up-to-date business solution.
To not break this promise, developers that bring apps to Microsoft AppSource, and resellers that provide PTEs to
respond to the unique needs of customers, have a responsibility to align their code to the Microsoft release
rhythm.
The following diagram illustrates the time for how updates roll out for Business Central online and how you can
use previews to test your apps ahead of time:
An inability for Microsoft to update tenants because of publishers incompatible code causes serious disruption
in the service and must be avoided since it impacts the trustworthiness of the service and customer satisfaction.
Resources
To help app publishers keep up with their update responsibilities, Microsoft provides the following resources:
Release plans about what's new and planned
For more information, see Dynamics 365 release plans.
Access to pre-release bits
Business Central partners have access to the next major, next minor, and daily pre-release bits in Docker
through Microsoft Collaborate. To get access to Collaborate, follow steps 1 and 4 in the
https://aka.ms/bcpublisher article. Use the pre-release bits to test apps against upcoming updates.
Learn about the update lifecycle for apps and extensions and automated extension validation. Use the
AppSourceCop analyzer rules to keep your code compliant. Get agile with AL Go for GitHub and stay on
top of changes that way.
Information about what will be deprecated
With all Business Central releases, Microsoft controls and regulates breaking changes with major releases
and communicates upcoming breaking changes at least one year in advance. If developers missed this
above info, the compiler in Visual Studio Code also warns for potential controls that will become obsolete
in future versions and how to deal with them. Use the analyzers actively to make sure your code is ready
for the next update.
Policy definitions and terms
The publisher agreement and the commercial marketplace certification policies describe the
responsibilities of app providers for how to publish and maintain apps in the Microsoft monthly rhythm.
When a PTE gets installed, the publisher also agrees to the terms to keep that code current and updatable.
Training and coaching
Microsoft provides a set of tools, training, and documentation to help partners find the info they need to
keep up with these responsibilities on continuous integration and continuous deployment. External
providers, including ISV Development Centers, MasterVARs, and training centers, can provide in-person
training and coaching.
Service notifications
Business Central online will support app and PTE publishers with extra warnings about potential technical
incompatibility. If publishers respond to these notifications in due timing and avoid incompatibilities
repeatedly, Microsoft will stand with these publishers to help where needed. If a publisher includes a
telemetry key in their app, then, starting with 2020 release wave 2, Business Central also provides
publishers with telemetry about upgrade failures that happen in production because of issues in the
publisher's upgrade code.
If publishers lack to keep their code updatable, they risk that ultimately their apps or PTEs will be removed from
the customer's tenant, and this will most likely result in important data not being captured as it should. For apps,
this also means removal from the marketplace.
Since resellers are the first line contact point for customers, they carry responsibility to explain what it means to
load code in a customer's environment. The best way is to explain this is with terms.
We advise these terms include topics like intellectual property rights, upgrade responsibilities, associated costs
to keep code updatable, support options, data privacy, and so on.
IMPORTANT
Microsoft tests code based on technical compatibility. As the publisher, you are still responsible for all functional and
logical validation. For more information, see The Lifecycle of Apps and Extensions for Business Central.
NOTE
If an app has been published through AppSource, it should not be tested, installed, or in other ways treated as a PTE since
this will create conflicts.
See also
The Lifecycle of Apps and Extensions
Update Lifecycle for Customizations
Microsoft Responsibilities for Apps on Business Central online
Technical Support for Business Central online
Sending Extension Telemetry to Azure Application Insights
Major Updates and Minor Updates for Business Central Online
Discontinuing an AppSource app
2/6/2023 • 2 minutes to read • Edit Online
The following section describes the process that we recommend AppSource partners follow to remove an app
from the AppSource marketplace.
NOTE
As the offer can still be installed by new customers, we recommend switching the listing type to 'Contact Me' in order for
you to control who is installing the app, see Listing Types. You can also define custom logic within your app to define who
is allowed to install it.
FAQ
Do I have to uninstall the app for every tenant?
No. It is the responsibility of the partner maintaining the environment to uninstall the app when they see fit.
Does the customer receive any kind of notification?
The customer does not receive any notification from Business Central about the fact that the offer has been
deprecated. It is your responsability to reach out to your customers. If at some point, the app blocks the upgrade
of the environment, then the partner maintaining the environment will be notified that the app is blocking
upgrade. The partner maintaining the environment, can then decide at that point to uninstall it or to contact you
for additional information. For more information, see Maintain AppSource Apps and Per-Tenant Extensions in
Business Central Online.
See Also
The Lifecycle of Apps and Extensions for Business Central
Maintain AppSource Apps and Per-Tenant Extensions in Business Central Online
App Identity
Development of a Localization Solution
2/6/2023 • 5 minutes to read • Edit Online
If you want to bring the capabilities of the Dynamics 365 Business Central to your local market, then there are
several reasons why you would want to choose Dynamics 365 Business Central:
Easy to translate and strong base capabilities ready for localization.
Reach more customers by showcasing your localization apps on Microsoft AppSource.
Dynamics 365 Business Central provides a proven ERP platform and application for your localization apps,
which adapts functional areas to the requirements of the local market.
Localization apps are simply apps for Dynamics 365 Business Central - learn more about getting onboarded as
an app publisher here: Get Started with Building Apps.
NOTE
If you have questions for building localization apps, please contact the Microsoft localization team.
See Also
Get Started with Building Apps
The SMB Opportunity for App Publishers
Get Started as a Reseller of Business Central Online
Countries and Translations Supported
Business Central Learning Catalog
Microsoft Responsibilities for Apps on Business
Central online
2/6/2023 • 2 minutes to read • Edit Online
Business Central online is a cloud service for small to medium-sized businesses that is built on and for Microsoft
Azure. Business Central brings together the business management solution, business intelligence, infrastructure,
computing, and database services in a single offering that enables organizations to run horizontal or industry-
specific apps from Independent Software Vendors (ISVs), without the hassle of managing infrastructure.
The Business Central online model distinguishes specific roles and responsibilities for partner-provided vertical
solutions, system integrators, resellers, and Microsoft throughout the life cycle of the service. Microsoft
maintains the Business Central service by deploying, actively monitoring, and servicing the customers'
production tenants that are running on the service. This includes allocating the required system infrastructure to
run the service and proactively communicating to customers about the service's health (which is done through
the Service Health dashboard in the Microsoft 365 Admin Portal).
Microsoft responsibilities in the Business Central online service include:
Lifecyle Services portal (EmbedApp program) Development, deployment, and support of the portal
functionality
High availability and disaster recovery
Monitoring, updating and patching
First-line support for partners
See Also
Get Started as a Reseller of Business Central Online
Maintain AppSource Apps and Per-Tenant Extensions in Business Central Online
Administration of Business Central Online
Technical Support for Dynamics 365 Business Central
Components and Capabilities
2/6/2023 • 2 minutes to read • Edit Online
When you build an app for Business Central, be it an AppSource app or an Embed App, you must be aware of
which components and deployment steps are provided by Microsoft and which you must provide.
Components
Base application
The base application is the Business Central application provided by Microsoft, customized and extended to fit
the needs of a market segment that an app wants to serve. Major releases and cumulative updates (CUs) of the
base application are publicly available on Microsoft Download and as artifacts for use with Docker.
Pre-released versions of the base application are available as artifacts for participants of the “Ready and Go”
program via Microsoft Collaborate for use with Docker. Although we recommend always using the latest version
of the base application, partners can choose any version they need. The only requirement is that the partner
makes sure that the base application version that they base their app on is available in Business Central online
production environments.
AppSource apps must specify the dependency of a specific base application in the settings for their app. In
contrast, the base application is an optional part of an Embed App package. If the partner has implemented all
required functionality in their library extensions, they do not have to include the base application itself with the
Embed App. Instead they should specify, in the metadata of the Embed App, which version of the Business
Central base application they are targeting, just like an AppSource app.
Microsoft recommends all partners to move towards a model where the code-customization of the base
application is not used. Keep track of new capabilities in the base application and platform in the release plans.
Platform
Partners who build apps for Business Central online must make sure that it is compatible with a supported
version of Business Central platform.
The Microsoft platform is updated in the following way:
Minor updates
Microsoft will ship minor platform updates monthly and major platform updates every six months.
Minor updates can include bug fixes and improvements which should not affect the compatibility of the
platform with the previous version of the application. In rare situations, partners may be asked to
recompile their solution to work with a minor update of a Business Central platform.
Major updates
Major updates will include changes that can require partners to perform a technical upgrade to make
their application work with the new version of the platform. For more information, see the Dynamics 365
release plans
Ecosystem
Business Central online is part of a rich ecosystem of other Microsoft and 3rd party services, which partners and
customers can decide to take advantage of.
The following integration capabilities of the Business Central can be considered:
IN T EGRAT IO N C A PA B IL IT Y STAT US
Dynamics 365 API endpoint Available if the base application objects are unchanged
Microsoft 1st party integration apps included with Business Available, but in many cases the partner must set up a
Central (Yodlee, Quick Books, OCR, AMC, and others) separate agreement with these service providers
See Also
Microsoft Responsibilities
Embed App Overview
Add your App to AppSource
2/6/2023 • 2 minutes to read • Edit Online
AppSource is a market place where partners can provide marketing details, such as descriptions, whitepapers, or
videos about their app for Business Central.
Embed App partners can choose to promote themselves and their Embed App on AppSource.
IMPORTANT
Unlike all other apps, solutions that are part of the Embed App program are not uploaded to AppSource itself. Instead,
the app package is uploaded, deployed and tested via Lifecycle Services. AppSource in this case is used for the marketing
purposes, not as a repository of Apps.
All other apps do submit their app to App Source. For more information, see Technical Validation Checklist and Marketing
Validation Checklist.
IMPORTANT
As soon as your app has been uploaded to the AppSource marketplace, it will be used as a baseline during the technical
validation of your next submission(s). As a consequence, you won't be allowed to perform breaking changes without
obsoleting the AL objects first and you won't be allowed to perform schema breaking changes; breaking changes on
tables or table extensions. This applies also if your extension isn't used by customers yet. You should then not submit your
app to the AppSource marketplace if you are still developing it and expect to change it in the near future.
See Also
Get Started as a Reseller of Business Central Online
Build Your Business on Dynamics 365 Business Central
Marketing Validation Checklist
Technical Validation Checklist
Embed App Overview
Marketing Validation Checklist
2/6/2023 • 3 minutes to read • Edit Online
The storefront details on AppSource are the first impression that prospects get regarding your offer. First
impressions last, so make sure to invest some time in developing the content on the storefront, so it gives a
good impression from the beginning. Failing to do so will jeopardize the hard work you put in, when developing
your offer, likely leaving the prospect confused or looking elsewhere. Accordingly, we recommend you put in the
time, effort and due diligence when developing this content.
You use Partner Center to submit your offer to AppSource. In the following, you can find information on all the
marketing-related items that you need to fill out in Partner Center prior to submitting your app to AppSource.
Follow this marketing validation checklist and get your app passed on the first submission.
Microsoft images Make sure not to use any Microsoft Read more
images (for example, the Business
Central icon or Dynamics 365 logo).
App type Read more about the types of apps Read more
you can submit to AppSource.
Properties
IT EM REQ UIREM EN T DETA IL S
Terms and conditions Outline the terms and conditions that Read more
the customer must accept before they
can use your offer.
Offer listing
IT EM REQ UIREM EN T DETA IL S
Offer name Enter a descriptive name for the offer. Read more
Products your app work with Add specific products that your app Read more
works with.
Privacy policy link The link to your offer’s privacy policy. Read more
Support link The link to your offer’s support page. Read more
Availability
IT EM REQ UIREM EN T DETA IL S
Markets (countries) Choose the markets that your app is Read more
available in (make sure that it
resembles the supported countries
paragraph in the description text).
Hide key The hide key is a token that is used to Read more
view the preview of your offer in
AppSource before going live.
Do you have any tips and tricks for what I should write in the
description text?
Yes. We have detailed guidelines and good advice about that here.
What are the requirements for my offer’s help and support page?
You're required to submit two distinct pages for support and help that is, they cannot be the same. You can see
what you have to include on both pages in the table below.
H EL P SUP P O RT
Learning material such as FAQs, step by step guides, video At least two contact options (for example, e-mail, phone,
tutorials, webinars etc. chat) and a defined SLA for how much time it takes before
you answer to support inquires.
See Also
Marketing Validation Checklist
Technical Validation
2/6/2023 • 8 minutes to read • Edit Online
Below you'll find a checklist of all requirements that you must meet before submitting an extension for
validation. You'll also find a description of how the Business Central Validation team is performing technical and
manual validation and how you can implement a validation pipeline to perform the same technical validation
yourself.
TIP
If you have questions around validation for your app, see Technical Validation FAQ for more information about who to
contact.
The app.json file has mandatory properties that you must Mandatory app.json properties
include. The 'name', 'publisher', and 'version' properties must
match the values set in your offer description. Here you can
also read more about dependency syntax and multiple
countries per a single app syntax.
Coding of Date must follow a specific format (no longer Use the format yyyymmddD . For example, 20170825D .
region-specific)
Remote services (including all Web services calls) can use Guidance on HTTP use
either HTTP or HTTPS. However, HTTP calls are only possible
by using the HttpRequest AL type.
Only JavaScript based Web client add-ins are supported. The Control Add-Ins
zipping process is handled automatically by the compiler.
Include the new AL controladdin type, JavaScript sources,
and build the app.
The .app file must be digitally signed. Sign an APP Package File
Set the application areas that apply to your controls. Failure Application Area guidance
to do so will result in the control not appearing in Dynamics
365 Business Central.
Permission set(s) must be created by your extension and Exporting Permission Sets
when marked, should give the user all setup and usage Managing Users and Permissions
abilities. A user must not be required to have SUPER
permissions for setup and usage of your extension.
REQ UIREM EN T EXA M P L E/ GUIDA N C E
Before submitting for validation, ensure that you can How to publish your app
publish/sync/install/uninstall/reinstall your extension. This
must be done in a Dynamics 365 Business Central
environment .
Thoroughly test your extension in a Dynamics 365 Business Testing Your Extension
Central environment.
Include the proper upgrade code allowing your app to Upgrading Extensions
successfully upgrade from version to version.
Pages and code units that are designed to be exposed as Web Services Usage
Web services must not generate any UI that would cause an
exception in the calling code.
You're required to register affixes for your publisher name Prefix/Suffix Guidelines
and to use them in your extension.
We strongly recommend you're using automated testing, Testing the Advanced Sample Extension
using the AL Test Toolkit. You aren't required to include the
test package with your extension.
You must use the Profile object to add profiles instead of Profile Object
inserting them into the Profiles table.
Use addfirst and addlast for placing your actions on Placing Actions and Controls
Business Central pages. This eliminates breaking your app
due to Business Central core changes.
The extension submitted must not be a runtime package. Creating Runtime Packages
The extension submitted must use translation files. Working with Translation Files
The extension submitted must specify the Application The Application manifest property is required in order to
manifest property. compute the minimum release of Business Central targeted
by your submission. For more information, see Computation
of Releases for Validation
IMPORTANT
It is recommended that all partners run the self-validation documented below before submitting apps for validation to
maximize chances of validation success.
1. The manifest of all extensions in the submission is validated. If any mandator y proper ties or required
proper ty values are missing, the submission is rejected..
2. The registration of affixes for the publisher name of all the extensions in the submission is validated. If the
publisher name does not have any registered affixes, the submission is rejected.
3. The signature of all extensions in the submission are validated. If any extension is not signed or its
signature is not valid, the submission is rejected.
4. The consistency of the main extension information (name, publisher, version) is validated against the offer
description. If any differences are noticed, the submission is rejected.
5. The extensions in the submission are validated. If any runtime packages are present, the submission is
rejected.
Once the extension has passed these first validation steps, the minimum release for your submission is
computed as described in Computation of Releases for Validation.
For each countr y and each release targeted by your submission, the following steps are run for each
extension in the submission:
1. If the extension with the same version has already been validated for the country, further validation for this
extension is skipped.
2. The set of dependencies for your extension is resolved. Any unresolved dependencies will cause the
submission to be rejected. If you include extensions created by Microsoft in your submission, it
will also be rejected.
NOTE
You are required to include the dependencies for your extension as part of your submission only if you are submitting a
newer version for them. If you do not include them in your submission, they will be downloaded automatically if they are
available in Business Central for the targeted countries/regions. If you are making your libraries available in new countries,
you should increase the version number.
3. The set of baselines for your extension is resolved by using the App Management API.
4. The extension is compiled against the set of dependencies resolved. If the compilation fails, the
submission is rejected.
5. The extension is tested against the resolved baselines using the AppSourceCop analyzer. If any violations or
breaking changes are identified, the submission is rejected.
6. If the runtime version of the extension is not suppor ted by the release targeted, the submission
is rejected.
If all extensions in the submission succeed the validation for each country and release without errors, the
submission is accepted..
All array parameters can also be specified as a comma-separated string. For more information, you can also
check this blog post Run-AlValidation and Run-AlCops.
Please include app and all library apps in both previousApps and apps and please include all countries on which
you want to validate.
NOTE
The Run-AlValidation cannot see whether the affixes to specify have been correctly registered with Microsoft using your
MPN ID and app publisher name, please make sure registration is in place.
IMPORTANT
The computer on which you run this command must have Docker and the latest BcContainerHelper PowerShell module
installed and be able to run Business Central on Docker.
If you are having issues with Business Central on Docker, you might be able to find help here:
https://freddysblog.com/2020/10/12/troubleshooting-business-central-on-docker.
You can use https://aka.ms/getbc?artifacturl=bcartifacts%2fsandbox%2f%2fus%2flatest to create an Azure VM, which has
all prerequisites installed to run Business Central on Docker.
NOTE
It is recommended that all partners set up DevOps processes to ensure that this validation process happens automatically
and regularly.
You can find resources for how to set up full plug-and-play DevOps processes using AL-Go for Github: https://aka.ms/AL-
Go.
NOTE
If multiple extensions are contained in your submission, the minimum release for the submission is the highest minimal
release computed for each of the extensions in the submission.
IMPORTANT
The minimum release computed for your submission also defines the availability in Business Central of all the extensions
in your submission.
For example, if the minimum release computed is 18.1, your extensions will be available starting from release 18.1.
Example
If your extension's manifest is defined as follows, the minimum release where your extension can be installed is
18.0 because the manifest requires the Application extension to be available with a version higher or equal to
18.0.0.0.
{
"application": "18.0.0.0",
}
See Also
Developing AL Language extensions
Technical Validation FAQ
2/6/2023 • 21 minutes to read • Edit Online
This article addresses some of the most frequently asked questions around validation of apps for AppSource
submission.
IMPORTANT
The minimum release computed for your submission also defines the availability in Business Central of all the extensions
in your submission.
For example, if the minimum release computed is 18.1, your extensions will be available starting from release 18.1.
NOTE
30 days before the release of a new Business Central major version, all submissions are validated against the upcoming
release. The apps in your submission must then be compatible with the upcoming release. The goal is to ensure that your
customers won't be blocked during the upgrade of their environment.
When you're adding new localizations in Business Central, these countries/regions can be added to Partner
Center before they're ready in Business Central. If you're targeting a country/region marked as 'Planned' in
Country/regional availability, depending on when your submission is processed, your apps might not be
uploaded to Business Central if the localization isn't yet ready in Business Central. Generally, it's possible to
upload apps for 'Planned' localizations a few weeks before they're officially released. When the localization
becomes available, if you're experiencing issues installing your apps, you should increase the version in the
app.json and submit the packages again in Partner Center. If you're using Azure Application Insights, you can
check whether the country/region was validated using this Troubleshooting Guide (TSG).
Against which baselines are my apps validated?
The service will verify that your extensions don't introduce breaking changes by comparing them to the latest
version available in AppSource for each country validated.
You can know which versions of your extensions were used as baseline during the breaking change validation
by enabling Azure Application Insights in your extension and running this Troubleshooting Guide (TSG).
IMPORTANT
As soon as your app has been uploaded to the AppSource marketplace, it will be used as a baseline during the technical
validation of your next submissions. As a consequence, you won't be allowed to perform breaking changes without
obsoleting the AL objects first and you won't be allowed to perform schema breaking changes; breaking changes on
tables or table extensions. This applies also if your extension isn't used by customers yet. You should then not submit your
app to the AppSource marketplace if you are still developing it and expect to change it in the near future.
NOTE
If some apps in your submission already have been uploaded to Business Central with the same version for some
countries/regions, then the app will not be validated again for these countries/regions.
IMPORTANT
If one or more libraries in your submission have their own offer, their listing(s) in the AppSource marketplace won't be
updated automatically. In order to keep the listing(s) in sync with the version of the app(s) uploaded to Business Central,
you should submit a submission for their related offer(s).
NOTE
If you include the dependencies of your extension as part of the submission, these dependency versions will be used
during the validation, even if there are higher versions already available in Business Central.
If you didn't include the dependencies for your app and they aren't available, your submission will fail during the
"Automated Application Validation" stage. Failing to find the dependencies for an extension results in error
messages with the diagnostic codes AVS0005 or AVS0101 .
If you receive an error with the diagnostic code AVS0107 and a message similar to
The extension 'MyApp' by 'MyPublisher' (version '1.2.3.4') has already been uploaded to Business Central for
the country/region 'US'
for one of your library apps, it means that you've already published another .app file for this extension to
Business Central as part of a previous submission. This can happen if you submit a .app file with different
content, or created by a different build (each .app file created has a specific build ID stamped, so building
multiple times the same project results in .app files with different build IDs). If this version of the library is
already available for all countries targeted by your submission, you can just remove the extension from the
submission. If you're making your library available in new countries, you should use the .app file that has
already been uploaded to Business Central or increase the version number in the manifest of the extension (the
app.json file).
My app failed at the "Automated application validation" stage, what do I do next?
At this stage, your extensions are validated to assess whether they meet the requirements specified in the
Technical Validation Checklist.
If this stage failed with an error message similar to
The validation of the submission failed for X out of Y tasks , you must investigate what has caused the error.
If you're using Azure Application Insights, information about the validation results is logged in Azure Application
Insights. You can also use this Troubleshooting Guide (TSG) in order to get started. If you're experiencing issues
with Azure Application Insights, refer to the dedicated section below.
If this stage failed with an error message similar to
The extension 'MyApp' by 'MyPublisher' (version '1.2.3.4') has already been uploaded to Business Central for
the country/region 'US'
, you must update the list of extensions submitted. For more information, see "When should I include my library
apps as part of my submission?".
If this stage failed with an error message similar to
The submission must target at least one existing country/region of Business Central , your submission doesn't
target any countries/regions currently available in Business Central. If your submission targets a country/region
marked as 'Planned' in Country/regional availability, you must wait for the localization to become available in
Business Central and resubmit your offer. Generally, it's possible to upload apps for new localizations, a few
weeks before they're made available to customers.
If this stage failed with an error message similar to
The extension 'MyApp' by 'MyPublisher' (version '1.2.3.4') contains inconsistent information about the
package id/name/publisher/version
, it means that something went wrong when the package included in your submission was built. In order to
mitigate the issue, you must rebuild the package and submit it again.
If this stage failed with an error message similar to
The App ID '<some-Guid>' is already used for Per-Tenant-Extensions in Business Central and cannot be used for
the AppSource extension with name 'MyApp' and publisher 'MyPublisher'
, this means that there exists one or many PTEs with the same App ID in the service. Since Business Central
doesn't support having AppSource apps and PTEs with the same App ID, it's then recommended to change the
ID of your extension before submitting it in Partner Center. For more information, see Moving a PTE to
AppSource. If the PTEs with that App ID aren't used in any customer environments anymore, you can create a
support case in Partner Center to request an exception.
If this stage failed with the following error message
Automated validation of the submission has failed. Please retry the operation and contact Partner Center
support if it fails again.
, you should create a new submission in Partner Center. If your submission fails again, you should create a
support case in Partner Center as documented in this article.
NOTE
Because the extensions in your submission are validated for each release and country/region targeted by the submissions,
the validation results can be really verbose and cannot always be displayed in their full length in Partner Center. The error
message will then end with ...(Truncated) . If that happens for your submission, you should either enable Azure
Application Insights in your extension, run the self-validation script, or fix the errors visible and iterate on your submission.
NOTE
Instead of writing your own queries, we recommend using the executable Azure Data Studio Troubleshooting Guide (TSG).
This guide contains queries that will process the signals for your submission and extract the important information.
IMPORTANT
The App ID is a critical part of the identity of apps in Business Central, and changing it is a breaking change for all
extensions depending on it. You should then not change the App ID of extensions which are installed for customers in
Business Central Online.
If you are submitting a new version of your extension with a different App ID for an existing offer, then this new
version will be considered as a different extension. This means that all extensions that depend on the extension
with the old app ID must be updated to reference the new App ID. If they are not updated, this will cause issues
such as customer environment upgrade failures which must be fixed within the required time period, see
Maintain AppSource Apps and Per-Tenant Extensions in Business Central Online. Since the app ID is part of how
data is stored in Business Central, this also means that you will have to migrate the data for all customers that
have the extension with the old App ID installed. Note that we do not provide tools for performing data
migration in SaaS, but you can create your own solution to export data from the old extension and re-import
the data after the extension change.
Is it possible to have multiple apps with the same App ID in AppSource?
Each unique codebase has one unique ID. If you have four apps in AppSource, you need to have four unique IDs
for these apps. Otherwise you'll get conflicts.
What if we already have an app on AppSource but we need to create the same app for another country; can
we then have the same app ID for two different apps targeting two different countries?
If they're different apps (different code), they should have different identity. Identity is used in, for example, app
management, dependencies, support cases, and telemetry. If reused across different apps, identity uniqueness is
lost. Another approach could be a common shared (internal/library) app across countries (with one app identity)
and localized functionality as extensions on top (with their own identity).
NOTE
The App ID is used as part of the URL of the offer listing and is used as a key to retrieve to customer review left on the
offer listing. Not preserving the App ID means that the offer URL will change and customer reviews will be lost.
IMPORTANT
If you're using Azure Application Insights, before opening a support case for a failure at the 'Automated application
validation', you must analyze the signals emitted in your Azure Application Insights storage. You can do so by using the
Troubleshooting Guide (TSG). When opening a support case, you must include the Kusto queries you used and the
diagnostic messages that you found. Including the results from the TSG is also recommended.
See also
Technical Validation Checklist
How to Make Compelling Videos
2/6/2023 • 9 minutes to read • Edit Online
Why use video? It's worth investing time and resources to create marketing videos for your app, it's taken
seriously in a business environment.
Choose the video format that is relevant for the audience that you
want to target
Video type 1: “Why” video
How to set up “Why” videos
Recommended length: 60-90 seconds
Purpose:
Your video should clearly communicate WHY prospects need to buy your solution now.
Focus:
Make sure the prospect is the hero of the story, not you or your company. Prospects aren't interested
in hearing about your company at this stage. They're simply trying to determine if what you offer is of
value to THEM.
Your video should speak to the principal challenges and goals of your core decision-maker persona.
Describe the desired end state they'll achieve by using your app.
A client/customer speaking about the benefits they received from your app is far more credible and
compelling than anyone from your organization.
Don’t only rely on “features” to acquire new customers.
How to speak to a WHY persona in a video
Target audience:
Owner/executive/leadership
They have limited time and financial resources as well as many competing priorities and resource
requirements
You need to elevate the discussion to a strategic level, where you highlight market share,
competitiveness, profitability, differentiation, revenue loss, and more.
Message:
The question you must answer beyond a doubt is WHY should they invest the time and money to buy
your app? What will they get out of it?
Why should they spend money on a new system now? Can’t they put it off?
The WHY messaging teaches people something and it's industry specific and results oriented, as well
as being memorable. It engages the emotional/limbic brain and leads to meaningful action.
Video tips
How to structure your video and practical things to keep in mind when producing videos
How to structure the flow in your video?
Gain immediate attention in the first 10 seconds of the video Stimulate curiosity by including a hook
phrase/comment that will elude to solving a pain point. Ask questions about the prospects’ core business
challenges or ask about something they would like to do but can’t accomplish today.
Highlight the prospects’ problems: Use an empathetic approach when describing their current situation and
demonstrate that you understand their current business challenges. They must relate to this if they're to
continue watching.
Give them new learning Teach them something they don’t know. Demonstrate you have expertise and
knowledge about their business or industry that they might not. Show you can offer strategic value to them.
Paint a picture of a desired outcome they would love to have or state they crave to experience. Highlight the
benefits, rewards, and value they'll enjoy after they purchase from you. Include both what it looks like and
how it will feel.
Prove what you’re saying is true Prospects don’t trust us when we say our products are great. Include
objective and credible proof in the form of data, charts, graphs, quotes, statistics, or testimonials as evidence
of your claims.
Ask them to take action. Include a call to action at the end of all videos. When viewers watch your videos,
they should feel inspired to take the next step towards purchasing. Tell them what to do next and include an
interactive link to the next step in the buying cycle. Use scarcity to compel them to action. Provide a time
limited offer or, for example, say it is “only for the first 20 customers”.
Practical things to keep in mind when producing and distributing your video
Does and don’t when producing your video
Don’t make the video too long As our attention span is 8 seconds the ideal length of video is 90 seconds
(minimum 30 seconds/maximum 2 minutes).
Add interactivity where possible Overlay text, charts, animation, questions etc. Visually call out key messages.
Make sure your audio is high quality.
Make your video easily shareable
Enable your video to be shared on multiple media. Track views and attention span. Observe and measure
viewer patterns so that you can learn from prospects’ actual behaviors and then improve future content.
How to make a good narrative that speak to the right persona in the right way?
Your narrative should have a beginning, middle, and end.
Lead with a story, not with your app or the technology.
Don’t turn your videos into a product pitch.
You’ll build more brand affinity and trust by shedding light on a problem your prospects care about
rather than by pitching your solutions to them directly.
The brain is on alert at the beginning of the video and at the end.
Make sure the first and last 10 seconds are compelling, memorable, and interesting.
Speak directly to a particular persona in the second person.
Don't talk about them in the third person, and avoid using terms like “our clients” and “companies”;
instead, use “you” language as often as possible.
Use many industry specific vocabulary, terminology, and visuals. If possible, film onsite at a
customer’s location rather than in your office or in a studio.
Speak to a particular persona:
Don't try to appeal to everyone at once, as you may not fully engage anyone with this approach.
Keep your delivery casual and authentic to instill trust. Speak directly to the prospect as if you were
having a fireside chat
The prospect should be the hero of the story, that is, don't speak about you and your company.
Ask rhetorical questions that stimulate pain and anxiety in your prospects in order to demonstrate that you
understand their business problems.
For example: Are your margins decreasing? Having cash flow problems because you can’t collect
payments sooner than 90 days? Had another large write-off? Lost an important customer recently
due to a late delivery?
Use visual and auditory language to help the prospect imagine a new possible future.
For example: “imagine seeing”, “picture yourself”, or “how would you like to hear your clients say…”
and so on.
Use contrast whenever possible.
Compare prospects’ experience now versus what it could be after the implementation of your
solution.
Call out your competitive differentiators while anchoring your solution in prospects’ minds so that
they can compare all others against the bar you set.
How to make a good narrative that speak to the right persona in the right way?
Where possible, use tangible, concrete language.
Include quantifiable proof in the form of data or visual pictures.
No vague claims like “transform your business with the cloud”. This is an emotionless statement.
Providing customer references and testimonials is much more compelling and effective than selling your
company or product yourself.
Let others speak for you. A customer testimonial video will always be more believable and compelling
than a video of you saying the same thing.
Surprise and delight them.
Use humor to make them smile. We take ourselves and our problems too seriously. Be warm,
memorable, and unique.
Guideline on Creating an Effective Sales Landing
Page for Your App
2/6/2023 • 10 minutes to read • Edit Online
App name & app logo Include a visual logo of your product
name and a one sentence positioning
statement.
Logo
The upper-left corner of the landing page is the most valuable section of the entire landing page.
Place your company logo in this location.
If you need help with formulating a positioning statement, try the value proposition generator located at here.
There should ideally be 5 or fewer choices; don't include more than seven options.
The menu text should state what the prospect gains if they select on the menu item
The text should be written from their perspective, not yours.
Recommended menu items:
How to Buy, Benefits Gained, Why Us, and Contact.
Include a headline question Get your prospects’ attention by “Struggling to manage your ingredient
asking them a compelling pain-based inventory and fretting over allergens?”
question that they can relate to.
Microsoft Dynamics 365 product Somewhere on the landing page, make Insert this paragraph: Microsoft
description sure you include the standard Dynamics 365 Business Central is a
Microsoft Dynamics 365 Business comprehensive business management
Central product description provided solution for small and medium-size
by Microsoft This is a requirement businesses (SMBs) that have outgrown
because your product is adding value their basic accounting software. From
to and building on this foundational day one, this new application makes
solution. ordering, selling, invoicing, and
reporting easier and faster. Dynamics
365 Business Central is deeply
integrated with Microsoft 365 and
includes built-in intelligence, so it's
easy to use and helps users make
better business decisions.
- Describe the most significant benefits - For example, “Save time and money
and rewards that your prospect will (benefits) by having a system that
realize after purchase. does all the tracking and calculations
for you (features).”
Messaging (Prove your claims) Include specific calls-to-action on your “Reduce how long it takes to set up
app page. your recipes in the morning from 1
hour to 10 minutes.”
Target market - If you support multiple countries or languages, this is a key selling feature. • Find a way to show
this visually.
This can be your free trial; a time-limited special price; a scheduled walk-through demonstration; and so on.
The words "free” and “save” are highly emotional words in the English language, so they should be used.
Use bright colors, such as orange, yellow, or red, to call attention to your buttons.
Button text should use benefit language rather than descriptive language.
For example, instead of “Download” write “Click here to start saving money now.”
Try not to send prospects away from your page – always have an embedded next step in your call to action
that brings them back to your landing page.
Messaging (Create a sense of Help your prospect gain a sense of Your bakery profitability will decrease
urgency by teaching the urgency to buy by teaching them one over the next five years due to an
prospects) thing about how they can be more increase of 3% in the cost of key
efficient or profitable now. inputs, such as wheat and sugar. Want
to know five key strategies that can
help you mitigate this challenge? Click
here to find out how to preserve your
profit margin
Show them how their performance in one key business area is below that of their competitors.
For an example you can provide a quick online self-assessment, a top-10 tips blog post, and much more.
Visual elements
Pictures (Differentiation Show them, don’t tell them Show the before and after state.
comparison images)
This is a visual image of how your prospects do things now versus how they'll be able to do it in the future.
You aren't telling them but showing them using a visual.
Compelling proof screenshots Visually demonstrate all the claims that Quickly and easily view inventory
you're making. items.
EL EM EN T DESC RIP T IO N
Videos (Tell your story using videos not text) Include as many videos as possible.
Videos have a much higher level of engagement and viewing time and convey much more than you can ever
say with words.
Include at least one customer testimonial video on your app landing page.
Your client should speak specifically about the pains they had before and the benefits they gained after, not
product features. It should be all about your customers, not you.
Include one product demonstration video.
See the video best practices https://aka.ms/ReadyToGo.
Elements that reduce anxiety and risk, while increasing trust
EL EM EN T DESC RIP T IO N
Customer testimonials Don’t sell your product; let your customers do that for you.
Social proof is more credible and trustworthy to prospects. The purpose of testimonials is to reduce the
buyer's anxiety and fear.
Your testimonials should answer the following questions:
“Will this work for my situation?”
“What benefit will I really get if I buy this?”
“Is this going to be too hard?”
“How long is this going to take?"
“Can I trust this company?”
EL EM EN T DESC RIP T IO N
Live chat Include live chat, with a photo of one of your team members
smiling at an appropriate time to increase conversion, such
as when a prospect selects the back button on your pricing
page.
SHORT lead capture form Include a lead capture form on your page.
Only ask for their name and email address, you can get the rest later.
Your forms shouldn't have more than four or five fields to fill out. You haven't yet earned the right or enough
trust to ask for too much information at this point.
Most lead capture forms are way too long, demanding, and intimidating, and have low completion rates.
NOTE
Nobody has the time or is willing to fill out an annoying form, which is of no value to them, especially if it is purely self-
serving from your standpoint.
EL EM EN T DESC RIP T IO N
Ideally, include a phone number and an email address with an employee photo.
This alone could double your conversion rate.
AppSource app page link & social Include a link back to your listing on Return to AppSource.
share AppSource, so the prospect can return
when ready.
Also, enable visitors to share and forward your app with others!
EL EM EN T DESC RIP T IO N
Close them! Add a get star ted button Include a specific call-to-action button with the option to
buy or try.
Embed App Overview
2/6/2023 • 4 minutes to read • Edit Online
Embed App is a term that defines an end-to-end solution meeting the specific needs of a vertical or micro-
vertical industry.
Dynamics 365 Business Central plays a vital role in the Embed App, as Business Central is embedded as an
integral part of the overall solution.
Some examples of an Embed App include:
A Dentist solution
A Real Estate Agent solution
A Food Processing solution
An Embed App refers to what is being provided to a given customer segment, unrelated to how the solution is
being implemented or architected. An Embed App can be built using AL, in other words extension, code-
customization, and a combination of extensions and code-customization.
Components
On a high level, an Embed App is a package that consists of the following parts:
Library extensions
This is the functionality of the Embed App that is implemented by the ISV partner in a form of extensions.
Third party extensions
These are add-on extensions coming from other ISVs that contribute to and enhance the Embed App. The
extensions are validated to be compatible by the Embed App owner.
Extended metadata
This includes additional Embed App properties that are specific to this type of app and not otherwise
available for other types of apps (see the list below).
Base application and tenant template (optional)
The following capabilities are only available for the Embed App and not for other types of Business Central apps
(Connect and Add-on).
Partner Branding
The Embed App will promote the partner's brand in several places:
Web Client and Web Service URLs
Client: https://[application name].bc.dynamics.com
Web Services: https://[application name].api.bc.dynamics.com
Name, image, and icon on the provisioning page of the Fixed Client Endpoint
Splash screen of the client
Title bar of the browser tab (for example, "Fabrikam Apples")
A dedicated product tile, icon, and short marketing description in the Dynamics shell
(https://home.dynamics.com)
In-product messages (such as pop-up errors, warnings, notifications)
Exclusivity
The partner can control which third party apps can be installed for their Embed App.
Safe listing of the 3rd party apps - no other apps will be possible to install, except the ones explicitly
approved by the partner
App install/uninstall controlled by the partner
The partner can choose to allow a customer to install other extensions from the AppSource, but this will be
an explicit partner decision, not the default behavior
Code -customizations of the base application
Partners can choose to bring their own code-customized base application as an Embed App for several reasons:
Shortening time-to-market ("lift and shift" approach).
The partner's current solution is a significantly customized version of the Dynamics NAV application and
it will require substantial time and effort to migrate it into extensions. A partner can lift their solution as-
is (upgraded to a supported platform) to Business Central service and start offering it to their new and
prospective customers. Then, they can gradually start moving their functionality into extensions to
achieve the benefits that come with the extension model. The earliest version of the Business Central
application you can bring to the service is version 16.
Usage of .NET interoperability and custom assemblies.
Partners that use .NET interoperability in their current application to address multiple business scenarios.
Although extensions today allow a number of these scenarios to be implemented in AL, they don't and
cannot cover for all possible scenarios of .NET usage. Therefore, the partner can choose to import the
required .NET add-ins into the Add-ins table of the base application, and these add-ins will automatically
be deployed into the environment where they will be running.
Additional settings (metadata)
An Embed App is the property of the partner, so the customers of the Embed App must be able to find the
partner's own legal, privacy, contact, community and feedback links (not Microsoft links) when they work
with the app:
Safe listed domains for embedding Embed App pages into other web sites, including SharePoint ("frame
ancestors")
Target version of Dynamics 365 Business Central platform
Target version of Dynamics 365 Business Central base application (if not included with the Embed App)
Azure KeyVault account for storing application secrets, such as accounts for connecting to 1-3rd party
services
Base application + tenant template. This is an optional component of an Embed App. The partner can
choose to include it or simply specify which version of the Dynamics 365 Business Central base
application the Embed App should use as a base application.
At this stage, within the extensions and base application, the partner can work in their own Object ID range.
Platform version availability
Microsoft is going to make new versions of the Business Central platform available to Embed App partners
through the Lifecycle Services portal (LCS). The partner will then have to pick the platform they want to use for
deployment of their solution.
Deploying versions
When a partner deploys a solution through the LCS portal, they can pick from the last three available versions of
the platform (minor and major). Every newly released minor or major platform update will be added to the list
and simultaneously one older version will be removed form that list.
Any existing deployments, running on platform versions that are older than 3 updates, will enter a grace period
of 30 days. And after that, if the deployment is not upgraded, it will be moved out of the standard SLA.
See Also
Microsoft Responsibilities
Qualification and Onboarding
Managing in Microsoft Lifecycle Services
Components and Capabilities
Deployment of Dynamics 365 Business Central
Administration of Business Central Online
Administration of Business Central On-Premises
Qualification and Onboarding of Partners to the
Embed App Program
2/6/2023 • 2 minutes to read • Edit Online
If you as a software development partner are interested in developing an app that meets the description of
Embed App in Embed App Overview, your app must meet qualification requirements. The main criteria for
Embed App onboarding at this point are:
Partner must provide all day, every day support. Their customers do not get to call Microsoft support. They
always call the partner.
Partner must live up to the standards for user assistance and documentation that are outlined in Dynamics
365 Business Central User Assistance Model. Good user assistance is part of Embed App success and uptake,
and it also lowers the work load on their support center.
Partner is committed to stay on the supported platform.
Partner provides an SLA for requests from Microsoft towards the partner
Partners must have a support agreement with Microsoft
Apps with a code-customized base application will have additional volume (number of users) requirements
associated with it.
When an Embed App is qualified for onboarding to Business Central online, the partner must provide the
following information about the Embed App to the Microsoft’s onboarding team:
The name of the application to be used for the client and web service URL. For example, an ISV for the
fabrikamapples app would provide the following information:
Client: https://fabrikamapples.bc.dynamics.com
Web Services: https://fabrikamapples.api.bc.dynamics.com
Entitlements for their application objects, per license type. For more information, see Licensing in
Dynamics 365 Business Central.
The rest of the information will be included with the Embed App package that the partner deploys through
LifeCycle Services.
See Also
Embed App Overview
Microsoft Responsibilities
Embed Apps Deployment
2/6/2023 • 2 minutes to read • Edit Online
This article provides an overview of the process for deploying an Embed App to the Business Central Online
service. The deployment involves the following tasks:
Create a deployment package The deployment package is a .zip file Creating Deployment Packages for
that contains components required for Embed Apps
any Embed app, including:
ISV branding elements, like
images, icons, names, and so
on
An application database and
tenant template databases
A manifest-json file that
provides additional metadata
and deployment instructions.
Upload your apps to the App The apps are the individual extensions App Management API
Repository that make up your application. Apps
are delivered as .app files. You upload
your apps into the App Repository by
using the App Management API.
Upload the deployment package to Once you have the deployment Managing Embed Apps in Microsoft
Microsoft Lifecycle Services (LCS) package, and your apps have been Lifecycle Services
uploaded, you can deploy your
package to an LCS project.
See Also
Embed App Overview
Qualification and Onboarding
Managing Embed Apps in Microsoft Lifecycle Services
Creating Deployment Packages for Embed Apps
2/6/2023 • 13 minutes to read • Edit Online
To deploy an Embed App, you'll need a deployment package and your apps. This article describes how to create
a deployment package for an Embed App.
The apps are the individual extensions that make up your application. Apps are delivered as .app files, which you
upload to the App Repository via the App Management API. For information about this task, see App
Management API.
Once you've created the deployment package and uploaded your apps, you then upload the deployment
package to a registered project in Microsoft Lifecycle Services.
[FOLDER] branding/
- favicon.ico
- splash.png (or .gif)
- splash_narrow.png (or .gif)
- header.png (or .gif)
[FOLDER] databases/
- app.bacpac
- tenant.bacpac
manifest.json
IMPORTANT
You must only use the sandbox artifacts (Get-BcArtifactUrl -type sandbox) for your online deployments.
Unique Base Application ID, Name, and If any change is applied to the Create and assign your own unique
Publisher Microsoft Base Application objects App ID for it in the app.json file. Also,
change the Publisher property and the
Application name to your own in the
app.json file. You can't use the original
values of the Microsoft Base
Application unless you've extracted all
your customizations from that app
into your own app(s).
Use System Application Always Your Embed app must be built on top
of the Microsoft System Application.
The System Application must not be
customized and must be used as a
dependency for your customized or
non-customized Base Application.
REQ UIREM EN T C O N DIT IO N DESC RIP T IO N
Use Microsoft_Application.app file If you use customized Base Application Use Microsoft_Application.app to
encapsulate references to your own
customized Base Application, instead
of referencing that app as a direct
dependency in each extension
separately. This will also allow other
apps (like AppSource apps) to refer to
your solution via the
Microsoft_Application.app . For
more information about the
Microsoft_Application.app , see
The Microsoft_Application.app File.
Custom .NET add-ins If your solution uses custom .NET Import components into the Add-in
Server components (.NET add-ins) table in the application database. You
register the control add-ins, import
and manage the files by using the
New-NAVAddin cmdlet, Set-NAVAddin
cmdlet, Get-NAVAddin, or Remove-
NAVAddin cmdlets from the Business
Central Administration Shell.
"branding"
"images"
IMPORTANT
The combined size of all images you include with the deployment package must not exceed 490 KB.
"databases"
SET T IN G TYPE DESC RIP T IO N
"links"
"apps"
This section of the manifest.json file must list all the apps used by your solution and their dependencies. Even if
the dependency app belongs to a different publisher, for example Microsoft, you must include it. This list will be
used by the deployment routine to publish and install these apps to your service and for your environments.
If "allowedUpdates" is set to
"none" , then the exact version of the
app you specify must be available in
the App Repository. In this case, a full
initial version number must be
specified.
Sample manifest
Sample of the manifest.json file.
{
"manifestSchemaVersion":"3.0",
"id": "201e5067-99cc-4974-900a-b50bd4fbe777",
"name": "Fabrikam Rentals",
"description": "Harness the power of the most feature-rich office furniture rentals solution from
Fabrikam.",
"publisher": "Fabrikam",
"version": "16.1.50043.50321",
"branding": {
"productName": "Fabrikam Rentals",
"productNameShort": "Rentals",
"marketingName": "Fabrikam Rentals",
"images": {
"appleTouchIconPath": "branding/appletouch.ico",
"faviconPath": "branding/favicon.ico",
"headerPath": "branding/header.png",
"splashLandscapePath": "branding/web-wide.png",
"splashPortraitPath": "branding/web-narrow.png"
}
},
"databases": {
"applicationBacpacPath": "databases/app.bacpac",
"tenantTemplateBacpacPath": "databases/tenant.bacpac"
},
"links": {
"baseHelpUrl": "https://help.fabrikam.com/help/",
"baseHelpSearchUrl": "https://help.fabrikam.com/help/",
"communityUrl": "https://fabrikam.com/au/contact",
"feedbackUrl": "https://fabrikam.com/au/contact",
"legalUrl": "https://fabrikam.com/au/legal",
"privacyUrl": "https://fabrikam.com/au/privacy",
"signInHelpUrl": "https://fabrikam.com/au/contact",
"comingSoonUrl": "https://go.microsoft.com/fwlink/?linkid=2047422",
"blogUrl": "https://go.microsoft.com/fwlink/?linkid=2076643",
"contactSalesUrl": "https://go.microsoft.com/fwlink/?linkid=828707"
},
"apps": [
{
"id": "63ca2fa4-4f03-4f2b-a480-172fef340d3f",
"initialVersion": "16.1",
"name": "System Application",
"publisher": "Microsoft",
"allowedUpdates":"hotfix",
"publishOnly": false,
"publishOnly": false,
"blockUninstall": true
},
{
"id": "6d4391a2-9cae-41e9-a270-136af8acfbc7",
"initialVersion": "16.1.5",
"name": "Fabrikam Rentals Add-on",
"publisher": "Fabrikam",
"allowedUpdates":"minor",
"publishOnly": false,
"blockUninstall": true
},
{
"id": "201e5067-99cc-4974-900a-b50bd4fbe777",
"initialVersion": "16.1.50043.50321",
"name": "Fabrikam Rentals",
"publisher": "Fabrikam",
"allowedUpdates":"minor",
"publishOnly": false,
"blockUninstall": true
}
]
}
[FOLDER] branding/
- favicon.ico
- splash.png (or .gif)
- splash_narrow.png (or .gif)
- header.png (or .gif)
[FOLDER] databases/
- app.bacpac
- tenant.bacpac
manifest.json
Now, you can deploy your package to Business Central Online service. See Managing Embed Apps in Microsoft
Lifecycle Services for more information.
See Also
Embed App Overview Qualification and Onboarding Managing Embed Apps in Microsoft Lifecycle Services
Managing an Business Central Embed App in
Microsoft Lifecycle Services
2/6/2023 • 7 minutes to read • Edit Online
Microsoft provides essential functionality within Microsoft Lifecycle Services collaboration portal (LCS) to
support qualified ISVs in managing the Embed App based on Business Central online.
IMPORTANT
Even though the project will be created by one user, every user you are planning to add to your LCS project will have to
activate the "Microsoft Dynamics 365 Business Central (SaaS)" feature using the same preview code you received from
Microsoft. Without this activation, the users you add to your LCS project will run into permissions issues when trying to
open the LCS project that you created.
Navigate back to the main page and start creating a new project by selecting the "+" action. Choose Migrate,
create solutions, and learn category as the purpose of the project. On the next page, provide the project
name.
NOTE
You will have to create a separate project for each country, even if your Embed app is going to be exactly the same.
Therefore we recommend that you use the name of your Embed app appended by the country code as the name of your
project, for example "Fabrikam Rentals, DK", "Fabrikam Rentals, US" and so on.
Next, provide a short description for your project (optional), select Microsoft Dynamics NAV as the product
name and Microsoft Dynamics 365 Business Central (SaaS) as the product version. Select the Create
button to complete creation of the project.
After you create the project, send its ID to the e-mail alias specified on the main project page for safe listing
purposes. You can find the project ID in the URL displayed in your browser, such as
https://lcs.dynamics.com/V2/NavProjectDashboard/[projectID]
Once your LCS project ID has been safe listed by Microsoft, you can start performing deployments of your
solution to Business Central service.
IMPORTANT
The Business Central platform is updated monthly. You are responsible for updating the Embed App to operate with the
updated version of Business Central. The Embed App must run on a supported build of Business Central, for example, the
current version of Business Central or one of the two immediately preceding versions. The immediately preceding versions
can be both minor and major versions of Business Central. The list of supported versions is displayed in the LCS portal on
the Deploy package wizard in the Target platform field. The versions, which aren't displayed on that list are out of
support. You customers running on these versions can't be serviced at the service levels set forth in the published Service
Level Agreement.
The partner can then pass the URL to their customers, either from the partner's own marketing page or in a
welcome e-mail, for example.
To work with an Embed App, the customers would use a URL that looks something like this:
Client: https://[application name].bc.dynamics.com
Web Services: https://[application name].api.bc.dynamics.com
In contrast, to work with Business Central, they would use these URLs:
Client: https://businesscentral.dynamics.com
Web Services: https://api.businesscentral.dynamics.com
Once you've established the reseller relationship with the customer and added Business Central subscriptions
with required number of licenses for them, you must use your own branded Embed app URL to sign in their
environment and Business Central Administration center.
To create a new production environment for your customers, go to this URL:
Each environment that you signed up for the Embed App is then displayed on the Tenant list part in your LCS
project. On this part, you can find more details about the environment, including the name and the URL to sign
in to each one. You can see which environments are running on which application version by selecting
application version on the list.
NOTE
The logs typically appear in LCS with a delay of 15 minutes.
For easier troubleshooting, we recommend exporting the logs to a CSV file, using Expor t to CSV action, and
then analyzing them in Microsoft Excel instead.
It's important to always review the logs before submitting any issues to Microsoft. When reporting issues, attach
the relevant logs in TXT or CSV format, don't use screenshots.
See Also
Embed App Overview
Licensing in Dynamics 365 Business Central
Components and Capabilities
Microsoft Responsibilities for Apps on Business Central online
Preparing Demonstration Environments of Dynamics 365 Business Central
Preparing Test Environments of Dynamics 365 Business Central
Using Application Family in Embed App
2/6/2023 • 2 minutes to read • Edit Online
Business Central service is a part of rich ecosystem of surrounding applications and services. One of the
prominent Embed App capabilities is to promote and use the ISV brand in various places of the overall service
experience.
During onboarding, the ISV provides the application family name. The application family helps identify their
solution among other Business Central apps and Embed App's of other ISVs.
The following table describes different aspects of using the application family when interacting with Business
Central components and surrounding services.
H O W TO USE W IT H T H E EM B ED
A REA A P P L IC AT IO N FA M ILY A DDIT IO N A L DETA IL S
Business Central Web client Use the application family in the URL: Web Client URL
[application
family].bc.dynamics.com
Business Central web services Use the application family in the URL: Introduction to automation APIs
[application
family].api.bc.dynamics.com
Business Central mobile app Use the application family in the URL: Getting Business Central on Your
Mobile Device
ms-
businesscentral://[application
family].bc.dynamics.com/
Business Central administration center Application family is displayed for each The Business Central Administration
environment Center
In-code URL generation (GETURL) GETURL returns the branded endpoint, GetUrl Method
including the application family.
Development endpoint for Visual To publish and debug apps in a JSON Files
Studio Code Sandbox environment, use the
"applicationFamily" property in the
launch.json file
Microsoft AppSource To install AppSource apps, use the Installing apps by selecting a direct
branded URL with the following app link in AppSource (for example,
parameters: "Get it now" or "Free trial") isn't
supported. This action redirects to the
https://[application standard Business Central URL.
family].bc.dynamics.com/[TenantID]/?
noSignUpCheck=1&filter=%27ID%27%20IS%20%27[AppID]%27&page=2503
Microsoft Power BI Supported for connecting to the Enabling Your Business Data for Power
environment data from Power BI and BI
embedding Power BI pages in the
Business Central Web client.
H O W TO USE W IT H T H E EM B ED
A REA A P P L IC AT IO N FA M ILY A DDIT IO N A L DETA IL S
Power Automate, Power Apps, Logic Business Central standard connector Custom connector FAQ for Azure Logic
apps currently can't be used (support is Apps, Power Automate, and Power
coming soon). The ISV needs to build a Apps
custom connector. The custom
connector is required anyway, also for
the Business Central environments, if
you want to include data from other
tables that aren't included with the
standard Business Central connector.
See Also
Embed App Overview
Licensing in Dynamics 365 Business Central
Components and Capabilities
Microsoft Responsibilities for Apps on Business Central online
Preparing Demonstration Environments of Dynamics 365 Business Central
Preparing Test Environments of Dynamics 365 Business Central
Application Access Management for the Embed
App
2/6/2023 • 4 minutes to read • Edit Online
In this article, you'll learn how you can control which customers can create online environments based on your
Embed App application family, by enabling your resellers (VARS) to use the Application Management API.
Overview
Both Business Central and Embed Apps are distributed by Cloud Solution Provider (CSP) resellers. Embed Apps
use standard Business Central licenses—the same licenses used for Business Central. So any reseller who sells
Business Central can also create online environments that run on your Embed App by default.
As an Embed App owner, you'll want to control which customers and which resellers can create online
environments based on your Embed App application. You'd also like to allow these resellers to control whether
customers have access to both Business Central and your Embed App or only to the Embed App.
To support these capabilities, two features are available, depending on your role:
RO L E W H AT Y O U C A N DO
Embed App ISV Enable application access management for all environments
in your LCS project.
VAR Once you've been registered by the Embed App ISV, you can
allow or block access to the Embed App or Business Central
app for specific customers.
IMPORTANT
This step enables application access management. Once you have allowed VARs to approve customers, it won't
take effect until you save the change. Be aware that once you save, any existing VAR customers already using your
Embed App and any new customers will be blocked from access by default, until the VAR explicitly enables the app
for them.
IMPORTANT
If you specify that VARs cannot approve customers, even if the VARs are still listed on the Manage VARs access page,
the environment access settings made by VARs for their customers will be ignored. The existing access settings will be
enforced again once you allow the VARs to approve customers again and save the changes.
See Also
Application Access Management API
Using Application Family Managing an Business Central Embed App in Microsoft Lifecycle Services
Application Access Management API
2/6/2023 • 2 minutes to read • Edit Online
As a Delegated Global Administrator or as a Delegated Dynamics 365 Administrator , you can manage
access to application families available in the service. The application family is Business Central or Embed App
applications that may be provisioned through the service.
NOTE
This API endpoint can only be used by Delegated Users. Service-to-service authentication using an AAD App authorized
in the Business Central administration center is not supported.
You can get the list of applications that are available to the customer tenant. From this list you can determine, by
setting the access property, for which applications an environment may be created on the tenant.
GET /admin/v2.15/manageableapplications
Response
Returns a wrapped array of applications.
{
"value": [
{
"applicationFamily": string, // The name of the family for a given Business Central offered
application. (Typically this will just be "BusinessCentral")
"access": boolean, // Indicates if the tenant has access to the application family/country code
combination
"countryCode": string, // The country code of the application.
}
]
}
Example (PowerShell)
$url = "https://api.businesscentral.dynamics.com/admin/v2.3"
$result = Invoke-WebRequest -Uri "$($url)/manageableapplications" -Headers @{"Authorization" = "Bearer
$token"} | ConvertFrom-Json
Write-Host $($result.value | ConvertTo-Json)
Route Parameters
applicationFamily - The name of the family for a given Business Central offered application. (Typically this value
will just be "BusinessCentral")
countryCode - Country code for the targeted application.
Body
{
<boolean> // Desired access state
}
NOTE
It is not possible to disable the access to an application family for the AAD tenant which already has an environment
created in that family.
$url = "https://api.businesscentral.dynamics.com/admin/v2.3"
$country = 'DK'
$applicationFamily = 'frentals'
$access = "true"
Invoke-WebRequest -Uri "$($url)/manageableapplications/$($applicationFamily)/countries/$($country)" -
Headers @{"Authorization" = "Bearer $token"} -Body $access -Method Put -ContentType "application/json"
See Also
Application Access Management
Using Application Family
App Management for ISVs
2/6/2023 • 2 minutes to read • Edit Online
Each Business Central environment is built as a collection of apps. These apps include Microsoft apps and apps
from AppSource that reselling partners have installed for customers. The apps are working together to provide
customers with a broad set of features to address their various business, market, and industry needs.
As an authorized ISV, you can deliver your functionality or your services as apps in AppSource. For more
information, see Get Started with Building Apps. To help you manage your apps running in different customer
Business Central environments, Business Central provides the App Management API.
NOTE
Currently, direct access to the API is only available for the ISVs working with the Embed apps; not Add-on and Connect
apps. To manage versions of Add-on and Connect apps, you use Partner Center to upload the new app versions to
Business Central offers. The apps will undergo a technical and marketing validation before becoming available on
AppSource. After passing validation, the new versions are made available in Business Central administration center to the
customers that have these apps installed.
Legal information
The apps that are stored in the App Repository are governed by the Microsoft Publisher Agreement. For more
information, see Publishing your business application.
The App Management API is governed by Microsoft APIs Terms of Use. For more information, see Microsoft APIs
Terms of Use
See Also
Manage Apps in the Business Central Administration Center
App Management API
2/6/2023 • 13 minutes to read • Edit Online
Entities
App
Description
The app entity represents a Business Central App that has been registered with the service and so it can be
managed via the API. The app entity contains some basic metadata about the app, such as:
its ID
the Azure Active Directory Tenant ID of the publisher's organization
which Azure location the respective .app files and other metadata should be stored in.
NOTE
An app doesn't refer to any specific .app file or version of the app.
Properties
NAME DESC RIP T IO N SC H EM A
Available Endpoints
List apps
Lists all apps that match the provided (optional) filter that the current principal can access.
GET https://apps.businesscentral.dynamics.com/v1.0/apps?$filter=<odata_filter>
Parameters
Example Request
Example Response
{
"value": [
{
"id": "36d697e1-1982-43a5-9927-7f8f2a3eb361",
"publisher": "Contoso",
"publisherAadTenantId": "49cf52d4-fc10-41af-91ab-2d7cd011db47",
"publisherContactEmail": "publisher@contoso.com",
"storageLocation": "West Europe",
"_etag": "5c47bfb0-d80c-4780-99ed-c3a3d38ac539"
}
]
}
Country
The country entity represents a country that an app is available in.
A country is represented by its ISO 3166-1 alpha-2 (2-letter) country code.
Specific versions of Business Central Apps can be made available for specific countries.
Properties
NAME DESC RIP T IO N SC H EM A
Available Endpoints
List countries
Lists all countries the specified app has been made available in.
GET https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/countries
Parameters
Example Request
GET https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-f10f36a2e213/countries
Example Response
{
"value": [
{
"countryCode": "US",
"_etag": "f6039211-0dea-481a-80a5-38498dcea011"
},
{
"countryCode": "DK",
"_etag": "bb8f8166-a6cc-4562-b135-0b13257b032f"
}
]
}
Get country
Gets the country with the specified country code in the specified app .
GET https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/countries/{countryCode}
Parameters
Example Request
GET https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-f10f36a2e213/countries/US
Example Response
{
"countryCode": "US",
"_etag": "f6039211-0dea-481a-80a5-38498dcea011"
}
PATCH https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/countries/{countryCode}
Parameters
Example Request
PATCH https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-f10f36a2e213/countries/AT
{
"countryCode": "AT"
}
Example Response
{
"countryCode": "AT",
"_etag": "584915f0-6319-4aab-a23c-743c0c4d9aeb"
}
Principal
Description
The principal entity represents an Azure Active Directory user or application that has some level of access to
an app .
Principal can have different roles that determine which actions they're allowed to do. The currently supported
roles are:
- Owners are allowed to do all available actions on all entities.
Owner
Contributor - Contributors have similar permissions to owners, except that they aren't allowed to
add/update principals.
Reader - Readers can read information about the various entities, but can't add/update anything.
Properties
NAME DESC RIP T IO N SC H EM A
Available Endpoints
List principals
Lists all principal s that match the provided filter within the specified app .
GET https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/principals?$filter=<odata_filter>
Parameters
Example Request
GET https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-f10f36a2e213/principals?
$filter=type eq 'User' and 'Owner' in roles
Example Response
{
"value": [
{
"id": "c07b7af3-8c9a-4bb1-9a0b-03692ba98d6d",
"type": "User",
"aadTenantId": "0c1cbce0-b823-4acf-be2f-1ac3a4e81c21",
"roles": [
"Owner"
],
"_etag": "c99541ab-a0d2-4807-86f8-e1eb1853eb4f"
}
]
}
Get principal by ID
Gets the principal with the specified ID in the specified app .
GET https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/principals/{id}
Parameters
GET https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-
f10f36a2e213/principals/c07b7af3-8c9a-4bb1-9a0b-03692ba98d6d
Example Response
{
"id": "c07b7af3-8c9a-4bb1-9a0b-03692ba98d6d",
"type": "User",
"aadTenantId": "0c1cbce0-b823-4acf-be2f-1ac3a4e81c21",
"roles": [
"Owner"
],
"_etag": "c99541ab-a0d2-4807-86f8-e1eb1853eb4f"
}
Remove principal
Removes the principal with the specified ID in the specified app .
Note: Only principals with the Owner role are allowed to remove principals.
DELETE https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/principals/{id}
Parameters
Example Request
DELETE https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-
f10f36a2e213/principals/c07b7af3-8c9a-4bb1-9a0b-03692ba98d6d
PATCH https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/principals/{id}
Parameters
Example Request
PATCH https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-
f10f36a2e213/principals/c07b7af3-8c9a-4bb1-9a0b-03692ba98d6d
{
"aadTenantId": "20ba9ed9-d37b-4db0-ade4-f64322ad7c02",
"Type": "User",
"roles": [
"Reader"
]
}
{
"id": "c07b7af3-8c9a-4bb1-9a0b-03692ba98d6d",
"type": "User",
"aadTenantId": "0c1cbce0-b823-4acf-be2f-1ac3a4e81c21",
"roles": [
"Reader"
],
"_etag": "a98992bf-d7f6-460b-83bb-1498459a6a75"
}
Version
Description
A version represents an .app file that has been uploaded for a specific country in an app .
If a version of an app should be available in multiple countries, then the .app file needs to be uploaded to each
country separately.
Properties
Version
uploadedOn The UTC date and time the version was string (date-time)
uploaded on.
Dependency
List versions
Lists all versions that match the provided filter.
GET https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/countries/{countryCode}/versions?$filter=
<odata_filter>
Parameters
Example Request
GET https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-
f10f36a2e213/countries/US/versions?$filter=MajorVersion eq 16 and MinorVersion eq 0
Example Response
{
"value": [
{
"version": "16.0.1.2",
"appId": "41a68924-7fcf-4fd0-9200-f10f36a2e213",
"countryCode": "US",
"packageId": "01d39741-8ab1-4fcc-b353-d9208ba475e3",
"publisher": "Example Publisher",
"name": "ExampleApp",
"uploadedOn": "2019-07-09T11:54:45.5414576Z",
"availability": "Available",
"status": "Uploaded",
"dependencies": [
{
"appId": "1914cafc-93b9-46fd-b825-707f1743caee",
"name": "Example Dependency",
"publisher": "Other Publisher",
"version": "1.0.0.0"
}
],
"majorVersion": 16,
"minorVersion": 0,
"buildVersion": 1,
"revisionVersion": 2,
"_etag": "50fec40a-99b6-4743-bbe7-42e95cde2cfa"
}
]
}
Upload version
Uploads an .app file into the specified app and country based on the provided package contents.
POST https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/countries/{countryCode}/versions
IMPORTANT
Make sure that you registered your app with the service and added a country to it, before you attempt to upload the app
version.
NOTE
If you want to update app to a version that introduces breaking changes, see Upgrading an App by Using ForceSync.
Parameters
initialAvailability The initial availability that the uploaded enum (Preview, Available, Deprecated)
app version should have.
Example Request
POST https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-
f10f36a2e213/countries/US/versions
{
"initialAvailability": "Preview",
"packageContents": <contents>
}
Example Response
{
"version": "16.0.1.2",
"appId": "41a68924-7fcf-4fd0-9200-f10f36a2e213",
"countryCode": "US",
"packageId": "01d39741-8ab1-4fcc-b353-d9208ba475e3",
"publisher": "Example Publisher",
"name": "ExampleApp",
"uploadedOn": "2019-07-09T11:54:45.5414576Z",
"availability": "Preview",
"status": "Uploaded",
"dependencies": [
{
"appId": "1914cafc-93b9-46fd-b825-707f1743caee",
"name": "Example Dependency",
"publisher": "Other Publisher",
"version": "1.0.0.0"
}
],
"majorVersion": 16,
"minorVersion": 0,
"buildVersion": 1,
"revisionVersion": 2,
"_etag": "50fec40a-99b6-4743-bbe7-42e95cde2cfa"
}
Download version
Downloads the .app file linked to the specified version.
POST
https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/countries/{countryCode}/versions/{versionNumber}
/getPackageContents -OutFile {saveToFile}
Parameters
Example Request
Downloads an app file.
POST https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-
f10f36a2e213/countries/US/versions/16.0.1.2/getPackageContents -OutFile "C:\temp\ExampleApp-16.0.1.2.app"
Get version
Gets the version in the specified app and country .
GET
https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/countries/{countryCode}/versions/{versionNumber}
Parameters
Example Request
GET https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-
f10f36a2e213/countries/US/versions/16.0.1.2
Example Response
{
"version": "16.0.1.2",
"appId": "41a68924-7fcf-4fd0-9200-f10f36a2e213",
"countryCode": "US",
"packageId": "01d39741-8ab1-4fcc-b353-d9208ba475e3",
"publisher": "Example Publisher",
"name": "ExampleApp",
"uploadedOn": "2019-07-09T11:54:45.5414576Z",
"availability": "Preview",
"status": "Uploaded",
"dependencies": [
{
"appId": "1914cafc-93b9-46fd-b825-707f1743caee",
"name": "Example Dependency",
"publisher": "Other Publisher",
"version": "1.0.0.0"
}
],
"majorVersion": 16,
"minorVersion": 0,
"buildVersion": 1,
"revisionVersion": 2,
"_etag": "50fec40a-99b6-4743-bbe7-42e95cde2cfa"
}
Update version
Updates the version in the specified app and country with the provided updated data.
Note: only some properties can be updated.
PATCH
https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/countries/{countryCode}/versions/{versionNumber}
Parameters
Example Request
Marking an app version as deprecated.
PATCH https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-
f10f36a2e213/countries/US/versions/16.0.1.2
{
"availability": "Deprecated"
}
Example Request
Marks older versions of your app as incompatible with a dependency app, starting with a specific version. In
such cases, make sure you upload another version of your app that is compatible with the new version of the
dependency app.
PATCH https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-
f10f36a2e213/countries/US/versions/16.0.1.2
{
"dependencies": [
{
"appId": "63ca2fa4-4f03-4f2b-a480-172fef340d3f",
"incompatibleFromVersion": "16.0.0.0"
}
]
}
Example Response
{
"version": "16.0.1.2",
"appId": "41a68924-7fcf-4fd0-9200-f10f36a2e213",
"countryCode": "US",
"packageId": "01d39741-8ab1-4fcc-b353-d9208ba475e3",
"publisher": "Example Publisher",
"name": "ExampleApp",
"uploadedOn": "2019-07-09T11:54:45.5414576Z",
"availability": "Deprecated",
"status": "Uploaded",
"dependencies": [
{
"appId": "1914cafc-93b9-46fd-b825-707f1743caee",
"name": "Example Dependency",
"publisher": "Other Publisher",
"version": "1.0.0.0"
}
],
"majorVersion": 16,
"minorVersion": 0,
"buildVersion": 1,
"revisionVersion": 2,
"_etag": "3c0f1fd2-266e-491b-82e3-74f09a975267"
}
Environment
Description
Represents a customer's environment that has a specific version of an app installed.
Properties
NAME DESC RIP T IO N SC H EM A
List environments
Lists the environment s in the specified app and country that have the app installed.
GET https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/countries/{countryCode}/environments
Parameters
Example Request
GET https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-
f10f36a2e213/countries/US/environments?$filter=version eq '16.0.1.2'
Example Response
{
"value": [
{
"aadTenantId": "539a833c-4e6a-42d8-a081-27fa9d810424",
"version": "16.0.1.2",
"appId": "41a68924-7fcf-4fd0-9200-f10f36a2e213",
"countryCode": "US",
"applicationFamily": "Business Central",
"locationName": "West Europe",
"name": "MyCustomer",
"type": "Production"
}
]
}
Environment Hotfix
Description
An environment hotfix represents the action of pushing out an update (new version ) of an app to a
customer's environment as part of fixing a critical issue.
Only version s where the major and minor components haven't changed can be pushed as hotfixes.
It is also not possible to apply a hotfix to an already installed application version of preview availability. To apply
a hotfix, you need to either uninstall the preview application version from the environment you are trying to
update or change the availability of that application version from preview to available .
Properties
NAME DESC RIP T IO N SC H EM A
completedOn Date and time (UTC) when the hotfix string (date-time)
was applied.
createdOn Date and time (UTC) when the hotfix string (date-time)
request was created.
runAfter Date and time (UTC) after which hotfix string (date-time)
should start to be applied.
star tedOn Date and time (UTC) when the hotfix string (date-time)
started to be applied.
GET https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/countries/{countryCode}/environmentHotfixes?
$filter=<odata_filter>
Parameters
GET https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-
f10f36a2e213/countries/US/environmentHotfixes?$filter=targetAppVersion eq '16.0.1.2'
Example Response
{
"value": [
{
"id": "db311b6a-062e-4756-b17e-73aeb89c45cc",
"environmentAadTenantId": "539a833c-4e6a-42d8-a081-27fa9d810424",
"sourceAppVersion": "16.0.0.5",
"targetAppVersion": "16.0.1.2",
"status": "Scheduled",
"createdOn": "2020-03-05T15:41:20.6468128Z",
"runAfter": "2020-03-05T17:30:00.0000000Z",
"appId": "41a68924-7fcf-4fd0-9200-f10f36a2e213",
"countryCode": "US",
"environmentApplicationFamily": "Business Central",
"environmentName": "MyCustomer",
"environmentType": "Production"
}
]
}
GET
https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/countries/{countryCode}/environmentHotfixes/{id}
Parameters
Example Request
GET https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-
f10f36a2e213/countries/US/environmentHotfixes/db311b6a-062e-4756-b17e-73aeb89c45cc
Example Response
{
"id": "db311b6a-062e-4756-b17e-73aeb89c45cc",
"environmentAadTenantId": "539a833c-4e6a-42d8-a081-27fa9d810424",
"sourceAppVersion": "16.0.0.5",
"targetAppVersion": "16.0.1.2",
"status": "Scheduled",
"createdOn": "2020-03-05T15:41:20.6468128Z",
"runAfter": "2020-03-05T17:30:00.0000000Z",
"appId": "41a68924-7fcf-4fd0-9200-f10f36a2e213",
"countryCode": "US",
"environmentApplicationFamily": "Business Central",
"environmentName": "MyCustomer",
"environmentType": "Production"
}
POST https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/countries/{countryCode}/environmentHotfixes
Parameters
Example Request
POST https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-
f10f36a2e213/countries/US/environmentHotfixes
{
"environmentAadTenantId": "539a833c-4e6a-42d8-a081-27fa9d810424",
"targetAppVersion": "16.0.1.2",
"runAfter": "2020-03-05T17:30:00.0000000Z",
"environmentApplicationFamily": "Business Central",
"environmentName": "MyCustomer",
"environmentType": "Production"
}
Example Response
{
"id": "db311b6a-062e-4756-b17e-73aeb89c45cc",
"environmentAadTenantId": "539a833c-4e6a-42d8-a081-27fa9d810424",
"sourceAppVersion": "16.0.0.5",
"targetAppVersion": "16.0.1.2",
"status": "Scheduled",
"createdOn": "2020-03-05T15:41:20.6468128Z",
"runAfter": "2020-03-05T17:30:00.0000000Z",
"appId": "41a68924-7fcf-4fd0-9200-f10f36a2e213",
"countryCode": "US",
"environmentApplicationFamily": "Business Central",
"environmentName": "MyCustomer",
"environmentType": "Production"
}
PATCH
https://apps.businesscentral.dynamics.com/v1.0/apps/{appId}/countries/{countryCode}/environmentHotfixes/{id}
Parameters
Example Request
PATCH https://apps.businesscentral.dynamics.com/v1.0/apps/41a68924-7fcf-4fd0-9200-
f10f36a2e213/countries/US/environmentHotfixes/db311b6a-062e-4756-b17e-73aeb89c45cc
{
"status": "Canceled"
}
Example Response
{
"id": "db311b6a-062e-4756-b17e-73aeb89c45cc",
"environmentAadTenantId": "539a833c-4e6a-42d8-a081-27fa9d810424",
"sourceAppVersion": "16.0.0.5",
"targetAppVersion": "16.0.1.2",
"status": "Canceled",
"createdOn": "2020-03-05T15:41:20.6468128Z",
"runAfter": "2020-03-05T17:30:00.0000000Z",
"appId": "41a68924-7fcf-4fd0-9200-f10f36a2e213",
"countryCode": "US",
"environmentApplicationFamily": "Business Central",
"environmentName": "MyCustomer",
"environmentType": "Production"
}
try {
Invoke-WebRequest ....
}
catch [System.Net.WebException]
{
$Exception = $_.Exception
$respStream = $Exception.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($respStream)
$respBody = $reader.ReadToEnd() | ConvertFrom-Json | ConvertTo-Json -Depth 100
$reader.Close();
Write-Error $Exception.Response.Headers["ms-correlation-x"]
Write-Error $Exception.Message
Write-Error $respBody -ErrorAction Stop
}
Please make sure you provide full output in textual format when reporting the issues to Microsoft.
See Also
App Management for ISVs
Upgrading an App by Using ForceSync
2/6/2023 • 2 minutes to read • Edit Online
This article provides guidelines for using ForceSync option to upgrade an app to a version that introduces
breaking changes.
Overview
When you upgrade an app to a new version, the database is synchronized with any schema changes introduced
by the new app version. Under normal operation, if the app introduces any breaking changes, like removing a
field or changing its data type, the synchronization will fail, preventing the upgrade. However, the service
includes a property called syncMode that you can set to "ForceSync" , which will apply the breaking changes. If
you're familiar with Business Central on-premises, this operation is similar to using the Sync-NAVApp cmdlet
with -mode ForceSync parameter.
This property only works with side-by-side upgrades using Microsoft Lifecycle Services (LCS). You can't use it for
breaking changes in a hotfix pushed from App Management API. So make sure you plan your changes when
preparing new minor or major upgrades.
IMPORTANT
Use this option with caution. When you use the syncMode = "ForceSync" , it applies breaking changes forcefully,
typically deleting the data in the objects that have new schema. It can also break other apps that run on top of your
objects. Before using this option in production, test it on both on-premises and online (using Sandboxes). It's also
recommended that you export a BACPAC of your production environment from the Business Central admin center before
the upgrade.
$version = 'target_version'
$url =
https://apps.businesscentral.dynamics.com/v1.3/apps/$appID/countries/$country/versions/$version
$body = @{
syncMode = "ForceSync"
}
Invoke-WebRequest -Uri $url -Headers $headers -Body (ConvertTo-Json $body) -Method Patch
Replace target_version with the new version of your app, for example, 18.0.23456.21212.
4. In LCS, upgrade an environment from the old version to the new version. The new app version will be
upgraded using ForceSync.
You can always switch to the normal sync mode for an app issuing another PATCH request that sets the
syncMode to "Sync" :
{
"syncMode": "Sync"
}
See Also
App Management API
Manage Apps in the Business Central Administration Center
Get Started as a Reseller of Business Central Online
2/6/2023 • 12 minutes to read • Edit Online
If you want to build your business on Dynamics 365 Business Central online, you must get set up as a reseller in
the Microsoft Partner Center. In this article, we take you through the first steps in your journey.
NOTE
When you buy Business Central offers on behalf of your CSP customers, the CSP offer must be available in both your own
tenant's country and in your customer's tenant's country. For example, if your tenant is located in Slovakia and the
customer's tenant is in Germany, you will not be able to sell Dynamics 365 Business Central Premium to that customer,
because this offer is currently not available in Slovakia.
Similarly, if your tenant is located in Germany and the customer's tenant is in Slovakia, you will not be able to sell
Dynamics 365 Business Central Premium to that customer, because this offer is currently not available in Slovakia.
In the Microsoft Partner Center documentation, you can learn how to request a reseller relationship with
customers, assign licenses to users, and create new subscriptions. Business Central is one of the subscriptions
that you can create, and there are Business Central-specific license types that you can assign to users.
You must also assign certain roles to users in your own organization so that they can support your customers.
Add users from your own organization
In most cases, your partner company includes employees with different responsibilities, and you can assign
different roles depending on people's responsibility. This way, you can be very explicit about who from your staff
can access your customers' data, for example.
For each user, you can assign permissions for 2 categories of tasks:
Managing your organization's account
This controls access to the functionality of the Partner Center portal
Assisting your customers
This controls access to your customers' environments
When you establish a reseller relationship with a customer in Partner Center, you must specify which people
from your organization will assist that customer's tenant as either Admin agent or Helpdesk agent. These users
can manage implementation, support, and troubleshooting tasks for your customers. Once the reseller
relationship with a customer is established, they will be able to login into the Business Central environments of
the customer without a license. The number of partner users that can access customer environments is not
restricted.
This way of accessing customer resources is called delegated administration, and the partner users are therefore
called delegated administrators or delegated admins in daily shorthand. For more information, see Delegated
Administrator Access to Business Central Online.
Since February 2022, you can set up security groups with granular delegated admin privileges to better control
who has access to which customers with which level of access to the customer's Business Central environment.
This way, the delegated admins no longer have to be global admins for the customer's Active Directory. For
more information, see the Delegated Administrator Access to Business Central Online section, and also the
Admin roles article in the Microsoft 365 admin content.
NOTE
These users cannot provide accounting services for the customers. For this purpose, the customers must use the
External Accountant license, which is also available via CSP.
Cau t i on
Quite often, partner users are registered as business-to-business (B2B) guest users in their customer's Azure
Active Directory (Azure AD), such as to collaborate through Teams. However, when a partner user is added as a
guest to their customer's Azure AD, they can no longer log in as a delegated admin into the customer's Business
Central. These guest users do not have a valid Business Central license assigned to them. But if the partner user
has granular delegated admin privileges, they can access the customer's Business Central administration center
and manage the environments there. Starting in 2022 release wave 2, partner users that are guest users and
have granular delegated admin privileges are no longer blocked from accessing Business Central. But we
continue to consider it a best practice that customers do not invite partner users to their tenant as guests but
ask them to set up granular delegated admin privileges, using the Dynamics 365 administrator role. For more
information, see Move to GDAP and remove DAP in the Partner Center FAQ.
For more information, see Delegated Administrator Access to Business Central Online.
Step 2: Go to market
When you become a Microsoft Partner Network member, you gain access to membership benefits that can help
you build and grow your business. For more information, see Explore your Go-To-Market with Microsoft offers
in the Partner Center docs.
As a Dynamics 365 reseller, you benefit from Microsoft's investments in an always up-to-date modern platform,
you can bundle recognized apps from the Microsoft commercial marketplace into an offering that fits the needs
of your customers, reach more customers by using Microsoft's commercial marketplace to promote your
packaged consulting service offerings or customization services, and streamline your own processes and build
tools with Power BI, Power Automate, and Power Apps connected to Business Central.
The Dynamics 365 Business Central Partner Portal landing site has plenty of material to help you build a
practice, go to market, drive readiness, and keep track of upcoming events (requires a partner account).
Marketing assets
Microsoft provides marketing assets that you can use to build a business based on Microsoft. For more
information, see the following sites:
Partner Network resources
Brand and trademark basics for partners
Go-to-market with Microsoft
Specifically for going to market with Business Central, Microsoft provides resources and guidance on the
Business Applications for small and medium-sized businesses (SMBs) site. For more information, see Business
Central Go-To-Market resources.
IMPORTANT
Specifically for businesses who want to convert a 30-day trial company into their actual production company, the first
user who signs into Business Central after the license was applied to their tenant must be a user with this license
assigned. This way, the 30-day trial ends, and any trial-related notifications disappear so that users can use Business
Central to do work.
If an administrator is the first person to sign in after the license was applied to the tenant and to users, then the trial will
continue until it expires.
If the customer has tried out Business Central using a pre-configured demonstration company that you have
prepared in other ways, they can now sign up for Business Central using their own work or school account so
that you can assign the Business Central license to their Microsoft 365 tenant.
You can help them migrate their data from their legacy system. For more information, see Migrate On-Premises
Data to Business Central Online.
See also
Administration of Business Central Online
Deployment of Dynamics 365 Business Central on-premises
Trials and Sign-ups for Business Central Online
Licensing in Dynamics 365 Business Central
Learn how to partner with indirect providers in the Cloud Solution Provider program
Dynamics 365 Business Central Partner Portal
Set Up Company Configuration Packages
2/6/2023 • 10 minutes to read • Edit Online
As you grow your business as a reseller of Business Central, you will likely come to rely on a set of company
types that you use with most of your Business Central prospects. You can streamline your implementation
process by turning these types into configuration packages that are available for reuse.
After you have set up a company in Business Central that suits your needs, you can create a configuration
package that contains relevant setup data from this company. You can then use it when you create a new
company that is to be configured in the same way.
To facilitate the import of master data, such as customer and vendor information, you can use configuration
templates. Configuration templates contain a set of default settings that are automatically assigned to the
records imported into Business Central. Configuration templates are an alternative to the cloud migration tools
that you can use to migrate customer data from supported products. For more information, see Migrate On-
Premises Data to Business Central Online.
TIP
Use these capabilities to scale your business as a reseller. Most of the relevant pages apply to both Business Central online
and on-premises. However, some processes rely on access to the underlying database and are too complex to use for
Business Central online. For Business Central on-premises, you probably want to use Windows PowerShell to help you
deploy. For more information, see Administration of Business Central On-Premises and Administration of Business Central
Online, respectively.
Configuration packages
By default, Business Central online comes with one configuration package for Microsoft's default application,
including local functionality. You can copy that and make relevant changes in the copy.
Many of our reselling partners create a configuration package for each functional area. For example, create a
package for the manufacturing functionality and another for sales. That lets you apply and set up new areas in a
company as you need them.
We recommend that you create configuration packages with most of the setup tables already filled in, so that
only a few settings must be tweaked for each customer. For example, when you create a new company, the No.
Series and the No. Series Line tables are filled in with a set of number series and starting numbers. The
corresponding No. Series fields in the setup tables are also filled in automatically. You do not have to do the
work of entering number series and other basic setup data. You can also manually change all default data that is
used with RapidStart Services by using the configuration worksheet.
Another approach would be to create a package that includes the tables that define setup, such as the following:
General Ledger Setup
General Posting Setup
VAT Posting Setup
Inventory Posting Setup
Purchases and Payables Setup
Sales and Receivables Setup
Warehouse Setup
Inventory Setup
Manufacturing Setup
Fixed Asset Setup
Marketing Setup
Service Setup
To see a complete list of setup tables in Business Central, choose the icon, enter Manual Setup , and then
choose the related link.
TIP
Optionally, use the configuration worksheet to gather together and categorize the information that you want to use to
configure a new company, and arrange tables in a logical way. Formatting in the worksheet is based on a simple hierarchy:
areas contain groups, which in turn contain tables. Areas and groups are optional but useful. You can then add the
worksheet lines to a new configuration package.
TIP
Take a look at the default configuration package for the demonstration company for inspiration for how to set up
the configuration.
a. Choose the Get Tables action. On the Get Config. Tables request page, specify the types of
tables that you want to add to the configuration, and set the relevant filters. Then choose the OK
button.
To exclude the configuration questionnaires, configuration templates, and configuration worksheet
tables from the package, select the Exclude Configuration Tables check box on the Config
Package Card page. Otherwise, these tables will be added to the list of package tables
automatically when you export the package.
b. To add related tables, choose the Get Related Tables action.
NOTE
Related tables will not be added with the Get Related Tables action if either of the following is true:
The relation is conditional.
Example: If you get related tables for the Customer table, then the Location table will not be added,
since it is only conditionally related to the Customer table, namely if the Location Code field in the
Customer table is filled in.
The related table is filtered.
Example: A field in the related table has a WHERE clause. The reason for this is that the involved
relations information is stored in the Field system table, which is not fully accessible to the application.
You must add such types of tables manually.
For each table, you can specify which fields to exclude, and you can modify the default processing
order for each field. Business Central checks if there are related fields that you must configure in
the Config. Package Fields page.
c. Optionally, for each table, modify which fields must be included in the package.
Select a table for which you want to specify field information, and on the Actions tab, in the Show
group, choose Fields .
To select just the fields you want to include, choose the Clear Included action. To add all fields,
choose the Set Included action.
To specify that the field data should not be validated, clear the Validate Field check box for the
field.
5. Assign the worksheet lines to an existing package.
a. Select the relevant lines, choose the Assign Package action, and then, in the Configuration
Packages page, choose the relevant package, or create a new one.
If a table is not already included in the package, it will now be added. The package code field on the
worksheet line will be filled in with the code of the package that the table is assigned to.
If you choose an existing package, you can see how many tables are already in the package by
reviewing the information in the No. of Tables field.
6. Optionally, create a questionnaire for the most frequently used setup tables so that you can get specific
information from your prospects and customers that will help you set up their Business Central.
a. On the Configuration Questionnaire page, add a new questionnaire, and then choose the
Questions Areas action.
b. In the Config. Question Area page, in the Table ID field, choose the ID of the table for which
you want to collect information. The Table Name field is automatically filled in.
c. Choose the Update Questions action. Each field in the table is added to the questionnaire with a
question mark following its caption in the Question field.
You can rephrase the question to make it clear that it is a question that should be answered. For
example, if a field is called Name , you could edit the related question to state What is the name of
the account. You can also provide guidance in the Reference field, including a URL to a page that
provides additional information for example.
You can also delete any questions that you do not want to include in the questionnaire.
NOTE
The Answer Option field describes the format that the answer to the question must meet, such as Code
or Text.
As needed, you can also define default answers in the Answer field. These values are used by default for
custom setup. However, the person filling in the questionnaire can modify and update the answer.
d. Repeat steps 2 and 3 for any additional areas that you want to add to the questionnaire, and then
return to the Configuration Questionnaire page.
Optionally, export the questionnaire to Excel. Then, you can use the Excel workbook to get answers
from your prospects and customers. There are worksheets for each of the question areas that have
been created for the questionnaire.
NOTE
You may encounter the following error when you run an English version of Excel, but have your regional
settings configured for a non-English language: Old format or invalid type library. To fix this error, make
sure that the language pack for the non-English language is installed.
7. Optionally, create configuration templates to make it easier to import master data, such as customers,
vendors, contacts, or items.
Use the built-in configuration templates, or create your own templates in the Configuration Templates
page. This is mainly useful if you're going to migrate customer data to Business Central on-premises and
then switch to the cloud. For more information, see Apply Company Configuration Packages.
You can export the templates as Excel workbooks so that you can work with customer data in Excel.
8. Export your package as a .rapidstart file, or export it to Excel.
The next time you're going to set up Business Central for a new customer, you can apply your configuration
packages and get started fast. For more information, see Apply Company Configuration Packages.
See Also
Apply Company Configuration Packages
Migrate On-Premises Data to Business Central Online
FAQ about Migrating to Business Central Online from On-Premises Solutions
Administration of Business Central Online
Administration of Business Central On-Premises
Get Started as a Reseller of Business Central Online
Onboarding experiences in Business Central
Onboarding experiences in Business Central
2/6/2023 • 2 minutes to read • Edit Online
Setting up Business Central for a customer usually involves manual setup from the partners' side. Often this
setup time is spent on basic settings that do not provide additional value to the specific customer but are more
generic and address the customer's industry or type of business. This is costly for the customer and can be a
bottleneck for you as a partner.
Microsoft provides tools you can use to help speed up this process and enable the customer to more easily learn
how to use the product and get to productive usage faster. This will save costs on the customer side and free up
your consultants' time.
The onboarding framework in Business Central presents all users with a consistent onboarding experience when
it comes to an introduction to the product itself. Partners can still use any other methodology that they prefer,
but the tools in the onboarding framework provides a native experience.
See also
Get Users Started with the Checklist
Onboard New Users with the Welcome Banner
Teaching tips and in-app tours for onboarding users
User Assistance Model
Extend and Collaborate on the Help
Migrate On-Premises Data to Business Central Online
FAQ for Developing in AL
2/6/2023 • 2 minutes to read • Edit Online
This topic contains a number of frequently asked questions and answers to these questions.
See Also
Get Started with AL
Keyboard Shortcuts
AL Development Environment
FAQ about Library and Dependency Apps in
Business Central
2/6/2023 • 2 minutes to read • Edit Online
This section contains answers to frequently asked questions about library apps and dependency apps in
Business Central.
When I get the latest updated version of my app, why don't I get the
updated library/dependency apps that my AppSource app depends
on?
Libraries are updated only when the new version of your app requires a higher version than the version
currently installed in your environment. If you want your library app to be automatically updated when your
AppSource app is updated, you must increase the minimum version required in the manifest (app.json) of your
AppSource app.
You can also uninstall and reinstall the library/dependency app to have it updated.
This section contains answers to frequently asked questions about testing your app when you submit an app for
Business Central.
I only made minor code changes in my updated app. Can I test just
these changes?
No. You should always test 100% coverage no matter what. Testing only what you changed isn't the correct
approach. Even minor changes can lead to breaking changes where you least expect it.
See also
FAQ about Updating your Business Central App
FAQ about Library & Dependency Apps in Business Central
Update Lifecycle for AppSource Apps FAQ
The Lifecycle of Apps and Extensions for Business Central
FAQ about Updating your Business Central App
2/6/2023 • 5 minutes to read • Edit Online
This section contains answers to frequently asked questions about updating your app for Business Central.
If I make changes to the library app, must I also submit an update for
the AppSource app?
You would upload the updated library app to Partner Center, leave the main app as is, and submit for validation.
We then see that the main app has not changed and only validate the library app.
See also
FAQ about Managing and Submitting your Business Central Offer
FAQ about Library & Dependency Apps in Business Central
Update Lifecycle for AppSource Apps FAQ
The Lifecycle of Apps and Extensions for Business Central
FAQ about Managing and Submitting your Business
Central Offer
2/6/2023 • 2 minutes to read • Edit Online
This section contains answers to frequently asked questions about managing the offer in Partner Center when
you submit an app for Business Central.
If I click the Go Live button, does that mean my app will go live to
AppSource?
No. This button is deceiving, and I wish it were worded differently. When you click this button, it triggers our
validation process and puts your app into our validation queue.
See also
FAQ about Updating your Business Central App
FAQ about Library & Dependency Apps in Business Central
Update Lifecycle for AppSource Apps FAQ
The Lifecycle of Apps and Extensions for Business Central
Marketing Validation FAQ
2/6/2023 • 2 minutes to read • Edit Online
Do you have any tips and tricks for what I should write in the
description text?
Yes. We have detailed guidelines and good advice about that here.
What are the requirements for my offer’s help and support page?
You're required to submit two distinct pages for support and help that is, they cannot be the same. You can see
what you have to include on both pages in the table below.
H EL P SUP P O RT
Learning material such as FAQs, step by step guides, video At least two contact options (for example, e-mail, phone,
tutorials, webinars etc. chat) and a defined SLA for how much time it takes before
you answer to support inquires.
See Also
Marketing Validation Checklist
Update Lifecycle for AppSource Apps FAQ
2/6/2023 • 5 minutes to read • Edit Online
Please see the following sections for frequently asked questions regarding updating apps on AppSource.
Does Microsoft now update my app (to this latest updated version)
on all tenants that already have a previous version?
Microsoft will only force update apps during the 2 major releases (release wave 1 and 2). For these releases,
each tenant will have their AppSource apps force updated to the latest available versions in our service.
Do you have any tips for us when submitting updates of our app?
Yes, we have some valuable tips we would like to share. These are tips that can save you time in the validation
process. They will help lead to fewer (and possibly zero) failures during validation. Most importantly; they will
lead to fewer issues being found in production by customers.
Follow the checklist, for more information see Technical Validation Checklist. The checklist is ever evolving
and requirements might change or be added. You might miss something from the checklist, leading to
validation failure and delaying the passing of your updated app.
Follow the technical validation FAQ, for more information see Technical Validation FAQ. We are regularly
updating it based on the questions and support cases raised by partners.
Use AppSourceCop, for more information see Using the Code Analysis Tool. This helps to catch any missing
prefix/suffix and DataClassification. Too often we see these fail the updated versions of apps.
Sign your app. This fails many app validations. We try to publish the app during validation and it is not
properly code-signed leading to failure to publish.
Publish and install your app. This is another big validation failure we see too often.
Test your app’s functionality with 100% coverage. You are the expert on the app and know it best. If you are
only testing a small percentage of your app, customers will most likely find issues resulting in you having to
update your app more often. And if customers are the ones finding your app issues, they may decide to
uninstall it. You should have a vested interest in providing a quality app.
Test the upgrade of your app. upgrade from the previous version to this latest. Your updated app will not pass
validation until the upgrade works. If it fails in our validation, we will return it to you, leading to a delay in it
going to our service.
Collect telemetry data in Microsoft Azure Application Insights. When you submit an app to AppSource, it
starts an automated validation process. This process ensures the extensions in the app meet the technical
requirements for going live. It goes through many of the same checks described in technical validation.
Starting with version 18.4, if an app's set up for it, telemetry traces for the app submission can be emitted to
and recorded in Application Insights. The data provides immediate details about the success or failure of
different phases of the validation. For more information, see Sending Extension Telemetry to Azure
Application Insights and Analyzing AppSource Submission Validation Trace Telemetry..
NOTE
The tips that we provide above are for your benefit to pass validation the first time through each submission. And to
emphasize these points, think of the delays that can arise when you don't follow these tips. If you submit, it can take a
couple days before we validate the app. Once we validate it, if all is good, it should pass quickly. If we find issues that lead
us to fail the validation, we send the app back to you as you have to make fixes. It could then take you days to properly
fix. Next time you submit, your app does not go to the front of the queue. It begins at the bottom again which means it
could be another couple days before we validate it again. By following our tips above, you can avoid those delays. Spend a
bit more time up front finding those issues yourself, leading to a quicker path to our service.
See Also
Retaining table data after publishing
Checklist for Submitting Your App
Upgrading Extensions
Using the Code Analysis Tool
FAQ About the Windows Client and Business
Central
2/6/2023 • 5 minutes to read • Edit Online
The first releases of Business Central on premises included an installed client derived from Dynamics NAV.
Starting with 2019 release wave 2, this legacy component, referred to as "the Windows client", will no longer be
available for Business Central. Find answers for some of the most common questions here.
See Also
FAQ for Developing in AL
Features not implemented in on-premises deployments of Dynamics 365 Business Central
Business Central Component and System Topology, Additional Components
Software Lifecycle Policy and Dynamics 365 Business Central On-Premises Updates
Dynamics 365 Business Central Compliance
FAQ for Dynamics 365 Update Policies
Dynamics 365 Resources
Welcome to Dynamics 365 Business Central
FAQ about Migrating to Business Central Online
from On-Premises Solutions
2/6/2023 • 5 minutes to read • Edit Online
This section contains answers to frequently asked questions about migrating from on-premises solutions to
Business Central online.
TIP
Check the tips in this article if your organization is not yet ready to migrate to Business Central online but are thinking
hard about it. For more information about migration, see Migrate On-Premises Data to Business Central Online.
See also
Troubleshooting Cloud Migration
Migrating On-Premises Data to Business Central Online
Update 21.4 for Microsoft Dynamics 365 Business
Central online 2022 release wave 2
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 21.4? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article and the downloads here.
Feature changes
Reuse launch configurations across workspace projects
Localization updates
C O UN T RY F EAT URE DESC RIP T IO N
Mexico [CDFI] New Electronic Document Electronic invoices in Mexico will have
Status for cancelling a stamp from a different statuses when they're being
Posted Sales Invoice cancelled. When a business cancels the
stamp on an invoice, Business Central
shows an In Progress status until
someone from SAT either approves or
rejects the cancellation. The status that
shows next depends on what’s done
on the SAT side. If SAT approves the
cancellation, the status of the
electronic invoice becomes cancelled.
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2022 release wave 2 (release from October 2022 through March 2023), find the link to the release plan
here.
Upgrade to 21.4
Please note that new customers will automatically get the latest builds of Business Central (21.4). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Impor tant: Take action before March 1 to retain your delegated admin access to your customers
Earlier this year, Microsoft Partner Center introduced Granular Delegated Administration Privileges (GDAP) as
replacement for Delegated Administration Privileges (DAP) to enable partner-customer relationships that are
time-bound and have more granular access rights. The timeline to migrate your existing DAP relationships to
GDAP has been moved to March 1, 2023. If you do not take action by this date you will lose access to your
customers' Business Central environments. Please refer to the Partner Center announcement here.
Release plan for 2023 release wave 1 is now live
The release plan for Business Central 2023 release wave 1 is live! Check out the product overview and what's
new and planned for Business Central here: https://aka.ms/BCReleasePlan.
Join us for updates on LinkedIn!
Follow the new company page for Microsoft Dynamics 365 Business Central on LinkedIn. We’ll share updates,
announcements, and other “good to know” stuff. Join us here.
Business Central newsletter for par tners
Yay! We're doing quarterly newsletters for Business Central partners. Each newsletter contains a summary of
relevant information related to Business Central. You can find it on aka.ms/BCNews.
Upcoming Business Central Office Hours Calls
In January and February, we will be hosting the following calls, which you can already register for today:
Februar y 7: Power Platform integrations
March 14: Onboarding your customers to Business Central
Register and stay tuned for upcoming calls: aka.ms/BCOfficeHours. Watch on-demand recordings:
aka.ms/BCOfficeHoursRecordings.
Discover resources on aka.ms/BCAll
Are you looking for relevant resources? Find it all in this article aka.ms/BCAll and remember to bookmark it!
Update 21.3 for Microsoft Dynamics 365 Business
Central online 2022 release wave 2
2/6/2023 • 4 minutes to read • Edit Online
Would you like to know what has changed in update 21.3? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article and the downloads here.
Feature changes
Reuse launch configurations across workspace projects
Media/image support for Business Central connectors
Power Apps and Power Automate support for document attachments
Reverse payment reconciliation journal entries
Access attachments on additional list pages
Scroll through more records in lists
Localization updates
C O UN T RY F EAT URE DESC RIP T IO N
Switzerland Enabling QR-Bill file that does not Swiss companies now can use QR bills
report Amount and other information with and without invoice amounts. If
user chooses option with amount,
system will automatically populate the
Amount field, but if user chooses
option without amount, the Amount
field will be editable and user can
populate it manually.
France, United Kingdom Intrastat localization extensions New Intrastat feature is now available
in France and United Kingdom.
W1 Changing VAT date with more entries When users have more VAT Entries for
for one document one document with different VAT
percentages, and they want to change
VAT date, they need to do only on one
entry and the system will update to
the other entries for the same
document.
W1 Disabling VAT date functionality fully or Users now can choose to use full VAT
partially date functionality or just partially
without changing VAT dates in posted
entries and documents. And
eventually, users can choose not to use
VAT date functionality, hiding and
making noneditable VAT fields from UI.
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2022 release wave 2 (release from October 2022 through March 2023), find the link to the release plan
here.
Upgrade to 21.3
Please note that new customers will automatically get the latest builds of Business Central (21.3). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Reverse payment reconciliation journal entries
With 21.3. you can reverse payment reconciliation journals that were used to also post a bank reconciliation.
With 21.4, we will enable reversal of regular payment reconciliation journals.
Shopify connector becomes extensible: Stock calculation
Shopify Connector has been non-extensible, but we're changing that. We're offering a few points of extensibility.
We'll keep the number of points to a minimum so that we can follow the rapid development on the Shopify side
without introducing breaking changes.
We are opening for extensibility for specific scenarios, based on feedback from our partners and customers
starting with Stock calculation .
For more details, please follow this repository on GitHub. Note that even though extensibility is limited, you can
submit improvements directly.
Power Apps and Power Automate suppor t for media/image and document attachments
Business Central connector (online only) for Power Platform and Azure Logic Apps has been enhanced with new
capabilities and actions to allow makers to access rich data from Business Central. Note that the updated
connector is rolling out to all Azure regions now and is backward compatible with latest Business Central online
versions (including version 21.3 discussed here), but in order to take advantage of these new capabilities in
Power Automate flows the user needs to create a new flow using the new action discussed here.
You can still watch the Business Central Launch Event recordings
We have 15+ What's New sessions and recorded Q&As available throughout January 2023. If you didn't watch
them yet, you can still go to aka.ms/BCLE to sign up. In November, two new sessions have been published for
the following topics: Embed Business Central in Teams tabs and Access Business Central with your Microsoft 365
license.
AL-Go for GitHub version 2.2
Version 2.2 of AL-Go for GitHub has been released with improved multi-project support and a few fixes in the
Pull Request workflow. See what has been added and changed in the v2.2 column in [aka.ms/AlGoRoadmap].
Impor tant: Take action before March 1 to retain your delegated admin access to your customers
Earlier this year, Microsoft Partner Center introduced Granular Delegated Administration Privileges (GDAP) as
replacement for Delegated Administration Privileges (DAP) to enable partner-customer relationships that are
time-bound and have more granular access rights. The timeline to migrate your existing DAP relationships to
GDAP has been moved to March 1, 2023. If you do not take action by this date you will lose access to your
customers' Business Central environments. Please refer to the Partner Center announcement here.
Business Central newsletter for par tners
Yay! We're doing quarterly newsletters for Business Central partners. Each newsletter contains a summary of
relevant information related to Business Central. You can find it on aka.ms/BCNews.
Upcoming Business Central Office Hours Calls
In January and February, we will be hosting the following calls, which you can already register for today:
Januar y 17: AL-Go for GitHub
Januar y 24: Onboarding your customers to Business Central
Februar y 7: Power Platform integrations
Register and stay tuned for upcoming calls: aka.ms/BCOfficeHours. Watch on-demand recordings:
aka.ms/BCOfficeHoursRecordings.
Discover resources on aka.ms/BCAll
Are you looking for relevant resources? Find it all in this article aka.ms/BCAll and remember to bookmark it!
Update 21.2 for Microsoft Dynamics 365 Business
Central online 2022 release wave 2
2/6/2023 • 4 minutes to read • Edit Online
Would you like to know what has changed in update 21.2? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article and the downloads here.
Feature changes
Use default attachments in email sent from Business Central
Easily comply with email sending limits through email throttling
Move custom fields to extensions during cloud migration
Integrated session using Service-to-Service (S2S) authentication can now schedule tasks
Localization updates
C O UN T RY F EAT URE DESC RIP T IO N
United States IRS 1099 Form Update for 2022 With this release, Form 1099 in the
United States has been updated to
fulfill 2022 year requirements for
reporting to IRS.
Mexico Extending CFDI with foreign trade With new release Business Central will
include the information to fill the
foreign trade details in the file, which is
mandatory by the SAT if a customer
performs an export to a foreign
country.
The Netherlands Added configuration for Electronic Tax Setup is extended so now users have
Declaration the endpoints setup under the new
“Endpoints” tab instead of hardcoded
endpoints. This change also includes
an upgrade Codeunit that fills the
value in this setup for the existing
tenants.
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2022 release wave 2 (release from October 2022 through March 2022), find the link to the release plan
here.
Upgrade to 21.2
Please note that new customers will automatically get the latest builds of Business Central (21.2). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Use Ser vice Suppor t Administrator role to manage suppor t requests on behalf of your customers
To better support this principle and align with the expectations of our customers, especially the Business Central
customers working with other Dynamics 365 products, together with the Power Platform Admin Center team
we introduce support for the Service Support Administrator role which gives access to manage support
requests on the customer's behalf. If you need to log support tickets on behalf of your customers using Power
Platform Admin Center, make sure you request this role in your GDAP relationship.
You can still watch the Business Central Launch Event recordings
We have 15+ What's New sessions and recorded Q&As available throughout January 2023. If you didn't watch
them yet, you can still go to aka.ms/BCLE to sign up. In November, two new sessions have been published for
the following topics: Embed Business Central in Teams tabs and Access Business Central with your Microsoft 365
license.
AL-Go for GitHub version 2.2
Version 2.2 of AL-Go for GitHub has been released with improved multi-project support and a few fixes in the
Pull Request workflow. See what has been added and changed in the v2.2 column in [aka.ms/AlGoRoadmap].
Impor tant: Take action before March 1 to retain your delegated admin access to your customers
Earlier this year, Microsoft Partner Center introduced Granular Delegated Administration Privileges (GDAP) as
replacement for Delegated Administration Privileges (DAP) to enable partner-customer relationships that are
time-bound and have more granular access rights. The timeline to migrate your existing DAP relationships to
GDAP has been moved to March 1, 2023. If you do not take action by this date you will lose access to your
customers' Business Central environments. Please refer to the Partner Center announcement here.
Business Central Performance toolkit VSCode extension
The Performance Toolkit extension is built for Independent Solution Vendors (ISVs) and Value Added Resellers
(VARs) who develop vertical solutions and customize Business Central for their customers. Because things
change between released versions, it's important that ISVs and VARs can test the performance of their solutions
to ensure that new versions don't introduce performance regressions when the volume of users grows. To help,
the Performance Toolkit lets developers simulate workloads in realistic scenarios to compare performance
between builds of their solutions. The Performance Toolkit extension helps answer questions such as, "Does my
solution for Business Central support X number of users doing this, that, and the other thing at the same time?".
Learn more here.
Business Central newsletter for par tners
Yay! We're doing quarterly newsletters for Business Central partners. Each newsletter contains a summary of
relevant information related to Business Central. You can find it on aka.ms/BCNews.
Upcoming Business Central Office Hours Calls
In December and January, we will be hosting the following calls, which you can already register for today:
December 13: Troubleshooting performance problems
Januar y 17: Exporting your Dynamics 365 Business Central data to the Azure Data Lake Storage
Januar y 24: Onboarding your customers to Business Central
Register and stay tuned for upcoming calls: aka.ms/BCOfficeHours. Watch on-demand recordings:
aka.ms/BCOfficeHoursRecordings.
Discover resources on aka.ms/BCAll
Are you looking for relevant resources? Find it all in this article aka.ms/BCAll and remember to bookmark it!
Update 21.1 for Microsoft Dynamics 365 Business
Central online 2022 release wave 2
2/6/2023 • 4 minutes to read • Edit Online
Would you like to know what has changed in update 21.1? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Feature changes
Access Business Central with your Microsoft 365 license
Embed Business Central in Teams tabs
Auto-Save as you work: due to popular demand, administrators can now choose to turn on or off the new
auto-saving behaviour using Feature Management
Business Central is available in 11 more countries
Accessibility declaration for Italy available
Use SharePoint Connector module in System Application to build integration between Business Central and
Sharepoint
Use multiline text fields with Word mail merge
Sync users based on environments security group
Localization updates
C O UN T RY F EAT URE DESC RIP T IO N
United States IRS 1099 All IRS 1099 form printouts are
updated accordingly with 2022
requirements. When users open the
1099 Form Boxes page, they will see
the notification about update to 2022
release. They can schedule an upgrade
and when it is finished, new reports
will be available for usage.
The Netherlands Electronic Tax Declaration Setup Previously used hardcoded endpoints
for electronic tax declaration have been
moved to the setup under the new
“Endpoints” tab, so users now can
configure endpoints manually. It will be
deployed to 21.1 tenants. But for
them, the upgrade would not be
executed, and they will see all the
values blank. But Digipoort solution
still would work and take the
hardcoded values if there are no values
in the setup. For 21.2 the system will
automatically run an upgrade.
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2022 release wave 2 (release from October 2022 through March 2022), find the link to the release plan
here.
Upgrade to 21.1
Please note that new customers will automatically get the latest builds of Business Central (21.1). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
You can still watch the Business Central Launch Event recordings
We have 15+ What's New sessions and recorded Q&As available throughout January 2023. If you didn't watch
them yet, you can still go to aka.ms/BCLE to sign up. In November, two new sessions have been published for
topics: Embed Business Central in Teams tabs and Access Business Central with your Microsoft 365 license.
Business Central at Ignite
At the Microsoft Ignite event on October 12, we unveiled new and exciting collaboration features for SMBs that
usher in a new era for collaborative applications. Check out the announcements in the Microsoft Ignite Book of
News and Dynamics 365 blog to learn how our customers can leverage 2022 release wave 2 to work smarter,
increase team performance, and quickly adapt their digital collaborative spaces to make data-driven decisions.
Impor tant: Take action before March 1 to retain your delegated admin access to your customers
Earlier this year, Microsoft Partner Center introduced Granular Delegated Administration Privileges (GDAP) as
replacement for Delegated Administration Privileges (DAP) to enable partner-customer relationships that are
time-bound and have more granular access rights. The timeline to migrate your existing DAP relationships to
GDAP has been moved to March 1, 2023. If you do not take action by this date you will lose access to your
customers' Business Central environments. Please refer to the Partner Center announcement here.
New versions of the Business Central mobile app for Android and iOS
New, updated 3.8.xxxx versions of the Business Central mobile app for Android and iOS have been released
featuring support for additional Business Central localization, some minor improvements an fixes and newest
requirements from mobile OS releases. Please note the required minimum supported versions of both
iOS/iPadOS and Android (currently Android 10 is required for Business Central mobile app). Please keep your
mobile app updated by downloading the update. Links:
iOS/iPadOS on App Store: https://go.microsoft.com/fwlink/?LinkId=734847
Android on Play Store: https://go.microsoft.com/fwlink/?LinkId=734849
Business Central newsletter for par tners
Yay! We're now doing quarterly newsletters for Business Central partners. Each newsletter will be a summary of
relevant information related to Business Central and you'll be able to find it on aka.ms/BCNews.
Upcoming Business Central Office Hours Calls
In November, we will be hosting the following calls, which you can already register for today:
November 15: Non-deductible and partly deductible VAT
November 22: Access Business Central using your Microsoft 365 license
Register and stay tuned for upcoming calls: aka.ms/BCOfficeHours. Watch on-demand recordings:
aka.ms/BCOfficeHoursRecordings.
Discover resources on aka.ms/BCAll
Are you looking for relevant resources? Find it all in this article aka.ms/BCAll and remember to bookmark it!
Update 20.6 for Microsoft Dynamics 365 Business
Central online 2022 release wave 1
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 20.6? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2022 release wave 1 (release from April 2022 through September 2022), find the link to the release plan
here.
Upgrade to 20.6
Please note that new customers will automatically get the latest builds of Business Central (20.5). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Join us for the Business Central Launch Event on October 10-12, 2022
Dynamics 365 Business Central 2022 release wave 2 will be released on October 3, after which new customers
will be able to sign up for version 21 of Business Central. To learn all about what's new in the latest release, we're
again bringing the latest innovations for Business Central to you via an all-access digital experience.
The Business Central Launch Event will take place from October 10-12, 2022. During the three days, you’ll be
able to watch sessions, ask questions and participate in live Q&As. After October 12, all sessions will be
available on-demand until January 2023.
Register now : aka.ms/BCLE
Impor tant: Take action before October 31 to retain your delegated admin access to your
customers
With this Partner Center announcement earlier this year, Microsoft introduced the Granular Delegated Admin
Privileges (GDAP) feature. GDAP addresses various security concerns by allowing customer administrators to
provide partners a proper level of time-bound access to their tenants.
The Partner Center team has now announced the timeline by which you need to migrate your customer
relationship to GDAP. Please make sure to read this new Partner Center announcement for more details about
milestone dates and the transition plan, as well as about the tools Microsoft provides to facilitate this process.
To manage Dynamics 365 Business Central customers via GDAP we recommend requesting the Dynamics 365
Administrator role as the least-privileged role. Read more about which other roles are supported for delegated
administration of Business Central here.
You can watch the GDAP Office Hours recording for Business Central here.
Business Central newsletter for par tners
Yay! We're now doing quarterly newsletters for Business Central partners. Each newsletter will be a summary of
relevant information related to Business Central and you'll be able to find it on aka.ms/BCNews.
Upcoming Business Central Office Hours Calls
In September and October, we will be hosting the following calls, which you can already register for today:
October 4: Get data-driven with Telemetry
November 11: Performance
Register and stay tuned for upcoming calls: aka.ms/BCOfficeHours. Watch on-demand recordings:
aka.ms/BCOfficeHoursRecordings.
Discover resources on aka.ms/BCAll
Are you looking for relevant resources? Find it all in this article aka.ms/BCAll and remember to bookmark it!
Update 20.5 for Microsoft Dynamics 365 Business
Central online 2022 release wave 1
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 20.5? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2022 release wave 1 (releases from April 2022 through September 2022), find the link to the release plan
here.
Upgrade to 20.5
Please note that new customers will automatically get the latest builds of Business Central (20.5). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Impor tant: Take action before October 31 to retain your delegated admin access to your
customers
With this Partner Center announcement earlier this year, Microsoft introduced the Granular Delegated Admin
Privileges (GDAP) feature. GDAP addresses various security concerns by allowing customer administrators to
provide partners a proper level of time-bound access to their tenants.
The Partner Center team has now announced the timeline by which you need to migrate your customer
relationship to GDAP. Please make sure to read this new Partner Center announcement for more details about
milestone dates and the transition plan, as well as about the tools Microsoft provides to facilitate this process.
To manage Dynamics 365 Business Central customers via GDAP we recommend requesting the Dynamics 365
Administrator role as the least-privileged role. Read more about which other roles are supported for delegated
administration of Business Central here.
You can watch the GDAP Office Hours recording for Business Central here.
Plan and prepare for Dynamics 365 Business Central 2022 release wave 2
The preview of Dynamics 365 Business Central 2022 release wave 2 will go live on August 31. Use Microsoft
Collaborate to submit your feedback or to report any potential issues that you discover in the preview. Discover
how to do so here: aka.ms/BCPreview. In addition, we have created a new subgroup on Yammer called Public
Preview 2022 release wave 2, which can be used to share feedback directly with the Microsoft product team or
ask questions related to the preview.
On October 1, 2022, the release will go live. You can discover what's new and planned here:
aka.ms/BCReleasePlan
Business Central newsletter for par tners
Yay! We're now doing quarterly newsletters for Business Central partners. Each newsletter will be a summary of
relevant information related to Business Central and you'll be able to find it on aka.ms/BCNews.
Upcoming Business Central Office Hours Calls
In September and October, we will be hosting the following calls, which you can already register for today:
September 6: Power Automate and Power Platform integrations
September 20: How we secure your data in Business Central
October 4: Get data-driven with telemetry
Register and stay tuned for upcoming calls: aka.ms/BCOfficeHours. Watch on-demand recordings:
aka.ms/BCOfficeHoursRecordings.
Discover resources on aka.ms/BCAll
Are you looking for relevant resources? Find it all in this article aka.ms/BCAll
Update 20.4 for Microsoft Dynamics 365 Business
Central online 2022 release wave 1
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 20.4? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Feature changes
Current user support for the SMTP email connector
Shopify prospects get a great first-run experience
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2022 release wave 1 (release from April 2022 through September 2022), find the link to the release plan
here.
Upgrade to 20.4
Please note that new customers will automatically get the latest builds of Business Central (20.4). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Plan and prepare for Dynamics 365 Business Central 2022 release wave 2
In October 2022, the new release will go live. You can already discover what's new and planned in the release
plan here: aka.ms/BCReleasePlan
Business Central newsletter for par tners
Starting June 2022, we're doing quarterly newsletters for Business Central partners. Each newsletter will be a
summary of relevant information related to Business Central and you'll be able to find it on aka.ms/BCNews.
Discover resources on aka.ms/BCAll
Are you looking for relevant resources? Find it all in this article and remember to bookmark aka.ms/BCAll.
Upcoming Business Central Office Hours Calls
For August and September, we will be hosting the following calls, which you can register for today:
August 23: Excel Layout and reporting
August 30: You know it, so share it in Microsoft Docs for Dynamics 365 Business Central
September 6: Power Automate and Power Platform integrations
Register and stay tuned for upcoming calls: aka.ms/BCOfficeHours. Watch on-demand recordings:
aka.ms/BCOfficeHoursRecordings.
Update 20.3 for Microsoft Dynamics 365 Business
Central online 2022 release wave 1
2/6/2023 • 3 minutes to read • Edit Online
Would you like to know what has changed in update 20.3? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we've gathered some good
to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Feature changes
Improved settings for managing updates (read more here)
New AppSourceCop allowing you to run validation to determine any code hit by obsoleted objects for a
given future version
As continuation for Support inventory pick and warehouse pick operations for jobs, we introduce a To-Job
Bin Code field on the Location Card page to support warehouse pick scenarios. You can also use it in
inventory picks if you prefer a specific bin to be set on a job planning line.
Localization updates
C O UN T RY F EAT URE DESC RIP T IO N
W1 Extended text functionality for VAT In some situations and countries, VAT
clauses Clauses can take more than allowed
number of characters. Because of that
Extended Texts logic is implemented in
the VAT Clauses and this extended text
can be shown on the sales invoice.
Germany Enhancements to Business Data Export Export file will use table and field
file (GDPdU / GoDB) names instead of captions. Also table
and field names won't be limited to 20
characters and it will show full name,
with blanks, dots, etc.
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2022 release wave 1 (releases from April 2022 through September 2022), find the link to the release plan
here.
Upgrade to 20.3
Please note that new customers will automatically get the latest builds of Business Central (20.3). If you're an
existing partner/customer, you'll receive an email notification as soon as your environment has been upgraded.
Good to know
A single tile to go to Business Central
During July 2022, we're rolling out a change to online customers where a single Business Central tile in the App
Launcher will be used to access both production and sandbox environments. Learn more here.
UI glitches introduced by recent browser updates
On Wednesday June 29, 2022, Microsoft began rolling out a fix for all Business Central online customers that
addresses UI glitches introduced by a recent Chromium browser update. The fix will also be included in
cumulative updates for supported versions of Business Central on premises. Learn how on premises customers
can fix or work around the issue here.
General availability of the Shopify Connector
In October 2021, we announced a new partnership with Shopify to help our customers create a better shopping
experience. The partnership was designed to better connect the easy-to-use commerce and merchant
experience of Shopify with the comprehensive business management capabilities of Microsoft Dynamics 365
Business Central. The Shopify connector is now available for Business Central online at no extra cost. Existing
customers that have been upgraded to 20.1 or later automatically get the Shopify extension installed. If they
don't need the app, it can be uninstalled by following this guidance. Read the blog, the FAQ, watch the on-
demand session, learn how to get started and view the listing on Shopify App Store.
Action required by July 2022 for Excel Add-in
Starting in July 2022, Microsoft will roll out an update to the Excel add-in that further secures the connection to
Business Central. The update requires that you modify your organization's Azure Active Directory (Azure AD)
configuration so that users can continue using the add-in. This issue impacts all Business Central on-premises
deployments that use the Excel add-in. Learn more here.
Business Central newsletter for par tners
Starting June 2022, we're doing quarterly newsletters for Business Central partners. Each newsletter will be a
summary of relevant information related to Business Central and you'll be able to find it on aka.ms/BCNews.
Discover resources on aka.ms/BCAll
Are you looking for relevant resources? Find it all in this article and remember to bookmark aka.ms/BCAll.
Upcoming Business Central Office Hours Calls
The Business Central office hours calls will be unavailable in July. For August and September, we'll be hosting the
following calls, which you can register for today:
August 23: Excel Layout and reporting
August 30: You know, so share it in the docs for Dynamics 365 Business Central
September 6: Power Automate and Power Platform integrations
Register and stay tuned for upcoming calls: aka.ms/BCOfficeHours. Watch on-demand recordings:
aka.ms/BCOfficeHoursRecordings.
Update 20.2 for Microsoft Dynamics 365 Business
Central online 2022 release wave 1
2/6/2023 • 3 minutes to read • Edit Online
Would you like to know what has changed in update 20.2? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Feature changes
Release and reopen multiple documents
Localization updates
C O UN T RY F EAT URE DESC RIP T IO N
W1 New field, Intrastat Par tner Type , The Intrastat Partner Type field has
on customer and vendor cards replaced the Parter Type field in
Intrastat reporting. Partner Type is
used in SEPA to define the SEPA Direct
Debit Scheme (Core or B2B). Intrastat
Partner Type is used for Intrastat
reporting only. This way, users can
specify different values for the two
fields if they need to. More details
about setup here.
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2022 release wave 1 (release from April 2022 through September 2022), find the link to the release plan
here.
Upgrade to 20.2
Please note that new customers will automatically get the latest builds of Business Central (20.2). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
General availability of the Shopify Connector
Last October, we announced a new partnership with Shopify to help our customers create a better shopping
experience. The partnership was designed to better connect the easy-to-use commerce and merchant
experience of Shopify with the comprehensive business management capabilities of Microsoft Dynamics 365
Business Central. The Shopify connector is now available for the online version of Business Central at no extra
cost. Existing customers that have been upgraded to 20.1 automatically get the Shopify extension installed. If
they do not need the app, it can be uninstalled by following this guidance. Read the blog, the FAQ, watch the on-
demand session, learn how to get started and view the listing on Shopify App Store.
A single tile to go to Business Central
We're simplifying access to Business Central online by transitioning to a single app tile starting in June 2022.
Learn more here.
Action required by July 2022 for Excel Add-in
Starting in July 2022, Microsoft will roll out an update to the Excel add-in that further secures the connection to
Business Central. The update requires that you modify your organization's Azure Active Directory (Azure AD)
configuration so that users can continue using the add-in. This impacts all Business Central on premises
deployments that use the Excel add-in. Learn more here.
Changes to the Per-Tenant Extensions Disclaimer
The disclaimer for per-tenant extensions has changed. Find the new Business Central PTE disclaimer here.
Upcoming Business Central Office Hours Calls
Join us for the upcoming office hours call on “Introducing Shopify for Business Central” on June 14 and
“Onboarding your customers to Business Central” on June 21 (Note: we will have two time slots, an early one
and a later one for the two calls). Register and stay tuned for upcoming calls: aka.ms/BCOfficeHours. Watch on-
demand recordings: aka.ms/BCOfficeHoursRecordings.
Business Central Launch Event
If you haven't watched them yet, remember that you still have access to a keynote and 20+ sessions about
what's new in Business Central 2022 release wave 1. You'll hear from product leaders as they share with you the
latest innovations and capabilities to help you confidently move to the cloud and unlock the insights needed to
adapt faster, work smarter, and perform better. Whether you are a business professional, developer, or
consultant at a Business Central partner, get ready to up level your game and drive business transformation.
Register on aka.ms/BCLE
Update 20.1 for Microsoft Dynamics 365 Business
Central online 2022 release wave 1
2/6/2023 • 5 minutes to read • Edit Online
Would you like to know what has changed in update 20.1? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Feature changes
Add action on card and list pages to trigger a chosen flow from Business Central web client
Power Platform and Azure Logic Apps connector for Business Central online no longer in preview
Fraud prevention headers for clients in the UK
Country/regional expansion in 20 new countries
Localization updates
C O UN T RY F EAT URE DESC RIP T IO N
Spain Posting Date or Document Date to be The user is now able to choose
used as Operation Date between Posting Date or Document
Date, to be used as Operation Date in
the XML sent via SII to the Tax
Authorities.
Denmark; W1 Country code in the VAT Registration In Denmark companies need to use
No. usage for Intrastat reporting different VAT Registration No. models
in Intrastat and Skat.dk (one with
Country Code and another without it).
To avoid issues for Stat.dk clients will
use only value from VAT Registration
No., but for intrastat clients will have
additional configuration with the
following options: VAT Reg. No.,
Country Code + VAT No., VAT No.
without Country Code. This feature is
available on W1.
C O UN T RY F EAT URE DESC RIP T IO N
France Intrastat FR new requirements for DEB For France, Intrastat management
2022 implies to separate the declaration
data for the statistical reporting and
for the fiscal reporting (recapitulative
statement of VAT), once for obligation
level 1 and once for obligation level 4.
Norway Add support of the free text for each This is an improvement of the existing
VAT return line feature. Previously, Business Central
only supported export of a list of the
predefined texts in the field "VAT Note
Code". Now the user can export the file
with added free text for each VAT
return line.
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online in 2022
release wave 1 (release from April 2022 through September 2022), find the link to the release plan here.
Good to know
Shopify Connector
Microsoft is teaming up with Shopify to help our Dynamics 365 Business Central customers create a better
online shopping experience. With update 20.1, the Shopify Connector is available for new customers and for
trial users to try it out. For existing customers, the Shopify connector will become available later in May,
releasing on AppSource and Shopify App Store. Read more here.
Changes to the Per-Tenant Extensions Disclaimer
The disclaimer for per-tenant extensions has changed. Find the new Business Central PTE disclaimer here.
Updated documentation and samples related to Power Automate
Documentation related to Power Automate integration and the new Automate feature has been updated in
May 2022 and is available at aka.ms/BCAutomate. There are also some sample flows published in our github
repository – find it under aka.ms/BCTech. We also recommend watching the What’s new in Business Central and
Power Platform session at he Business Central Virtual Launch Event. Find it on aka.ms/BCLE.
Discover the features for 2022 release wave 1
Discover what's new and planned for Dynamics 365 Business Central 2022 release wave 1. You can find the list
of features here: aka.ms/BCReleasePlan.
Reminder : Avoid an unexpected data upgrade during cloud migration
When you run cloud migration from a previous version of Business Central, one of the process steps is to run
the data upgrade logic to align the migrated data to the format of the current version. We strongly recommend
that you perform this step one time after you have completed the migration of all your customer’s data to the
online environment. If a planned Business Central major or minor update is applied to this environment, the
update will automatically include the upgrade of the data that was migrated by the cloud migration. These
planned updates also turn off cloud migration for the environment. To avoid this situation, and to allow you to
complete the migration and data upgrade for your environment, we recommend that you postpone any
scheduled major and minor updates for the target environment until you have completed cloud migration. You
can postpone updates in the Business Central admin center. For more information, see Managing Updates.
Upcoming Business Central Office Hours Calls
Join us for the upcoming office hours call on “Extending Business Central’s Email Capabilities” on May 24.
Register and stay tuned for upcoming calls: aka.ms/BCOfficeHours. Watch on-demand recordings:
aka.ms/BCOfficeHoursRecordings.
A new update to the Business Central mobile app for iOS and Android
There is a new update for the Business Central mobile app (version 3.7) for iOS and Android available in
respective app stores. This app – as before – handles Business Central online and on-premises and the update is
required for on-premises customers running Business Central 2022 release wave 1.
The legacy Windows desktop app based on UWP technology only suppor ts legacy on-premises
Business Central
Just an update that the Business Central desktop legacy UWP app version 3.6.3101 has been released to the
Microsoft Store - and marked as a mandatory update for Windows users.
From now on users of Windows devices will only be able to use that legacy UWP app to connect to on-
premises Business Central installations v19 or below. For v20 and later on-premises - see next point.
On-premises users of Business Central v20 or later will be able to use the PWA app installed from the
browser directly (see aka.ms/BCPWA for more).
All online Business Central users regardless of the version can use the new PWA app installed from the
browser OR from the Microsoft store (again, see aka.ms/BCPWA for more).
It is recommended to switch to the PWA technology as this is where customers can benefit fully from all web
client features.
Update 19.5 for Microsoft Dynamics 365 Business
Central online 2021 release wave 2
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 19.5? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Localization updates
C O UN T RY F EAT URE DESC RIP T IO N
Norway Updated SAF-T export Fixed issue with exporting bank data in
SAF-T in accordance with
BankAccountStructure
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2021 release wave 2 (release from October 2021 through March 2022), find the link to the release plan
here.
Upgrade to 19.5
Please note that new customers will automatically get the latest builds of Business Central (19.5). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Discover the features for 2022 release wave 1
Discover what's new and planned for Dynamics 365 Business Central 2022 release wave 1. You can find the list
of features here: aka.ms/BCReleasePlan.
Avoid an unexpected data upgrade during cloud migration
When you run cloud migration from a previous version of Business Central, one of the process steps is to run
the data upgrade logic to align the migrated data to the format of the current version. We strongly recommend
that you perform this step one time after you have completed the migration of all your customer’s data to the
online environment. If a planned Business Central major or minor update is applied to this environment, the
update will automatically include the upgrade of the data that was migrated by the cloud migration. These
planned updates also turn off cloud migration for the environment. To avoid this situation, and to allow you to
complete the migration and data upgrade for your environment, we recommend that you postpone any
scheduled major and minor updates for the target environment until you have completed cloud migration. You
can postpone updates in the Business Central admin center. For more information, see Managing Updates.
Upcoming Business Central Office Hours Calls
Make sure to join the office hours call 'Business Central apps in AppSource' on March 8. The call is at 5.00pm -
6.00pm CET / 08.00am -09.00am PST. Register and stay tuned for upcoming calls: aka.ms/BCOfficeHours. Watch
on-demand recordings: aka.ms/BCOfficeHoursRecordings.
Action needed: Client secret-based ser vice to ser vice authentication deprecation for Microsoft
hosted tenants integrating to Dataverse
To ensure no disruptions in integration between Business Central and Dataverse you must upgrade your
Business Central connection to Dataverse to certificate-based authentication.
The change will happen in March 2022. We strongly recommend you perform steps outlined in Upgrade
Connections from Business Central Online to Use Certificate-Based Authentication as soon as possible.
Join Directions NA on April 3-6, 2022
Directions North America is a Microsoft Dynamics 365 event driven by Partners – for Partners. Attendees will
build new business contacts, learn about best practices, and discover valuable tools for execution and success.
Attendees can also use the many networking opportunities at the conference to grow and enhance relationships
with other partners, ISVs, service providers, and Microsoft. Learn more and register here.
Update 19.4 for Microsoft Dynamics 365 Business
Central online 2021 release wave 2
2/6/2023 • 4 minutes to read • Edit Online
Would you like to know what has changed in update 19.4? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Feature changes
Allow Delegated Admin to setup and run Cloud Migration with approval from a licensed user
Localization updates
C O UN T RY F EAT URE DESC RIP T IO N
Norway February update for the Electronic VAT Various changes made for the existing
return submission feature Norwegian feature have been made:
Fix issue with opening service
connections when Electronic VAT Setup
does not exist, Fix issue with validating
the sign of VAT Statement Report Line
when VAT Code has "SAF-T VAT Code"
specified, Add missed VAT code “1T”,
and Add possibility to copy reporting
codes to SAF-T codes
Germany Improvement of the visibility of the We have added a possibility to see the
Elster xml file’s content amounts from the resulted Elster xml
file
Italy Intrastat changes Two new fields have been added to the
Intrastat export: Nature of transaction
and Country of origin. Section 5 “call-
of-stock” is not supported in Business
Central, however in the export file an
extra line has been added to Section 5
with all fields blank, for the reason of
keeping the fixed length structure of
the file format.
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2021 release wave 1 (release from April 2021 through September 2021), find the link to the release plan
here.
Upgrade to 19.4
Please note that new customers will automatically get the latest builds of Business Central (19.4). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Discover the features for 2022 release wave 1
Discover what's new and planned for Dynamics 365 Business Central 2022 release wave 1. You can find the list
of features here: aka.ms/BCReleasePlan.
o Use secondar y read-only database for Power BI repor ting
Please note that with newest Power BI Desktop update (expected in late February 2022) all new Business Central
Power BI reports will be now sourced from a secondary, read-only database. This leaves the main database
ready for transactions, which enhances performance of the system. This feature is part of the Power BI connector
for Business Central. After updating Power BI Desktop this feature it's enabled by default for all new reports but
turned off for existing reports. Read more here.
Avoid an unexpected data upgrade during cloud migration
When you run cloud migration from a previous version of Business Central, one of the process steps is to run
the data upgrade logic to align the migrated data to the format of the current version. We strongly recommend
that you perform this step one time after you have completed the migration of all your customer’s data to the
online environment. If a planned Business Central major or minor update is applied to this environment, the
update will automatically include the upgrade of the data that was migrated by the cloud migration. These
planned updates also turn off cloud migration for the environment. To avoid this situation, and to allow you to
complete the migration and data upgrade for your environment, we recommend that you postpone any
scheduled major and minor updates for the target environment until you have completed cloud migration. You
can postpone updates in the Business Central admin center. For more information, see Managing Updates.
Upcoming Business Central Office Hours Calls
Make sure to join the office hours call 'How to use OAuth, when calling Business Central APIs and web services'
on February 22. The call is at 5.00pm - 6.00pm CET / 08.00am -09.00am PST. Register and stay tuned for
upcoming calls: https://aka.ms/BCOfficeHours. Watch on-demand recordings:
https://aka.ms/BCOfficeHoursRecordings.
Action needed: Client secret-based ser vice to ser vice authentication deprecation for Microsoft
hosted tenants integrating to Dataverse
To ensure no disruptions in integration between Business Central and Dataverse you must upgrade your
Business Central connection to Dataverse to certificate-based authentication.
Although change will happen in March 2022, we strongly recommend you perform steps outlined in Upgrade
Connections from Business Central Online to Use Certificate-Based Authentication as soon as possible.
Join Directions NA on April 3-6, 2022
Directions North America is a Microsoft Dynamics 365 event driven by Partners – for Partners. Attendees will
build new business contacts, learn about best practices, and discover valuable tools for execution and success.
Attendees can also use the many networking opportunities at the conference to grow and enhance relationships
with other partners, ISVs, service providers, and Microsoft. Learn more and register here.
Update 19.3 for Microsoft Dynamics 365 Business
Central online 2021 release wave 2
2/6/2023 • 3 minutes to read • Edit Online
Would you like to know what has changed in update 19.3? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Localization updates
C O UN T RY F EAT URE C H A N GE
Thefollowing list provides more information about the new electronic VAT return capabilities in Norway:
Possibility to set up VAT Code in the VAT statement
New VAT codes which can be setup from the wizard
New entities related to the new VAT codes introduced:
VAT specification
VAT Note
You can now store and download multiple submission and response requests
The electronic VAT return only supports numbers. Any VAT registration no. with characters will be
converted into numbers only. A VAT registration no. such as NO 777777 MVA will be reported as 777777.
So you won't need to change the existing VAT registration no. in order to do reporting.
Learn more about Norwegian VAT reporting here.
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2021 release wave 1 (release from April 2021 through September 2021), find the link to the release plan
here.
Upgrade to 19.3
Please note that new customers will automatically get the latest builds of Business Central (19.3). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Upcoming Business Central Office Hours Calls
Make sure to join the office hours call 'How we secure your data in Business Central' on February 1. Note that
this call will be held in two different time zones; first call is at 08.00am-09.00am CET / 06.00pm-07.00 PM AEST
and second call is at 5.00pm-6.00pm CET / 08.00am-09.00am PST. Register and stay tuned for upcoming calls:
https://aka.ms/BCOfficeHours. Watch on-demand recordings: https://aka.ms/BCOfficeHoursRecordings.
Action needed: Client secret-based ser vice to ser vice authentication deprecation for Microsoft
hosted tenants integrating to Dataverse
To ensure no disruptions in integration between Business Central and Dataverse you must upgrade your
Business Central connection to Dataverse to certificate-based authentication. Although change will happen in
March 2022, we strongly recommend you perform steps outlined in Upgrade Connections from Business
Central Online to Use Certificate-Based Authentication as soon as possible.
Join Directions NA on April 3-6, 2022
Directions North America is a Microsoft Dynamics 365 event driven by Partners – for Partners. Attendees will
build new business contacts, learn about best practices, and discover valuable tools for execution and success.
Attendees can also use the many networking opportunities at the conference to grow and enhance relationships
with other partners, ISVs, service providers, and Microsoft. Learn more and register here.
Update 19.2 for Microsoft Dynamics 365 Business
Central online 2021 release wave 2
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 19.2? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article
Feature changes
Use two-dimensional barcodes in reports (Business Central online)
AL compiler diagnostic messages includes URLs
Synchronize multiline text fields between Business Central and Dataverse (and Dynamics 365 Sales)
Localization updates
All countries that use the Intrastat format have been updated to 2022 requirements
MX Carta de Porte 2.0
New VAT Return submission for Norway
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2021 release wave 1 (release from April 2021 through September 2021), find the link to the release plan
here.
Upgrade to 19.2
Please note that new customers will automatically get the latest builds of Business Central (19.2). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Upcoming Business Central Office Hours Calls
Make sure to join the office hours calls 'Universal Code Initiative' on January 11 and 'How we secure your data
in Business Central' on February 1. Note that these calls will be held in two different time zones; first call is at
08.00am-09.00am CET / 06.00pm-07.00 PM AEST and second call is at 5.00pm-6.00pm CET / 08.00am-09.00am
PST. Register and stay tuned for upcoming calls: https://aka.ms/BCOfficeHours. Watch on-demand recordings:
https://aka.ms/BCOfficeHoursRecordings.
Action needed: Client secret-based ser vice to ser vice authentication deprecation for Microsoft
hosted tenants integrating to Dataverse
To ensure no disruptions in integration between Business Central and Dataverse you must upgrade your
Business Central connection to Dataverse to certificate-based authentication. Although change will happen in
March 2022, we strongly recommend you perform steps outlined in Upgrade Connections from Business
Central Online to Use Certificate-Based Authentication as soon as possible.
Business Central Launch Event
On October 18, we released the Business Central Launch Event - an online event with 15 sessions on what's new
in Dynamics 365 Business Central 2021 release wave 2. The sessions are within the following four areas:
Administration and Development, Service and Platform, Better with Microsoft 365 and Modern Client. Register
and watch the 15 sessions now: aka.ms/BCLE.
Apps in AppSource
We now have 2000+ Business Central apps in AppSource! Find all the apps here: Business Central apps in
AppSource.
Update 19.1 for Microsoft Dynamics 365 Business
Central online 2021 release wave 2
2/6/2023 • 4 minutes to read • Edit Online
Would you like to know what has changed in update 19.1? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
IMPORTANT
Builds for Business Central in Ukraine are now released.
Hotfixes
Find an overview of hotfixes in this article.
Feature changes
Copying environments of different types
Operations log enhancements
Restart environments
Support for 2D barcodes
Shipping agent information is copied from sales orders to warehouse shipments
Localization updates
C O UN T RY F EAT URE C H A N GE DO W N LO A D L IN K
Mexico Complement to CFDI “Carta de Porte” Version 2017, Version 2018, Spring
1.0. Mexican companies must be able 2019, 2020 Release Wave 2, 2021
to print and send Carta de Porte- Release Wave 1, 2021 Release Wave 2
compliant packing slips and transfer
orders electronically as Comprobante
Fiscal Digital por Internet (CFDI) files.
As of December 1, 2021, the Waybill
(Carta de Porte) complement is
mandatory for taxpayers who
transport goods and merchandise in
the national territory. Business Central
supports CFDI and Carta de Porte so
that you can print packing slips and
transfer orders that have the required
digital signature.
C O UN T RY F EAT URE C H A N GE DO W N LO A D L IN K
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2021 release wave 1 (release from April 2021 through September 2021), find the link to the release plan
here.
Upgrade to 19.1
Please note that new customers will automatically get the latest builds of Business Central (19.1). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Business Central Office Hours Calls in November
Make sure to watch the office hours call recording on 'Improvements to data synchronization to Dataverse and
Dynamics 365 Sales' from November 9 and join 'Can Business Central Online (SaaS) handle large customers?'
on November 30. Register and stay tuned for the upcoming calls: https://aka.ms/BCOfficeHours. Watch on-
demand recordings: https://aka.ms/BCOfficeHoursRecordings.
Action needed: Client secret-based ser vice to ser vice authentication deprecation for Microsoft
hosted tenants integrating to Dataverse
To ensure no disruptions in integration between Business Central and Dataverse you must upgrade your
Business Central connection to Dataverse to certificate-based authentication. Although change will happen in
March 2022, we strongly recommend you perform steps outlined in Upgrade Connections from Business
Central Online to Use Certificate-Based Authentication as soon as possible.
Business Central Launch Event
On October 18, we released the Business Central Launch Event - an online event with 15 sessions on what's new
in Dynamics 365 Business Central 2021 release wave 2. The sessions are within the following four areas:
Administration and Development, Service and Platform, Better with Microsoft 365 and Modern Client. Register
and watch the 15 sessions now: aka.ms/BCLE.
Find Records action in Power Automate Business Central connector
Coming to you in the coming weeks together with a cloud-based update of Business Central online connector
for Power Automate is a new action allowing to find records based on a value (or any supported OData filter –
more here). This will allow you to create both instant or flows in Power Automate that get a value from the user
or any system in a form of automation, then find data in Business Central and then process data in business
Central. An example of such scenario was shown ad Directions EMEA 2021 in Milan in a form of chatbot hosted
inside Microsoft Teams and built using Power Virtual Agents – that chatbot took an input from the user, found an
item in Business Central and came back with inventory data.
Customer References
We now have 100+ Business Central customer stories on the Microsoft Customer Stories site. These stories
come in handy when prospects ask for reference stories, so remember to bookmark: Microsoft Customer Stories
Search.
AL Compiler Diagnostics
With the latest documentation refresh, the AL compiler diagnostics are published in preview. The AL diagnostics
section lists all of the compiler errors, warnings, etc. that you can get when coding and compiling in AL. The
topics are auto-generated and there is one topic per diagnostic rule, which allows for adding detailed help, hints,
reference, and more. At this point, the topics contain only the error message, and adding more information is
going to be a work in progress. To contribute with content, see instructions in AL Diagnostics.
Update 18.5 for Microsoft Dynamics 365 Business
Central online 2021 release wave 1
2/6/2023 • 3 minutes to read • Edit Online
Would you like to know what has changed in update 18.5? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
IMPORTANT
Builds for Business Central in Türkiye are now live.
Hotfixes
Find an overview of hotfixes in this article.
Feature changes
Extension validation on upgrade
Localization updates
C O UN T RY F EAT URE C H A N GE
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2021 release wave 1 (release from April 2021 through September 2021), find the link to the release plan
here.
Upgrade to 18.5
Please note that new customers will automatically get the latest builds of Business Central (18.4). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Business Central Office Hours Calls in September
Make sure to join the office hours call around 'How to use OAuth, when calling Business Central APIs and web
services' on September 14. Register and stay tuned for the upcoming calls: https://aka.ms/BCOfficeHours.
Action needed: Client secret-based ser vice to ser vice authentication deprecation for Microsoft
hosted tenants integrating to Dataverse
To ensure no disruptions in integration between Business Central and Dataverse you must upgrade your
Business Central connection to Dataverse to certificate-based authentication. Although change will happen in
March 2022, we strongly recommend you perform steps outlined in Upgrade Connections from Business
Central Online to Use Certificate-Based Authentication as soon as possible.
Join Directions EMEA
Directions EMEA is your opportunity to network with other partners in the Dynamics 365 Business Central
community, as well as to attend in-depth application, technical, sales & marketing, and executive sessions about
Business Central, alongside sessions around Power Platform and Dynamics 365 workloads. Microsoft is sending
50+ staff members to cover all areas of Business Central from product development and support to product
overview and future vision. There will be hands-on labs, round tables, and over 100 sessions that will dive into
all areas of the product to help partners be more successful. Microsoft will host keynotes, addressing what’s new
with Business Central, as well as future roadmap.
Conference details:
October 27-29 in Milan
MiCo Milano Convention Center, Piazzale Carlo Magno, 1 – 20149, Milan
Event website: https://directions4partners.com/events/directions-emea/
Customer Consent capabilities for all features that exchange data with 3rd par ty ser vices
Business Central capabilities enable companies to seamlessly integrate with other parties needed to achieve
business goals or statutory obligations.
In the Setup pages for each feature interchanging data from Business Central to another service, the user will
see a text informing that the affected Business Central data might be shared with third party systems and
flowing outside of the organization’s selected geographic boundaries with an option to enable/disable the
feature and therefore get even better control of the data share.
NOTE
If a feature is already made available and used, to avoid disruptions of ongoing business processes, it will remain available
until the administrator takes action to turn it off.
Features in scope:
AMC Banking Fundamentals
EU VAT Reg. No. Validation Service
OCR Services
PayPal Payments Standard
Electronic Invoicing - Tradeshift
Envestnet Yodlee Bank Feeds Service
United Kingdom: Making Tax Digital for VAT Capabilities in Dynamics 365 Business Central
Spain: SII - Invoice and Credit Memo Types in Sales and Purchase Documents
Czech Republic: Core Localization Pack for Czech
Registration number verification
Electronic registration of sales
Currency Exchange Rate
VAT unreliable payer check
Update 18.4 for Microsoft Dynamics 365 Business
Central online 2021 release wave 1
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 18.4? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Localization updates
C O UN T RY F EAT URE C H A N GE
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2021 release wave 1 (release from April 2021 through September 2021), find the link to the release plan
here.
Upgrade to 18.4
Please note that new customers will automatically get the latest builds of Business Central (18.4). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Business Central Office Hours Calls in August
Make sure to join the office hours call around 'Cloud Migration' on August 31. Register and stay tuned for the
upcoming calls: https://aka.ms/BCOfficeHours.
Action needed: Client secret-based ser vice to ser vice authentication deprecation for Microsoft
hosted tenants integrating to Dataverse
To ensure no disruptions in integration between Business Central and Dataverse you must upgrade your
Business Central connection to Dataverse to certificate-based authentication. Although change will happen in
March 2022, we strongly recommend you perform steps outlined in Upgrade Connections from Business
Central Online to Use Certificate-Based Authentication as soon as possible.
Users see notification when they open the obsolete repor ts 204, 205, 206, & 207
Before 2021 release wave 1, we announced that we were planning to replace several reports with newer
versions. As the time approaches for the final clean-up, we start displaying notifications so that the affected
users can take action before Business Central 2021 release wave 2.
If you still use one or more of the deprecated reports, now is the time to start using the recommended reports,
alternatively you can clone the deprecated reports to a custom range, and switch to the cloned reports.
To check if your company uses old reports, search for Repor t Selection – Sales , and check which reports are
configured to be used for Quote, Order, Quote, and Credit Memo. Remember to inspect the content of the
Custom Repor t Selection table (object ID 9657), to detect if these reports are used for specific customers. For
more information, see: View a table object directly from the client. Once you know which customers use these
reports, you can replace them on the Document Layout page for each affected customer, or you can use
configuration packages to update in bulk.
Update 18.3 for Microsoft Dynamics 365 Business
Central online 2021 release wave 1
2/6/2023 • 3 minutes to read • Edit Online
Would you like to know what has changed in update 18.3? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Feature changes
Service-to-service authentication
Dimension issues detection and repair tool
Integration of Word templates
Data administration and cleanup tasks page
Integration of Word templates with interaction templates
Export any list part to Excel
New countries added to the list of supported countries
Business Central Database capacity changes (as of July 1, 2021)
Upgrade to certificate-based Service-to-service (S2S) authentication for Dataverse and Dynamics 365
Integration
Get report (raw data) into Excel from request page (targeting end users) and Save report dataset to excel
from the request page (targeting developers)
Hotfixes
Find an overview of hotfixes in this article.
Localization updates
C O UN T RY F EAT URE C H A N GE
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2021 release wave 1 (release from April 2021 through September 2021), find the link to the release plan
here.
Upgrade to 18.3
Please note that new customers will automatically get the latest builds of Business Central (18.3). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Expor t any List to Excel
In this version an “Open in Excel” action has been added to list parts under the Manage group in action bar. This
is only present if the user or admin enabled the feature via Feature Management, so please make sure you do
that. Read more here.
Two new sessions added to the collection of Business Central Launch Event 2021r w1 recordings
We've added two new sessions to the collection of Business Central Launch Event recordings. The two sessions
are on 'Docker' and 'DevOps Processes for Per Tenant Extensions' with Freddy Kristiansen as the speaker on
both sessions. They can be found here.
Go Local: New Azure data center regions for Switzerland and Nor way
With the Business Central online service, we strive to provide the best experience and performance for our
customers. Therefore, we're moving the environments running on the Swiss version of Business Central to the
Switzerland North Azure region and the environments running on the Norwegian version of Business Central to
the Norway East Azure region. With 2021 release wave 1 minor update 18.3, all newly created Business Central
online environments will be created in the local Azure regions and we will start moving existing customers in
the weeks after release of minor update 18.3. Learn more about supported countries and Azure regions here.
Users see notification when they open the obsolete repor ts 204, 205, 206, & 207
Before 2021 release wave 1, we announced that we were planning to replace several reports with newer
versions. As the time approaches for the final cleaning up, we start displaying notifications so that the affected
users can take action before 2021 release wave 2.
If you still use one or more of the deprecated reports, now is the time to start using the recommended reports,
alternatively you can clone the deprecated reports to a custom range, and switch to the cloned reports.
To check if your company uses old reports, search for Repor t Selection – Sales , and check which reports are
configured to be used for Quote, Order, Quote, and Credit Memo. Remember to inspect the content of the
Custom Repor t Selection table (object ID 9657), to detect if these reports are used for specific customers. For
more information, see: View a table object directly from the client. Once you know which customers use these
reports, you can replace them on the Document Layout page for each affected customer, or you can use
configuration packages to update in bulk.
Action needed: Client secret-based ser vice to ser vice authentication deprecation for Microsoft
hosted tenants integrating to Dataverse
To ensure no disruptions in integration between Business Central and Dataverse you must upgrade your
Business Central connection to Dataverse to certificate-based authentication. Although change will happen in
March 2022, we strongly recommend you perform steps outlined in Upgrade Connections from Business
Central Online to Use Certificate-Based Authentication as soon as possible.
Update 18.2 for Microsoft Dynamics 365 Business
Central online 2021 release wave 1
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 18.2? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
IMPORTANT
Business Central online version 18.2 for India is now available. For more information, see Update 18.2 for Microsoft
Dynamics 365 Business Central 2021 Release Wave 1.
Hotfixes
Find an overview of hotfixes in this article.
Localization updates
C O UN T RY F EAT URE C H A N GE
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2021 release wave 1 (release from April 2021 through September 2021), find the link to the release plan
here.
Upgrade to 18.2
Please note that new customers will automatically get the latest builds of Business Central (18.2). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Available for all countries: Schedule minor updates and receive email notifications
All customers can now receive up-front email notifications seven days in advance and schedule minor updates
of Business Central within 21 days. We enabled this capability for US with 18.1, and are now enabling the same
experience for all other countries with 18.2. Learn more: https://aka.ms/BCUpdates.
New ways of working with Business Central data in Power BI
In the upcoming June update to Power BI Desktop we have included a new connector for Business Central
allowing you to get data faster from Business Central to Power BI. Note the update to Power BI Desktop is
scheduled later in June and you will get it automatically if you have installed Power BI Desktop from Microsoft
Store. Read more about the new capabilities here. Please note that this change is for Business Central online
only.
AboutTitle and AboutText proper ties
We’ve updated AL reference docs with plenty of details, including the list of page combinations where the About
properties have different or no effect. Update 18.2 fully reflects these behaviours.
Business Central Office Hours Calls in June
Make sure to join the office hours calls around 'Working with Dimensions' on June 15 and 'DevOps for Per
Tenant Extensions' on June 29. Register and stay tuned for the upcoming calls: https://aka.ms/BCOfficeHours.
Also, notice that in the month of July, there will be no office hours calls.
Suppor t for migrating data from earlier on-premises versions of Business Central to 2021 release
wave 1 (v.18)
With the Business Central cloud migration tool, customers can migrate their data from earlier on-premises
versions of the product to their online Business Central environment, running on the latest version. We've added
support for customers who are running on Business Central on-premises version 14, 15, 16, or 17 to migrate
their data to version 18 of Business Central online. We've implemented the necessary data upgrade logic in the
cloud migration tool, so customers don't have to upgrade their older version themselves in order to migrate
their data to the latest online release.
Update 18.1 for Microsoft Dynamics 365 Business
Central online 2021 release wave 1
2/6/2023 • 3 minutes to read • Edit Online
Would you like to know what has changed in update 18.1? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
IMPORTANT
Builds for Business Central version 18.1 on-premise are now available. For more information, see Update 18.1 for
Microsoft Dynamics 365 Business Central 2021 Release Wave 1.
Hotfixes
Find an overview of hotfixes in this article.
Feature changes
Editing in Excel more reliably
Support authentication of a SMTP connection using OAuth2
Extension lifecycle telemetry include signal from dependent extensions
Edit active prices in Prices Overview and implement price changes using Price Worksheet
Send documents as emails with any attached files automatically added as email attachments
Localization updates
C O UN T RY F EAT URE C H A N GE
Canada and US Updates for Include Tax with partial shipping and
prepayment credit memo
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2021 release wave 1 (release from April 2021 through September 2021), find the link to the release plan
here.
Upgrade to 18.1
Please note that new customers will automatically get the latest builds of Business Central (18.1). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Suppor t for migrating data from earlier on-premises versions of Business Central to 2021 release
wave 1 (v.18)
With the Business Central cloud migration tool, customers can migrate their data from earlier on-premises
versions of the product to their online Business Central environment, running on the latest version. We've added
support for customers who are running on Business Central on-premises version 14, 15, 16, or 17 to migrate
their data to version 18 of Business Central online. We've implemented the necessary data upgrade logic in the
cloud migration tool, so customers don't have to upgrade their older version themselves in order to migrate
their data to the latest online release.
US customers: Schedule minor updates and receive email notifications
US customers can now receive up-front email notifications seven days in advance and schedule minor updates
of Business Central within 21 days. We have enabled this new capability to be available for US with 18.1, and
plan to enable the same experience for all other countries with 18.2. Stay tuned for updates! Learn more:
https://aka.ms/BCUpdates.
Business Central Office Hours Calls in May
Make sure to join the office hours calls around ‘Report Extensibility’ on May 4 and ‘Snapshot debugging’ on
May 18. Register and stay tuned for the upcoming calls: https://aka.ms/BCOfficeHours.
Business Central Launch Event
You can still watch the 15+ on-demand sessions from the Business Central Launch Event. The sessions revolve
around the new Dynamics 365 Business Central features and capabilities — everything from working with
dimensions, permissions and entitlements, to product announcements and onboarding customers. Register for
free: aka.ms/BCLE.
Updated versions of the Business Central mobile apps are being released to all three stores this
month (covering some fixes and improvements):
Fixed a problem where the Windows UWP desktop/tablet app was sometimes displaying blank screen on
restart
Fixed a problem when iOS mobile app running on-premises in certain conditions required the user to enter
credentials with every login
Fixed a problem with iOS mobile app related to failed download when previewing a report
Fixed a problem with Android mobile app not being able to install on devices where a GPS module was
disabled or missing
Fixed connectivity problems with Business Central cloud
Please download and always use the latest version: Windows (Microsoft Store), iOS (Apple's App Store) or
Android (Google's Play Store). Currently recommended versions of these apps are 3.2.x and 3.3.x (or later).
Update 17.5 for Microsoft Dynamics 365 Business
Central online 2020 release wave 2
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 17.5? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Localization updates
C O UN T RY F EAT URE C H A N GE
Norway SAF-T update: Improved data export for Contact and Post
Code information
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2020 release wave 2 (release from October 2020 through March 2021), find the link to the release plan
here.
Upgrade to 17.5
Please note that new customers will automatically get the latest builds of Business Central (17.5). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Business Central Office Hours Calls in March
Make sure to join the office hours calls around ‘Integrating with Teams’ on March 9 and ‘Business Central apps
in AppSource’ on March 23. Register and stay tuned for the upcoming calls: https://aka.ms/BCOfficeHours.
OData V3 will be removed with 2021 Wave 1
As previously announced, OData Version 3.0 (V3) has been deprecated since April 2020 and support for it will
be removed in Dynamics 365 Business Central 2021 release wave 1. OData V4 is the current recommended
version of OData and current integrations needs to move to OData V4. To identify incoming OData V3 requests,
enable and use the Web Service Request telemetry that's available to partners. Notifications has also been sent
via M365 Message Center to tenants with identified usage.
Basic Authentication
Basic Authentication (Web Service Access Key) removal for Business Central online has been postponed until
April 2022. We see that some integrations needs more time to move from Web Service Access Key usage to
OAuth. PowerShell samples on how to connect to Business Central is published on GitHub.
It’s time to switch your Dynamics 365 Business Central browser to Microsoft Edge
On April 2, 2021, Microsoft will remove Internet Explorer 11 and Microsoft Edge Legacy browsers from the list
of supported browsers for the Business Central modern clients. Read the details, how it applies to you and
actions to take here.
Update 17.4 for Microsoft Dynamics 365 Business
Central online 2020 release wave 2
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 17.4? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Feature changes
Use recurring journals to allocate balances by dimension values
The Busines Central app for Microsoft Teams reaches General Availability
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2020 release wave 2 (release from October 2020 through March 2021), find the link to the release plan
here.
Upgrade to 17.4
Please note that new customers will automatically get the latest builds of Business Central (17.4). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
OData V3 will be removed with 2021 Wave 1
As previously announced, OData Version 3.0 (V3) has been deprecated since April 2020 and support for it will
be removed in Dynamics 365 Business Central 2021 release wave 1. OData V4 is the current recommended
version of OData and current integrations needs to move to OData V4. To identify incoming OData V3 requests,
enable and use the Web Service Request telemetry that's available to partners. Notifications has also been sent
via M365 Message Center to tenants with identified usage.
Release Plan for wave 1 2021 is out
The release plan for Dynamics 365 Busines Central wave 1 2021 is now live! You can find an overview of all the
new and planned features here.
Basic Authentication
Basic Authentication (Web Service Access Key) removal for Business Central online has been postponed until
April 2022. We see that some integrations needs more time to move from Web Service Access Key usage to
OAuth. PowerShell samples on how to connect to Business Central is published on GitHub.
Business Central Office Hours Calls in Februar y
Make sure to join the office hours calls around ‘Power Platform Integration, Power Apps, and Dataverse’ on
February 9 and ‘Performance Toolkit and Telemetry; How to deploy for performance’ on February 23. Register
and stay tuned for the upcoming calls: https://aka.ms/BCOfficeHours.
It’s time to switch your Dynamics 365 Business Central browser to Microsoft Edge
On April 2, 2021, Microsoft will remove Internet Explorer 11 and Microsoft Edge Legacy browsers from the list
of supported browsers for the Business Central modern clients. Read the details, how it applies to you and
actions to take here.
Update 17.3 for Microsoft Dynamics 365 Business
Central online 2020 release wave 2
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 17.3? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Feature changes
Restoring an Environment in the Admin Center
Use Shortcut dimensions in G/L Entries for Financial reporting
Signal from web service key authentication added to Application Insights telemetry for partners
Handle Price List Exceptions with Allow Updating Defaults
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2020 release wave 2 (release from October 2020 through March 2021), find the link to the release plan
here.
Upgrade to 17.3
Please note that new customers will automatically get the latest builds of Business Central (17.3). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Basic Authentication
Basic Authentication (Web Service Access Key) removal for Business Central online has been postponed until
April 2022. We see that some integrations needs more time to move from Web Service Access Key usage to
OAuth. PowerShell samples on how to connect to Business Central is published on GitHub.
Snapshot debugging is now enabled in production environments
From version 17.2 and forward it is now possible to use snapshot debugging to investigate production
environments. For more information, see the help page or view the Virtual Event for 2020 Wave 2 release
recording on the What's New in Visual Studio and AL, covering snapshot debugging in details.
Business Central Office Hours Calls in Januar y
Make sure to join the office hours calls around 'Customer Migration Tooling' on January 12 and 'Power Platform
Integration – Power BI' on January 26. Register and stay tuned for the upcoming calls:
https://aka.ms/BCOfficeHours.
Want to improve the performance of Business Central?
Visit https://aka.ms/bcperformance and learn about best practices, dos and don'ts and different ways to make
changes with a performance impact. The Performance Tuning Guide will help you understand and improve the
performance of Business Central whether you are a functional consultant, a developer, or an administrator.
It's time to switch your Dynamics 365 Business Central browser to Microsoft Edge
On April 2, 2021, Microsoft will remove Internet Explorer 11 and Microsoft Edge Legacy browsers from the list
of supported browsers for the Business Central modern clients. Read the details, how it applies to you and
actions to take here.
Update 17.2 for Microsoft Dynamics 365 Business
Central online 2020 release wave 2
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 17.2? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Feature changes
Application Performance Improvements
Signal from job queue execution added to Application Insights telemetry for partners
Signal from permission changes to added to Application Insights telemetry for partners
Signal from the retention policy feature added to Application Insights telemetry for partners
Signal from the sensitive field audit feature added to Application Insights telemetry for partners
Signal from the email feature added to Application Insights telemetry for partners
Signal from application packages lifecycle added to Application Insights Telemetry for partners
Snapshot Debugging
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2020 release wave 2 (release from October 2020 through March 2021), find the link to the release plan
here.
Upgrade to 17.2
Please note that new customers will automatically get the latest builds of Business Central (17.2). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Business Central Office Hours
The Office Hours are back! Find an overview of the topics and register here: https://aka.ms/BCOfficeHours.
Small update for Business Central mobile app
A small update for the Business Central mobile app (with added languages and some fixes) is being released to
the app stores on all three platforms (Windows, iOS, and Android). Please remember to update the Business
central app on your device (version 3.1.12032 or later). Direct links: Windows (Microsoft Store), iOS (Apple's App
Store), Android (Google's Play Store).
Watch what's new sessions on demand
You can still watch the sessions from the Business Central Launch Event in October. Register and get access to
30+ sessions here.
Migrate directly from version 14, 15, and 16 to Business Central online
Business Central includes a cloud migration tool that administrators can use to migrate customer data from on-
premises databases to Business Central online. Starting now, the Cloud Migration app also supports migration
from the earlier on-premises versions of Business Central, with the latest cumulative update applied: Migrate
directly from versions 14.x, 15.x, and 16.x to version 17.x. This helps customers reduce their costs of migrating to
the Business Central cloud significantly, as they can skip upgrading their on-premises environments to the latest
version of Business Central and just migrate the data, including all historical transactions. The Cloud Migration
app now includes all the necessary data upgrade logic to convert the data from the previous versions to the
data structure of 2020 release wave 2 (version 17.0). Learn more here.
Update 17.1 for Microsoft Dynamics 365 Business
Central online 2020 release wave 2
2/6/2023 • 3 minutes to read • Edit Online
Would you like to know what has changed in update 17.1? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Feature changes
Enhanced email capabilities
Notify users of high-risk changes in selected setup fields
Use new sales pricing experience
Control how Account Schedules for core financial reports are generated
Improved VAT Registration no. lookup
Extension lifecycle telemetry in Application Insights for ISVs
Use environmentType and environmentName launch.json properties instead of obsoleted sandboxName
Symbols can be downloaded with a snapshot initialize launch.json configuration, using above environment
properties
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2020 release wave 2 (release from October 2020 through March 2021), find the link to the release plan
here.
Upgrade to 17.1
Please note that new customers will automatically get the latest builds of Business Central (17.1). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
NEW! Migrate directly from version 14, 15, and 16 to Business Central online
Business Central includes a cloud migration tool that administrators can use to migrate customer data from on-
premises databases to Business Central online. Starting now, the Cloud Migration app also supports migration
from the earlier on-premises versions of Business Central, with the latest cumulative update applied: Migrate
directly from versions 14.x, 15.x, and 16.x to version 17.x. This helps customers reduce their costs of migrating to
the Business Central cloud significantly, as they can skip upgrading their on-premises environments to the latest
version of Business Central and just migrate the data, including all historical transactions. The Cloud Migration
app now includes all the necessary data upgrade logic to convert the data from the previous versions to the
data structure of 2020 release wave 2 (version 17.0). Learn more here.
Database size when migrating from Business Central on-prem to online
We have increased the limit we apply to the database size from 30 Gb to 80 Gb when migrating from Business
Central on-prem to Business Central online using the Cloud Migration tool. If you are looking at migrating a
larger database, we recommend that you contact the support team and work with them to make sure that the
migration is successful. Learn more here and read about running the cloud migration tool here.
Watch what's new sessions on demand
Watch the sessions from the Business Central Launch Event in October. Register and get access to 30+ sessions
here.
Snapshot debugging
Snapshot debugging has now been enabled for sandbox environments. It will be enabled in production in a later
minor. Learn more here.
Apps are moving to office.com
The home for all your business applications across Dynamics 365 and Microsoft Power Platform is moving to
office.com, where you'll find the Business Central tiles for production and sandbox environments. Learn more
here.
Easy access to production or sandbox environments from the mobile app
Users of mobile devices can now choose between their sandbox and production environments without the need
to use the pre-crafted URL as before. Partners running their own apps based on Business Central can also let
their users explore it from mobile devices. Learn more here.
Unblock multifactor authentication for mobile apps
We have updated core authentication components of the mobile app to support multifactor authentication.
Enabling such flow in the user setting on your Microsoft 365 account and then using it on a mobile device (via
an SMS code, authenticator app, or more) is now possible after updating the Business Central mobile app to
version 3.0 or higher. Learn more here.
Update 16.5 for Microsoft Dynamics 365 Business
Central online 2020 release wave 1
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 16.5? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Feature changes
Delete extension data
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2020 release wave 1 (release from April 2020 through September 2020), find the link to the release plan
here.
For a list of next wave release plans, see the 2020 release wave 2 release plan.
Upgrade to 16.5
Please note that new customers will automatically get the latest builds of Business Central (16.5). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
It’s time to switch your Dynamics 365 Business Central browser to Microsoft Edge
On April 2, 2021, Microsoft will remove Internet Explorer 11 and Microsoft Edge Legacy browsers from the list
of supported browsers for the Business Central modern clients. Read the details, how it applies to you and
actions to take here.
Leveraging IoT data in Dynamics 365 Business Central
Make sure to read the blog about getting started with leveraging the Internet of Things (IoT) data in Dynamics
365 Business Central using services from Microsoft Azure is easier than you may think.
Suppor t for an unlimited number of production and sandbox environments
With 2020 release wave 2 (October), we're introducing the ability for customers to buy additional Business
Central production environments to expand their business. More environments will open up new opportunities
like creating more business branches, moving into more countries, or expanding within their current country,
read more here.
Running a Container-Based Development Environment
From 16.4 and onwards Microsoft will stop producing docker images and instead publish builds as artifacts,
which can be used together with the generic Docker image to run the image you want. Read more here.
Update 16.4 for Microsoft Dynamics 365 Business
Central online 2020 release wave 1
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 16.4? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links that you might find interesting.
Hotfixes
Find an overview of hotfixes in this article.
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2020 release wave 1 (release from April 2020 through September 2020), find the link to the release plan
here.
For a list of next wave release plans, see the 2020 release wave 2 release plan.
Upgrade to 16.4
Please note that new customers will automatically get the latest builds of Business Central (16.4). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Running a Container-Based Development Environment
From 16.4 and onwards Microsoft will stop producing docker images and instead publish builds as artifacts,
which can be used together with the generic Docker image to run the image you want. Read more here.
Want to improve the performance of Business Central?
Visit aka.ms/bcperformance and learn about best practices, dos and don'ts and different ways to make changes
with a performance impact. The Performance Tuning Guide will help you understand and improve the
performance of Business Central whether you are a functional consultant, a developer, or an administrator.
Vir tual sessions of what is new in 2020 release wave 1?
Did you attend the #MSDyn365BCVirtualEvent on June 3rd? Don't forget to watch the 15+ virtual on demand
sessions featuring new innovations, tools, and in-depth product demonstrations from the experts. You just need
to register to view the sessions, but it’s free.
Update 16.3 for Microsoft Dynamics 365 Business
Central online 2020 release wave 1
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 16.3? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update. In addition, we have gathered some
good to know information and links, you might find interesting.
Hotfixes
Link to Hotfixes.
Feature changes
Bank reconciliation improvements
Extension lifecycle telemetry in Application Insights for partners
Client page view telemetry in Application Insights for partners
Installing AppSource apps updates in the Business Central administration center – rollout has been
completed. Customers can now discover and install all AppSource apps updates in the Business Central
Admin Center.
Feature Update: Page layout is now cached to browser storage
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2020 release wave 1 (release from April 2020 through September 2020), find the link to the release plan
here.
Upgrade to 16.3
Please note that new customers will automatically get the latest builds of Business Central (16.3). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Keep track on deployed builds
In between the Microsoft Dynamics 365 Business Central minor updates we deploy new builds as they become
available. Visit the Update History to see the latest important builds that have been pushed out automatically
since last minor update.
Want to improve the performance of Business Central?
Visit aka.ms/bcperformance and learn about best practices, dos and don'ts and different ways to make changes
with a performance impact. The Performance Tuning Guide will help you understand and improve the
performance of Business Central whether you are a functional consultant, a developer, or an administrator.
Are you a Business Central Wave 'Champ'?
Did you attend the #MSDyn365BCVirtualEvent on June 3rd? Don't forget to watch the 15+ virtual on demand
sessions featuring new innovations, tools, and in-depth product demonstrations from the experts. The best part
of it - it's all for free! You just need to register to become a Business Central 'Wave Champ' and boost your
knowledge.
Update 16.2 for Microsoft Dynamics 365 Business
Central online 2020 release wave 1
2/6/2023 • 2 minutes to read • Edit Online
Hotfixes
Link to Hotfixes
Feature changes
Migrate data from Business Central 14.x on-premises to Business Central 15.x online
Update error telemetry in Application Insights for partners
New URL parameter hides web client header
Improved user experience to keep things from going wrong
Use modern authentication to connect to Microsoft Dataverse and Dynamics 365 Sales
Installing AppSource apps updates in the Business Central administration center – please note gradual
availability! Until the feature is generally available, some AppSource apps can't be updated using this feature.
For information about the timeline, see here
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire 2020 release wave 1 (release from April 2020 through September 2020), find the link to the release plan
here.
Upgrade to 16.2
Please note that new customers will automatically get the latest builds of Business Central (16.2). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
A change to the Web client header
The top-most header in the Business Central Web client and desktop app have been updated to align with other
Microsoft 365 and Dynamics 365 apps. The most notable change is to the height of the header that has now
been reduced to 48 pixels.
Warning of performance impact when using configuration packages to impor t data
Configuration packages were designed to speed up the implementation of new companies. In case a customer
wants to use Configuration Packages as a quick way to import data -sometimes big data- from other systems to
Business Central, this small feature analyzes if the import will bring data to a new company or not and,
depending of that and the size of the package, alerts the user that the performance of its tenant could be
affected suggesting other ways to import or request partner help.
Want to improve the performance of Business Central?
Visit aka.ms/bcperformance and learn about best practices, dos and don'ts and different ways to make changes
with a performance impact. The Performance Tuning Guide will help you understand and improve the
performance of Business Central whether you are a functional consultant, a developer, or an administrator.
Are you a Business Central Wave ‘Champ’?
Did you attend the #MSDyn365BCVirtualEvent on June 3rd? Don’t forget to watch the 15+ virtual on demand
sessions featuring new innovations, tools, and in-depth product demonstrations from the experts. The best part
of it - it’s all for free! You just need to register to become a Business Central ‘Wave Champ’ and boost your
knowledge.
Update 16.1 for Microsoft Dynamics 365 Business
Central 2020 online release wave 1
2/6/2023 • 2 minutes to read • Edit Online
Hotfixes
Link to Hotfixes
Feature changes
Company lifecycle telemetry in Application Insights for partners
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire wave 1 (release from April 2020 through September 2020), find the link to the release plan here.
Upgrade to 16.1
Please note that new customers will automatically get the latest builds of Business Central (16.1). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Minimum requirements for Business Central Administration Center
We have updated system requirements with the list of browsers supported by the Administration Center.
When signing in from an unsupported browser that delivers a significantly degraded experience,
administrators will immediately see a message that prevents them from continuing to the Administration
Center. For example, it is not possible to access the Business Central Administration Center from Internet
Explorer.
See minimum requirements
Learn more about the Business Central Administration Center
Sandbox environment picker
When you navigate from the Business Central Sandbox tile in the Dynamics 365 Home portal or in the
App Launcher, a dialog will be displayed for you to choose exactly which sandbox environment from your
organization you would like to navigate to.
Read more about sandbox environments
Message to Global Admins about the capabilities
On login, Global Admins will get a message about the capabilities in Business Central according to their
license or suggesting one if they don't have any assigned.
Coming up: Vir tual par tner readiness event - register now!
We're excited to share the latest innovations for Business Central. Join us at the upcoming Business
Central All Access Virtual Event June 3rd with more than 15 deep dive sessions on what's new in 2020
release wave 1 (April release), also available on-demand.
Registration open now at aka.ms/virtual/businesscentral/2020RW1
Pssst…did we mention it's for free…
Major updates
Get an overview of what you need to know about how a major Business Central update rolls out. It
includes key dates, actions you need to take, and answers some common questions.
See Major Updates of Business Central Online
Update 15.4 for Microsoft Dynamics 365 Business
Central 2019 online release wave 2
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 15.4? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update.
Hotfixes
Link to Hotfixes
Feature changes
Bookmarking a report - rollout is complete. With Update 15.4, all environments now include this feature.
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire wave 2 (release from October 2019 through March 2020), find the link to the release plan here.
Upgrade to 15.4
Please note that new customers will automatically get the latest builds of Business Central (15.4). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Major updates
Get an overview of what you need to know about how a major Business Central update rolls out. It
includes key dates, actions you need take, and answers some common questions. See Major Updates of
Business Central Online.
Preview environments of next major update
Partners should start to prepare for the next major update of Business Central in April. Partners can try
out new functionality in preview environments, give Microsoft feedback and validate your extensions. See
more details in Prepare for major updates with preview environments
Visit our new aka.ms/bcperformance page and start your learning about Business Central performance.
Update 15.3 for Microsoft Dynamics 365 Business
Central 2019 online release wave 2
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 15.3? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update.
Hotfixes
Link to Hotfixes
Feature changes
View Your Reference and External Document No. on sales documents
Skip empty lines in the Account Schedule report
MICR fonts available in Business Central online
New events to unblock printer extensions in Business Central online
Bookmarking a report
Sign-in attempt telemetry in Application Insights for partners
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire wave 2 (release from October 2019 through March 2020), find the link to the release plan here
Upgrade to 15.3
Please note that new customers will automatically get the latest builds of Business Central (15.3). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Changes to Browser Cookie Policy
Avoid disruption by following these steps to prepare for tighter security policies starting February 2020
in Google Chrome and Microsoft Edge. For more information, see Preparing Dynamics NAV or Dynamics
365 Business Central for Upcoming Changes to Browser Cookie Policy.
Using Internet Explorer
From Update 15.3 onwards, users who access Business Central from Internet Explorer will receive a
notification suggesting they consider a different browser. Users who switch to a modern browser, such as
Microsoft Edge, typically observe improved performance and a generally smoother experience. Learn
more about our supported and recommended browsers for Business Central on premises and online.
To support partners who are interested in monetizing the app they have published to AppSource, update
15.3 comes with new options. These options allow partners to understand number, type and state of
Business Central licenses in the current tenant as well as number of allocated seats. That data enables the
partner to implement user-based billing into their apps. To learn more, see Azure AD Licensing.
Visit our new aka.ms/bcperformance page and start your learning about Business Central performance.
Update 15.2 for Microsoft Dynamics 365 Business
Central 2019 online release wave 2
2/6/2023 • 2 minutes to read • Edit Online
Would you like to know what has changed in update 15.2? Below you'll find an overview and relevant links to
what has been done on hotfixes and regulatory features in this update.
Hotfixes
Link to Hotfixes
Feature changes
Add the Name 2 field to customer and vendor cards
Include job information in archived sales and purchase documents
Use VAT clauses on different document types
View item availability by unit of measure
View the number of general journal lines
Release Plan
If you want to get a comprehensive overview of what's new and planned for Business Central online for the
entire wave 2 (release from October 2019 through March 2020), find the link to the release plan here
Upgrade to 15.2
Please note that new customers will automatically get the latest builds of Business Central (15.2). If you are an
existing partner/customer, you will receive an email notification as soon as your environment has been
upgraded.
Good to know
Please find an overview of new "How to videos" recently published on Dynamics 365 YouTube channel for the
Business users and the Functional Consultants. These videos complement the extensive MS Learn and
Documentation content already available for Business Central.
How to set up a customer
How to adjust exchange rates
How to set up a vendor
How to set up purchasers
How to prioritize vendors
How to set up schedule reports
How to set up sales people
How to apply a payment to multiple customer ledger entries
How to reconcile customer payments manually
How to create credit notes and applying across single and multiple ledgers
How to offer discounts and special prices
How to link purchase orders to a sales order
How to set up a new bank account
How to set up an item to sell
How to set up payment methods
How to set up chart of accounts
How to submit a support request
How to report a production outage
How to correct or cancel purchase invoices
How to adjust physical inventory levels
How to work with inventory costing
How to set up an inventory location
How to create purchase order
How to email documents
How to set up documents sending profiles
How to setup categories
How to set up customer approval workflow
How to open a new fiscal year (part of payment methods)
Resources for Help and Support for Dynamics 365
Business Central
2/6/2023 • 9 minutes to read • Edit Online
As a Business Central partner, you have access to resources that can help you support your Business Central
customers, and you have access to resources that can help you be more productive as a partner.
This page outlines the resources available to you.
Product Help
The functionality in the default version of Business Central is described on the learn.microsoft.com site as
described in the following table.
Business functionality docs learn.microsoft.com/dynamics365/busi Use this library to learn about business
ness-central functionality.
Development and administration docs learn.microsoft.com/dynamics365/busi Use this content to learn how to
ness-central/dev-itpro/ extend, customize, and administrate
Business Central.
AL developer documentation
In the Development in AL section, you find descriptions of processes such as compilation and debugging, and
conceptual information about object types such as tables and events.
The reference documentation of the AL language publishes under the AL Programming umbrella. This content is
partly generated automatically from code, but some of the reference content is maintained by hand. Use the
following landing pages to quickly find the reference content that you need:
Methods
Data Types and Methods in AL
Properties
Properties Overview
Triggers
Triggers Overview
Objects
Table object
Table extension object
Page object
Page extension object
Page customization object
Report object
XMLport object
Query object
Codeunit object
Profile object
Control add-in object
Product versions and Help versions
In general, the Business Central content on the learn.microsoft.com site reflects the latest version of Business
Central online with limited support for earlier versions.
If you support Business Central on-premises, your solution might be one or two versions older than the latest
version. This means that the content in the business functionality documentation might describe functionality
that your users do not have access to. For a better experience, we recommend that you take a copy of our
content at the time when that reflected the version that your on-premises solution is based on and deploy that
to your own website.
The source repo, dynamics365smb-docs, contains packages of Markdown files for major versions and
snapshots of the docs for the previous minor version.
For example, go to https://github.com/MicrosoftDocs/dynamics365smb-docs/releases to get the release that
you need for your solution.
For more information, see the On-premises deployments section in the Configure the Help Experience article.
Customize and extend the user assistance
If you customize or extend Business Central, you are expected to also customize the user assistance so that users
will have access to content that can help them get started, get unblocked, and learn more. For more information,
see User Assistance Model and Configure the Help Experience.
Support
As a Business Central reselling partner, you are an administrator of your customers' Business Central tenants,
and you are the first line of support. You can customize the support experience, and you have access to
information that can help you troubleshoot any issues that your customers report.
For more information, see Technical Support.
Training
You and your customers can find free eLearning content on the Microsoft Learn landing page for Business
Central with suggested collections for getting started, managing financials, and extending Business Central.
The Learn site also includes role-specific learning paths for developers, administrators, and functional
consultants.
Additionally, partners in the Business Central community offer training and books.
Resources
As a partner, you can keep on top of current and upcoming capabilities, and you can share Microsoft's roadmap
with your prospects, for example. This section provides links to places to keep track of for people who are new
to Business Central as well as for people who have been working with the product for years.
This article provides information about the following types of resources:
How to get started as a partner
Where to learn about current and upcoming capabilities
How to make a feature request
Where to find blog posts
Where to find communities
Where to file bugs and issues
Where to contribute to code or docs
Where to ask non-product related questions
Get set up as a partner
If you are not already a Microsoft partner, your company must get set up, and so must you as an employee. For
more information, see Get Started as a Reseller of Business Central Online and Get Started with Building Apps.
Learn about current or upcoming capabilities
You can learn about current and coming capabilities through a number of different resources as outlined in the
following table.
Integrating with Business Central learn.microsoft.com/dynamics365/busi Use this content to learn how to
using web services ness-central/dev-itpro/webservices/ integrate Business Central with other
products by using web services.
Migrate to Business Central online learn.microsoft.com/dynamics365/busi Use this content to learn how you can
ness-central/dev- move an on-premises solution to
itpro/upgrade/upgrading-to-business- Business Central online.
central-online
NAME LO C AT IO N DESC RIP T IO N
Features not implemented in on- learn.microsoft.com/dynamics365/busi Use this content to learn which
premises deployments ness-central/dev-itpro/features-not- capabilities in Business Central online
implemented-on-premises are not available in Business Central
on-premises deployments.
Business Central on the Dynamics 365 https://cloudblogs.microsoft.com/dyna Use this blog to learn about
blog mics365/it/product/business-central/ opportunities, processes, and tools for
the Business Central partner
community.
Some older blog posts are still
available on the Community site for
partners or the Community site for
business users.
ISSUE T Y P E SIT E
Submit support request on behalf of your Business Central Start at the Business Central administration center where
online customers you can easily submit a support request in the Power
Platform admin center
Collaboration on the AL language and developer experience The AL Developer Preview GitHub repo
As an ISV, report an issue in production code, such as a The Partner Center Support site - choose the Marketplace
problem with Microsoft's application, upgrade, or telemetry Offers category, and then choose the relevant category in
the Problem type field, such as Dynamics 365 Business
Central Development > Core Application issues. You'll be
asked to check resources and then to provide issue details.
Report bug in supported in-market versions of Business The Support for business site
Central on-premises
IMPORTANT
To submit support requests on behalf of your customer, you must be a delegated admin on the customer tenant. Your
company must also have the Advanced or Premier support plan. For more information, see the Escalating support issues
to Microsoft section.
For more information, see Technical Support for Dynamics 365 Business Central.
Engage with us on GitHub
GitHub brings together communities of developers and other contributors to discover, share, and build software.
Here are some useful repositories for Business Central:
Microsoft AL
For collaboration on the AL development environment in Visual Studio Code, use the GitHub repo here:
https://github.com/microsoft/al
Microsoft AL application add-ons
There are a couple of ways to engage with us in the https://github.com/microsoft/ALAppExtensions repo:
You can grab the code and contribute to the published apps.
If you're building your own app and need something specific from us, such as an event, you can help
improve the general extensibility of the business logic.
BcContainerHelper
Use this repo to collaborate around the source code and the scripts of BcContainerHelper PowerShell
module for Business Central: https://github.com/Microsoft/NavContainerHelper
Business Central Tech Samples
Find Microsoft's prototypes, experiments to test performance, and other examples of what Microsoft's
engineers get up to apart from shipping production code, in the https://github.com/microsoft/BCTech
repo.
Documentation
The product Help and developer and administration content is based on GitHub as well, and you can
collaborate and extend the docs. The GitHub repos are:
Product Help (English US): https://github.com/MicrosoftDocs/dynamics365smb-docs
Developer and administration content: https://github.com/MicrosoftDocs/dynamics365smb-devitpro-
pb
For more information, see Extend and Collaborate on the Help.
Non-product related questions
On occasion, as a partner, you will run into questions that are not directly related to the product. The following
list outlines how to get answers to those questions.
F O R Q UEST IO N S REL AT ED TO C O N TA C T
Problems with listing or publishing apps to AppSource due The Partner Center Support site - choose the Marketplace
to Commercial Marketplace issues offers category, and then choose the relevant category in
the Problem type field, such as Availability > Dynamics
365 Business Central offer.
Microsoft Partner Network, Partner Center, Cloud Solution The Partner Center Support site
Provider program
Technical issues with PSBC, PartnerSource, or Order Central Email IT MBS Support
Volume licensing The Call Logging Tool site or email Online Licensing
Trials
Giving prospects access to a pre-configured trial of Business Central is an elegant way to introduce them to
Business Central. You can use the standard trial provided by Microsoft, or you can prepare your own including
relevant extensions.
For more information, see Preparing Demonstration Environments.
See also
Technical Support
Configuring the Help Experience
Migrate Legacy Help
User Assistance Model
The Business Central Administration Center
Legal Landing Page for Microsoft Dynamics 365
Business Central Online
2/6/2023 • 2 minutes to read • Edit Online
This article provides links to legal information for Business Central online.
Product Terms
Commercial Licensing Terms for the Microsoft Customer Agreement program
Microsoft AL Language
AL Language - Terms of Use
AL Extension Third Party Notice
Lifecycle policy
Lifecycle policy for Business Central online
See Also
Privacy FAQ
Legal Resources for Business Central On-Premises
Developer and Administration Help for Microsoft Dynamics 365 Business Central
Technical Support for Dynamics 365 Business
Central
2/6/2023 • 5 minutes to read • Edit Online
Each customer of Business Central has a partner who assists with technical support. As a Business Central
reselling partner, you are an administrator of your customers' Business Central tenants, and you are the first line
of support. You will get requests for support from your customers that you must triage, investigate, and either
resolve or escalate to Microsoft.
In this section, you can learn about the tools that are available to you to help you troubleshoot your customers'
Business Central.
IMPORTANT
You must have set up users in your own tenant in Partner Center as either Admin agent or Helpdesk agent, and they
must have delegated administration privileges in your customer's Business Central to support the customer. For more
information, see Delegated Administrator Access to Business Central Online.
ISSUE T Y P E SIT E
Submit support request on behalf of your Business Central Start at the Business Central administration center where
online customers you can easily submit a support request in the Power
Platform admin center
Collaboration on the AL language and developer experience The AL Developer Preview GitHub repo
As an ISV, report an issue in production code, such as a The Partner Center Support site - choose the Marketplace
problem with Microsoft's application, upgrade, or telemetry Offers category, and then choose the relevant category in
the Problem type field, such as Dynamics 365 Business
Central Development > Core Application issues. You'll be
asked to check resources and then to provide issue details.
ISSUE T Y P E SIT E
Report bug in supported in-market versions of Business The Support for business site
Central on-premises
IMPORTANT
To submit support requests on behalf of your customer, you must be a delegated admin on the customer tenant. Your
company must also have the Advanced or Premier support plan. For more information, see the Escalating support issues
to Microsoft section.
TIP
When you submit your first support ticket as a partner, you must specify details about your company's support plan. If
you or your colleagues do not know these details, contact your Microsoft rep.
F O R Q UEST IO N S REL AT ED TO C O N TA C T
Problems with listing or publishing apps to AppSource due The Partner Center Support site - choose the Marketplace
to Commercial Marketplace issues offers category, and then choose the relevant category in
the Problem type field, such as Availability > Dynamics
365 Business Central offer.
Microsoft Partner Network, Partner Center, Cloud Solution The Partner Center Support site
Provider program
Technical issues with PSBC, PartnerSource, or Order Central Email IT MBS Support
Volume licensing The Call Logging Tool site or email Online Licensing
See Also
Inspecting and Troubleshooting Pages
The Business Central Administration Center
Managing Technical Support
Deployment Overview
Administration of Business Central Online
Administration of Business Central On-Premises
Provide technical support (Microsoft Partner Center)
Providing support to your customers (Microsoft Partner Center)
Dynamics 365 Business Central User Assistance
Model
2/6/2023 • 13 minutes to read • Edit Online
The Business Central user assistance model is based on the following principles:
Get started
Home pages give easy access to key tasks so users can easily get started with work every day. Embedded
user assistance implemented as teaching tips help users understand new or unfamiliar pages, and
checklists make it easy to get started in a new company.
Get unblocked
Embedded user assistance implemented as tooltips answers most immediate questions about what fields
and actions do.
Learn more
The Help menu and Learn more links on tooltips and teaching tips provide context-sensitive access to
Help articles with more information.
Apps, extensions, and customizations are expected to follow the same model by applying tooltips to controls on
page objects, and by providing links to Help for their functionality. For more information about customizing and
extending the user assistance, see Extend and Collaborate on the Help and Configure the Help Experience.
In this article, we'll talk about the user assistance model itself and what it does.
To help users set up Business Central on the first day, partners can add required steps to the checklist. The
checklist is intended to help users fill in necessary information and help themselves get familiar with Business
Central. For more information, see Get Users Started with the Checklist.
Teaching tips and tours
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
2021 release wave 1 brought an interpretation of teaching tips that you can add to your Business Central
solution. Use the teaching tips from the onboarding framework to introduce users to complex pages, and to
build tours that help users understand the purpose of a complicated area, for example. Create the teaching tips
in code by setting the AboutTitle and AboutText properties.
NOTE
Teaching tips supplement the tooltips that provide descriptions for all fields and actions.
TO O LT IP P O IN T IN G AT A F IEL D C A P T IO N T EA C H IN G T IP P O IN T IN G TO A F IEL D
Every field and action has a tooltip. Only the most important fields/actions have a
teaching tip.
Answers the question What is this?
Answers the question What can I do with this field or
Relevant for everything since every field/action has a action?
definition.
Isn't relevant for every field/action.
For more information, see Teaching tips and in-app tours for onboarding users.
Help pane
APPLIES TO: Business Central 2022 release wave 1 and later
When the user opens the Help pane, they see content and links to learn more based on where they are in the
product. Once users discover the Help pane, they will be able to help themselves get unblocked, we hope.
The Help pane shows up to four types of links:
A link about the current page
At the top of the pane, a card repeats the current page's teaching tip, if one exists. If there is no teaching
tip, then the card provides a single link to an article about the page. This link is based on the page-level
configuration of context-sensitive Help.
If Business Central can't find the relevant link, we show the landing page on learn.microsoft.com. For
example, if the page was part of an app that didn't add context-sensitive Help mapping to Business
Central, the Learn link defaults to the landing page.
Links to related articles from Microsoft Docs
These links are related to the current page and will change if you move to another page. The links are
limited to the learn.microsoft.com site. If there are more than three links, choose the Show more link to
expand the card. Choose any link, and the related article will open in a new browser tab.
Links to content for apps on the current page
These links are based on any app that extends the page or defines the page. These links are based on the
page-level configuration of context-sensitive Help.
Links to other resources
Three links are always available in the Help pane: Links to the Help & Suppor t page inside Business
Central, the Keyboard Shortcuts article, and the Business Central community. These links are always
shown, and the list cannot be modified.
If the automatically generated links do not answer the user's question, then the user can use the Search field to
search Microsoft's content, both documentation and e-learning material. Currently, search in the Business
Central Help pane cannot access sites other than the learn.microsoft.com site, including Microsoft Learn.
These descriptions are applied to controls on pages rather than table fields. Table fields can be read-only in one
page and editable in another, so the tooltips describe the difference. In Business Central, this type of "What is this
field?" content is embedded in the page objects, and resource files can be used for translated user interfaces. For
more information, see Working with Translation Files.
Most tooltips end with an automatically generated link to learn more as described in the Help users learn more
section; however, tooltips for actions do not have Learn more links:
TIP
Users can always use the Ctrl+F1 keyboard shortcut to access the learn more content that is configured for the currently-
selected item in the user interface. In 2022 release wave 1 and later, Ctrl+F1 opens the Help pane with automatically
generated links to related content from Microsoft and partners.
The tooltips in Business Central are conceptually similar to field descriptions in Dynamics 365 Finance and
related apps, and teaching tips in the Universal Windows Platform's Fluent Design guidelines. The onboarding
framework in 2021 release wave 1 added another interpretation of teaching tips that you can add to your
Business Central solution. For more information, see Teaching tips and in-app tours for onboarding users.
Guidelines for tooltip text
The Microsoft user assistance model requires a tooltip for all controls of type Action and Field that exist on page
objects. Follow these guidelines:
If the control is a field, begin with the verb Specifies.
If the control is an action, begin with a verb in the imperative form , such as Calculate or View .
Include the most valuable information that users need to perform the task(s) that the field or action
supports.
For example, for the Post action, do not write Post the document. Write, for example, Update ledgers with
the amounts and quantities on the document or journal lines.
Describe complex options in tooltips for option fields.
Use a colon to call out the option name and its description. See example 3 below.
Try to not exceed 200 characters including spaces.
This makes the tooltip easier to scan so the user can get unblocked quickly. However, the UI will render
longer tooltip text if you want to provide more detailed user assistance.
Do not use line breaks in the tooltip text.
The tooltip cannot render formatting or line breaks.
Examples
The following table shows examples of effective tooltips.
C O N T RO L N A M E TO O LT IP
Entries action View the history of transactions that have been posted for
the customer.
(72 characters including spaces)
C O N T RO L N A M E TO O LT IP
Account Type field Specifies the purpose of the account. Total: Used to total a
series of balances on accounts from many different account
groupings. To use Total, leave this field blank. Begin-Total: A
marker for the beginning of a series of accounts to be
totaled that ends with an End-Total account. End-Total: A
total of a series of accounts that starts with the preceding
Begin-Total account. The total is defined in the Totaling field.
(522 characters including spaces)
The Learn more links on tooltips and the Ctrl+F1 shortcut now open the Help pane. In most cases, the pane
shows the following types of content:
A link about the current page
At the top of the pane, a card repeats the current page's teaching tip, if one exists. If there is no teaching
tip, then the card provides a single link to an article about the page. This link is based on the page-level
configuration of context-sensitive Help.
If Business Central can't find the relevant link, we show the landing page on learn.microsoft.com. For
example, if the page was part of an app that didn't add context-sensitive Help mapping to Business
Central, the Learn link defaults to the landing page.
Links to related articles from Microsoft Docs
These links are related to the current page and will change if you move to another page. The links are
limited to the learn.microsoft.com site. If there are more than three links, choose the Show more link to
expand the card. Choose any link, and the related article will open in a new browser tab.
Links to content for apps on the current page
These links are based on any app that extends the page or defines the page. These links are based on the
page-level configuration of context-sensitive Help.
Links to other resources
Three links are always available in the Help pane: Links to the Help & Suppor t page inside Business
Central, the Keyboard Shortcuts article, and the Business Central community. These links are always
shown, and the list cannot be modified.
The partner-provided links are based on the mechanism for adding links through app-level and page-level
configuration. For more information, see Configure Context-Sensitive Help.
The following screenshot illustrates the Help pane when it is opened from the Purchase Invoice page.
In this case, the Purchase Invoice page has not been extended by any apps. If two apps had extended the page,
their page-level and app-level configuration would be used to add links on a card after the Related articles from
Microsoft Docs card.
The base version of Business Central uses content that is published to an online library,
(learn.microsoft.com/dynamics365/business-central), so that it can also serve as onboarding material and as
feature overviews that you can share with prospects. The content is written in MarkDown, and our source files
are available in a public GitHub repo that you can extend for your customers.
NOTE
Currently, Business Central does not require the Help for your own functionality to be created in a specific format. But we
expect you to make it available on a website that the users of your functionality can access. For more information, see
Configure Context-Sensitive Help.
For the base version of Business Central, free online learning is also available on Microsoft Learn. For more
information, see the Business Central Learning Catalog.
Feedback and contributions
On learn.microsoft.com, each article has two buttons at the end of the article. The Product feedback button
sends you to the Ideas site, and the Sign in to give documentation feedback button lets you submit feedback
about the content through GitHub. In both cases, you must create an account if you do not already have one. For
product feedback, you must sign in with your work or organizational email account. For access to GitHub, you
can use any email address when you create an account.
We welcome your contributions, both as pull requests with suggestions or corrections to the content, and as
GitHub Issues with bugs or questions. However, we can only accept feedback and contributions to the content in
the dynamics365smb-docs and dynamics365smb-devitpro-pb repos. Also, we cannot address issues or
questions about the product.
IMPORTANT
If you have feedback about translations, you can report a GitHub issue in the dynamics365smb-docs repo.
Style
At Microsoft, we are in process of simplifying and unifying our style guides. To get to know the Microsoft style,
use the Microsoft Writing Style Guide as a good starting point. The Business Central follows most of the
guidelines in the Microsoft Writing Style Guide with exceptions for industry terminology and other product-
specific issues.
NOTE
The RSS feed returns a list of the 100 articles most recently updated. The list is sorted by date, but it can take up to a
week before the most recently updated articles make it to the list.
See Also
Configure the Help Experience
Adding Help Links from Pages, Reports, and XMLports
ToolTip Property
InstructionalText Property
Development of a Localization Solution
Translate documentation files
Resources for Help and Support
Blog post: Extending and customizing the Help
Blog post: Collaborate on content for Business Central
Docs Contributor Guide
Docs Authoring Pack for Visual Studio Code
Microsoft Cloud Style Guide (requires login)
Microsoft Writing Style Guide
Onboarding experiences in Business Central
Teaching tips and in-app tours for onboarding users
Configuring the Help Experience for Dynamics 365
Business Central
2/6/2023 • 11 minutes to read • Edit Online
The default version of Business Central comes with conceptual overviews and other articles that publish to the
learn.microsoft.com/dynamics365/business-central/ site. This location is accessible from the Help menu and
through the Learn More links in all tooltips. Each extension that you add will include its own tooltips and links
to Help that can be accessed through the Learn More links and the Ctrl+F1 keyboard shortcut.
But what if you want to deploy Business Central locally? Or if you have a vertical solution so that you want to
refer your customers to your own website for Help? Or if you have a legacy Help collection based on the
Dynamics NAV Help Server? These and other scenarios are also supported in Business Central.
TIP
The website does not have to be publicly accessible, but it must be accessible to all users of the solution that it supports.
You can add Microsoft's content to your website, or you can deploy just your own content. The choice is yours
and depends on the requirements of your users, the size of your app, and the amount of customization you
want to make. The custom Help toolkit includes tools that can help you prepare and deploy content. For more
information, see Custom Help Toolkit.
TIP
You are not required to use the toolkit. It's available for you to use if it makes sense for your Business Central solution.
If your solution extends Business Central online with additional capabilities, we recommend that you set up a
website with your own content. To build the HTML files, use any third-party tool that you prefer, such as DocFX.
For inspiration for how to create a website that can host your content, explore this tutorial. The tutorial
demonstrates how to create a static web app and add a search service in a few relatively straightforward steps.
On-premises deployments
For deploying Business Central on-premises, you can choose between using any online website or the legacy
Dynamics NAV Help Server, and you can configure different Help experience for each Business Central Web
Server instance. For supported versions, the legacy Dynamics NAV Help Server component is a simple website
that requires your Help to be in a specific format (HTML files). Other types of websites can host any content that
you want to make available. Your choice depends on the needs of your solution and your users. If you add
configuration for an online library, you must remove any settings for Help Server.
IMPORTANT
The legacy Dynamics NAV Help Server component was deprecated and removed in 2021 release wave 1 (version 18). We
recommend that you invest in a different type of website. For more information, see the deprecation notice.
TIP
The content on the learn.microsoft.com/dynamics365/business-central/ site and in the various GitHub repos reflects the
latest version of Business Central, unless otherwise specified.
If, for some reason, you need a copy of Microsoft's content, then get it close to the time the subsequent major version of
Business Central becomes available. For example, if you are deploying version 19.4, you could have taken a snapshot of
the content in GitHub before version 20.0 became available.
The source repo, dynamics365smb-docs, contains packages of Markdown files for major versions and
snapshots of the docs for the previous minor version.
For example, go to https://github.com/MicrosoftDocs/dynamics365smb-docs/releases to get the release that
you need for your solution.
Online library
To display content from a website that hosts your user assistance content, specify the URL in the settings for the
Business Central Web Server. The navsettings.json file must contain the following setting in the
ApplicationIdSettings element:
{
"NAVWebSettings": {
// [...more keys]
},
"ApplicationIdSettings": {
//BaseHelpUrl: The location of Help for this application.,
"BaseHelpUrl": "https://mysite.com/{0}/documentation/",
// [...more keys]
}
}
NOTE
Replace the value of the BaseHelpUrl key with the URL for your own website. The parameter, {0}, represents the locale of
the browser that the user is using, such as en-us or da-dk, and is set automatically at runtime.
For more information, see Configuring Business Central Web Server Instances.
TIP
The website does not have to be publicly accessible, but it must be accessible to all users of the solution that it supports.
TIP
You are not required to use the toolkit. It's available for you to use if it makes sense for your Business Central solution.
For example, if you deploy Business Central on-premises, you might want to set up a dedicated website with
customer-specific content that includes customized content from Microsoft. However, Microsoft's content is
optimized for the learn.microsoft.com site.
Legacy Help Server
APPLIES TO : 2020 release wave 2 and earlier versions
If you want to use Help Server, then you must specify the server and port in the installation options. The Help
Server website can also serve as a starting point for adding a library to your existing website, for example.
IMPORTANT
In version 18 and later versions, if you use the legacy Dynamics NAV Help Server component as a standalone website,
then you must use the settings for the online library that is described in the previous section.
For more information, see Configuring Microsoft Dynamics NAV Help Server in the developer and
administration content for Dynamics NAV.
IMPORTANT
If you use Help Server, context-sensitive Help does not work anymore. Neither the UI-to-Help mapping functionality that
is described in Configure Context-Sensitive Help, nor the original Help lookup mechanism that was based on filenames
that reflected the object IDs, such as N_123.htm for the page object with the ID 123. For more information, see the blog
post Reusing classic object-based Help on your Dynamics 365 Business Central Help Server.
TIP
If you are upgrading from Microsoft Dynamics NAV 2013 R2 or later, you can reuse your existing Help Server content by
simply replacing the product name and make any other changes that apply to your Business Central environment. But we
encourage you to deploy the content to another website.
You can still download the files that were made available for Microsoft Dynamics NAV 2017. The download
consists of 45 CAB files with the content from the Dynamics NAV 2016 DVD rebranded to Microsoft Dynamics
NAV 2017. The download includes CAB files with the W1 application Help translated into each of the supported
languages plus the local functionality for the country/region where that language is spoken. There are also CAB
files with local functionality in English. The files were published as a single download so each administrator
could choose exactly the files that they needed at the time. For more information, see Microsoft Dynamics NAV
2017 Classic Help Download.
However, you must switch to the UI-to-Help mapping functionality that is described in Configure Context-
Sensitive Help.
IMPORTANT
Currently, search in the Business Central Help pane cannot access sites other than the learn.microsoft.com site, including
Microsoft Learn.
However, to help prepare for the day when partner-provided and customer-provided content can also be indexed and
found by in-product search and the help pane, get your content deployed to a website and make it discoverable.
In versions older than 2022 release wave 1, the in-product search includes searching content on the
learn.microsoft.com/dynamics365/business-central site. In 2022 release wave 1 and later, this search is replaced
by the search capabilities of the Help pane. But the restrictions remain the same.
Optional: Get Microsoft's content
If you deploy a solution that customizes Microsoft's default application, then you might want to include a
customized version of Microsoft's business functionality content on your website. In most other cases, such as if
you build an add-on app, you do not need Microsoft's content. Your own content will supplement Microsoft's
content in the same way that your code supplements Microsoft's code. For more information, see Configure
Context-Sensitive Help.
IMPORTANT
The remainder of this section is for those people who need a copy of Microsoft's content to deploy to a website along
with their own content. In many cases, you do not need to customize Microsoft's content, and this section is irrelevant for
you. However, if you deploy a customized solution on-premises or in a closed environment, then you might need to
include Microsoft's content in your Help website.
We encourage you to use apply the ROBOTS: NOINDEX, NOFOLLOW metadata to any customized versions of
Microsoft's content. The intent is that search engines will find Microsoft's original content on the
learn.microsoft.com site rather than any customizations that you and hundreds of other may have published. Set
the metadata in the individual files, or set it in the globalMeta section of docfx.json if you build using docfx.exe.
For an example, see the ui-work-with-notes.md file in GitHub, which we have deprecated but kept in the repo as
an example.
If you use the docfx.json file to build HTML files for non-Microsoft functionality, then set the value of the ROBOTS
property when you build Microsoft's content. You can also add other global metadata, or metadata that applies
to specific subfolders.
Microsoft's source files are available as downloadable packages for each major release in the
https://github.com/MicrosoftDocs/dynamics365smb-docs/ GitHub repo in English (US) only.
IMPORTANT
The HTMLFromRepoGenerator tool is being deprecated. To generate HTML files from Markdown, use another tool, such
as DocFX.
The language-specific repositories are also being deprecated, and will no longer be available at the end of the 2022
calendar year.
TIP
The content on the learn.microsoft.com/dynamics365/business-central/ site and in the various GitHub repos reflects the
latest version of Business Central, unless otherwise specified.
The source repo, dynamics365smb-docs, contains packages of Markdown files for major versions and snapshots of the
docs for the previous minor version.
For example, go to https://github.com/MicrosoftDocs/dynamics365smb-docs/releases to get the release that you need
for your solution.
Use any tool or script that you prefer. If you want to create your own tooling and processes around DocFX,
examples are available in the Build HTML files section of the contributor guide.
IMPORTANT
We encourage you to use apply the ROBOTS: NOINDEX, NOFOLLOW metadata to any customized versions of Microsoft's
content. The intent is that search engines will find Microsoft's original content on the learn.microsoft.com site rather than
any customizations that you and hundreds of other may have published. Set the metadata in the individual files, or set it
in the globalMeta section of docfx.json if you build using docfx.exe. For an example, see the ui-work-with-notes.md file
in GitHub, which we have deprecated but kept in the repo as an example.
If you use the docfx.json file to build HTML files for non-Microsoft functionality, then set the value of the ROBOTS
property when you build Microsoft's content. You can also add other global metadata, or metadata that applies to specific
subfolders.
We suggest that your website clearly indicates what is under Microsoft's copyright and what is under your own
copyright. You are still welcome to make any relevant customizations of Microsoft's content, and to deploy this
customized content to your own website. But to help users clearly identify whether a given search result applies
to their Business Central experience or not, do not apply a title suffix such as Microsoft Docs. We also discourage
reproduction of the visual styling of the learn.microsoft.com site for the same reason.
TIP
You are not required to use the toolkit. It's available for you to use if it makes sense for your Business Central solution.
See Also
User Assistance Model
Adding Help Links from Pages, Reports, and XMLports
Migrate Legacy Help to the Business Central Format
Building Your First Sample Extension With Extension Objects, Install Code, and Upgrade Code
Building an Advanced Sample Extension
Development of a Localization Solution
Resources for Help and Support
Blog post: Extending and customizing the Help
Blog post: Collaborate on content for Business Central
Blog post: Reusing classic object-based Help on your Dynamics 365 Business Central Help Server
Working with Dynamics NAV Help Server
Docs Contributor Guide
Docs Authoring Pack for Visual Studio Code
Configure Context-Sensitive Help
2/6/2023 • 7 minutes to read • Edit Online
A key pillar of helping users help themselves is to give them access to Help for the particular part of Business
Central that they are working in. When you build an app for Business Central online, we expect you to provide
Help for your solution that can be accessed from the Learn more links on tooltips. For more information, see
Help users learn more.
Starting in 2022 release wave 1, version 20, the Learn more links open the Help pane. The same mechanism
makes sure that your page-level links are available in the Help pane.
The Learn more links are generated based on two configuration settings:
App-level configuration of the URL
Page-level configuration of page-specific article
App-level configuration
Specify where the Help for your functionality is published in the contextSensitiveHelpUrl property in the
app.json file. For example, if you publish your content to https://mysite.com/documentation :
"contextSensitiveHelpUrl": "https://mysite.com/documentation/",
In this example, when the user is using your app's functionality, the contextSensitiveHelpUrl property specifies
that the links to Help will go to the mysite.com site. When the user is using functionality from the base
application, then the Help calls will go to the learn.microsoft.com site.
If your app only supports a limited number of locales, you can specify that as well as shown in the following
example:
"contextSensitiveHelpUrl": "https://mysite.com/{0}/documentation/",
"supportedLocales": [
"en-GB", "en-IE
],
The contextSensitiveHelpUrl and supportedLocales properties specify that the links to the Help for page objects
in this app must go to the mysite.com site, but that the site only supports those two languages. All other Help
calls from objects in this app will go to the default locale on the specified webserver, in this case the equivalent
of https://mysite.com/en-GB/documentation/my-feature .
TIP
For tips and tricks for how to deploy content to your own website, see the Configuring the Help Experience for Dynamics
365 Business Central.
Help calls for Microsoft objects will continue to go to the learn.microsoft.com site.
Localization apps
Specifically for localization apps that translate Business Central into languages that are not offered by Microsoft,
the app.json file must be set to specify the destination of links to Help as shown in the following example:
"helpBaseUrl": "https://mysite.com/{0}/documentation/",
"supportedLocales": [
"ca-es"
],
The helpBaseUrl property represents the URL that will be used to overwrite the default Microsoft help link,
which is (/{0}/dynamics365/business-central) . The value of the property must contain a placeholder for the
user's locale culture, {0} .
The property specifies the list of locales that are supported by the URL specified in the
supportedLocales
helpBaseUrl property and used in the translation app. If the user's current locale is among the
supportedLocales of the extension, the user will be re-directed to the help base URL that you specified.
In this example, the helpBaseUrl and supportedLocales properties specify that the links to the Help must go to
the mysite.com site when the user is using the product in Catalan. If the user switches the application language
to English (US), then the Help calls will go to the learn.microsoft.com site.
Page-level configuration
Your target website is expected to have a default page that will display if nothing else is specified. But for each
page or page extension in your app, you can specify the Help page that describes this page or the fields that the
page extension adds to the page. You can do that using the ContextSensitiveHelpPage property as shown in the
following example:
In this example, the app contains a page object that is mapped to the sales-rewards Help file on the website that
the app.json specifies. As a result, the Learn more link in the tooltips for this page will go to the equivalent of
https://mysite.com/documentation/sales-rewards .
Similarly, the following code example shows a page extension object that sets the ContextSensitiveHelpPage
property so that the Learn more link in tooltips for the fields that this page extension adds to the Customer Card
will go to the https://mysite.com/documentation/sales-rewards rather than the default location at
learn.microsoft.com:
You can use the ContextSensitiveHelpPage property to direct Help calls from multiple page objects or actions to
the same article. For example, Microsoft has chosen to group the context-sensitive links depending on the
granularity of the Help for specific area in the base application. If the Help for a specific area is made more
granular, then the context-sensitive Help mapping is updated accordingly.
Your target website is expected to have a default page that will display if no other page is appropriate. For every
page where ContextSensitiveHelpPage is not set, this default Help page will be shown.
For page extensions, the value of the ContextSensitiveHelpPage property will apply only to the controls that the
page extension adds to the extended page objects. For example, if your page extension adds two new controls to
the base application's Customer Card page, then the Learn more links in the tooltips for those two controls will
go to the Help page that you have specified. The Learn more links in the rest of the controls will go to the default
Help that is specified in the base application. This way, multiple apps can extend the same page object and each
apply their own content-sensitive Help link without overwriting the context-sensitive links for other apps.
NOTE
The app.json file also contains a help property that is used by AppSource to specify the link that describes the app or
solution.
While it is possible to reuse the Dynamics NAV legacy Help with the legacy Dynamics NAV Help Server, and to
populate the system table, Page Documentation , we recommend that you convert any existing content to the
Business Central format, and that you fork our GitHub repos. For more information, see Extend and Collaborate
on the Help for Dynamics 365 Business Central and Migrate Legacy Help to the Dynamics 365 Business Central
Format.
In the following example, you have chosen not to apply context-sensitive Help links to your page objects and
instead you want to overwrite the UI-to-Help mapping that Microsoft has made in the system table.
Let's assume that the current mapping is:
You want to replace the values of the fields in the Relative Path column with classic page-level Help files:
PA GE ID PA GE N A M E REGIO N / C O UN T RY REL AT IVE PAT H
Once you have done this mapping, you can apply it to the Page Documentation table by using a script that
updates the table in the SQL Server database, for example.
You can find a couple of suggestions for how to go about this in our blog post, Reusing classic object-based Help
on your Dynamics 365 Business Central Help Server.
See also
User Assistance Model
Resources for Help and Support for Dynamics 365 Business Central
Adding Help Links from Pages, Reports, and XMLports
Migrate Legacy Help to the Business Central Format
Building Your First Sample Extension With Extension Objects, Install Code, and Upgrade Code
Building an Advanced Sample Extension
Development of a Localization Solution
JSON Files
Blog post: Extending and customizing the Help
Blog post: Collaborate on content for Business Central
Blog post: Reusing classic object-based Help on your Dynamics 365 Business Central Help Server
Docs Contributor Guide
Docs Authoring Pack for Visual Studio Code
Custom Help Toolkit
2/6/2023 • 2 minutes to read • Edit Online
Microsoft has published a GitHub repository with scripts and tools that can help you prepare customized Help
for your Business Central solution. This Help content can then be accessed from the user interface through the
Learn more links as described in Configure Context-Sensitive Help. You are welcome to use any tools or
processes to build and deploy content; this toolkit is intended to help you in some of the steps that are required.
TIP
You are not required to use the toolkit. It's available for you to use if it makes sense for your Business Central solution.
For example, if you deploy Business Central on-premises, you might want to set up a dedicated website with
customer-specific content that includes customized content from Microsoft. However, Microsoft's content is
optimized for the learn.microsoft.com site.
If your solution extends Business Central online with additional capabilities, we recommend that you set up a
website with your own content. To build the HTML files, use any third-party tool that you prefer, such as DocFX.
The GitHub repository includes source code for the tools, and we welcome contributions and feedback to
collaborate on improving the toolkit.
Custom Help
Depending on your solution, you are expected to deploy Help to a website that can be accessed by users of your
solution to supplement or replace Microsoft's content. For more information, see User Assistance Model and
Configuring the Help Experience. The toolkit is especially useful if you deploy a customer-specific solution that is
based on Microsoft's base application. If your solution extends Business Central online with additional
capabilities, we recommend that you set up a website with your own content. To build the HTML files, use any
third-party tool that you prefer, such as DocFX.
TIP
Microsoft's content in the various GitHub repos is optimized for the learn.microsoft.com site and the tools that are used
for this site. We encourage you to supplement our content with solution-specific content as opposed to attempting to
customize our content to fit your needs. But we acknowledge that there are situations when customizations are required,
and the toolkit's tools can help you achieve that.
See also
Configure Context-Sensitive Help
User Assistance Model
Migrate Legacy Help to the Dynamics 365 Business Central Format
Extend and Collaborate on the Help for Dynamics 365 Business Central
Custom Help Toolkit: The FieldTopicTextExtractor
tool
2/6/2023 • 2 minutes to read • Edit Online
If you are migrating a solution from Dynamics NAV to Business Central, you can use this tool to export the text
contained in the first paragraph of field-level Help topics for Microsoft Dynamics NAV 2018 or earlier versions.
You can then use these paragraphs as tooltip text in your Business Central solution.
NOTE
The tool does not import the tooltip text directly into your Business Central page objects. It creates a spreadsheet that
will make it easier to reuse the text from field-level Help topics in your Business Central solution.
PA RA M ET ER DESC RIP T IO N
n Specifies the path to the HTML files with Dynamics NAV field
topics.
Examples
The following example extracts the introductory paragraph from T_*.html files in D:\NAV to an Excel spreadsheet
with the name Field_topic_summaries*.xlsx in D:\BC:
See also
Custom Help Toolkit
Migrate Legacy Help to the Business Central Format
Extend and Collaborate on the Help for Dynamics
365 Business Central
2/6/2023 • 18 minutes to read • Edit Online
The source files for the Help for the base application are available in public GitHub repos so that you can easily
extend and customize the content for your customers. In this section, you can learn about working with the
GitHub repos and Markdown files. You can also find guidance in the Learn Contributor Guide.
The dynamics365smb-docs and dynamics365smb-devitpro repos contain the source content in English (US).
When Microsoft publishes an update to the content, the main branch in the corresponding public GitHub repo is
updated. Typically, the source repo is updated weekly.
TIP
You do not have to get acquainted with GitHub if you just want to get the Microsoft content in HTML format to deploy
to a website, for example. You do not even have to get a GitHub account, as shown in the Getting by without GitHub
section. However, in many scenarios, you might want to join us in GitHub for closer collaboration and easier extensibility.
If you fork one of our repos, you can choose to update your fork with regular updates from the Microsoft repo.
The source repo, dynamics365smb-docs, contains packages of Markdown files for major versions and
snapshots of the docs for the previous minor version.
For example, go to https://github.com/MicrosoftDocs/dynamics365smb-docs/releases to get the release that
you need for your solution.
Guidance about what the Microsoft-provided content for Business Central is all about is available at User
Assistance Model.
The following table lists some of the key subjects that you should know about.
Files and subfolders in the GitHub repos What the GitHub repos contain
How to interact with the GitHub repos Get updates from Microsoft
The mechanics of working in GitHub based on our internal Get started with GitHub
contributor guide
TO L EA RN M O RE A B O UT T H IS SUB JEC T GO TO T H IS SEC T IO N
Potential problems you might have when you customize Known issues with Microsoft's content
Microsoft's content
Using the Dynamics 365 Translation Service to manage Translate the content
translations
TIP
The source repo, dynamics365smb-docs, contains packages of Markdown files for major versions and snapshots of the
docs for the previous minor version.
For example, go to https://github.com/MicrosoftDocs/dynamics365smb-docs/releases to get the release that you need
for your solution.
If you want to contribute to the developer and administration content, clone or fork the
https://github.com/MicrosoftDocs/dynamics365smb-devitpro-pb repo.
$languages = $("da-dk","de-ch","de-de")
$git = "C:\Program Files\Git\cmd\git.exe"
$docfx = "C:\GitHub\DocFx\docfx.exe"
$365docs = "C:\GitHub\MSFT\dynamics365smb-docs"
$langDir = "c:\Working\help\dynamics365smb-docs-pr."
TIP
You can also use DocFX to generate content for the legacy Dynamics NAV Help Server. In that case, use the NAV
docfx.json file from dynamics365smb-docs.
Learn more at Properties for build section in the DocFx user manual.
The docfx.json files in the Microsoft repos have additional settings for the learn.microsoft.com site. If you
build the HTML files based on the docfx.json in the Microsoft repos, make sure that you have configured
it for your needs.
For example, in the globalMetadata section, set the ROBOTS property. We encourage you to use apply the
ROBOTS: NOINDEX, NOFOLLOW metadata to any customized versions of Microsoft's content. The intent is that
search engines will find Microsoft's original content on the learn.microsoft.com site rather than any
customizations that you and hundreds of other may have published. Set the metadata in the individual
files, or set it in the globalMeta section of docfx.json if you build using docfx.exe. For an example, see the
ui-work-with-notes.md file in GitHub, which we have deprecated but kept in the repo as an example.If you
use the docfx.json file to build HTML files for non-Microsoft functionality, then set the value of the
ROBOTS property when you build Microsoft's content. You can also add other global metadata, or
metadata that applies to specific subfolders.
3. Go to your desktop and open a command prompt.
4. Go to the docfx installation folder.
5. Run the equivalent of the following command:
docfx "c:\GitHub\MSFT\dynamics365smb-docs\business-central\docfx.json"
The files are generated as .html files and stored in the output location that is specified in the docfx.json file.
IMPORTANT
DocFx is no longer used internally in Microsoft and does not support YAML and other changes that we're making to our
content. Depending on the website that the HTML files will be deployed to, you might not be able to use the table of
contents file (TOC.html) that is generated in this process. That file is structured based on the configuration of the
https://learn.microsoft.com site. If you use the legacy Dynamics NAV Help Server, then you must use the ToC.xml file
instead.
The root of the MicrosoftDocs repos contain files that are related to internal Microsoft processes, such as
.openpublishing.build.ps1 . These scripts are used to validate and preview content, but they rely on internal
Microsoft resources that are not publicly available. The .openpublishing.redirection.json file lists files that were
published to the learn.microsoft.com site but have been deprecated later. As part of standard website practices,
the learn.microsoft.com site uses redirection to avoid broken links when a page is deleted, and the
.openpublishing.redirection.json file provides the mapping for redirection.
For inspiration for how to build your own help website, go to How-to: Customize DFM Engine in the DocFx user
manual and the Azure App Service documentation.
For tips and tricks about writing in Markdown, go to the Authoring Guide.
Links to anchors across languages
If your website supports two or more locales, you can use DocFx to generate HTML files for the relevant
languages. However, you may experience problems with links to anchors, also known as bookmarks.
For example, if your content has a link from article1.md to a specific section in article2.md, that link would be
formatted like this: [My translated subheading](article2.md#my-translated-subheading) . Then, when you run
DocFx to generate HTML files in Danish, DocFx will convert that link to
[Min oversatte overskrift](article2.md#min-oversatte-overskrift) . That is not a problem because the link will
work in both English and Danish.
But if you then want to use that link elsewhere, the link only works for one of the languages because the anchor
changed its name in the Danish translation. If you link to that subheading in article2 from your marketing site or
support site, or if you use it as the value of the ContextSensitiveHelpPage property, then it only works in English.
To work around this problem, we recommend that you create explicit anchors by tagging your subheading to
give it a fixed anchor. The following example illustrates how that would look in MarkDown:
### <a name="subheading"></a>My translated subheading
You would then be able to use the same link across all locales:
[My translated subheading](article2.md#subheading) , which would render in HTML as
myurl.com/docs/article2#subheading across all languages.
For more information, see Using hashtag in cross reference in the GitHub documentation.
NOTE
Adding fixed anchors is only relevant if you want to generate a link to a subheading that works consistently across
languages.
Alternatively, you can add a post-processing step to the script that you use to run DocFx to change the
equivalent of <h3 id=da-DK-anchor-name> with <h3 id=en-US-anchor-name> . In this example, the step would
change <h3 id=min-oversatte-overskrift'> to <h3 id=my-translated-subheading'> .
Contributing
A benefit of GitHub is the ability for you to contribute to the core content that the Microsoft team provides for
Business Central. There is a lot of good advice and best practices published in the Microsoft Docs contributor
guide. But this section provides information about how to apply that advice to the Business Central content.
We have two public GitHub repos that you can contribute to:
MicrosoftDocs/dynamics365smb-docs
This repo contains a copy of the source files for the business functionality content that publishes at
https://learn.microsoft.com/en-us/dynamics365/business-central
MicrosoftDocs/dynamics365smb-devitpro-pb
This repo contains a copy of the source files for the developer and admin content that publishes at
https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro
For example, you might have a new article that you think would be beneficial, or you might have a correction to
an existing article. If you would like to contribute to the Business Central content on the Microsoft Docs website,
you create a pull request from your repo to the target repo. The Microsoft team will then review the request and
include the changes as appropriate.
Get started
If you want to suggest a minor (or major) change to an existing article, follow these steps:
1. Find the published article, such as Using OData to Return or Obtain a JSON Document.
2. In the top right corner of the article, choose the Edit button.
Choosing the button takes you to the source file on GitHub. In this example, that's
https://github.com/MicrosoftDocs/dynamics365smb-devitpro/blob/main/dev-itpro/webservices/return-
obtain-json-document.md.
NOTE
If you're not already signed in with a GitHub account, you'll be prompted to sign in or create a new account. You
cannot contribute to the Business Central content without a GitHub account.
3. In the top right corner of the Markdown file, choose the pencil icon. Depending on who you are, you'll be
taken to a fork of Microsoft's repo, or you'll be able to work in a branch in Microsoft's repo.
4. Make the relevant changes (and remember to save the changes!).
5. Submit a pull request to the source repo.
You'll have something like this configuration in a browser:
See also
Business Central User Assistance Model
Configuring the Help Experience
Custom Help Toolkit
Custom Help Toolkit: The FieldTopicTextExtractor tool
Authoring Guide
Docs Contributor Guide
Docs Authoring Pack for Visual Studio Code
Getting started with writing and formatting on GitHub
Visual Studio Code
Atom
DocFX
Blog post: Extending and customizing the Help
Blog post: Collaborate on content for Business Central
Authoring Guide for Dynamics 365 Business Central
2/6/2023 • 15 minutes to read • Edit Online
If you are contributing to the Business Central Help, or if you are customizing and extending the Microsoft
content for your own solution, you will probably want to use the same tools, processes, and style guide that
Microsoft uses.
Resources
The Microsoft Style Guide is published online
The content on the learn.microsoft.com site generally follows the Microsoft Style Guide. The content for
Business Central varies in certain ways, partly with product-specific terminology, and a generally more
conservative approach to contractions, for example. Also, since navigation in the Business Central user
interface is different from that of other Dynamics 365 apps, our guidance for steps that describe such
navigation is slightly different. For more information, see the Write for accessibility section.
Extend and Collaborate on the Help shows you the basics of collaborating on content for Business Central
The Docs Contributor Guide has many tips and tricks for authoring in MarkDown
The Docs Authoring Pack for Visual Studio Code adds productivity tools to Visual Studio Code
Most of Microsoft's articles use a different MarkDown formatting for illustrations, such as the following:
![Lightbulb that opens the Tell Me feature.](media/ui-search/search_small.png "Tell me what you want to do")
Both formats are valid MarkDown, and both formats are supported by DocFx.exe. For more information, see
Images in the Docs Contributor Guide.
Navigation in the product
The Describing interactions with UI article in the Microsoft Style Guide also applies to Business Central content.
However, the navigation in Business Central is very different from many other Microsoft products, and users can
even pin actions and personalize their workspace in other ways that change the navigation path.
As a result, we often choose to be not very specific about how to find a given action. We write Choose the
Register Payments action, rather than try to predict if the user will find that action pinned to their action bar or
hidden away under More options , for example.
But we also have written something like this: To map text on the vendor invoice to a specific debit account, on
the Actions tab, in the General group, choose Map Text to Account, and then fill the Text-to-Account Mapping
Worksheet page.. In this example, the guidance is now outdated - the actual action is, in the default configuration
of the CRONUS demonstration company, easily discoverable in the Process part of the action bar, which is the
first place people tend to look for things. In other words, the instructions Choose the Map Text to Account action
would have made it easier for users to find the action.
The following table provides examples of how to write about the user interface in a helpful but futureproof way,
with accessibility in mind.
List On the Oppor tunity List page, Most list pages have relatively few
select the opportunity, and then actions, so let's keep things simple.
choose the Assign Sales Quote Also, most actions in the action bar for
action. list pages apply to the line entry that
you have selected.
Card On the General FastTab, in the Cards can have several FastTabs that
External Document No. field, enter each have multiple fields. Telling the
the invoice number. user to find a certain field on a specific
FastTab can save time.
Card On the Customer Card page, choose This type of action is relatively easy to
the Merge With action. find in the Actions part of the action
bar.
Document On the Lines FastTab, in the Item No. Documents, such as sales orders, have
field, enter the number of an inventory a header section and a lines section,
item or service. typically. So letting the user know
which section the field is in can save
time.
Authoring in MarkDown
The Business Central content is styled using a MarkDown syntax as described below. Extended guidance is
available in the MarkDown Reference section in the Docs Contributor Guide.
Headings
Use # for headings. For more information, see Headings in the Docs Contributor Guide.
In the source files for the Business Central content, which publishes as English (US) on the learn.microsoft.com
site, the title of an article is expected to use Title Case (capitalize each word, except prepositions) whereas
subsequent headings use Sentence case (capitalize the first word, only). The Microsoft Style Guide recommends
a different approach.
Metadata
The content on the learn.microsoft.com site includes metadata that is used by the site and feeds our internal
telemetry dashboards. The metadata is required for Microsoft's content but not necessarily for content that
extends or customizes Microsoft's content.
However, some metadata is recommended as a best practice as outlined in the following table.
M ETA DATA TA G DESC RIP T IO N
Bulleted lists
Use - or * to create bullets as shown in the following example:
- first option
- second option
- third option
TIP
It doesn't matter if you use - or * , but the current version of the Docs Authoring Pack requires each article to use one
or the other and not mix them up.
As a best practice, the MarkDown validation in the current version of the Docs Authoring Pack recommends a
blank line between options in a bulleted list for better readability in MarkDown.
Ordered lists
Use numbers for ordered lists. Do not add spaces between the lines.
1. Choose the ![Lightbulb that opens the Tell Me feature.](media/ui-search/search_small.png "Tell me what
you want to do") icon, enter **Payment Journal**, and then choose the related link.
2. In the **Payment Journal** window, on the first journal line, enter the relevant information about the
payment entry.
3. To apply a single vendor ledger entry:
4. In the **Applies-to Doc. No.** field, choose the field to open the **Apply Vendor Entries** window.
MarkDown syntax for nested tables is limited, so we recommend using HTML-syntax for nested tables in
ordered and unordered lists use HTML-syntax.
Placeholders
Rather than repeating text in two or more articles, use includes. For more information, see Included Markdown
files.
For Business Central, we use includes for boilerplate text, for content that is repeated in more than one article,
and for the product name. That way, we can make changes in just one location - and so can you.
TIP
In the dynamics365smb-docs repo, the includes are in the business-central\includes subfolder.
In December 2020, the two placeholders for the product name, prodshort.md and prodlong.md, were renamed to
prod_short.md and prod_long.md. The change solved a problem internally at Microsoft, because we have a tool that helps
identify spelling error, and that tool generated warnings for prodshort.md and prodlong.md.
Comment syntax
Useful for sections that are not ready and will not pass build checks.
Examples:
Links
Ordinary link to a different topic in the same folder
These links have the format [link text](filename.md) .
Example: [Managing Payables](payables-manage-payables.md)
target-heading is the text of the heading that you want to link to, except it is all lowercase and spaces between
words are replaced with hyphens. For example, here is the link:
[How Autoscaling Works](#how-autoscaling-works)
targetarticlename is the file name of the article, including the .md file type. target-heading is the text of the
heading that you want to link to, except it is all lowercase and spaces between words are replaced with hyphens.
For example, to link to the heading "How autoscaling works" in the article Autoscaling.md, add the following
code: [How autoscaling works](Autoscaling.md#how-autoscaling-works)
Links to anchors across languages
If your website supports two or more locales, you can use DocFx to generate HTML files for the relevant
languages. However, you may experience problems with links to anchors, also known as bookmarks.
For example, if your content has a link from article1.md to a specific section in article2.md, that link would be
formatted like this: [My translated subheading](article2.md#my-translated-subheading) . Then, when you run
DocFx to generate HTML files in Danish, DocFx will convert that link to
[Min oversatte overskrift](article2.md#min-oversatte-overskrift) . That is not a problem because the link will
work in both English and Danish.
But if you then want to use that link elsewhere, the link only works for one of the languages because the anchor
changed its name in the Danish translation. If you link to that subheading in article2 from your marketing site or
support site, or if you use it as the value of the ContextSensitiveHelpPage property, then it only works in English.
To work around this problem, we recommend that you create explicit anchors by tagging your subheading to
give it a fixed anchor. The following example illustrates how that would look in MarkDown:
### <a name="subheading"></a>My translated subheading
You would then be able to use the same link across all locales:
[My translated subheading](article2.md#subheading) , which would render in HTML as
myurl.com/docs/article2#subheading across all languages.
For more information, see Using hashtag in cross reference in the GitHub documentation.
NOTE
Adding fixed anchors is only relevant if you want to generate a link to a subheading that works consistently across
languages.
#[Overview](overview.md)
##[Topic 1](topic-1.md)
##[Topic 2](topic-2.md)
##[Topic 3](topic-3.md)
##[Topic 4](topic-4.md)
Standard phrases
All fields in Business Central have tooltips; therefore, do not document fields in Help. To refer readers to the
tooltips, use this standard phrase where relevant:
"Choose a field to read a short description of the field or link to more information."
TO P IC T IT L E N A M IN G
Sales sales-manage-sales.md
Country-specific content
To simplify content localization and translation, country-specific articles live in country-specific folders. The TOC
entries live under the "Local Functionality" parent node.
C O N T RO L N A M E TO O LT IP
Entries action View the history of transactions that have been posted for
the customer.
(72 characters including spaces)
Account Type field Specifies the purpose of the account. Total: Used to total a
series of balances on accounts from many different account
groupings. To use Total, leave this field blank. Begin-Total: A
marker for the beginning of a series of accounts to be
totaled that ends with an End-Total account. End-Total: A
total of a series of accounts that starts with the preceding
Begin-Total account. The total is defined in the Totaling field.
(522 characters including spaces)
USE IN ST EA D O F
The document has been posted. The %1 has been posted. (Translators cannot determine
the gender.)
The Unit Cost field is updated. The %1 field is updated. (Where %1 always represents
"Unit Cost".)
Teaching tips
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
2021 release wave 1 brought an interpretation of teaching tips that you can add to your Business Central
solution. Use the teaching tips from the onboarding framework to introduce users to complex pages, and to
build tours that help users understand the purpose of a complicated area, for example. Create the teaching tips
in code by setting the AboutTitle and AboutText properties.
See also
Business Central User Assistance Model
Extend and Collaborate on the Help
Configuring the Help Experience
Docs Contributor Guide
Docs Authoring Pack for Visual Studio Code
Getting started with writing and formatting on GitHub
Visual Studio Code
Atom
DocFx
Blog post: Extending and customizing the Help
Blog post: Collaborate on content for Business Central
Migrate Legacy Help to the Dynamics 365 Business
Central Format
2/6/2023 • 5 minutes to read • Edit Online
If you are building an app for Business Central, we expect you to comply with the user assistance model. That
means that tooltips and callouts explain all fields and actions, and conceptual descriptions of functionality are
published to a website. Fortunately, there are many ways in which you can migrate and reuse your existing Help
within this model.
NOTE
For apps for Business Central online, you must apply tooltips to controls and actions in both page objects and page
extensions, and you must supply context-sensitive links. For more information, see Configuring the Help Experience.
Moving to MarkDown
Converting your existing content to MarkDown can be done using third-party tools, including but not limited to
PanDoc or the Writage plugin for Word.
Once you have converted your content to MarkDown, we recommend storing your content in a repository from
where you can publish to your website, such as the following:
A Git repo in Azure DevOps
A private or public repo in GitHub
A project in MkDocs
Use open-source tools such as DocFx to generate content for your website. By working in MarkDown, you have
access to a world of open-source tools.
If you do not yet have a website that you publish content to, then there are several ways in which you can create
such a site. For example, the MkDocs project generates a website for you. You can also work with a web designer
to build a site to host your content. We recommend deploying to an Azure web app. Business Central does not
require a special design of your website, unlike the now deprecated Dynamics NAV Help Server. It's your choice
what the website looks like, including the styling.
See Also
Configuring the Help Experience
Extend and Collaborate on the Help
User Assistance Model
Development of a Localization Solution
System Requirements
Administration of Business Central Online
2/6/2023 • 11 minutes to read • Edit Online
Administrators that can manage Business Central online tenants are either an internal administrator, who is an
employee of the company that bought the Business Central subscription, or an administrator from the reselling
partner company. Some of the tools are the same, and some tools are available to partners only. Here you can
learn which tools are available to you as an administrator.
IMPORTANT
You must have a Business Central license in order to set up integration to other products, or perform any other tasks in
Business Central, except the two mentioned above. For information about licensing, see Microsoft Dynamics 365 Business
Central Licencing Guide.
For other tasks, you can access the Business Central administration center, where you can manage upgrade
schedules and other tasks. For more information, see The Business Central Administration Center.
You can also use telemetry to track usage and monitor user sessions, for example. For more information, see
Monitoring and Analyzing Telemetry and Managing Sessions.
Administration of a trial
If your organization has signed up for a Business Central trial, you can extend the free trial, and you can start the
process of finding a reselling partner to help you get a subscription. For more information, see Dynamics 365
Business Central Trials and Subscriptions.
Administration in the Microsoft 365 admin center
The Global admin role makes you an administrator of your organization's Microsoft 365 tenant. This role
means that you can manage the subscription, add or remove users, and assign or remove licenses in the
Microsoft 365 admin center. For more information, see Microsoft 365 Admin help center.
Collaboration with reselling partners
When your organization subscribes to Business Central, you have a relationship with an authorized partner of
Microsoft. The partner company assists with licensing, configuration, and other tasks. They can also help you get
telemetry about your Business Central environment.
The partner will have access to your tenant as a delegated administrator. You can configure their access to your
data. Starting in February 2022, the partner can request granular delegated admin privileges, and we
recommend that you work with your partner or partners to change their access to your tenant to use the
Dynamics 365 administrator role rather than the Global admin role. For more information, see Managing
delegated permissions as an internal administrator.
If your organization decides to switch to another partner, you must take the following steps:
1. Ask your current partner to remove the reseller relationship with you in the Partner Center
2. Remove their delegated administration privileges
a. In the Microsoft 365 admin center, under Settings , choose Par tner relationships , and then select
the partner of interest
b. In the details pane, choose Remove delegated admin
c. In the confirmation pane, choose Remove
d. Disable their user accounts in Business Central
3. Remove any settings in the Business Central administration center if the partner did not already clear
their settings.
For more information, see Internal administrators.
4. Add your new partner to your subscription, and work with them to get them set up
Unsubscribing from Business Central
If the organization decides not to continue with Business Central, you can then cancel the subscription.
In the Microsoft 365 admin portal, you can remove licenses from users. As the administrator, you can remove a
trial subscription from your company's account. But to cancel a paid subscription, you must contact your
reselling partner, and they can cancel the relevant subscription in the Partner Center. For more information, see
the Data and access when a trial or subscription ends section.
Administration as a partner
As a Business Central reselling partner, you are the administrator of the Business Central tenants of your
customers. You have access to the administration tools of their Microsoft 365 account and their Business Central
administration center where you can specify update windows. You can also log into their Business Central as a
delegated administrator if you want to reproduce errors.
Join the Microsoft Partner Network
Microsoft Partner Network (MPN) membership unlocks our best resources to differentiate your business, take
your product to market, and sell your solutions. To become a partner, you must join the Microsoft Partner
Network (MPN), at which time you will be assigned an MPN ID. MPN membership is free to all partners; you can
enroll in the MPN here.
Once signed up, you will get an MPN ID – your gateway to access all the membership resources and benefits for
your partnership with Microsoft. There is no cost to obtain a MPN ID as a Network member, and with options to
upgrade to an Action Pack subscription or work toward a competency, you can access even more benefits.
Set up your Partner Center account
Once you have joined the Microsoft Partner Network (MPN), you can set up your Partner Center (PC) account.
The Microsoft Partner Center is a generic portal where partners can sell and manage customer subscriptions for
Microsoft services, such as Microsoft 365, Azure, Dynamics 365, and others, as well as for some third-party
products. For more information, see the Partner Center documentation.
Your Partner Center account provides you with access to pricing information, tools and services, and enables
you to manage admin credentials for your company's work account. Partner Center is also where you can
purchase or renew subscriptions to Microsoft Action Packs, create a business profile to receive and manage
sales leads from Microsoft, and see if you qualify for co-selling opportunities.
Enroll in the CSP program
The Cloud Solution Provider (CSP) program helps your company to be more involved in your customers'
businesses, beyond reselling licenses. In CSP, you can choose to enroll as an indirect reseller or a direct bill
partner.
In most cases, you will enroll as an indirect reseller and then work with an indirect provider, also referred to as a
distributor, who then manages all interaction with Microsoft in terms of licensing and technology, so that you
can focus on sales and support. If you decide to enroll as a direct bill partner in order to fully own the end-to-
end relationship with both customers and Microsoft, make sure that you meet the eligibility requirements. For
more information, see Enroll in the Cloud Solution Provider program in the Microsoft Partner Center content.
The Microsoft Partner Center is a generic portal where partners can sell and manage customer subscriptions for
Microsoft services, such as Microsoft 365, Azure, Dynamics 365, and others, as well as for some third-party
products. For more information, see the Partner Center documentation.
Some indirect providers (distributors) provide their resellers with a custom portal that optimizes and enhances
the experience beyond the Partner Center. They can also provide indirect resellers with an API to automate some
of the customer onboarding steps. Contact your indirect provider to find out more.
Both indirect resellers and direct bill partners can access and support their customers' Business Central by
setting up a reseller relationship with them.
To service customers in a specific country, your partner company's Azure Active Directory (Azure AD) tenant and
CSP account must be registered in the regional CSP market that covers that country. For more information, see
Cloud Solution Provider program regional markets and currencies.
NOTE
When you buy Business Central offers on behalf of your CSP customers, the CSP offer must be available in both your own
tenant's country and in your customer's tenant's country. For example, if your tenant is located in Slovakia and the
customer's tenant is in Germany, you will not be able to sell Dynamics 365 Business Central Premium to that customer,
because this offer is currently not available in Slovakia.
Similarly, if your tenant is located in Germany and the customer's tenant is in Slovakia, you will not be able to sell
Dynamics 365 Business Central Premium to that customer, because this offer is currently not available in Slovakia.
In the Microsoft Partner Center documentation, you can learn how to request a reseller relationship with
customers, assign licenses to users, and create new subscriptions. Business Central is one of the subscriptions
that you can create, and there are Business Central-specific license types that you can assign to users.
You must also assign certain roles to users in your own organization so that they can support your customers.
Add users from your own organization
In most cases, your partner company includes employees with different responsibilities, and you can assign
different roles depending on people's responsibility. This way, you can be very explicit about who from your staff
can access your customers' data, for example.
For each user, you can assign permissions for 2 categories of tasks:
Managing your organization's account
This controls access to the functionality of the Partner Center portal
Assisting your customers
This controls access to your customers' environments
When you establish a reseller relationship with a customer in Partner Center, you must specify which people
from your organization will assist that customer's tenant as either Admin agent or Helpdesk agent. These users
can manage implementation, support, and troubleshooting tasks for your customers. Once the reseller
relationship with a customer is established, they will be able to login into the Business Central environments of
the customer without a license. The number of partner users that can access customer environments is not
restricted.
This way of accessing customer resources is called delegated administration, and the partner users are therefore
called delegated administrators or delegated admins in daily shorthand. For more information, see Delegated
Administrator Access to Business Central Online.
Since February 2022, you can set up security groups with granular delegated admin privileges to better control
who has access to which customers with which level of access to the customer's Business Central environment.
This way, the delegated admins no longer have to be global admins for the customer's Active Directory. For
more information, see the Delegated Administrator Access to Business Central Online section, and also the
Admin roles article in the Microsoft 365 admin content.
NOTE
These users cannot provide accounting services for the customers. For this purpose, the customers must use the
External Accountant license, which is also available via CSP.
Trials
Organizations can sign up for different types of trials, and some trials can be extended. For more information,
see Trials and Subscriptions.
Data and access when a trial or subscription ends
Trials can expire, and so can a paid subscription, such as if the organization does not renew the subscription,
stops payments, or if they cancel the subscription.
When a subscription expires, two special periods kick in:
Grace period
Data retention period
The grace period is a period of 30 days when the customer can still access the product without any restrictions.
After the grace period, the subscription enters the data retention period, which is another 90 days during which
only the admin users of the Azure Active Directory tenant can login into the product. After those 90 days,
Microsoft deletes the data automatically.
This policy is general across Microsoft's online offerings, as you can see in this example from Microsoft 365:
What happens to my data and access when my Microsoft 365 for business subscription ends?.
The same applies to trials that are based on the Dynamics 365 Business Central Premium Trial license. But
this does not apply to viral trials.
See Also
The Business Central Administration Center
The Business Central Administration Center API
Submitting support requests on behalf of your customer
Resources for Help and Support for Dynamics 365 Business Central
How does Microsoft handle database sizes?
Version numbers in Business Central
Get Started as a Reseller of Business Central Online
Deliver consulting services as a VAR: aka.ms/BusinessCentralConsultingServices
Monitoring and Analyzing Telemetry
Trials and Subscriptions
Understanding the infrastructure of Business Central online
Understanding the Infrastructure of Business Central
Online
2/6/2023 • 5 minutes to read • Edit Online
When someone wants to buy Business Central online, a couple of questions must be answered because
Business Central can be configured along several different axes. In this section, we describe the topology of
Business Central online so that you can make qualified decisions for how a Business Central tenant will be
deployed and configured.
TIP
Business Central is available in a limited number of markets. For more information, see Country/regional availability and
supported languages. For a visual overview of where Business Central online is deployed, see the Geographical availability
site.
TIP
For some customers, the right approach is to have multiple Azure AD tenants due to their own organizational structure.
However, in Business Central, all users of an environment must belong to the same Azure AD tenant.
If an organization's structure changes over time, admins can transfer environments from one Azure AD tenant to
another. For more information, see Move an Environment to another Azure Active Directory organization.
NOTE
The Premium and Essential subscription types give each Business Central customer one production environment and
three sandbox environment free of extra charge. If the customer requires more production environments, they can buy
additional environments through their CSP partner. Each additional production environment comes with three additional
sandbox environments and 4 GB additional, tenant-wide database capacity. In addition, starting in 2023 release wave 2,
there's a limit on how many companies you can have on a single tenant (see Operational limits).
Administrators can create the additional environments in the Business Central administration center. The
environments can be created and used in any country or region where Business Central is available, including
the countries or regions where the customer's existing environments are running. The environments quota is
applied when you try to create a new environment, or copy an existing environment, in the Business Central
administration center.
Each environment can be divided into multiple companies, where each company defines a legal entity or a
business unit that has separate accounting requirements. All users who have a Business Central license for a
specific Azure AD tenant can access all companies in each Business Central environment that the Azure AD
tenant has. You can define different permissions inside Business Central. For more information, see Create Users
According to Licenses in the business functionality content.
Example
Let's review a scenario for an organization that is based in Denmark but has a subsidiary in Germany. They have
three business units in Denmark and two in Germany. The following diagram illustrates how this fictitious
company has set up their Business Central:
In this example, the production environment that is based on the Danish localization of Business Central is part
of the default assignment as described earlier. This production environment has three companies to represent
the following business units, all located in central Jutland:
The administrative headquarters
The production facilities
The Danish sales office
Contoso has chosen to add a sandbox environment with two companies so that their users can train new
employees in a safe environment. The sandbox started out as a copy of the Danish production environment.
Over time, it has become a proper training ground with some sample data that Contoso's reselling partner came
up with for them.
Because Contoso has a German subsidiary that has separate accounting requirements, they decided to buy
another production environment. This extra environment has two companies, one for the sales offices in
Munich, and one for the warehouse near Stuttgart.
The users in all three environments are defined in the same Azure AD tenant. This way, all licensed users can
work in all environments. Individual access to various capabilities is controlled through permissions.
Alternatively, the organization could have chosen to use a separate Azure AD tenant for the German subsidiary
so that the German environment could use the Essentials license type rather than the Premium license type.
The following diagram illustrates how things would look for Contoso if they wanted to use two different license
types:
In this type of configuration, users from the Danish Azure AD tenant cannot access the German environments.
However, Business Central supports consolidation of financial data from different companies so that Contoso's
HQ can still get a complete overview of the business.
IMPORTANT
As the examples illustrate, the Azure AD tenant plays an important role in how users can access Business Central. Users
from one Azure AD tenant cannot access environments that belong to another Azure AD tenant.
Contoso is just an example to illustrate how the Azure AD tenant both affects and reflects the organizational
structure. In some cases, this example is overly simplistic; in other cases, the example is too complicated. We
recommend that customers work closely with their Microsoft reselling partner to understand how to configure
their Business Central online.
TIP
For information about how to find out which Azure region a Business Central environment is deployed to, see the
overview at Country/regional availability and supported languages.
See Also
Administration of Business Central Online
Production and Sandbox Environments
The Business Central Administration Center
The Business Central Administration Center API
Version numbers in Business Central
Monitoring and Analyzing General Data Protection Regulation
Get Started as a Reseller of Business Central Online
Deliver consulting services as a VAR: aka.ms/BusinessCentralConsultingServices
Get Started as a Reseller of Business Central Online
2/6/2023 • 12 minutes to read • Edit Online
If you want to build your business on Dynamics 365 Business Central online, you must get set up as a reseller in
the Microsoft Partner Center. In this article, we take you through the first steps in your journey.
NOTE
When you buy Business Central offers on behalf of your CSP customers, the CSP offer must be available in both your own
tenant's country and in your customer's tenant's country. For example, if your tenant is located in Slovakia and the
customer's tenant is in Germany, you will not be able to sell Dynamics 365 Business Central Premium to that customer,
because this offer is currently not available in Slovakia.
Similarly, if your tenant is located in Germany and the customer's tenant is in Slovakia, you will not be able to sell
Dynamics 365 Business Central Premium to that customer, because this offer is currently not available in Slovakia.
In the Microsoft Partner Center documentation, you can learn how to request a reseller relationship with
customers, assign licenses to users, and create new subscriptions. Business Central is one of the subscriptions
that you can create, and there are Business Central-specific license types that you can assign to users.
You must also assign certain roles to users in your own organization so that they can support your customers.
Add users from your own organization
In most cases, your partner company includes employees with different responsibilities, and you can assign
different roles depending on people's responsibility. This way, you can be very explicit about who from your staff
can access your customers' data, for example.
For each user, you can assign permissions for 2 categories of tasks:
Managing your organization's account
This controls access to the functionality of the Partner Center portal
Assisting your customers
This controls access to your customers' environments
When you establish a reseller relationship with a customer in Partner Center, you must specify which people
from your organization will assist that customer's tenant as either Admin agent or Helpdesk agent. These users
can manage implementation, support, and troubleshooting tasks for your customers. Once the reseller
relationship with a customer is established, they will be able to login into the Business Central environments of
the customer without a license. The number of partner users that can access customer environments is not
restricted.
This way of accessing customer resources is called delegated administration, and the partner users are therefore
called delegated administrators or delegated admins in daily shorthand. For more information, see Delegated
Administrator Access to Business Central Online.
Since February 2022, you can set up security groups with granular delegated admin privileges to better control
who has access to which customers with which level of access to the customer's Business Central environment.
This way, the delegated admins no longer have to be global admins for the customer's Active Directory. For
more information, see the Delegated Administrator Access to Business Central Online section, and also the
Admin roles article in the Microsoft 365 admin content.
NOTE
These users cannot provide accounting services for the customers. For this purpose, the customers must use the
External Accountant license, which is also available via CSP.
Cau t i on
Quite often, partner users are registered as business-to-business (B2B) guest users in their customer's Azure
Active Directory (Azure AD), such as to collaborate through Teams. However, when a partner user is added as a
guest to their customer's Azure AD, they can no longer log in as a delegated admin into the customer's Business
Central. These guest users do not have a valid Business Central license assigned to them. But if the partner user
has granular delegated admin privileges, they can access the customer's Business Central administration center
and manage the environments there. Starting in 2022 release wave 2, partner users that are guest users and
have granular delegated admin privileges are no longer blocked from accessing Business Central. But we
continue to consider it a best practice that customers do not invite partner users to their tenant as guests but
ask them to set up granular delegated admin privileges, using the Dynamics 365 administrator role. For more
information, see Move to GDAP and remove DAP in the Partner Center FAQ.
For more information, see Delegated Administrator Access to Business Central Online.
Step 2: Go to market
When you become a Microsoft Partner Network member, you gain access to membership benefits that can help
you build and grow your business. For more information, see Explore your Go-To-Market with Microsoft offers
in the Partner Center docs.
As a Dynamics 365 reseller, you benefit from Microsoft's investments in an always up-to-date modern platform,
you can bundle recognized apps from the Microsoft commercial marketplace into an offering that fits the needs
of your customers, reach more customers by using Microsoft's commercial marketplace to promote your
packaged consulting service offerings or customization services, and streamline your own processes and build
tools with Power BI, Power Automate, and Power Apps connected to Business Central.
The Dynamics 365 Business Central Partner Portal landing site has plenty of material to help you build a
practice, go to market, drive readiness, and keep track of upcoming events (requires a partner account).
Marketing assets
Microsoft provides marketing assets that you can use to build a business based on Microsoft. For more
information, see the following sites:
Partner Network resources
Brand and trademark basics for partners
Go-to-market with Microsoft
Specifically for going to market with Business Central, Microsoft provides resources and guidance on the
Business Applications for small and medium-sized businesses (SMBs) site. For more information, see Business
Central Go-To-Market resources.
IMPORTANT
Specifically for businesses who want to convert a 30-day trial company into their actual production company, the first
user who signs into Business Central after the license was applied to their tenant must be a user with this license
assigned. This way, the 30-day trial ends, and any trial-related notifications disappear so that users can use Business
Central to do work.
If an administrator is the first person to sign in after the license was applied to the tenant and to users, then the trial will
continue until it expires.
If the customer has tried out Business Central using a pre-configured demonstration company that you have
prepared in other ways, they can now sign up for Business Central using their own work or school account so
that you can assign the Business Central license to their Microsoft 365 tenant.
You can help them migrate their data from their legacy system. For more information, see Migrate On-Premises
Data to Business Central Online.
See also
Administration of Business Central Online
Deployment of Dynamics 365 Business Central on-premises
Trials and Sign-ups for Business Central Online
Licensing in Dynamics 365 Business Central
Learn how to partner with indirect providers in the Cloud Solution Provider program
Dynamics 365 Business Central Partner Portal
Country/regional availability and supported
languages
2/6/2023 • 7 minutes to read • Edit Online
This page lists the countries/regions where Dynamics 365 Business Central is available and which languages are
supported.
NOTE
In countries where Microsoft has not delivered a localization, partners can build localizations using translation and
localization apps that are published on AppSource. These apps are built on top of the international (W1) version of
Dynamics 365 Business Central.
The following table provides the list of all countries/regions where Dynamics 365 Business Central is available
or in planning for future availability. The table also specifies the abbreviation of the relevant country-specific
environment that you'll see in the admin center. Finally, the table and states whether the localization is provided
by Microsoft or partner(s).
NOTE
Availability in the list concerns Dynamics 365 Business Central online. It does not apply to partner localizations. Please
check partner localization app availability on AppSource.
For an overview of where Business Central online is deployed, see the Geographical availability site.
Supported languages
To maximize productivity Dynamics 365 Business Central supports many languages. It is important to know that
language support requires translation of platform captions and application captions (UI). Translated platform
captions are provided by Microsoft for all supported languages. Application languages are provided by both
Microsoft and partners, depending on the language.
Application languages delivered by Microsoft are provided as language apps, available on AppSource, that can
be installed if needed. Partners can also provide application translation for any platform supported language. To
use one of these languages the app publisher must be contacted through AppSource.
This table gives an overview of supported languages and how application languages are provided.
L A N GUA GE LO C A L E T RA N SL AT IO N A P P P RO VIDED B Y
See Also
Rules and Guidelines for AL Code
Checklist for Submitting Your App
Delegated Administrator Access to Business Central
Online
2/6/2023 • 10 minutes to read • Edit Online
As a Business Central reselling partner, you must set up your employees to work in Partner Center, and you
must assign employees to support your customers. When you request a reseller relationship with a customer,
you can choose to include delegated administration privileges for Azure Active Directory (Azure AD) and
Microsoft 365 in the request email that you send to the customer.
TIP
Since February 2022, you can request access to your customer's tenant with granular delegated admin privileges. This
way, you set up security groups to specify which users in your own organization must have access to a specific customer
as Dynamics 365 administrator or any other role you prefer. For more information, see Introduction to granular delegated
admin privileges (GDAP) in the Partner Center content. We recommend that you switch off any existing relationship and
request granular delegated admin privileges instead. For more information, see the GDAP FAQ.
When a customer accepts a partner's request for granular delegated administration privileges, the relevant
members of the specified security group in the partner's Azure AD tenant get access as indicated in the
following list:
The Dynamics 365 Administrator role gives access to manage Dynamics 365 for the customer, including
support requests
The Service Support Administrator role gives access to manage support requests on the customer's behalf
The Helpdesk Administrator role gives access to the customer's Azure AD tenant.
For more information, see Least-privileged roles in the GDAP section of the Partner Center content.
The members of the security group have either the Admin agent or Helpdesk agent role in your own Azure AD
tenant. For more information, see Assign roles and permissions to users.
For certain tasks, you can access the Business Central administration center, which is a powerful tool for you to
manage your customers' tenants. From the administration center, you can manage upgrades and access the
tenants as the delegated administrator. For more information, see The Business Central Administration Center.
TIP
Always include the domain or the Azure Active Directory ID of the customer in the URL when you log in as a delegated
admin, such as in https://businesscentral.dynamics.com/contoso.com/admin . This way, you always know exactly
which customer you are trying to access.
Cau t i on
Quite often, partner users are registered as business-to-business (B2B) guest users in their customer's Azure
Active Directory (Azure AD), such as to collaborate through Teams. However, when a partner user is added as a
guest to their customer's Azure AD, they can no longer log in as a delegated admin into the customer's Business
Central. These guest users do not have a valid Business Central license assigned to them. But if the partner user
has granular delegated admin privileges, they can access the customer's Business Central administration center
and manage the environments there. Starting in 2022 release wave 2, partner users that are guest users and
have granular delegated admin privileges are no longer blocked from accessing Business Central. But we
continue to consider it a best practice that customers do not invite partner users to their tenant as guests but
ask them to set up granular delegated admin privileges, using the Dynamics 365 administrator role. For more
information, see Move to GDAP and remove DAP in the Partner Center FAQ.
NOTE
Customers can choose to configure conditional access that may restrict delegated admin access further. For example, it's a
best practice to set up a conditional access policy to require multi-factor authentication for admins, and to set up terms of
use policies. Learn more at Azure AD Conditional Access documentation.
TIP
If the partner has requested access to your tenant using granular delegated admin privileges, then you can see the
relevant users in the Users list in Business Central, and you can see them in the Sign in log in your Microsoft 365 admin
center. With granular delegated admin privileges, the partner typically does not have global admin access to your tenant
but only access to Dynamics 365. You will not be able to see the name of the partner user, but you can see an ID and the
name of their company.
Delegated administrators aren't visible in the customer's Azure AD user list and can't be managed by the
customer's internal admin. However, when a delegated admin logs into a Business Central environment on
behalf of their customer, they're automatically created as a user inside Business Central. This way, the actions
performed by a delegated admin are logged in Business Central, such as posting documents, and associated
with their user ID.
With granular delegated admin privileges (GDAP), the user is shown in the Users list and can be assigned any
permissions. They aren't shown with name and other personal information but with a unique ID and their
company name. Both internal and external admins can see these users in the Users list, and they have full
transparency into what these users do through the change log, for example. But they can't see the actual name
of these users. GDAP users are listed with user names such as USER_1A2B3C4D5E6F , and an email address such as
USER_1A2B3C4D5E6F@partnerA.com , which isn't the person's actual email address. Because they aren't part of their
customer's Azure AD, their authentication email address isn't an email address at all but reflects the company
that they work for, such as Partner A . This way, the GDAP user accounts don't reveal personal information. If
you need to find out who the person behind such a pseudonym is, you'll have to reach out to the company that
this user works or worked for.
Customers can choose to configure conditional access that may restrict delegated admin access further. For
example, it's a best practice to set up a conditional access policy to require multi-factor authentication for
admins, and to set up terms of use policies. Learn more at Azure AD Conditional Access documentation.
If you don't need delegated admin help continuously, you can restrict access for the partner users into your
environment. There are two approaches that you can use to restrict delegated admin access to a Business Center
environment:
Disable a specific delegated admin user within the Business Central environment. For more information, see
How to remove a user's access.
Revoke delegated administration rights from all partner users at once in the Microsoft 365 admin center,
without breaking the reseller relationship with the partner.
In the Microsoft 365 admin center, internal administrators can find information about their partner relationships
in the Settings/Partner Relationship menu. On the same page, you can remove delegated permissions from the
partner, to restrict their access to Business Central and other services, while still keeping the reseller relationship
with them.
If you then want to allow access to your environment again, you can ask the partner to share the "Request a
reseller relationship" invitation link with you again.
For more information, see Customers delegate administration privileges to partners in the Partner Center
content.
NOTE
Quite often, partner users are registered as business-to-business (B2B) guest users in their customer's Azure Active
Directory (Azure AD), such as to collaborate through Teams. However, when a partner user is added as a guest to their
customer's Azure AD, they can no longer log in as a delegated admin into the customer's Business Central. These guest
users do not have a valid Business Central license assigned to them. But if the partner user has granular delegated admin
privileges, they can access the customer's Business Central administration center and manage the environments there.
Starting in 2022 release wave 2, partner users that are guest users and have granular delegated admin privileges are no
longer blocked from accessing Business Central. But we continue to consider it a best practice that customers do not
invite partner users to their tenant as guests but ask them to set up granular delegated admin privileges, using the
Dynamics 365 administrator role. For more information, see Move to GDAP and remove DAP in the Partner Center FAQ.
See also
Administration of Business Central Online
Get Started as a Reseller of Business Central Online
Exporting Databases
Business Central Trials and Subscriptions
2/6/2023 • 9 minutes to read • Edit Online
Organizations across the world sign up for a free Business Central trial to explore the experience. Then, when
they're ready, they talk to a reselling partner about getting a subscription. In this article, we describe how the
different types of trials work, and how the admin can remove licenses from users or cancel a subscription.
NOTE
To explore the full capabilities in Business Central, change the user experience to Premium in the Company Information
page. For more information, see Change Which Features are Displayed in the business functionality content.
Depending on the country or region, the trial includes the languages and functionality that the country or region
requires. For more information, see Changing Language and Locale.
NOTE
Business Central resellers can also set up tailored demo environments.
Make sure you understand the limitations of this type of trial, before you offer it to a prospect or customer. It is
easy to convert this type of trial to a paid subscription, but if the prospect needs more than 30 days to decide, or
if they want to add more than 25 users, then the viral trial is probably a better fit for them.
Extend trials
An organization can sign up for a free trial of Business Central. When they first sign up for Business Central, they
get access to an evaluation version that does not include all capabilities in Business Central. They can then
switch to the 30 day trial experience to enable all capabilities.
However, sometimes a 30 day trial is not enough to decide if they want to buy Business Central. In that case,
they can extend their trial with an additional 30 days. For more information, see Need More Time to Decide
Whether to Subscribe? in the business functionality content for Business Central.
NOTE
If you are a reselling partner, we recommend that you set up demo environments for prospects that need longer time to
decide if they want to buy Business Central. You can also use demo environments to help customers train their
employees, for example. Using the 30 days trials for training should be limited to just that short period. However, demo
environments cannot be used for production. For more information, see Preparing Demonstration Environments.
If the prospect wants to extend the trial further than those 30 days, they must contact a partner. The partner can
extend it another 30 days if the delegated administrator signs into the prospect's Business Central and runs the
Extend Trial Period guide.
After those additional 30 days, the prospect must either purchase Business Central or abandon Business Central.
At this point, they will have had up to 90 days with the trial experience.
TIP
As a reselling partner, you can suggest your prospects sign up for a trial, but you can also help set up a customized
demonstration environment based on a sandbox environment or a trial environment. In both cases, you can easily add or
remove functionality based on your prospects' expectations. For more information, see Preparing Demonstration
Environments.
IMPORTANT
When you share Business Central with other people from your organization, you must make sure other people are not
logged in when you delete a company.
NOTE
If a Business Central viral trial is left unused for 45 days, Microsoft considers the trial as expired, and the Business Central
is deleted.
If the trial is converted to a paid subscription before the trial expires, the countdown to 45 days of non-usage does not
apply.
IMPORTANT
Specifically for businesses who want to convert a 30-day trial company into their actual production company, the first
user who signs into Business Central after the license was applied to their tenant must be a user with this license
assigned. This way, the 30-day trial ends, and any trial-related notifications disappear so that users can use Business
Central to do work.
If an administrator is the first person to sign in after the license was applied to the tenant and to users, then the trial will
continue until it expires.
For more information about what you can do with Business Central, see Get Ready for Doing Business and
Business Functionality.
Removing a subscription
If an organization decides to stop using Business Central, an administrator must remove the subscription in the
Microsoft 365 admin center. An email notification is sent to all administrators of the account. Deleting the
subscription blocks all users from accessing their Business Central, and deletes all data.
WARNING
The subscription is deleted immediately and can not be reactivated.
For more information, see Suspend or cancel a subscription in the Partner Center content.
NOTE
Sandboxes created this way contain demonstration data for the fictitious CRONUS company. No data is copied or
otherwise transferred from the production environment.
The administrator of your Business Central and your reselling partner can create more environments in the
administration center. For more information, see The Business Central Administration Center.
See also
Sign up for a free Dynamics 365 Business Central trial
Dynamics 365 Business Central trial FAQ
Trials and Sign-ups for Business Central Online
Migrate Data
Choosing Your Dynamics 365 Business Central Development Sandbox Environment
Country/Regional Availability and Supported Translations
Get Started as a Reseller of Business Central Online
Preparing Demonstration Environments (as a partner)
Major Updates and Minor Updates for Business
Central Online
2/6/2023 • 19 minutes to read • Edit Online
This article provides an overview of what you need to know about how a major or minor update for Business
Central rolls out, and how the underlying service updates. It includes key dates, actions you need take, and
answers some common questions.
Business Central online is a service that consists of a Microsoft-maintained platform and business functionality.
Many Microsoft partners provide extra business functionality, such as to address specific industry or localization
needs. Both business functionality and service components are monitored continuously and updated as
appropriate.
New capabilities roll out in release waves that consist of a major update and monthly minor updates. Most
capabilities are made available in major updates, but some become available in minor updates. Critical fixes roll
out as soon as possible after they pass tests and have been verified in Microsoft's protected staging
environment. You can always refer to the release plan for an overview of new and upcoming functionality. And
keep an eye out for the minor updates at aka.ms/bclastminorupdate.
TIP
All updates that Microsoft applies to Business Central online are also shipped with the subsequent cumulative update for
Business Central on-premises. For example, see Update 18.3 for Microsoft Dynamics 365 Business Central online 2021
release wave 1 and Dynamics 365 Business Central On-Premises 2021 Release Wave 1 Updates, respectively.
Microsoft is committed to delivering predictable updates to the service. Updates are continuous, touchless
updates that provide new features and functionality. They eliminate the need to do expensive upgrades every
few years. Administrators can set a maintenance window for each environment that determines when Microsoft
is allowed to update that environment. For more information, see Managing Updates in the Business Central
Admin Center. Microsoft then schedules updates of the business functionality to be applied during these
maintenance windows.
You are in control and manage how your organization receives these updates. Microsoft applies updates to each
environment based on your configuration. The only exception is how Microsoft maintains the underlying
platform with invisible updates during low traffic hours, for example. For more information, see the Service
updates section.
Each new update is designed and developed by the Dynamics 365 team. Any new update is first validated by the
feature team, then validated in combination with the full product. During this time, extensive testing is done on
various test topologies. A compatibility checker also runs tests to ensure backward compatibility.
The following table describes the milestones with example dates for the two release waves in any given calendar
year.
Update starts rolling out April 8 October 8 The default date when
Microsoft starts upgrading
your environments. Once
the update is scheduled,
you can change that date,
within the allowed date
range, to a date that suits
you better.
Last scheduled update date June 1 December 1 The last date you can
choose to extend your
upgrade date to.
IMPORTANT
The update window was temporarily extended during the CoViD-19 pandemic and throughout 2022 release wave 2 and
2023 release wave 1. In 2022 release wave 2 and 2023 release wave 1, the update window remains 60 days. Based on
feedback, we're currently evaluating the best longer-term processes for major updates and update windows. We expect
that on October 1, 2023, when we release 2023 release wave 2, new policies will be in place that could include a return to
an update window that again is 30 days after an update is available.
We recommend that you keep any apps and per-tenant extensions ready for upgrade at any given time, and that you
actively test compatibility. We encourage everyone to use the time until October 1, 2023, to get apps, per-tenant
extensions, and processes ready for a shorter update window.
TIP
There are many benefits to keeping code current and staying on top of updates. Microsoft and members of the
community continue to provide more and more tools and best practices to help.
Developers can get tips and guidance in the developer docs here: Maintain AppSource Apps and Per-Tenant Extensions.
Admins can install, update, and uninstall apps in the Business Central administration center as described here: Managing
Apps.
The following table describes the milestones with example dates for a minor update in any given calendar year.
Update is available May 07 The date when the new minor version
of Business Central is first available and
admins can schedule the update.
Update rolls out automatically May 14 The default date when Microsoft starts
upgrading your environments, 7 days
after the first availability date. Once
the update is scheduled, you can
change that date, within the allowed
date range, to a date that suits you
better.
Last scheduled update date May 28 The last date you can choose to extend
your upgrade date to, 21 days after
the update is available.
TIP
The minor updates tend to become available on the first Friday of any given month, except the months when a major
update becomes available. Microsoft aims to update the last environments 2-3 weeks later.
Update availability
The major updates are typically made available twice a year, in April and in October. Minor updates roll out every
month. Get an overview of the release plans at Dynamics 365 and Microsoft Power Platform release plans. For
Business Central release plans, select a release wave under Dynamics 365 , then look under SMB in the table of
contents.
On the release day for any update, all new sign-ups and all newly created environments (sandbox and
production), are directed to the new version. For existing environments that run on the previous version,
updates are made available gradually across the supported regions over the coming days and weeks as
indicated earlier in this article. It's not possible to speed up this process for your environment through Microsoft
Support.
Schedule updates
When the update becomes available for your environment, a notification email is sent to all notification
recipients that you've registered in Business Central administration center. A notification about the update
availability is also shown in the Business Central administration center itself.
Starting this day, you can use the Business Central administration center to schedule the date when you prefer
the update to happen.
The following fields on the environment page can help you plan the update:
Available Update Version Specifies the version to which you can update your
environment
Update Scheduling Available Specifies whether it's possible for you to change the update
date. The options are Yes or No .
Scheduled Update Date Specifies the default update date set by Microsoft. You can
change this date to one you prefer, if Update Scheduling
Available is set to Yes
Update Window (UTC + offset) Specifies the hours of the day that an update can run. (UTC
+ offset) indicates the time zone, represented as
Coordinated Universal Time plus or minus the difference in
hours and minutes.
Update Rollout State Microsoft can sometimes postpone the updates for various
reasons. This field provides information that can help you
track the current state of the rollout. For more information
about what happens in such cases, see Postponed updates
IMPORTANT
If you don't set a date in the Scheduled Update Date field, Microsoft will update the environment automatically on any
day between the default date and the date that is shown as the last possible update date in your notification email. If you
don't want your environment to be updated automatically, change the update date to one that fits you better.
When the scheduled update date arrives, the update runs automatically within the update window that you've
specified for this environment. All users will be disconnected from this environment, and all attempts to sign in
during the update will be blocked with the message Service is under maintenance .
IMPORTANT
We strongly encourage that you set an update window for all production environments so that updates don't start
during business hours.
For more information, see Set the update window for each environment.
NOTE
When you select a current date for your update, but the update window defined for this environment has already passed,
the update will start within that time window, but on the day after the one that you defined for your environment.
For example, if you're changing the Scheduled update date to the current date at 6 PM, and your update window is
set to 1 AM - 7 AM, the update will not start immediately, but after 1 AM on the next day.
TIP
Make sure each environment has the right contacts set up t get email notification. For more information, see Managing
Tenant-Specific Notifications.
Postponed updates
In critical circumstances, Microsoft can decide to postpone the rollout of the updates, such as if a critical issue is
discovered in the upcoming major version. While Microsoft is working on addressing the issue, the updates will
be postponed. You'll receive email notification, and you'll see the notification displayed in the Business Central
administration center. The Version Management section for each environment will show the update rollout
state as Postponed.
If we do not know the nature of the issue and the solution in advance, we can't predict when the updates will
resume again. As a result, neither the email nor the notification in Business Central administration center will
contain the information about the expected resume date. In these extreme cases, Microsoft actively works on
resuming updates as a matter of highest priority once the issue is addressed. You'll receive another email
notification when updates have resumed. The last available date will be prolonged by the number of days that
the update was postponed.
If it happens that you schedule the update of an environment to a date when the updates are postponed, the
environment will not be updated. Microsoft will not send separate notification. You can reschedule the update to
a later date, or you can wait until you have received the email notification that the updates have resumed. All
environments that missed their scheduled update date will be rescheduled automatically to run the update
within seven days from the date the updates were resumed. You can change that date to any other allowed date,
including the current date.
If you didn't explicitly set a date for your environment update in the Business Central administration center, this
environment will be picked up for updating automatically, shortly after the updates have been resumed. The
update will still be executed within the specified update time window.
Prepare, test, and learn before a major update
You can prepare yourself, users, and any customizations by trying out the new major version before your
production environment is updated. The following sections provide recommendations for how to prepare for an
update.
IMPORTANT
We strongly recommend that you test any critical business scenarios before your production environments are updated
to the new major or minor version.
NOTE
Previews roll out gradually across the world, so if the option is not showing up for you today, please try again tomorrow.
The newly created preview sandbox environment contains demonstration company data. Trying the preview on
a copy of your current production data is not yet supported; nor is testing the upgrade from your current
version to the preview. However, you can use the newly created sandbox environment for exploring and learning
the new product capabilities. You can also use the preview environment to validate that any per-tenant
extensions are still working as expected.
If you run your tests on a preview environment one month before the announced major release of Business
Central, it is more likely that the coming updates of your production environments will go smoother. This way,
you, your customers, and your code are better prepared for the official release.
We expect to update the preview version only if we discover critical issues before the major update is generally
available for production environments. Apart from these potential fixes, we do not expect any further changes to
the product between the preview and the official release. You can start your testing and learning activities
immediately, without waiting for the official release.
NOTE
You will be able to test the update on a copy of your production data in a sandbox environment when we release the new
update in production in April or October, respectively. When the official release becomes available, you can continue your
tests on that version. You will no longer be able to create new preview sandboxes.
IMPORTANT
The preview version as well as all sandbox environments that are based on it will be removed 30 days after the official
release becomes available.
For more information, see Prepare for major updates with preview environments.
Prepare for major updates just before the production environment is updated
As soon as you're notified that the new major update is available, you can test the new version. Just create a
sandbox environment that you then schedule to be updated. Start by copying your production environment into
a sandbox on the same version as your production environment. All newly created environments are
automatically included in the update process within one hour. You'll get notified that the update is available, and
you'll be able to schedule the newly created sandbox for update within one hour after it was created. By default,
the newly created environments are scheduled to run the update within seven days from the date they were
created, but you can change that date to any other allowed date, including the current date.
If you change the update date to the current date, the update will start within the closest available update time
window you specified for the environment. If you want to start the update of your sandbox environment
immediately, you can set the update time window for this sandbox environment to be 24 hours.
Microsoft monitors each update of an environment. If we detect any errors during the update, you'll receive
email notification that describes the detected issues.
Any environments that fail to update due to per-tenant extension compatibility issues or any other issues are
automatically restored to the original application version. Within one hour, they are automatically rescheduled
for another update attempt. The scheduled update date is automatically set to seven days in the future to give
you time to resolve the issues. If you address the compatibility issues sooner, you can change the date to an
earlier date, including the current date. This pattern repeats until the environment is updated successfully.
IMPORTANT
Changing date to an earlier date might be blocked up to 24 hours after the last failed attempt to update.
Overview of the timeline for preparing for the next major update
The following figure illustrates the suggested steps for getting a preview of a major update with example dates
for the two release waves in any given calendar year.
The following table provides more information for the suggested steps with example dates for the two release
waves in any given calendar year.
A few days before you March 31 September 30 You create a new sandbox
know that the update is environment based on your
announced existing production
environment (copy your
production environment
into a sandbox) and wait for
it to be updated to the new
version.
Preview sandboxes are May 1 November 1 30 days after the new major
deleted update is announced, the
preview sandboxes are
deleted. There will be no
option to keep these
sandboxes or export data
from them.
Service updates
The service components apply to multiple environments, such as all tenants in a region. So Microsoft schedules
those updates to a time when traffic is lower in each region, typically during the evening or night. Typically, these
service updates are transparent to any users, as the service is designed to manage traffic in a way that any users
still working in Business Central are not affected by these service updates.
These updates do not add or remove functionality, and they are transparent to business users.
See also
Managing Major and Minor Updates of Business Central Online
Working with Administration Tools
The Business Central Administration Center
Managing Environments
Managing Tenant Notifications
Introduction to automation APIs
Version numbers in Business Central
2/6/2023 • 2 minutes to read • Edit Online
Business Central online and on-premises consists of different components that must work together. If you are a
an enduser, this doesn't matter in the course of your normal work day. But if you are an administrator, knowing
the version numbers is important for troubleshooting, development, and on-premises upgrade scenarios.
You can use the information about which version the tenant is on to help you troubleshoot an issue that a user
has reported, for example. This information is listed in the Troubleshooting section of the Help and Suppor t
page in Business Central in the following format:
In the Business Central administration center, the version information is rendered slightly differently:
The numbers are updated based on Microsoft's builds. In the default version of Business Central online, platform
and application have the same major version number but different build numbers. If you perform a technical
upgrade of Business Central on-premises, then platform and application will have different versions.
The following list describes the meaning of each of the numbers in a full version number:
major is the major version of Business Central
20 is the Business Central 2022 release wave 1 update in April 2022 and forward
19 is the Business Central 2021 release wave 2 update in October 2021 and forward
18 is the Business Central 2021 release wave 1 update in April 2021 and forward
17 is the Business Central 2020 release wave 2 update in October 2020 and forward
16 is the Business Central 2020 release wave 1 update in April 2020 and forward
15 is the Business Central 2019 release wave 2 update in October 2019 and forward
14 is the Business Central April 2019 release
13 is the Business Central October 2018 release
12 is the April 2018 launch of Business Central
minor is the monthly update number, such as 0, 1, or 5.
build is the five digit build number, such as 23456.
revision is set to 0 for the original release and can remain at 0. However, if the tenant is patched with a
hotfix, then that build number can be applied.
In other words, if you see a version number such as 20.1.23456.26323 , then it means major version 20, update
number 1, build number 23456, and hotfix number 26323.
The same version numbers are used to identify versions in Business Central on-premises, including when you
deploy containers on Docker.
See Also
Managing Technical Support
Installing a Cumulative Update
Administration of Business Central Online
Operational Limits for Business Central Online
2/6/2023 • 7 minutes to read • Edit Online
To ensure the availability and quality of Business Central services, there are limits on certain operations. This
article describes the limits and, in some cases, the strategy behind them.
TIP
Telemetry is gathered on some of the operations that have a limit. The telemetry provides insight into operations for
which limits were exceeded. For more information, see Monitoring and Analyzing Telemetry.
Max file size The maximum size of files that can be 350 MB
uploaded to or downloaded from the
service.
Maximum stream read size The maximum number of bytes that 1,000,000 bytes
can be read from a stream (InStream
object) in a single AL read operation.
Examples include READ or
InStream.READTEXT method calls. This
setting pertains to UTF-8 and UTF-16
text encoding; not MS-DOS encoding.
Database limits
SET T IN G DESC RIP T IO N VA L UE
SQL connection idle timeout The time that a SQL connection can 5 minutes
remain idle before being closed.
SQL connection timeout The time to wait for the service to 1.5 minutes
connect to the database. When the
time is exceeded, the attempt is
canceled and an error occurs. This
setting also applies to begin, rollback,
and commit of transactions.
Long running SQL query threshold The amount of time that an SQL query 1000 ms
can run before a warning telemetry
event occurs. If this threshold is
exceeded, the following event is
logged: Action completed successfully,
but it took longer than the given
threshold.
Background sessions default wait The maximum amount of time that 8 hours
timeout background sessions will wait to be
processed.
Child sessions max queue length The maximum number of child 100
sessions that can be queued per
parent session. If the value is exceeded,
an error occurs.
SET T IN G DESC RIP T IO N L IM IT
Page background task default timeout The default amount of time that page 2 minutes
background tasks can run before being
canceled. Page background tasks can
be also given a timeout value when
enqueued at runtime. This limit is used
when no timeout is provided when the
page background task is enqueued.
Page background task max timeout The maximum amount of time that 10 minutes
page background tasks can run before
being canceled. Page background tasks
can be also given a timeout value
when enqueued at runtime. If a page
background task is enqueued with a
timeout greater than this limit, this
limit is ignored.
Report limits
SET T IN G DESC RIP T IO N L IM IT
Default max execution timeout The maximum execution time that it 6 hours
can take to generate a report by
default. Users can override this setting
on a report-basis from the report
request page. If exceeded, the report
will be canceled.
Query limits
SET T IN G DESC RIP T IO N L IM IT
TIP
This company limit will take effect in 2023 wave 1 release. When in effect, exceeding the limit will prevent you from doing
some environment operations. For information about the consequences of exceeding the limit, go to Operational
challenges with many companies per environment.
If you already have more than 300 companies in one environment, distribute them across more environments to avoid
problems later.
Max body size The maximum request body size. 350 megabytes
Max page size The maximum number of entities 20,000 entities per request
returned per OData request.
Max batch size The maximum number of operations in 100 operations per batch
an OData $batch request.
See Also
Working with API Rate Limits
Microsoft API Terms of Use
Technical Support for Dynamics 365 Business
Central
2/6/2023 • 5 minutes to read • Edit Online
Each customer of Business Central has a partner who assists with technical support. As a Business Central
reselling partner, you are an administrator of your customers' Business Central tenants, and you are the first line
of support. You will get requests for support from your customers that you must triage, investigate, and either
resolve or escalate to Microsoft.
In this section, you can learn about the tools that are available to you to help you troubleshoot your customers'
Business Central.
IMPORTANT
You must have set up users in your own tenant in Partner Center as either Admin agent or Helpdesk agent, and they
must have delegated administration privileges in your customer's Business Central to support the customer. For more
information, see Delegated Administrator Access to Business Central Online.
ISSUE T Y P E SIT E
Submit support request on behalf of your Business Central Start at the Business Central administration center where
online customers you can easily submit a support request in the Power
Platform admin center
Collaboration on the AL language and developer experience The AL Developer Preview GitHub repo
As an ISV, report an issue in production code, such as a The Partner Center Support site - choose the Marketplace
problem with Microsoft's application, upgrade, or telemetry Offers category, and then choose the relevant category in
the Problem type field, such as Dynamics 365 Business
Central Development > Core Application issues. You'll be
asked to check resources and then to provide issue details.
ISSUE T Y P E SIT E
Report bug in supported in-market versions of Business The Support for business site
Central on-premises
IMPORTANT
To submit support requests on behalf of your customer, you must be a delegated admin on the customer tenant. Your
company must also have the Advanced or Premier support plan. For more information, see the Escalating support issues
to Microsoft section.
TIP
When you submit your first support ticket as a partner, you must specify details about your company's support plan. If
you or your colleagues do not know these details, contact your Microsoft rep.
F O R Q UEST IO N S REL AT ED TO C O N TA C T
Problems with listing or publishing apps to AppSource due The Partner Center Support site - choose the Marketplace
to Commercial Marketplace issues offers category, and then choose the relevant category in
the Problem type field, such as Availability > Dynamics
365 Business Central offer.
Microsoft Partner Network, Partner Center, Cloud Solution The Partner Center Support site
Provider program
Technical issues with PSBC, PartnerSource, or Order Central Email IT MBS Support
Volume licensing The Call Logging Tool site or email Online Licensing
See Also
Inspecting and Troubleshooting Pages
The Business Central Administration Center
Managing Technical Support
Deployment Overview
Administration of Business Central Online
Administration of Business Central On-Premises
Provide technical support (Microsoft Partner Center)
Providing support to your customers (Microsoft Partner Center)
Production and Sandbox Environments
2/6/2023 • 11 minutes to read • Edit Online
You can create environments of different types. Which type of environment to choose depends on what you
need it for.
TIP
If you're new to environments, get an overview of how Azure Active Directory, environments, and companies work in
Business Central online at Understanding the infrastructure of Business Central online.
Production environments
Production environments are meant to be precisely that: Environments that a business can run their daily
business in Business Central in, deployed on performance tiers in Azure with a guaranteed high level of
availability and support.
Production environments are backed up automatically and frequently to help protect business data. For more
information, see How often are production databases backed up?.
You can create additional production environments for training or performance testing, for example. However,
for training purposes, in many cases organizations will prefer to create a sandbox environment with production
data. You can also create additional production environments to support offices in different countries.
NOTE
The Premium and Essential subscription types give each Business Central customer one production environment and
three sandbox environment free of extra charge. If the customer requires more production environments, they can buy
additional environments through their CSP partner. Each additional production environment comes with three additional
sandbox environments and 4 GB additional, tenant-wide database capacity. In addition, starting in 2023 release wave 2,
there's a limit on how many companies you can have on a single tenant (see Operational limits).
Administrators can create the additional environments in the Business Central administration center. The
environments can be created and used in any country or region where Business Central is available, including
the countries or regions where the customer's existing environments are running. The environments quota is
applied when you try to create a new environment, or copy an existing environment, in the Business Central
administration center.
NOTE
A production environment can have a state of suspended if the subscription has been suspended, or if the environment
has not been accessed for a long time. In those cases, you can only publish extensions to such an environment if it only
has evaluation companies. If the suspended environment has been used for actual production so that it contains
companies that are not evaluation companies, then you cannot publish extensions to it.
IMPORTANT
Apps that are published to a sandbox from the development environment or created using Designer are published within
the scope of the service node that hosts the environment. When the sandbox is upgraded, these apps are removed
because the environment is moved to another node that is running the new version. However, the data of the app is not
removed, so you only have to re-publish and install the app to make it available.
Apps that are uploaded to the environments of both types (production and sandbox) using the Upload Extension
action from the Extension Management page are published within a global scope. When the environment is upgraded
or moved, these apps are downloaded to the service node and installed, which means that they will not disappear.
You can also safely use sandboxes for training, such as for following a learning path from Microsoft Learn,
because it's a safe environment to experiment with. If anything goes wrong, you just delete the sandbox and
start over.
IMPORTANT
The automatic backup that applies to production environments does not apply to sandbox environments. If you want to
export data from a sandbox environment, you can use Excel or RapidStart, but you cannot request a database export.
You can create a sandbox environment that includes data from your production environment for debugging
purposes, for example. But if you want to run performance tests, or similar benchmarking, the sandbox is not
reliable enough for that purpose. This is because sandboxes run in a different performance tier on Azure than
production environments. Instead, create a dedicated environment based on the Production environment type -
this gives you the exact experience and performance that users will experience in the actual production
environment.
Sandbox environments are handy for certain types of development scenarios because the debugging endpoint
is open by default. This means that you can attach Visual Studio Code to a running system and debug through
running code. It also allows you to publish directly to the environment from Code.
If your organization has more than one sandbox environment, you can switch between environments by
opening the App Launcher, choosing the Dynamics 365 tile, then choose the Business Central Sandbox tile. The
sandbox environment picker shows the available sandboxes, so choose the one that you want to switch to.
NOTE
The Premium and Essential subscription types give each Business Central customer one production environment and
three sandbox environment free of extra charge. If the customer requires more production environments, they can buy
additional environments through their CSP partner. Each additional production environment comes with three additional
sandbox environments and 4 GB additional, tenant-wide database capacity. In addition, starting in 2023 release wave 2,
there's a limit on how many companies you can have on a single tenant (see Operational limits).
Administrators can create the additional environments in the Business Central administration center. The
environments can be created and used in any country or region where Business Central is available, including
the countries or regions where the customer's existing environments are running. The environments quota is
applied when you try to create a new environment, or copy an existing environment, in the Business Central
administration center.
Partner sandboxes
As a partner, you can buy the Dynamics 365 Business Central Partner Sandbox license. You'll need a valid
Microsoft Partner Network (MPN) ID. You must also have at least five employees who will use the partner
sandboxes that you create using this license. This offer was made available in February 2022 to support
partners that need non-production environments to learn, test, and deliver end-to-end customer demos with
their solutions. The Partner Sandbox license gives access to Business Central Premium functionality.
IMPORTANT
The environments that you acquire through the Dynamics 365 Business Central Partner Sandbox license are strictly
meant for use only on the partner’s tenant. You are not allowed to use this license in a customer tenant, nor in a
production environment.
Use the Partner Sandbox license for an Microsoft 365 account that does not currently have a Business Central
license. This gets you 1 production environment + 3 sandboxes. Alternatively, use the Partner Sandbox license to
replace existing Business Central licenses in an existing environment; however, the license will not give you any
additional environments on top of the environments you already had.
Partners can purchase the unique, partner-only license via Web Direct to create flexible, cost-effective solutions
that do not expire. Accessing the SKUs and pricing is simple: Go to experience.dynamics.com and submit a
request for the Dynamics 365 Business Central Partner Sandbox license. Use a valid MPN ID. Once your request
is approved, you receive a token to purchase the SKUs directly. Pay by credit card. If the total billing is over
$500/month for your company, then you can pay by invoice.
Precautions for sandbox environments with production data
When an environment is created as a copy of another environment, a number of precautions are taken for that
copy:
Tasks in the job queue are automatically stopped
To see which scheduled jobs are stopped, and to decide which jobs to restart in the new environment, go
to the Scheduled Tasks page in Business Central. There, you can set tasks to be ready to run in the job
queue. However, only tasks that are marked as belonging to the current environment can run. For more
information, see View Scheduled Tasks in the business functionality content.
Any base application integration settings are cleared
Any irreversible features that were enabled in the original environment will also be turned on in the copy.
For more information, see Features that can't be turned off.
Development extensions that are published from AL-Go for GitHub or Azure DevOps and any extensions
that depend on them are uninstalled when the source environment is a sandbox. Any data that was
created in the original environment by the extensions that are now uninstalled in the copy will not be
deleted. Any updates to per-tenant extensions that are slotted to be upgraded with the next minor or
major upgrade will be retained.
Outbound HTTP calls from extensions are blocked by default and must be approved for each extension,
otherwise instead of an external call, the system will display the following error message: The request
was blocked by the runtime to prevent accidental use of production services.
To enable outbound HTTP calls, go to the Extension Management page in Business Central, and choose
Configure . Then, on the Extension Settings page, make sure that Allow HttpClient Requests is
selected. This setting must be enabled for each extension, including libraries.
Any General Data Protection Regulation (GDPR) action must be handled separately and repeated for the
environment. There is no synchronization with the original environment after the copy has been created.
The internal administrator has the same tools and responsibilities for the copy as they do for the original
environment. As a data processor, Business Central offers the same level of data protection and data
handling restrictions to all types of environments, both sandboxes and production environments.
The following setups are set to status disabled
Doc. Exch. Service Setup
Curr. Exch. Rate Update Setup
VAT Reg. No. Srv Config
Graph Mail Setup
CRM Connection Setup
CDS Connection Setup
All records in the Service Connection table
All records in the Exchange Sync table
The following data is cleared
Password in the OCR Service Setup table
SMTP Server in SMTP Mail Setup
Exchange Service URL in the Marketing Setup table
The following changes are made for first-party extensions
AMC Banking 365 Fundamentals
The Service URL in AMC Banking Setup is reset to default for Sandbox environments
Email - Outlook REST API
All email accounts of types "Microsoft 365" and "Current User" are deleted. Deleting these
records turns any existing field monitoring setup non-valid.
Email - SMTP Connector
SMTP Server details are deleted
The following changes are made for specific localizations
Spain
SII Setup is set to disabled
United Kingdom
Password in GovTalk Setup table is deleted
Netherlands
All Digipoort related fields in the Elec. Tax Declaration Setup table are cleared
Manage sandbox environments
Use the Business Central administration center to manage the environments manually. For more information,
see Managing Production and Sandbox Environments.
Alternatively, use the Administration Center API.
Pre -sales performance evaluation
If you want to provide a prospect with an online environment where you want to demonstrate the performance
and reliability of Business Central online in addition to demonstrating functionality, you must take a few extra
steps.
To demonstrate the functionality of the default version of Business Central, without focusing on performance,
you can quite simply use your own trial experience based on a Microsoft 365 demo account. We recommend
that you show the full functionality of the default version by switching the tenant to the 30 day trial and the
associated My Company. You can then enable the Premium user experience in the new My Company's
Company Information page, populate the new company with the data required for their evaluation scenarios,
and present the environment to the prospect.
To demonstrate the functionality of the service, with a focus on performance, you can take the same step as
outlined above, but then also sign up the prospect for the Business Central Premium Trial offer that is available
through your CSP access in the Partner Center, wait 24 hours, and then run your performance evaluation. For
more information, see Preparing Test Environments of Dynamics 365 Business Central.
That 30 day trial is as close to an actual production environment performance as you can get. You only have
those 29 days to run your tests and convince the prospect, of course, but provided that you have prepared
everything in advance, it should give you time enough.
If the prospect is convinced and decides to buy Business Central, you can then either let them keep the
environment that they are currently using, or create a new production environment for them. If the tenant is
yours rather than the prospect's, then a new tenant will be provided to them.
For more information about performance and Business Central, see Performance Overview.
Advanced user experience
It is possible to enable and try the full functionality of the standard version of Business Central in a sandbox
environment by setting the Experience field on the Company Information page to Premium. Find the
Company Information page in the menu in Business Central. However, we recommend that you as the
admin set up dedicated demonstration environments instead. For more information, see Preparing
Demonstration Environments.
Complete sample data
The standard demonstration company in Business Central includes sample data for a limited number of
scenarios. You can also create a new company with the Advanced Evaluation - Complete Sample Data
option. In this type of company, users can take training or step through walkthroughs that require more sample
data, such as Walkthrough: Receiving and Putting Away in Basic Warehouse Configurations. This sample data is
different from the standard sample data, and we advise that you do not capture and share screenshots with this
advanced sample data.
For more information, see Creating New Companies in Business Central in the business functionality content.
See also
Managing Environments in the Administration Center
Preparing Demonstration Environments
Preparing Test Environments
Steps to set up a sandbox environment and Visual Studio Code
Get started with the Container Sandbox Development Environment
Prepare Demonstration Environments of Dynamics
365 Business Central
2/6/2023 • 14 minutes to read • Edit Online
As a Business Central reselling partner, you might want to have an environment that you can show prospects as
part of pre-sales demonstrations. Depending on your requirements, you have several different options that are
described in this article.
Learn more about Business Central trials and subscriptions here.
TIP
We recommend that you use profiles in the Microsoft Edge browser rather than InPrivate or Incognito browser
mode. For more information, see Microsoft Edge documentation.
By now, you have a dedicated demonstration organization in Azure that includes multiple demo users with
Microsoft 365 licenses, and a Business Central environment.
The initial Business Central demo environment comes with two companies:
The CRONUS demonstration company
An empty company with the nameMy Company, but it might have a different display name for demo
purposes
You can keep using the demonstration company until the tenant expires, if you use it a couple of times per week.
However, if you start the trial experience or switch to the empty My Company, that experience will expire after
30 days. If the trial expires, you canextend the trial, create a new environment, or return to the CRONUS
demonstration company. For more information, see Dynamics 365 Business Central Trials and Subscriptions in
the business functionality content for Business Central.
You can now enable the Premium user experience in the new company's Company Information page,
populate the company with any data that is required for their evaluation scenarios, and present the environment
to the prospect.
IMPORTANT
Environments that are based on Microsoft 365 demo accounts are intended for demonstration and training purposes. If a
prospect uses such an environment to help run their business, then they risk losing their company data when the demo
environment or the Microsoft 365 demo account expires. If a prospect wants to use Business Central to help run their
business, they should sign up for a trial using their own email account. For more information, see Dynamics 365 Business
Central Trials and Subscriptions in the business functionality content for Business Central.
For example, if you sign up for a trial with a Microsoft 365 demo account, you can keep that environment for up
to a year. However, if you switch to the actual trial experience in Business Central, that experience will expire after
30 days. At that point, you can extend the trial, or you can return to the CRONUS demonstration experience,
which will still be available until your Microsoft 365 demo account expires.
Customize the demo environment
Since 2022 release wave 1, you can add the Contoso Coffee Demo Data app to your demo company to
showcase advanced supply chain functionality. Learn more here. 2022 release wave 2 adds connectivity apps
that you can learn more about here.
Because you are logged in as the global administrator of the demonstration tenant, you can access the Microsoft
365 administration center. The following list illustrates the types of work that your demo account can do:
Subscribe to additional apps and services that may be relevant to your demos
Configure apps and services by accessing their administration centers
Modify or add user accounts, and assign licenses
Set up the organizational profile to reflect your prospect's business and brand
Your administrator account also gives you access to the Business Central administration center, where you can
make further customizations, such as the following:
Create additional environments within the available quota, depending on your needs.
For example, you can create a Business Central environment for a specific country/region, or create a
dedicated sandbox that you then apply your solution to, such as by deploying your app straight from
Visual Studio Code. For more information, seeManaging Environments.
Specify the update window and date for your environments, so that planned updates will not interfere
with your demos.
Add your own email address to the list of notification recipients, so that you will be informed of upgrades
to your Business Central environments or any issues that may impact your planned demos.
Try out new functionality in preview environments that are available about two months before a major
update. For more information, seePrepare for major updates with preview environments.
With your administrator account, you can install apps from AppSource, and you can set up integrations between
Business Central and other services. For example, you can add the Business Central app for Microsoft Teams,
and you can run theSet up your Business Inbox in Outlook assisted setup guide on behalf of the
organization as described in the Use Business Central as your Business Inbox in Outlook article. You can also add
Dynamics 365 Customer Service,Dynamics 365 Sales,Power Automate,Power Apps, and many more.
Some content packs provide additional demonstration data for non-administrator accounts, such as example
channels and conversations in Microsoft Teams that can reduce the time needed to customize the experience for
a demo. You can log in with the demo user account, often called meganb@M365B123456.onmicrosoft.com , or
something similar, for the non-administrator experience.
Use profiles in Microsoft Edge
If you demo in the new Microsoft Edge browser, you can easily switch between different browser profiles. That
way, you do not have to use private mode for browsing, and you can let Microsoft Edge save passwords and
sites to any of your browser profiles, including a Microsoft 365 demo account. Business Central also performs
well in the Microsoft Edge for even better demos. You can also switch the page layout to Focused to minimize
demo distraction. For more information, see Microsoft Edge documentation.
TIP
We recommend that you connect to a low-latency network for a faster response time during demos, and that you always
plug in your laptop if you are about to demo anything. Performance impact may vary depending on your device and
choice of browser, but being plugged in generally helps overall snappiness.
NOTE
To explore the full capabilities in Business Central, change the user experience to Premium in the Company Information
page. For more information, see Change Which Features are Displayed in the business functionality content.
This type of environment can be useful if you want to demonstrate the general user interface, for example, or
talk about how they can add capabilities with apps from AppSource.
IMPORTANT
Specifically for businesses who want to convert a 30-day trial company into their actual production company, the first
user who signs into Business Central after the license was applied to their tenant must be a user with this license
assigned. This way, the 30-day trial ends, and any trial-related notifications disappear so that users can use Business
Central to do work.
If an administrator is the first person to sign in after the license was applied to the tenant and to users, then the trial will
continue until it expires.
If a prospect has signed up for a free trial, and they use Business Central to help run their business, then they
must decide whether to subscribe within the first 60 days. If they extend their trial once, and they are still not
sure, they must contact a partner.
However, in many cases, you will probably prefer to show prospects more tailored experiences with your own
trial as described in the Microsoft 365 demo plus Business Central section.
NOTE
If a Business Central viral trial is left unused for 45 days, Microsoft considers the trial as expired, and the Business Central
is deleted.
If the trial is converted to a paid subscription before the trial expires, the countdown to 45 days of non-usage does not
apply.
Connectivity apps
Starting in 2022 release wave 2, Business Central online environments can list one or more apps on the
Connectivity Apps and Banking Apps pages. We recommend that the admin opens the Connectivity Apps
page from the Extension Management page and allows the underlying extension to connect to its external
service either once or always. Business Central then connects to AppSource to generate a short list of apps that
have been approved for that country or region. These particular apps can connect to external services, such as
online banking.
If you are an ISV and want your banking app to show up in the Connectivity Apps page, reach out to us at
Microsoft. We're testing the suggested apps according to business and functional requirements. The list relies on
AppSource and is intended to show the best apps in that business's country or region for core connectivity
scenarios. Learn more at Requirements for Connectivity Apps.
TIP
Integration between Business Central and Sales happens through Dataverse. For more information, see Integrating with
Dynamics 365 Sales in the business functionality content.
To add Dynamics 365 Sales Professional to your Microsoft 365 demo account
1. In a dedicated browser window, sign in as the admin account for the Microsoft demo account that you
created in the To get a demo environment based on Microsoft 365 content packs section. For more
information, see the Use profiles in Microsoft Edge section.
2. Go to the Microsoft Dynamics 365 Sales Professional marketing page, and choose the Tr y free action,
and then follow the guidance in the steps to add the Sales trial to your account.
Once the trial is available, proceed to the next step.
3. In another browser tab, sign into Business Central at https://businesscentral.dynamics.com/?
redirectedFromSignup=1.
4. Choose the icon, enter Dataverse Connection Setup , and then choose the related link.
5. Follow the steps in the wizard to connect to your Sales trial.
To finish setting up the connection, you must run the Sales-specific assisted setup.
6. Choose the icon, enter Dynamics 365 Connection Setup , and then choose the related link.
7. Follow the steps in the wizard to connect to your Sales trial.
NOTE
The trial environment will have the Type field set to Trial (29 days). Do not convert the default environment.
After a few minutes, the trial environment is converted to a production environment, and the Type field
changes to Production.
5. Choose the converted environment again, and then choose the Conver t to sandbox action.
We recommend that you convert the environment to a sandbox environment for demo purposes. In the
sandbox environment, you can:
Reset the environment without any Dynamics 365 apps, which effectively gives you an empty Dataverse
database to connect to using the Set up Dataverse connection assisted setup if you want to integrate
Business Central just to Dataverse.
For more information, see Reset environment in the Power Platform docs, and Integrating with Microsoft
Dataverse in the business functionality content for Business Central.
Reset the environment with specific Dynamics 365 apps with or without sample data to demo to various
audiences. For more information, see Reset environment.
For example, when you reset the sandbox environment, you can choose to deploy Sales enterprise and
demo integration between Business Central and the full capabilities of Dynamics 365 Sales. For more
information, see Integrating with Dynamics 365 Sales in the business functionality content.
NOTE
Sandboxes are limited in functionality, including performance. For more information, see Sandbox environments.
Starting in February 2022, partners can request dedicated licenses to set up additional sandbox environments.
For more information, see Partner sandboxes.
See also
Preparing Test Environments of Dynamics 365 Business Central
Trials and Subscriptions
The Business Central Administration Center
Managing Environments
Administration of Business Central Online
Data and access when a trial or subscription ends
Deployment of Dynamics 365 Business Central
Offer your customers trials of Microsoft products
Preparing Test Environments of Dynamics 365
Business Central
2/6/2023 • 2 minutes to read • Edit Online
As a Business Central reselling partner, you might want to have an environment that you can use for testing or
pre-sales demonstrations. You can create such environments based on free 30 day trials, or you can set up a
dedicated environment if you have a Business Central subscription yourself.
F IEL D VA L UE
b. Make a note of the Admin credentials that are shown on the last page of the customer creation
wizard. You will need these credentials later.
2. In Partner Center, once the test customer has been created, create a new test user. For more information,
see Create user accounts for a customer in the Partner Center documentation.
3. Assign that user 1 Premium license.
NOTE
It may take up to 10 minutes for the available licenses to show up on the Users page.
Also, make a note of the user credentials shown on the last page of the user creation wizard. You will use
this information in step 55
4. In the Ser vice Management section, choose the Dynamics 365 Business Central link.
This opens the Business Central administration center at the equivalent of the following URL:
https://businesscentral.dynamics.com/contoso.onmicrosoft.com/admin
In the Business Central administration center, you can create new production and sandbox environments
for the test customer.
TIP
Always include the domain or the Azure Active Directory ID of the customer in the URL when you login as a
delegated admin. This way, you always know exactly which customer you are trying to access.
5. Access Business Central as the local user that you created in step 2.
a. Open another browser window in InPrivate or Incognito mode. This way, you can make sure that
you are not logging in with your own credentials.
TIP
We recommend that you use profiles in the Microsoft Edge browser instead. For more information, see
Microsoft Edge documentation.
b. Go to https://businesscentral.dynamics.com/, and then, when you are asked to sign in, use the
credentials of the user you created in step 2.
The Business Central environment is created automatically when you use the environment URL to login the first
time.
See also
The Business Central Administration Center
Managing Environments
Preparing Demonstration Environments
Prepare for major updates with preview environments
Administration of Business Central Online
Deployment of Dynamics 365 Business Central
Get Started as a Reseller of Business Central Online
Offer your customers trials of Microsoft products
Prepare for major updates with preview
environments
2/6/2023 • 4 minutes to read • Edit Online
About one month before a major update, you can try out new functionality in preview environments. Preview
environments are Business Central online sandbox environments that you create on a preview version of the
application. When you create the new sandbox environment, choose the preview version marked as (Preview)
from the version list. This way, you get a new sandbox environment with a preview version of the application.
Use Microsoft Collaborate to submit your feedback or to report any potential issues that you discover in the
preview. For more information about getting access to Collaborate, see Step 4 in the readiness section for
developers.
NOTE
Previews roll out gradually across the world, so if the option is not showing up for you today, please try again tomorrow.
The newly created preview sandbox environment contains demonstration company data. Trying the preview on
a copy of your current production data is not yet supported; nor is testing the upgrade from your current
version to the preview. However, you can use the newly created sandbox environment for exploring and learning
the new product capabilities. You can also use the preview environment to validate that any per-tenant
extensions are still working as expected.
If you run your tests on a preview environment one month before the announced major release of Business
Central, it is more likely that the coming updates of your production environments will go smoother. This way,
you, your customers, and your code are better prepared for the official release.
We expect to update the preview version only if we discover critical issues before the major update is generally
available for production environments. Apart from these potential fixes, we do not expect any further changes to
the product between the preview and the official release. You can start your testing and learning activities
immediately, without waiting for the official release.
NOTE
You will be able to test the update on a copy of your production data in a sandbox environment when we release the new
update in production in April or October, respectively. When the official release becomes available, you can continue your
tests on that version. You will no longer be able to create new preview sandboxes.
IMPORTANT
The preview version as well as all sandbox environments that are based on it will be removed 30 days after the official
release becomes available.
The following figure illustrates the suggested steps for getting a preview of a major update with example dates
for the two release waves in any given calendar year.
For more information, see Major Updates and Minor Updates for Business Central Online.
See also
Major Updates of Business Central Online
Managing Major and Minor Updates of Business Central Online
Working with Administration Tools
The Business Central Administration Center
Managing Environments
Managing Tenant Notifications
Step 4: Getting access to preview bits
The Business Central Administration Center
2/6/2023 • 3 minutes to read • Edit Online
The Business Central administration center provides a portal for administrators to do administrative tasks for a
Business Central tenant. Here, administrators can:
view and work with production and sandbox environments for the tenant.
set up upgrade notifications.
view telemetry for events on the tenant.
Internal administrators
As the internal administrator, you can choose the link in the Settings menu when you're signed in to Business
Central.
Alternatively, you can access the administration center from the URL, use the following pattern but replace
[TENANT_ID] with the tenant ID of your Business Central:
https://businesscentral.dynamics.com/[TENANT_ID]/admin
TIP
The tenant ID is shown in the Help and Suppor t page in your Business Central.
In the administration center, you can create and monitor environments. This is also where you manage the
people who must be notified of administrative events for your tenant.
Your partner can help you set up telemetry for production environments, including integration with Application
Insights in Azure.
Cleaning up settings
If your organization decides to switch to another partner, you must make sure that some settings that your
current partner made in your Business Central administration center are removed. This includes the following
settings:
Support contact details
1. In the Business Central administration center, choose the relevant environment, and then, in the
Suppor t menu, choose Manage Suppor t Contact .
2. Verify that the values in the Name , Email address , and the Website fields are still relevant; if not,
then delete or modify the values.
Notification recipients
1. In the Business Central administration center, on the left side, choose Notification recipients
2. Verify that the list of email addresses are still relevant; if not, then delete or modify the values.
Application Insights key (if this was set up by the partner)
1. In the Business Central administration center, choose the relevant environment, and then, in the top
menu, choose Application Insights Key .
2. Remove the value of the Instrumentation Key
Authorized Azure Active Directory Apps (if this was set up by the partner)
1. In the Business Central administration center, navigate to 'Authorized AAD Apps' and remove any apps
authorized by the partner.
2. Revoke consent granted to the AAD App belonging to the partner from your AAD Tenant. For more
information, see here.
3. Removed apps may have additional permissions assigned to execute certain administration
operations, such as the D365 BACKUP/RESTORE permission. Any apps set up with permissions in
Business Central can be disabled from the Azure Active Director y Applications page. For more
information, Assign Permissions to Users and Groups.
When you establish a relationship with a new partner, they will fill in these fields again.
NOTE
As the partner, there are certain tasks that you cannot do in your customers' Business Central. For more information, see
Acting as a delegated administrator.
See also
Production and Sandbox Environments
Managing Environments
Tenant Notifications
Environment Telemetry
Administration Center API
Managing Technical Support
Business Central Data Security
Introduction to automation APIs
Microsoft Partner Dashboard
Add a new customer in the Partner Center
Assign licenses to users in the Partner Center
Create new subscriptions in the Partner Center
Cloud Solution Provider program - selling in-demand cloud solutions
Managing Production and Sandbox Environments in
the Admin Center
2/6/2023 • 11 minutes to read • Edit Online
The Environments tab of the Business Central administration center provides you with an overview of the
Business Central production and sandbox environments for the tenant, and you can manage updates for each
environment.
Types of environments
You can create environments of different types. Choose the type of environment based on what you need it for.
For more information, see Production and Sandbox Environments.
Production environments
Production environments are meant to be precisely that: Environments that a business can run their daily
business in Business Central in, deployed on performance tiers in Azure with a guaranteed high level of
availability and support.
Production environments are backed up automatically and frequently to help protect business data. For more
information, see How often are production databases backed up?.
You can create additional production environments for training or performance testing, for example. However,
for training purposes, in many cases organizations will prefer to create a sandbox environment with production
data. You can also create additional production environments to support offices in different countries.
A production environment can have a state of suspended if the subscription has been suspended, or if the
environment has not been accessed for a long time. In those cases, you can only publish extensions to such an
environment if it only has evaluation companies. If the suspended environment has been used for actual
production so that it contains companies that are not evaluation companies, then you cannot publish extensions
to it.
NOTE
The Premium and Essential subscription types give each Business Central customer one production environment and
three sandbox environment free of extra charge. If the customer requires more production environments, they can buy
additional environments through their CSP partner. Each additional production environment comes with three additional
sandbox environments and 4 GB additional, tenant-wide database capacity. In addition, starting in 2023 release wave 2,
there's a limit on how many companies you can have on a single tenant (see Operational limits).
Administrators can create the additional environments in the Business Central administration center. The
environments can be created and used in any country or region where Business Central is available, including
the countries or regions where the customer's existing environments are running. The environments quota is
applied when you try to create a new environment, or copy an existing environment, in the Business Central
administration center.
Sandbox environments
Sandbox environments are meant to be precisely that: Environments that you can play around with, use as a
testbed for development, and delete at will. You can deploy apps straight from Visual Studio Code to a sandbox
environment, and you can attach a debugging session to a sandbox.
IMPORTANT
Apps that are published to a sandbox from the development environment or created using Designer are published within
the scope of the service node that hosts the environment. When the sandbox is upgraded, these apps are removed
because the environment is moved to another node that is running the new version. However, the data of the app is not
removed, so you only have to re-publish and install the app to make it available.
Apps that are uploaded to the environments of both types (production and sandbox) using the Upload Extension
action from the Extension Management page are published within a global scope. When the environment is upgraded
or moved, these apps are downloaded to the service node and installed, which means that they will not disappear.
You can also safely use sandboxes for training, such as for following a learning path from Microsoft Learn,
because it's a safe environment to experiment with. If anything goes wrong, you just delete the sandbox and
start over.
IMPORTANT
The automatic backup that applies to production environments does not apply to sandbox environments. If you want to
export data from a sandbox environment, you can use Excel or RapidStart, but you cannot request a database export.
You can create a sandbox environment that includes data from your production environment for debugging
purposes, for example. But if you want to run performance tests, or similar benchmarking, the sandbox is not
reliable enough for that purpose. This is because sandboxes run in a different performance tier on Azure than
production environments. Instead, create a dedicated environment based on the Production environment type -
this gives you the exact experience and performance that users will experience in the actual production
environment.
Sandbox environments are handy for certain types of development scenarios because the debugging endpoint
is open by default. This means that you can attach Visual Studio Code to a running system and debug through
running code. It also allows you to publish directly to the environment from Code.
If your organization has more than one sandbox environment, you can switch between environments by
opening the App Launcher, choosing the Dynamics 365 tile, then choose the Business Central Sandbox tile. The
sandbox environment picker shows the available sandboxes, so choose the one that you want to switch to.
NOTE
The Premium and Essential subscription types give each Business Central customer one production environment and
three sandbox environment free of extra charge. If the customer requires more production environments, they can buy
additional environments through their CSP partner. Each additional production environment comes with three additional
sandbox environments and 4 GB additional, tenant-wide database capacity. In addition, starting in 2023 release wave 2,
there's a limit on how many companies you can have on a single tenant (see Operational limits).
Administrators can create the additional environments in the Business Central administration center. The
environments can be created and used in any country or region where Business Central is available, including
the countries or regions where the customer's existing environments are running. The environments quota is
applied when you try to create a new environment, or copy an existing environment, in the Business Central
administration center.
Pre -sales performance evaluation
If you want to provide a prospect with an online environment where you want to demonstrate the performance
and reliability of Business Central online in addition to demonstrating functionality, you must take a few extra
steps.
To demonstrate the functionality of the default version of Business Central, without focusing on performance,
you can quite simply use your own trial experience based on a Microsoft 365 demo account. We recommend
that you show the full functionality of the default version by switching the tenant to the 30 day trial and the
associated My Company. You can then enable the Premium user experience in the new My Company's
Company Information page, populate the new company with the data required for their evaluation scenarios,
and present the environment to the prospect.
To demonstrate the functionality of the service, with a focus on performance, you can take the same step as
outlined above, but then also sign up the prospect for the Business Central Premium Trial offer that is available
through your CSP access in the Partner Center, wait 24 hours, and then run your performance evaluation. For
more information, see Preparing Test Environments of Dynamics 365 Business Central.
That 30 day trial is as close to an actual production environment performance as you can get. You only have
those 29 days to run your tests and convince the prospect, of course, but provided that you have prepared
everything in advance, it should give you time enough.
If the prospect is convinced and decides to buy Business Central, you can then either let them keep the
environment that they are currently using, or create a new production environment for them. If the tenant is
yours rather than the prospect's, then a new tenant will be provided to them.
For more information about performance and Business Central, see Performance Overview.
NOTE
The Premium and Essential subscription types give each Business Central customer one production environment and
three sandbox environment free of extra charge. If the customer requires more production environments, they can buy
additional environments through their CSP partner. Each additional production environment comes with three additional
sandbox environments and 4 GB additional, tenant-wide database capacity. In addition, starting in 2023 release wave 2,
there's a limit on how many companies you can have on a single tenant (see Operational limits).
Administrators can create the additional environments in the Business Central administration center. The
environments can be created and used in any country or region where Business Central is available, including
the countries or regions where the customer's existing environments are running. The environments quota is
applied when you try to create a new environment, or copy an existing environment, in the Business Central
administration center.
You can create new environments that are either production environments or sandboxes. You can also copy an
existing environment. For more information, see Copy a Production or Sandbox Environment.
To create a new environment that isn't a copy of an existing environment
1. On the Environments tab of the Business Central administration center, choose the New action on the
action ribbon.
2. In the Create Environment pane, Specify a name for the new environment.
3. In the Environment Type list, choose Production or Sandbox .
4. In the Application family field, specify the type of solution that this environment is based on if it isn't
Business Central.
5. In the Countr y list, select the country for the environment. The specified country determines the
localization for the environment and the Azure region in which the environment is created and stored.
NOTE
The new environment will be created with a default update window that guarantees future updates won't run
between 8:00 PM and 6:00 AM local time for the environment country. This update window can be changed after
the environment has been created. For more information, see Managing Updates in the Business Central Admin
Center.
6. In the Version list, specify the relevant application version for the new environment if more than one
version is available.
7. Choose the Create action.
NOTE
The new environment won't be accessible until the State shows Active.
New production environments are based on the latest production version of Business Central. New sandboxes
are based on the specified version.
IMPORTANT
Make sure that you understand the limitations of a sandbox before you create a new sandbox environment. For more
information, see the Sandbox environments section.
To delete an environment, choose the environment on the Environments tab of the Business Central
administration center, and then choose Delete on the action ribbon.
Selecting a version for a new sandbox environment
If you create a sandbox that isn't a copy of an existing environment, you must specify an application version for
the new environment. The version list will show the latest production version, which is the version used for new
production environments.
The version list may also have one or more preview versions. Preview versions are early release candidates of
upcoming releases of Business Central that are made available specifically for sandbox environments. This list
gives you access to review new functionality, validate extension compatibility, and other general testing of the
upcoming release.
When you create a sandbox environment on a preview version, the environment will automatically be updated
to new preview versions when they become available. However, the environment won't be updated to the
production version. Once a sandbox environment is on a preview version, it must stay on a preview version until
it's deleted. The environment can also be deleted if an update between preview versions fails. We recommend
that preview versions are used only for temporary testing of an upcoming release.
Delete an environment
You can delete environments in the admin center, such as when a sandbox environment isn't longer needed.
IMPORTANT
Make sure no user is using the environment before you delete it.
Also, be very careful before you choose the Delete action for the environment. The action is irreversible.
EXT EN SIO N
TYPE DESC RIP T IO N A DM IN C EN T ER API M A N A GEM EN T PA GE
Retention period
The operations are kept for 180 days, after which they're deleted.
See also
Managing Tenant Notifications
Managing Apps
Updating Environments
Managing Sessions
Copy a Production or Sandbox Environment
Rename Environments
Restoring an Environment
Move an Environment to another Azure Active Directory organization
Introduction to automation APIs The Business Central Administration Center
Manage Access to Environments
2/6/2023 • 3 minutes to read • Edit Online
This article describes admin center features that you use for controlling user access to environments. In addition
to what you do in the admin center, these features typically require configuration and set up in either Business
Central or another product or service.
NOTE
The restrictions imposed by a security group don't apply to administrators. Local and delegated admins can freely sign in
to all environments, regardless of the assigned group.
NOTE
If there are more than 10,000 groups in Azure AD, they can't all be retrieved and displayed in the admin center.
Instead, you'll see the message You have too many groups to display them all. In this case, you'll have to
enter the object ID of the group that you want to assign. You get the object ID from the Azure portal.
NOTE
This setting is only available for environments of platform version 21.1 or later.
Enabling access to an environment is one of multiple steps required to configure this capability. We recommend
that you complete all other setup steps before enabling access for an environment from the Business Central
admin center. Learn more at Set Up Access with Microsoft 365 licenses.
To turn access on or off, complete the following steps:
1. SelectEnvironments , then select the environment on which you want to change license access.
2. On the environment details page, select Modify for the Access with Microsoft 365 licenses setting.
3. In the Microsoft 365 licenses pane, turn the switch on or off.
4. Select Save and accept the confirmation dialog. The change takes effect immediately.
See also
Managing Environments
Managing Apps
2/6/2023 • 5 minutes to read • Edit Online
A Business Central environment is built as a collection of apps. These apps include Microsoft apps and third-
party apps, for example, apps from AppSource. The apps work together to provide customers with a broad set
of features to address their various business, market, and industry needs.
Updates are frequently made available for these apps by Microsoft, partners, and ISVs. App updates add new
features and fix known problems. To keep your environment up to date and running smoothly, you should check
for and install the latest updates regularly.
To help you manage app updates, the administration center includes the Manage Apps page.
Like other features in the administration center, this functionality can be used by the partner (delegated
administrator) or a local customer admin.
NOTE
In the current version, it's not possible to install new apps, either main apps or their dependencies (library apps), by using
the Manage Apps . To install the apps, continue using the Extension Management page within your Business Central
environment.
The Manage Apps lists all the apps installed on the environment and indicates whether updates are available.
When first opened, the system will start checking for updates. Wait for this operation to complete.
IMPORTANT
When an ISV provides a new version of their AppSource app, Microsoft validates it against the latest, currently available
version of Business Central at the time. If the new app version passes validation, it's made available for the customers'
environments that are running on that version of Business Central and greater. So if you're not seeing an AppSource app
update in the list, your environment may not yet be running on the version the app was registered for.
When completed, if an update is available for an app, there are two indications:
The Latest Available Version column contains the new version number of the app.
The Available Update Action column contains one of the following actions:
A C T IO N S DESC RIP T IO N S
Action required This action means that you have to do something before
you install the update for the app. For example, you may
have to first update another app or install a new app.
Select the link and read the Requirements for App
Updates pane to see what is required. For more
information, see Resolving requirements for app updates.
Install update This action means that the app is ready to install. Select
the link to start the installation.
IMPORTANT
The update will be applied immediately after you accept the confirmation dialogue. The users can continue
working during update installation, but depending on the app changes coming with the update, they may receive
a message asking them to log out and login again. It is therefore recommended that you apply the updates
outside of working hours.
TIP
Use the environment switch box at the top of the page to quickly change to your production environment.
See also
Working with Administration Tools
The Business Central Administration Center
Production and Sandbox Environments
Managing Environments
Updating Environments
Managing Tenant Notifications
Introduction to automation APIs
Managing Capacity
2/6/2023 • 7 minutes to read • Edit Online
To help our customers manage and plan their storage costs on an ongoing basis, the Business Central
administration center includes the Capacity page. The Capacity page provides an overview of the total
database storage usage, with details about the storage used by every environment. The page also displays the
currently used and the maximum allowed number of production and sandbox environments available for the
customer.
By default, Business Central customers can use up to 80 GB of database storage capacity across all their
environments (production and sandbox). This limit means that the sum of database capacity usage across all of
their environments must not exceed 80 GB. If a tenant exceeds this limit, Microsoft restricts administrative
actions that create additional environments. Exceeding the storage limit will not interrupt transaction processing
within the existing environments.
Some businesses have unique scenarios that may require additional storage. For those organizations that need
more space, there's an option to purchase extra database capacity.
Customers can purchase additional database capacity and environments through their reselling partner by
using the following add-ons to their existing license:
Dynamics 365 Business Central Database Capacity (1 GB)
Dynamics 365 Business Central Database Capacity (100 GB)
Dynamics 365 Business Central Database Capacity Overage (1 GB)
This lower-priced add-on is only available for the customers who purchased at least one Dynamics 365
Business Central Database Capacity (100 GB) add-on.
Dynamics 365 Business Central Additional Environment Add-on
Number of environments
Business Central administrators can create multiple sandbox and production type environments for various
purposes, like:
Creating more business branches
Moving into more countries
Expanding within their current country
Development
Testing changes
Learning new product capabilities
Every Business Central customer with Business Central Premium or Essential subscriptions can use one
production environment and three sandbox environments, at no extra charge.
Customers can also choose to purchase any number of additional production environments via their CSP
partner. Each additionally purchased production environment comes with three additional sandbox
environments.
Production and sandbox environments can be created and used in any country where Business Central service
is available, also in the country where the default Business Central environments are located. Additional
environments can be created by customers, administrators, and partners by using the Business Central
administration center.
When customer administrators create users in Microsoft 365 Admin Center and assign them Business Central
licenses, each user, by default, gets access to all Business Central environments (sandbox and production) under
the same single Business Central license, still acting within the scope of their license within each of these
environments. Administrators can limit users' access to any particular environment by changing their
permissions, or by removing users' access within that environment.
Customers with Premium or Essentials subscriptions purchased before October 1 2020
Existing customers with Business Central Premium or Essentials subscriptions purchased before October 1 2020
will keep their existing environment entitlements (three production and three sandbox environments) for one
year, until October 1 2021 or until their subscription is renewed or ended, whichever occurs last.
Access to two additional production environments during this period won't increase your overall database
storage capacity and won't enable extra sandbox environments. These benefits are only activated with the
production environments purchased by the customers separately.
Examples:
Your Business Central subscription renews before October 1 2021
You can use up to three production environments until October 1 2021. After that date, you'll only be
entitled to one production and three sandbox environments.
Your Business Central subscription renews after October 1 2021
You can use up to three production environments until the day your subscription renews. After that date,
you'll only be entitled to one production and three sandbox environments.
When your entitlement for two additional production environments expires, the additional production
environments you may have created during that period will still be fully available. You won't be automatically
charged for the extra environments. But to become compliant, you'll have to purchase additional production
environments via your CSP partner within 30 days following the expiration date. For more information, see the
Exceeding capacity quotas section.
Use the Capacity page to see how many environments of each type you have available for your organization.
Storage
Storage capacity usage of Business Central is represented by Database on the Capacity page.
By default, Business Central customers can use up to 80 GB of database storage capacity across all their
environments (production and sandbox). This limit means that the sum of database capacity usage across all of
their environments must not exceed 80 GB. If a tenant exceeds this limit, Microsoft restricts administrative
actions that create additional environments. Exceeding the storage limit will not interrupt transaction processing
within the existing environments.
Some businesses have unique scenarios that may require additional storage. For those organizations that need
more space, there's an option to purchase extra database capacity.
NOTE
The Premium and Essential subscription types give each Business Central customer one production environment and
three sandbox environment free of extra charge. If the customer requires more production environments, they can buy
additional environments through their CSP partner. Each additional production environment comes with three additional
sandbox environments and 4 GB additional, tenant-wide database capacity. In addition, starting in 2023 release wave 2,
there's a limit on how many companies you can have on a single tenant (see Operational limits).
Administrators can create the additional environments in the Business Central administration center. The
environments can be created and used in any country or region where Business Central is available, including
the countries or regions where the customer's existing environments are running. The environments quota is
applied when you try to create a new environment, or copy an existing environment, in the Business Central
administration center.
Apart from the default storage capacity, the customer is entitled to additional storage capacity based on the
number of Business Central licenses they own:
L IC EN SE T Y P E A DDIT IO N A L STO RA GE ( F O R EA C H L IC EN SE O F T H IS T Y P E)
Premium 3 GB
Essential 2 GB
Device 1 GB
Customers can purchase additional database capacity and environments through their reselling partner by
using the following add-ons to their existing license:
Dynamics 365 Business Central Database Capacity (1 GB)
Dynamics 365 Business Central Database Capacity (100 GB)
Dynamics 365 Business Central Database Capacity Overage (1 GB)
This lower-priced add-on is only available for the customers who purchased at least one Dynamics 365
Business Central Database Capacity (100 GB) add-on.
Dynamics 365 Business Central Additional Environment Add-on
The Storage capacity, by source section shows how much capacity is available by default, how much extra
capacity is added with user licenses, and how much additional capacity was specifically purchased via CSP.
NOTE
Since July 1, 2021, along with introduction of lower-priced capacity add-ons and per-license capacity quota extensions,
the capacity occupied by the files or Blob data stored in the Business Central database (the content of the Tenant Media
and Tenant Media Thumbnails tables) is counted towards the overall database storage capacity of the customer (tenant).
See also
Working with Administration Tools
The Business Central Administration Center
Managing Environments
Managing Apps
Updating Environments
Managing Tenant Notifications
Introduction to automation APIs
Manage Tenant-Specific Notifications
2/6/2023 • 8 minutes to read • Edit Online
You can get notified of administrative events that occur on environments in a Business Central online tenant. For
example, we send notifications when a major update is available for environments, when an environment
update has succeeded or failed, or when extensions require changes to be compatible with an upcoming update.
When these and other similar events occur on the tenant, an email is sent to the notification recipients for the
tenant.
NOTE
If a prospect has signed up for a trial of Business Central, make sure that they understand that they must sign up for
notifications. This is especially important if the prospect moves to My Company so that the tenant will expire after 30
days. For more information, see Dynamics 365 Business Central Trials and Subscriptions in the business functionality
content for Business Central.
Communication channels
Environment lifecycle events are communicated through various channels, each with their own benefits.
Email notification
Notifications are sent to all email addresses that are listed in the Notification recipients list of the Business
Central administration center. Manage the list manually by adding and removing recipients to ensure the right
individuals are notified of the event.
NOTE
It is important that at least one administrator's email address has been entered as a notification recipient to ensure
proper awareness of events requiring administrative attention.
IMPORTANT
To not miss update notifications from Microsoft, you must verify that the emails are not redirected to a spam folder by
your email software. The notifications are sent from the Microsoft account, no-reply-dynamics365@microsoft.com .
This Logic App runs every number of days (specified in deployment) and lists all updates made available to
environments that emit telemetry to the specified Application Insights resource for the specified period.
Administrators can use this to replace the many email notifications they would receive for each individual
enviroment when set up as notification recipient.
Ex a m p l e : N o t i fi c a t i o n fo r d e l e t e d e n v i r o n m e n t
This Logic App queries Application Insights every number of minutes (specified in deployment) and notifies a
user (also specified in deployment) of any deleted environments in Microsoft Teams. The action that sends the
notification in Teams can be updated to notify a Channel or Group Chat instead.
Ex a m p l e : Ta k e a c t i o n o n fa i l e d e n v i r o n m e n t u p d a t e s
This Logic App runs a query that returns any failed environment updates ever number of hours (specified in
deployment). Customize the Logic App after deploying to action the failed update, for example by opening a
case in Dynamics 365 Customer Service using the Dataverse connector.
Ex a m p l e : P o st a d a p t i v e c a r d s i n Te a m s fo r e a c h a v a i l a b l e e n v i r o n m e n t u p d a t e
This Logic App queries Application Insights every number of minutes (specified in the deployment) and posts an
adaptive card to a specified Microsoft Teams channel for each environment that has an update available. Based
on the user's choice, the Logic App will call the Business Central admin center API using an authorized service-
to-service Azure Active Directory app (configuration details specified in the deployment). The adaptive card
gives the user four choices:
Schedule the update as soon as possible ("Run Now"), and allow the update to start outside of the update
window for the environment
Reschedule the update to a specified other day
Ignore information about the update and close the card
Open the admin center
Reporting
To help you analyze Business Central telemetry, find the Power BI app in Microsoft AppSource. This app includes
an Administration report which shows an inventory of environments including various environment operations
details built with the environment lifecycle telemetry in Application Insights. Learn more here, or get it
immediately from Microsoft AppSource.
NOTE
The Power BI reports and dataset that make up this app are available on the Business Central BCTech repository on
GitHub. You can customize those resources for your own needs and publish from Power BI desktop.
T EN A N T A DM IN
M IC RO SO F T 365 M IC RO SO F T 365 C EN T ER
A P P L IC AT IO N EM A IL M ESSA GE SERVIC E H EA LT H O P ERAT IO N S
- IN SIGH T S N OT IF IC AT IO N C EN T ER [ 1] DA SH B O A RD PA GE
Environment
Created
Update Available
Update
Scheduled
Updates
Postponed/Resu
med
Update Started
Update
Succeeded/Failed
[2]
Environment
Hotfix
T EN A N T A DM IN
M IC RO SO F T 365 M IC RO SO F T 365 C EN T ER
A P P L IC AT IO N EM A IL M ESSA GE SERVIC E H EA LT H O P ERAT IO N S
- IN SIGH T S N OT IF IC AT IO N C EN T ER DA SH B O A RD PA GE
Environment
Restart
Environment
Started/Stopped
Environment
Copy
Environment
Restore
Environment
AAD Tenant
Move
Cancel Session
Environment
Setting Change
[3]
Environment
Deleted
Environment
Renamed
AppSource App
Install/Update
Scheduling
AppSource
App/PTE
Install/Update
AppSource App
Uninstall
Scheduling
AppSource
App/PTE
Uninstall
AppSource
App/PTE
Dependency
Install & Update
Orchestration
T EN A N T A DM IN
M IC RO SO F T 365 M IC RO SO F T 365 C EN T ER
A P P L IC AT IO N EM A IL M ESSA GE SERVIC E H EA LT H O P ERAT IO N S
- IN SIGH T S N OT IF IC AT IO N C EN T ER DA SH B O A RD PA GE
Installed PTE
incompatible
with next version
Service Incidents
and Advisories
Feature Change
and Deprecation
Announcements
Messages for environment lifecycle events are coming to Microsoft 365 Message Center soon.
2
Application Insights and Operations page include full failure details, email notification and Message Center
cover fewer failure reasons but include mitigation steps.
3
Examples of setting changes include changes to the environment update window, assigned security groups, and
Application Insights settings.
Cleaning up settings
If you end the relationship with a customer where you have set up your email address as a notification recipient,
you must remove the email address while you still have access to that customer's Business Central
administration center.
See also
Managing Updates in the Business Central Admin Center
The Business Central Administration Center
Managing Environments
Introduction to automation APIs
Working with Administration Tools
Managing Updates in the Business Central Admin
Center
2/6/2023 • 5 minutes to read • Edit Online
Business Central environments are updated according to the Business Central roadmap with two major updates
in April and October each year, and monthly, minor updates. For more information, see Major Updates and
Minor Updates for Business Central Online and the Dynamics 365 Release Plans.
Updates of the base application and platform are managed by Microsoft. As an internal administrator or as a
partner, you use the Business Central administration center to specify the timing of updates for each
environment and who receives notifications of when an update is available. You can also help prepare your
solution and your users by creating preview environments so that you can get acquainted with new functionality
in the product. For more information, see Major Updates and Minor Updates.
NOTE
Desktop users who are signed in during the update will receive an alert in Business Central before the update starts.
Available Update Version Specifies the version to which you can update your
environment
Update Scheduling Available Specifies whether it's possible for you to change the update
date. The options are Yes or No .
Scheduled Update Date Specifies the default update date set by Microsoft. You can
change this date to one you prefer, if Update Scheduling
Available is set to Yes
Update Window (UTC + offset) Specifies the hours of the day that an update can run. (UTC
+ offset) indicates the time zone, represented as
Coordinated Universal Time plus or minus the difference in
hours and minutes.
Update Rollout State Microsoft can sometimes postpone the updates for various
reasons. This field provides information that can help you
track the current state of the rollout. For more information
about what happens in such cases, see Postponed updates
IMPORTANT
If you don't set a date in the Scheduled Update Date field, Microsoft will update the environment automatically on any
day between the default date and the date that is shown as the last possible update date in your notification email. If you
don't want your environment to be updated automatically, change the update date to one that fits you better.
NOTE
You can choose to ignore the environment's update window when scheduling a specific update by switching
Allow the update to run outside the update window to Yes . If an update is scheduled for the same day,
this option lets it start immediately, and it lets large upgrades run for longer than 24 hours if required.
IMPORTANT
To not miss update notifications from Microsoft, you must verify that the emails are not redirected to a spam folder by
your email software. The notifications are sent from the Microsoft account, no-reply-dynamics365@microsoft.com .
For versions earlier than 2021 release wave 1, admins can't schedule the monthly minor updates. Until such
environments are updated to version 18.0 and later, the update is applied to tenant environments as it becomes
available. No notifications are sent to tenant administrators prior to the update. Notifications are sent only after
the update is applied.
See also
Major Updates of Business Central Online
Prepare for major updates with preview environments
Working with Administration Tools
The Business Central Administration Center
Managing Environments
Managing Tenant Notifications
Introduction to automation APIs
Managing Sessions in the Admin Center
2/6/2023 • 2 minutes to read • Edit Online
For each environment in the Business Central administration center, you can use the Manage Sessions page to
view information about active sessions on an environment and cancel selected sessions.
To open the page, select Manage Sessions . Use the Show session details check box to show more or fewer
details.
Cancel sessions
Canceling a session is sometimes the only way to unblock a customer. For example, a long-running report is
locking data in a table, preventing warehouse employees from working.
To cancel a session, select it from the list and then select Cancel selected sessions .
Restart environment
In some cases, canceling the sessions does not solve the problem. In those cases, you may want to restart the
environment.
To restart an environment that is causing problems for you, go to the Manage Sessions page, choose the
relevant environment, and then choose the Restar t Environment action.
IMPORTANT
Make sure that all users are signed out of all companies in the environment before you restart it.
See also
Managing Tenant Notifications
Managing Apps
Updating Environments
Rename Environments
Restoring an Environment
Move an Environment to another Azure Active Directory organization
Introduction to automation APIs
Copy a Production or Sandbox Environment in the
Admin Center
2/6/2023 • 4 minutes to read • Edit Online
You can create an environment that is a copy of an existing environment, such as a sandbox that is based on
production for troubleshooting, or a production environment that is based on a sandbox, for example. When
you create an environment as a copy of another environment, the new environment is created on the same
application version as the environment that you are copying. The new environment will contain all per-tenant
extensions and AppSource extensions that are installed and published in the original environment that is being
copied.
To copy an environment
1. In the Business Central administration center, select Environments , then select the environment that you
want to copy.
2. On the Environment Details page, choose the Copy action.
3. In the Copy environment pane, specify the type of environment that you want to create based on the
current environment.
4. Specify a name for the new environment.
5. Choose the Create action.
When the process starts, you can go to the list of your environments and see the status of the new environment.
At first, you'll see the new environment with the state Preparing , and then Active once the new environment is
fully up and running. Further status details of the copy operation can be found on the Operations page. The
original environment that the new environment is based on remains active.
Environment copies
When an environment is created as a copy of another environment, a number of precautions are taken for that
copy:
Tasks in the job queue are automatically stopped
To see which scheduled jobs are stopped, and to decide which jobs to restart in the new environment, go
to the Scheduled Tasks page in Business Central. There, you can set tasks to be ready to run in the job
queue. However, only tasks that are marked as belonging to the current environment can run. For more
information, see View Scheduled Tasks in the business functionality content.
Any base application integration settings are cleared
Any irreversible features that were enabled in the original environment will also be turned on in the copy.
For more information, see Features that can't be turned off.
Development extensions that are published from AL-Go for GitHub or Azure DevOps and any extensions
that depend on them are uninstalled when the source environment is a sandbox. Any data that was
created in the original environment by the extensions that are now uninstalled in the copy will not be
deleted. Any updates to per-tenant extensions that are slotted to be upgraded with the next minor or
major upgrade will be retained.
Outbound HTTP calls from extensions are blocked by default and must be approved for each extension,
otherwise instead of an external call, the system will display the following error message: The request
was blocked by the runtime to prevent accidental use of production services.
To enable outbound HTTP calls, go to the Extension Management page in Business Central, and choose
Configure . Then, on the Extension Settings page, make sure that Allow HttpClient Requests is
selected. This setting must be enabled for each extension, including libraries.
Any General Data Protection Regulation (GDPR) action must be handled separately and repeated for the
environment. There is no synchronization with the original environment after the copy has been created.
The internal administrator has the same tools and responsibilities for the copy as they do for the original
environment. As a data processor, Business Central offers the same level of data protection and data
handling restrictions to all types of environments, both sandboxes and production environments.
The following setups are set to status disabled
Doc. Exch. Service Setup
Curr. Exch. Rate Update Setup
VAT Reg. No. Srv Config
Graph Mail Setup
CRM Connection Setup
CDS Connection Setup
All records in the Service Connection table
All records in the Exchange Sync table
The following data is cleared
Password in the OCR Service Setup table
SMTP Server in SMTP Mail Setup
Exchange Service URL in the Marketing Setup table
The following changes are made for first-party extensions
AMC Banking 365 Fundamentals
The Service URL in AMC Banking Setup is reset to default for Sandbox environments
Email - Outlook REST API
All email accounts of types "Microsoft 365" and "Current User" are deleted. Deleting these
records turns any existing field monitoring setup non-valid.
Email - SMTP Connector
SMTP Server details are deleted
The following changes are made for specific localizations
Spain
SII Setup is set to disabled
United Kingdom
Password in GovTalk Setup table is deleted
Netherlands
All Digipoort related fields in the Elec. Tax Declaration Setup table are cleared
See also
Managing Production and Sandbox Environments in the Admin Center
Managing Tenant Notifications
Managing Apps
Updating Environments
Managing Sessions
Rename Environments
Restoring an Environment
Move an Environment to another Azure Active Directory organization
Introduction to automation APIs The Business Central Administration Center
Rename Environments in the Admin Center
2/6/2023 • 4 minutes to read • Edit Online
NOTE
This feature is in preview. It might change or be removed in the future updates.
You can change the name of any environment. The name uniquely identifies the environment from your other
environments. Before you change a name, you must consider that the name also is part of the environment's
URL. The URL is used in links to the environment in various ways. So changing the name can have significant
impact.
The renaming of an environment is logged and shown in the operations log.
To rename an environment
1. Select Environments , then select the environment you want to rename.
2. On the Environment Details page, select Rename .
3. On Rename environment page, read the information.
4. Enter the new name, and then select Rename .
5. Confirm your intent to rename the environment.
At this point, the environment state will first change to Preparing | Rename Scheduled , then to Active again
when the rename has been completed. The new name will be available immediately. The environment will no
longer be accessible using the old environment name.
You can also review the log for the Rename operation on the Operations page afterwards.
See also
Managing Tenant Notifications
Managing Apps
Updating Environments
Rename Environments
Restoring an Environment
Move an Environment to another Azure Active Directory organization
The Business Central Administration Center
Introduction to automation APIs
Exporting Databases in the Admin Center
2/6/2023 • 6 minutes to read • Edit Online
From the Business Central administration center, you can export the database for Business Central online
environments as BACPAC files to an Azure storage container.
NOTE
For each environment, you can export the database a maximum of 10 times per month. You can see the number of
exports still remaining for the current month in the Create Database Expor t pane when creating the export file.
IMPORTANT
While you can import the downloaded BACPAC file into your own SQL Server instance, Microsoft does not provide
support for creating a working on-premises environment from the BACPAC that you download from Business Central
online.
For more information, see Quickstart: Import a BACPAC file to a database in Azure SQL Database, Migrating to
Single-Tenancy From Multitenancy, and When to choose on-premises deployment.
NOTE
If you are getting an error saying your file contains corrupted data when importing the bacpac file please ensure you are
using the .NET Core version of SqlPackage.exe.
See also
SQL Server technical documentation
Quickstart: Import a BACPAC file to a database in Azure SQL Database
Delegated Administrator Access to Business Central Online
Working with Administration Tools
The Business Central Administration Center
Managing Environments
Updating Environments
Managing Tenant Notifications
Introduction to automation APIs
Restoring an Environment in the Admin Center
2/6/2023 • 7 minutes to read • Edit Online
As an administrator, you can restore an existing environment from a time in the past, within the retention period
that applies to both production and sandbox environments.
Database backups are an essential part of any business continuity and disaster recovery strategy, because they
protect your data from corruption or deletion. Business Central online uses Azure SQL Database as the
underlying database backup technology for its environments. All databases are protected by automated backups
that are continuously created and maintained by the Azure SQL service. For more information, see Databases
and backups.
Restore an environment
To restore an environment, you'll have to provide a name for the environment and a date/time from which to
restore the database.
1. Select Environments and then open the environment you want to restore.
2. Select Restore .
3. In the Restore Environment pane, specify the date and time in the past to which you want to restore
the environment.
4. Select the type to be used for the restored environment.
5. Specify a name for the restored environment.
6. Select Restore .
NOTE
For newly created environments it may take up to 30 min for the backups to be initialized, so you may not be able
to restore an environment if you have just created it.
7. When the process starts, you can go to the list of your environments and see the status of the restored
environment. At first, you'll see the new environment with state Preparing . The original environment
state remains as Active .
The restore operation duration is affected by several factors. For large or highly active databases, the restore
might take several hours. You can find more details about the factors that affect the recovery time at Recovery
time.
Once the restore is completed, the environment state will change to Active . If the restore operation fails, you
can find the failure details on the Operations page. In this case, delete the failed environment, and then try to
restore again. Contact Microsoft Support if the issue persists.
When you're satisfied with the data in the restored database, enable the users, start the job queues, and let your
organization know that the restore process is now completed and they can again use the environment.
See also
Managing Tenant Notifications
Managing Apps
Updating Environments
Rename Environments
Restoring an Environment
Move an Environment to another Azure Active Directory organization
The Business Central Administration Center
Introduction to automation APIs
Service Overview for Business Central Online
Move an Environment to another Azure Active
Directory organization
2/6/2023 • 3 minutes to read • Edit Online
In some cases, the Azure Active Directory (Azure AD) organization (also known as the Azure AD tenant) of a
Business Central customer changes after they acquire a Business Central environment. This situation can occur
for various reasons, such as the following:
Business entities merge.
An acquisition takes place.
The customer decides to use one Azure AD tenant in a specific region and stop using Azure AD tenants they
created in other regions.
The environment was mistakenly created by the reselling partner for the wrong Azure AD tenant.
In all such cases, the customers want to preserve the Business Central environments they created for the
original Azure AD tenants, and link them to the new ones instead. Microsoft Support can move an environment
from one Azure AD tenant to another, based on a support request.
Considerations
Environment data will remain unchanged during the move operation. The exact same environment will be
linked to a specified Azure AD tenant.
The country, Azure region, and type of the environment (production or sandbox) will remain the same, and
can't be changed during this operation.
The operation will involve a downtime period for the environment being moved (typically not exceeding 2
hours). So the operation needs to be coordinated with the customer and Microsoft Support.
Business Central Support doesn't provide help with moving the Business Central subscriptions, domains, and
other resources between the Azure AD tenants. Your support representative or account manager will assist
you in contacting billing to cancel or credit your previous subscription, if needed.
NOTE
User personalizations will be lost.
You might need to reconfigure some add-ins, external applications, and settings after the tenant-to-tenant
migration. Some examples include the Business Central Outlook add-in, Excel add-in, Power BI, Power
Apps, Power Automate connectors, Dataverse, user personalizations, and more.
See also
Managing Tenant Notifications Managing Apps Updating Environments Rename Environments Restoring an
Environment Managing Production and Sandbox Environments The Business Central Administration Center
Introduction to automation APIs
Environment Telemetry in the Business Central
administration center
2/6/2023 • 2 minutes to read • Edit Online
The Business Central administration center provides telemetry for the tenant environments to enable
troubleshooting and support for the tenant. The Telemetry tab provides telemetry of top-level AL events, and
any errors resulting from calls through the telemetry stack.
TIP
If your users complain of a confusing error message such as Sorry, we just updated this page. Please close and reopen.,
then you can often find the underlying problem by analyzing telemetry in the Business Central administration center. For
example, in the case of the Sorry, we just updated this page. Please close and reopen. message, the underlying problem is
often that two users are trying to modify the same data. So if both users open the same sales order, and both change a
field, then one of them will see the Sorry, we just updated this page. Please close and reopen. message, because Business
Central saves changes as soon as you move to the next field or close the page.
Filter by environment
To filter the telemetry for an environment:
1. Select a base point-in-time for the timestamp of the telemetry messages.
2. Enter a number of minutes before or after the base point-in-time to set a range of time for the timestamp. A
negative number indicates a number of minutes before the base point-in-time, and a positive number
indicates a number of minutes following the base point-in-time. For example, a value of -15 filters messages
to a timestamp range of up to 15 minutes before the base point-in-time.
3. Choose the message type.
4. Choose the environment.
5. Select Filter .
Get richer telemetry to help you troubleshoot by sending telemetry to Microsoft Azure Application Insights. For
more information, see Enable Sending Telemetry to Application Insights.
Application Insights is a service hosted within Azure that gathers telemetry data for analysis and presentation.
For more information, see What is Application Insights?.
For an overview of the telemetry types that are currently emitted, see Monitoring and Analyzing with Telemetry.
IMPORTANT
In Business Central 2020 release wave 2 (v17) and earlier, don't use an Azure Application Insights resource in Germany
regions, such as (Europe) Germany West Central or (Europe) Germany Nor th . If you do, traces from Business
Central might not be recorded in Application Insights. The mitigation is to create an Azure Application Insights resource in
a region outside of Germany. Then, when the relevant time comes, move the resource to the preferred region.
See also
Monitoring and Analyzing Telemetry
Enabling Application Insights
Working with Administration Tools
The Business Central Administration Center
Managing Environments
Managing Tenant Notifications
Introduction to automation APIs
The Business Central Admin Center API
2/6/2023 • 7 minutes to read • Edit Online
The Business Central administration center API enables administrators to programmatically do administrative
tasks for a Business Central tenant. With the API, administrators can, for example:
Query and work with production and sandbox environments for the tenant.
Set up administrative notifications.
View telemetry for events on the tenant.
For more information about administrative capabilities, see The Business Central Administration Center. This
article describes the API contracts for these administrative capabilities.
IMPORTANT
For delegated admin access, you must add the Azure Active Directory (Azure AD) application to the AdminAgents
group. If the Azure AD application is not added, the consent flow will show an error such as Need pre-consent. For more
information, see Pre-consent your app for all your customers in the Graph documentation.
Location
The Business Central administration center API is located at the following URL:
https://api.businesscentral.dynamics.com.
The Business Central administration center API supports authentication using AAD Apps.
1. Sign in to the Azure portal.
2. Register an application for Business Central administration center in your Azure Active Directory tenant.
Follow the general guidelines at Register your application with your Azure Active Directory tenant.
When you add an application to an Azure AD tenant, you must specify the following information:
Redirect URI Optional. You can grant consent from the Azure portal if
left empty.
When completed, an Over view displays in the portal for the new application.
3. Create a client secret for the registered application as follows:
a. Select Cer tificates & secrets > New client secret .
b. Add a description, select a duration, and select Add .
NOTE
Copy the secret's value for use in your client application code. This secret value is never displayed again after you
leave this page.
For the latest guidelines about adding client secrets in Azure AD, see Add credentials in the Azure
documentation.
NOTE
Copy the Application (client) ID of the registered app. You'll need this later. You can get this value from the Over view
page.
NOTE
If you intent to use the same AAD App with the Automation API and Business Central Web Services you can also
grant API.ReadWrite.All and Automation.ReadWrite.All permissions. Learn more here.
5. (optional) Grant admin consent on each permission by selecting it in the list, then selecting Grant admin
consent for <tenant name> . This step isn't required if you'll be granting consent from the Business
Central administration center. It is possible to grant consent from this page only for your own current
tenant. This works for single-tenant apps, but for multi-tenant apps you have to grant consent for each
tenant from that tenant's Azure AD portal or the Business Central administration center
6. Go to the Business Central administration center and navigate to the 'Authorized AAD Apps' page. Paste
the Application (client) ID of your app in the form to authorize an app.
7. If not already completed in step 5 you can grant consent for your app from the 'Authorized AAD Apps'
page in the Business Central administration center.
Note: There might be a short delay until the Granted status is visible in the TAC UI after refreshing.
8. (optional) Some operations in the Business Central administration center API require that the app has a
permissions assigned in the environment in addition to the authorization in the Business Central
administration center. Follow the instructions in Task 2 here to assign permissions.
NOTE
Learn more about permissions required for App Management operations here and learn more about permissions
required for Database Exports here.
NOTE
In the PowerShell example above, the guid specified to acquire the token (996def3d-b36c-4153-8607-a6fd3c01b89f) is
the resource ID of Business Central. The example gets the client credential using the app secret, but the recommended
way would be to rely on X.509 certificates.
# @name auth
POST https://login.microsoftonline.com/{{tenantId}}/oauth2/v2.0/token HTTP/1.1
Content-type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id={{clientId}}
&client_secret={{clientSecret}}
&scope={{scope}}
# @name GetEnvironments
GET {{url}}/applications/BusinessCentral/environments HTTP/1.1
Authorization: {{accessHeader}}
NOTE
If Dynamics 365 Business Central doesn't show up in search, it's because the tenant doesn't have any
knowledge of Dynamics 365 Business Central. To make it visible, an easy way is to register for a free trial for
Dynamics 365 Business Central with a user from the directory.
6. Make a note of both the Application ID and the Redirect URI . They'll be needed later.
Getting an access token with Authorization Code Flow
HTTP requests sent to the Business Central administration center API must include the Authorization HTTP
header, and the value must be an access token.
The following examples show how to obtain such a token using PowerShell. Using C# is straightforward.
PowerShell example without prompt:
$cred = [Microsoft.IdentityModel.Clients.ActiveDirectory.UserPasswordCredential]::new($UserName,
$Password)
$ctx =
[Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext]::new("https://login.windows.net/$Ten
antName")
$token =
[Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions]::AcquireToke
nAsync($ctx, "https://api.businesscentral.dynamics.com", <Application ID>,
$cred).GetAwaiter().GetResult().AccessToken
$ctx =
[Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext]::new("https://login.windows.net/$ten
antName")
$redirectUri = New-Object -TypeName System.Uri -ArgumentList <Redirect URL>
$platformParameters = New-Object -TypeName
Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters -ArgumentList
([Microsoft.IdentityModel.Clients.ActiveDirectory.PromptBehavior]::Always)
$token = $ctx.AcquireTokenAsync("https://api.businesscentral.dynamics.com", <Application ID>,
$redirectUri, $platformParameters).GetAwaiter().GetResult().AccessToken
Error Format
If an error occurs during the execution of an API method, it will respond back with an error object. While the
specifics of any error will vary from endpoint to endpoint and by the error, the error object returned should
adhere to the following structure. When an error occurs that doesn't fit this structure, it typically indicates that
an error occurred in sending the request or during authentication of the request. For example, it could be that
the API hasn't yet received the request.
Error Response Object:
{
"code": string, // A stable error code describing the type an nature of the error. Ex: EnvironmentNotFound
"message": string, // A message with a readable description of the error and cause. Intended to assist with
debugging or troubleshooting the API, it's not intended to be displayed.
("target": string), // Optional - Provides information about what part of a request caused the error. Ex:
The name of a property on the request body.
("extensionData": {...}), // Optional - A key/value dictionary object containing additional information
about the error.
("clientError": [ // Optional - A nested list of error objects containing more details about the error
encountered. For instance, this may be used if multiple errors are encountered to list them all out.
{
"code": string,
"message": string,
"target": string,
"extensionData": {...},
"clientError": [...]
})
]
}
NOTE
These permissions sets are the same permission sets that allow you to use Extension Management page in tenant.
Other App management endpoints, like update or availableupdates , don't require these permission sets.
Install an App
INTRODUCED IN: API version 2.6
Installs an app on an environment.
Content-Type: application/json
POST /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/apps/{appId}/install
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment.
appId - ID of the targeted app.
Body
{
"targetVersion": "1.2.3.4", // Optional. If not provided, latest version will be installed. Required if
"allowPreviewVersion": true
"useEnvironmentUpdateWindow": false/true, // If true, the operation will be executed only in the
environment update window. It will appear as "scheduled" before it runs in the window.
"allowPreviewVersion": false/true, // If "allowPreviewVersion": true, targetVersion is required
"installOrUpdateNeededDependencies": false/true, // Value indicating whether any other app dependencies
should be installed or updated; otherwise, information about missing app dependencies will be returned as
error details
"acceptIsvEula": false/true, // Must be true for installation to proceed. Setting this to true means you
agree to the terms described in the acceptIsvEula section that follows.
"languageId": "en-US" // Optional. Specifies locale ID language code, for example, "en-US". This setting
corresponds to what the user can set in Extension Management page in tenant.Full list of values can be found
in /openspecs/office_standards/ms-oe376/6c085406-a698-4e12-9d4d-c3b0ee3dbc4a under BCP 47 Code column
}
acceptIsvEula
IMPORTANT
By setting the acceptIsvEula property to true , you not only agree with ISV's end-user license terms (EULA) but also
with these terms:
I give Microsoft permission to use or share my account information so that the provider or Microsoft can
contact me regarding this product and related products and Microsoft may share contact, usage, and
transactional information for suppor t, billing, and other transactional activities. I agree to the provider's
terms of use and privacy policy 2 and understand that the rights to use this product do not come from
Microsoft, unless Microsoft is the provider. Use of AppSource is governed by separate terms and privacy .
2 You should be able to find the terms of use and privacy policy from
the app's download page on AppSource.
Links to these documents are typically under Details + Suppor t > Legal . Or, if you can't find this information,
contact the provider.
Response
Example 200 OK response with body:
{
"id": "35601559-224a-47d5-8089-86ac88b2b995", // ID of the operation used for tracking the update request
"type": "install", // Type of the operation, for this endpoint, it's "install"
"sourceAppVersion": "", // Current version of app on the tenant. In case of Install, it is always empty as
no version is installed
"targetAppVersion": "1.2.3.4", // Version of app that will be installed.
"status": "scheduled", // An enum that indicates the status. Values include: "scheduled", "running",
"succeeded", "failed", "canceled", "skipped"
"createdOn": "2021-03-22T15:44:57.9067589Z", // Date and time the request was created
"errorMessage": "" // Error message for failed operations
}
Example 400 Bad Request response when dependent apps need to be installed first:
{
"code": "EntityValidationFailed", // Error code
"message": "Error details", // Detailed error message
"data": { // Any additional data for the error. For example, when "installOrUpdateNeededDependencies" in
the request body was set to false, and there are dependencies that must be first installed or updated.
"requirements": [ // List of requirements you need to fulfil before you can run the request
{
"appId": "1ed76016-b288-401c-92e1-75b2d47ff223",
"name": "Contoso App",
"publisher": "Contoso",
"version": "16.0.32.0",
"type": "install" // enum | "install", "update", "uninstall")
}
]
}
}
Uninstall an App
INTRODUCED IN: API version 2.6
Uninstalls an app from an environment.
Content-Type: application/json
POST /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/apps/{appId}/uninstall
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment.
appId - ID of the targeted app.
Body
{
"useEnvironmentUpdateWindow": false/true, // If set to true, the operation will be executed only in the
environment update window. It will appear as "scheduled" before it runs in the window.
"uninstallDependents": false/true // Value indicating whether any other dependent apps should be
uninstalled, otherwise information about dependent apps will be returned in error details
"deleteData": false/true // Deletes data and syncs clean the extension. Exactly the same as deleting data
in Extension Management page in tenant.
}
Response
Example 200 OK response with body:
{
"id": "35601559-224a-47d5-8089-86ac88b2b995", // ID of the operation used for tracking the update request
"type": "uninstall", // Type of the operation. For this endpoint, it's "uninstall".
"sourceAppVersion": "1.2.3.4", // Current version of app on the tenant.
"targetAppVersion": "", // Target version of the app on the tenant. For uninstall, it will be always
empty.
"status": "scheduled", // An enum that indicates the status. Values include: "scheduled", "running",
"succeeded", "failed", "canceled", "skipped"
"createdOn": "2021-03-22T15:44:57.9067589Z", // Date and time the request was created
"errorMessage": "" // Error message for failed operations
}
Example 400 Bad Request response when dependent apps need to be uninstalled first:
{
"code": "EntityValidationFailed", // Error Code
"message": "Error details", // Detailed error message
"data": { // Any additional data for the error. For example, when "uninstallDependents" in the request
body was set to false, and there are existing dependent apps that need to be uninstalled first. The list of
requirements is all apps that depend on app 35601559-224a-47d5-8089-86ac88b2b995.
"requirements": [ // List of requirements you need to fulfil before you can run the request
{
"appId": "1ed76016-b288-401c-92e1-75b2d47ff223",
"name": "Contoso App",
"publisher": "Contoso",
"version": "16.0.32.0",
"type": "uninstall" // (enum | "install", "update", "uninstall")
}
]
}
}
GET /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/apps
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment.
Response
Returns information about the apps installed on the environment.
{
"value":
[
{
"id": Guid, // Id of the installed app
"name": string, // Name of the installed app
"publisher": string, // Publisher of the installed app
"version": string, // Version of the installed app
"state": string, // (enum | "Installed", "UpdatePending", "Updating")
"lastOperationId": Guid, // Id of the last update operation that was performed for this app
"lastUpdateAttemptResult": string // (enum | "Failed", "Succeeded", "Canceled", "Skipped")
}
]
}
GET /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/apps/availableUpdates
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment.
Response
{
"value":
[
{
"id": Guid, // Id of the app
"name": string, // Name of the app
"publisher": string, // Publisher of the app
"version": string, // New version available of the app
"requirements": // List of other apps that need to be installed or updated before this app can be
updated
[
{
"id": Guid, // Id of the app
"name": string, // Name of the app
"publisher": string, // Publisher of the app
"version": string, // Version the required app needs to be updated to or installed
"type": string // (enum | "Install", "Update")
}
]
}
]
}
Update an App
Updates an app using an existing endpoint, but when new parameters in the request body are available.
Content-Type: application/json
POST /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/apps/{appId}/update
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment.
appId - ID of the targeted app.
Body
{
"useEnvironmentUpdateWindow": false/true, // If set to true, the operation will be executed only in the
environment update window. It will appear as "scheduled" before it runs in the window.
"targetVersion": "1.2.3.4", // Always required. There's no option to update to the latest. You have to
first do a "availableAppUpdates", call then use the version here.
"allowPreviewVersion": false/true,
"installOrUpdateNeededDependencies": false/true, // Value indicating whether any other app dependencies
should be installed or updated; otherwise, information about missing app dependencies will be returned as
error details
}
Example 400 Bad Request response when dependent apps need to be updated first:
{
"code": "EntityValidationFailed", // Error Code
"message": "Error details", // Detailed error message
"data": { // Any additional data for the error. For example, when when "installOrUpdateNeededDependencies"
in the request body was set to false, and dependencies need to be installed or updated.
"requirements": [ // List of requirements you need to fulfil before you can run the request
{
"appId": "1ed76016-b288-401c-92e1-75b2d47ff223",
"name": "Contoso App",
"publisher": "Contoso",
"version": "16.0.32.0",
"type": "install" // (enum | "install", "update", "uninstall")
}
]
}
}
GET
/admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/apps/{appId}/operations/[{opera
tionId}]
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment.
appId - Id of the targeted app.
operationId - Id of the app update operation. Used for getting information about a specific operation.
Response
Returns the list of app update operations for the specified app. Note: operationId is provided, the single
operation is returned instead.
{
"value":
[
{
"id": Guid, // Id of the operation
"createdOn": string, // Date and time the request was created
"startedOn": string, // Date and time the installation process started
"completedOn": string, // Date and time the installation process completed
"status": string, // (enum | "Scheduled", "Running", "Succeeded", "Failed", "Canceled", "Skipped")
"sourceVersion": string, // Version of the app that was installed before the installation process
started
"targetVersion": string, // Version the installed app will be updated to
"type": string, // The type of app operation
"errorMessage": string // The error message provided when update installation fails
}
]
}
NOTE
Samples of custom notifications and automations are shared by Microsoft and third parties in the Business Central
BCTech repository on GitHub. You can also share your Application Insights alerts and automations with the community
on GitHub.
The sample below can help getting started with alerting in Microsoft Teams when app updates are available for
an environment. When updates are available, an adaptive card will be created in a Teams channel, which allows
for the automation of app updates by using S2S authentication that targets the admin center API.
Example - Run a recurrent alerting API query that sends a Teams notification when app updates are available
This Logic App runs a specified number of times a day (parameter in deployment pipeline) and lists all app
updates made available for selected environment (parameter in deployment pipeline).
Prerequisites
Business Central admin center API is configured for S2S authentication of Azure active Directory (Azure AD)
apps. For more information, go to Authenticate using service-to-service AAD Apps.
Preparation
You'll need the following information about Business Central and your Teams service to deploy the Logic App:
SERVIC E IN F O RM AT IO N
IMPORTANT
Deploying a Logic App to Azure also creates the API connection resources necessary to authenticate certain actions in the
Logic Apps. In this example, the deployment will create a connection resource for the Teams API.
If you already have an API connection resource for Teams in your resource group, you can reuse the existing connection
resource by providing its name during deployment.
See Also
The Business Central Administration Center API
Manage Apps
Microsoft Dynamics 365 Business Central Server Administration Tool
Authorized Azure AD Apps
2/6/2023 • 2 minutes to read • Edit Online
Authorized Apps are Azure Active Directory Apps authorized to call the Business Central administration center
API.
GET /admin/v2.15/authorizedAadApps
Response
[
{
"appId": "00000000-0000-0000-000000000000",
"isAdminConsentGranted": false
},
{
"appId": "11111111-1111-1111-111111111111",
"isAdminConsentGranted": true
}
]
PUT /admin/v2.15/authorizedAadApps/<appClientId>
Response
{
"appId": "00000000-0000-0000-000000000000",
"isAdminConsentGranted": false
}
DELETE /admin/v2.15/authorizedAadApps/<appClientId>
See Also
The Business Central Administration Center API
Manage Apps
Microsoft Dynamics 365 Business Central Server Administration Tool
Available Applications
2/6/2023 • 2 minutes to read • Edit Online
Get information about the currently available application families, countries, rings, and versions that
environments can be created on. The API endpoints here should be utilized to determine what values can be
used for environment creation or copying
GET /admin/v2.15/applications/
Response
{
"value": [
{
"applicationFamily": string, // The name of the family for a given Business Central offered
application. (Typically this will just be "BusinessCentral")
"countriesringDetails": {
"countryCode": string, // Code for a country that the application family supports creating
environments within.
"rings": [{ // A list of logical ring groupings where environments can be created
"name": string, // The API name of the ring (for example, PROD, PREVIEW)
"productionRing": bool, // Indicates that the ring is a production ring. Currently there should
only be one production ring within a country.
"friendlyName": string, // The display friendly name of the ring
}]
}
}
]
}
GET /admin/v2.15/applications/{applicationFamily}/Countries/{countryCode}/Rings/{ringName}
Route Parameters
applicationFamily - Family of the ring's application (for example, "BusinessCentral")
countryCode - Code for the ring's country.
ringName - Name of the ring to inspect.
Response
{
"value": [ // A list of the available application versions within the ring that environments can be
created on
"<version string>",
"<version string>",
...
]
}
See Also
The Business Central Administration Center API
Manage Apps
Microsoft Dynamics 365 Business Central Server Administration Tool
Environments
2/6/2023 • 18 minutes to read • Edit Online
Environments are the instances of the application that have been set up for the tenant. An instance can be of
either a production type or a sandbox type. The environment APIs can be used to:
Get information about the environments currently set up for the tenant
Get information about the used storage and allowed quotas
Create a new environment using sample data or as a sandbox copy of the production environment
Delete an environment.
NOTE
Special care should be taken when deleting a production environment as the data will not be recoverable
GET /admin/v2.15/applications/environments
GET /admin/v2.15/applications/{applicationFamily}/environments
Route Parameters
applicationFamily - Family of the environment's application as is. (for example, "BusinessCentral)
Response
Returns a wrapped array of environments.
{
"value":
[
{
"friendlyName": string, // Display name of the environment
"type": string, // Environment type (for example, "Sandbox", "Production")
"name": string, // Environment name, unique within an application family
"countryCode": string, // Country/Region that the environment is deployed in
"applicationFamily": string, // Family of the environment (for example, "BusinessCentral")
"aadTenantId": Guid, // Id of the Azure Active Directory tenant that owns the environment
"applicationVersion": string, // The version of the environment's application
"status": string, // (enum | "NotReady", "Removing", "Preparing", "Active")
"webClientLoginUrl": string, // Url to use to log into the environment,
"webServiceUrl": string, // Url to use to access the environment's service API
"locationName": string, // The Azure location where the environment's data is stored
"platformVersion": string, // The version of the environment's Business Central platform
"ringName": string, // Name of the environment's logical ring group (such as Prod, Preview)
"appInsightsKey": string // The environment's key for Azure Application Insights
}
]
}
GET /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
Response
Returns a single environment if exists.
{
"friendlyName": string, // Display name of the environment
"type": string, // Environment type (for example, "Sandbox", "Production")
"name": string, // Environment name, unique within an application family
"countryCode": string, // Country/Region that the environment is deployed in
"applicationFamily": string, // Family of the environment (for example, "BusinessCentral")
"aadTenantId": Guid, // Id of the Azure Active Directory tenant that owns the environment
"applicationVersion": string, // The version of the environment's application
"status": string, // (enum | "NotReady", "Removing", "Preparing", "Active")
"webClientLoginUrl": string, // Url to use to log into the environment,
"webServiceUrl": string, // Url to use to access the environment's service API
"locationName": string, // The Azure location where the environment's data is stored
"platformVersion": string, // The version of the environment's Business Central platform
"ringName": string, // Name of the environment's logical ring group (such as Prod, Preview)
"appInsightsKey": string // The environment's key for Azure Application Insights
}
Content-Type: application/json
PUT /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}
Route Parameters
applicationFamily - Family to create the new environment within (for example, "BusinessCentral")
environmentName - The name of the new environment. See the section below about valid environment names to
see what values are allowed.
NOTE
The Create, Copy, and Delete operations are asynchronous.
With API v2.8 and earlier, the response objects are returned before the underlying operation has completed. The final
results of the operation are reflected in the status field of the environment that the operations affect. In practice this
means that polling of the Get Environments endpoints must be done to determine if the given operation was successful.
With API v2.9 and later, consumers should rely on the status field of the corresponding EnvironmentOperation
response to monitor the status of the underlying operation. So, to get the updated status of the operation, consumers
should poll the Get environment operations for all environments endpoint rather than Get Environments and
inspect the status of the relevant operation.
Body
{
"environmentType": string, // The type of environment to create (enum | "Production", "Sandbox")
"countryCode": string, // The country to create the environment within
("ringName": string), // Optional - The logical ring group to create the environment within. Currently
only Sandbox type environments may be created in a 'Preview' ring. If not provided then the production ring
will be used.
("applicationVersion": Version), // Optional - The version of the application the environment should be
created on. If not provided then the latest available version will be used.
}
NOTE
The values for the countryCode , ringName , and applicationVersion properties should be derived from the API
endpoints described in the Available Applications section below.
Response
API v2.9 and later
EnvironmentOperation response with HTTP status code 202 (Accepted) with the following format:
{
"id": "11111111-aaaa-2222-bbbb-333333333333",
"type": "create",
"status": "scheduled", // Will eventually switch to running and then one between succeeded/failed
"aadTenantId": "",
"createdOn": "2021-09-27T08:13:46.65Z",
"startedOn": "2021-09-27T08:13:47.3Z",
"completedOn": "2021-09-27T08:15:02.073Z",
"createdBy": "",
"errorMessage": "",
"parameters": {
"sourceEnvironmentName": "",
"sourceEnvironmentType": "",
"destinationEnvironmentName": "NewEnvironment",
"destinationEnvironmentType": "Production",
"applicationVersion": "19.0.28719.0",
"countryCode": "US"
},
"environmentName": "NewEnvironment",
"environmentType": "Production",
"productFamily": "BusinessCentral"
}
{
"friendlyName": string, // Display name of the environment
"type": string, // Environment type (for example, "Sandbox", "Production")
"name": string, // Environment name, unique within an application family
"countryCode": string, // Country/Region that the environment is deployed in
"applicationFamily": string, // Family of the environment (for example, "BusinessCentral")
"aadTenantId": Guid, // Id of the Azure Active Directory tenant that owns the environment
"applicationVersion": string, // The version of the environment's application
"status": string, // (enum | "NotReady", "Removing", "Preparing", "Active")
"webClientLoginUrl": string, // Url to use to log into the environment,
"webServiceUrl": string, // Url to use to access the environment's service API
"locationName": string, // The Azure location where the environment's data is stored
"platformVersion": string, // The version of the environment's Business Central platform
"ringName": string, // Name of the environment's logical ring group (such as Prod, Preview)
"appInsightsKey": string // The environment's key for Azure Application Insights
}
Copy environment
Creates a new environment with a copy of another environment's data.
Content-Type: application/json
POST /admin/v2.15/applications/{applicationFamily}/environments/{sourceEnvironmentName}/copy
Content-Type: application/json
POST /admin/v2.15/applications/{applicationFamily}/environments/{sourceEnvironmentName}
Route Parameters
applicationFamily - Family of the source environment's application (for example, "BusinessCentral")
sourceEnvironmentName - Name of the environment to copy from.
NOTE
The Create, Copy, and Delete operations are asynchronous.
With API v2.8 and earlier, the response objects are returned before the underlying operation has completed. The final
results of the operation are reflected in the status field of the environment that the operations affect. In practice this
means that polling of the Get Environments endpoints must be done to determine if the given operation was successful.
With API v2.9 and later, consumers should rely on the status field of the corresponding EnvironmentOperation
response to monitor the status of the underlying operation. So, to get the updated status of the operation, consumers
should poll the Get environment operations for all environments endpoint rather than Get Environments and
inspect the status of the relevant operation.
Body
{
"environmentName": string, // The name of the new environment.
"type": string // The type of environment to create. With API v2.8 and earlier, only the value "Sandbox"
is supported.
}
Response
API v2.9 and later
EnvironmentOperation response with HTTP status code 202 (Accepted) with the following format:
{
"id": "11111111-aaaa-2222-bbbb-333333333333",
"type": "copy",
"status": "scheduled", // Will eventually switch to running and then one between succeeded/failed
"aadTenantId": "",
"createdOn": "2021-09-27T08:13:46.65Z",
"startedOn": "2021-09-27T08:13:47.3Z",
"completedOn": "2021-09-27T08:15:02.073Z",
"createdBy": "",
"errorMessage": "",
"parameters": {
"sourceEnvironmentName": "SourceEnvironment",
"sourceEnvironmentType": "Production",
"destinationEnvironmentName": "NewEnvironment",
"destinationEnvironmentType": "Sandbox",
"applicationVersion": "19.0.28719.0",
"countryCode": "US"
},
"environmentName": "NewEnvironment",
"environmentType": "sandbox",
"productFamily": "BusinessCentral"
}
environmentReservationFailed - another environment within the same application family already has the same
name
maximumNumberOfEnvironmentsAllowedReached - the limit on the number of allowed environments of the provided
type has been reached
maximumStorageCapacityUsageReached - the limit of the storage capacity usage has been reached
Delete environment
Deletes the specified environment. Warning: A production environment shouldn't be deleted.
DELETE /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}
Route Parameters
applicationFamily - Family of the environment's application. (for example "BusinessCentral")
environmentName - Name of the environment to delete.
NOTE
The Create, Copy, and Delete operations are asynchronous.
With API v2.8 and earlier, the response objects are returned before the underlying operation has completed. The final
results of the operation are reflected in the status field of the environment that the operations affect. In practice this
means that polling of the Get Environments endpoints must be done to determine if the given operation was successful.
With API v2.9 and later, consumers should rely on the status field of the corresponding EnvironmentOperation
response to monitor the status of the underlying operation. So, to get the updated status of the operation, consumers
should poll the Get environment operations for all environments endpoint rather than Get Environments and
inspect the status of the relevant operation.
Response
API v2.9 and later
EnvironmentOperation response with HTTP status code 202 (Accepted) with the following format:
{
"id": "8924140b-0da8-4bbb-8a4f-dac047944e72",
"type": "delete",
"status": "scheduled", // Will eventually switch to running and then one between succeeded/failed
"aadTenantId": "",
"createdOn": "2021-09-27T08:13:46.65Z",
"startedOn": "2021-09-27T08:13:47.3Z",
"completedOn": "2021-09-27T08:15:02.073Z",
"createdBy": "",
"errorMessage": "",
"parameters": {
"environmentName": "EnvironmentToDelete",
"environmentType": "sandbox",
"productFamily": "BusinessCentral",
"countryCode": "US",
"applicationVersion": "19.0.28719.0"
},
"environmentName": " EnvironmentToDelete",
"environmentType": "sandbox",
"productFamily": "BusinessCentral"
}
Rename environment
INTRODUCED IN: API version 2.3
Schedules a rename operation on an environment.
Content-Type: application/json
POST /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/rename
Routing parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral").
{
"NewEnvironmentName":"sandbox"
}
Response
202 Accepted with body. Follows the general "Operations" format, but with specific operation parameters
{
"id":"11111111-aaaa-2222-bbbb-333333333333",
"type":"environmentRename", // Operation type
"status":"scheduled",
"aadTenantId":"44444444-aaaa-5555-bbbb-666666666666",
"createdOn":"2021-04-22T12:29:06.668254Z",
"createdBy":"greg.chapman@contoso.com",
"errorMessage":"",
"parameters":{ // Operation-specific parameters
"oldEnvironmentName":"prod-1", // The old name of the environment
"newEnvironmentName":"prod-2" // The new name of the environment (the target name)
}
}
Restore environment
INTRODUCED IN: API version 2.4
Schedules a restore operation an existing environment from a time in the past.
Content-Type: application/json
POST /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/restore
Routing parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral").
{
"EnvironmentName":"x-restored", // Mandatory. The name of the new environment that will be created as the
result of the resore operation.
"EnvironmentType":"production", // Mandatory. The type of the new environment.
"PointInTime":"2021-04-22T20:00:00Z" // The point in time to which to restore the environment. Must be in
ISO 8601 format in UTC.
}
Response
202 Accepted with body. Follows the general "Operations" format, but with specific operation parameters.
{
"id":"11111111-aaaa-2222-bbbb-333333333333", // Operation ID
"type":"pitRestore", // Operation type
"status":"queued", // Status
"aadTenantId":"44444444-aaaa-5555-bbbb-666666666666",
"createdOn":"2021-04-23T09:41:28.8300669Z",
"createdBy":"greg.chapman@contoso.com",
"errorMessage":"",
"parameters":{ // Parameters mimic the same from the request body
"environmentName":"x-restored",
"environmentType":"Production",
"restorePointInTime":"2021-04-22T20:00:00Z"
}
}
Expected Error Codes
Follows the general "Error response" format, but with specific error codes.
Operation-specific error codes:
PitRestoreFailed - the restore operation failed
GET applications/{applicationType}/environments/{environmentName}/availableRestorePeriods
Response
200 OK with body. Body represents an ordered list of available restore periods that are non-overlapping and
sorted in ascending order by period start date-time. If there are no available restore periods, the list will be
empty.
{
"value":[
{
"from":"2021-01-25T14:57:04.967Z",
"to":"2021-01-25T21:06:17.737Z"
},
{
"from":"2021-01-25T21:14:48Z",
"to":"2021-01-27T14:33:15.0007416Z"
}
]
}
GET /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/usedstorage
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
Response
Returns used storage information of a single environment if exists.
{
"environmentType": string, // Environment type (for example, "Sandbox", "Production")
"environmentName": string, // Environment name, unique within an application family
"applicationFamily": string, // Family of the environment (for example, "BusinessCentral")
"databaseStorageInKilobytes": int // Used database storage in kilobytes
}
NOTE
If an error occurs when calculating database storage, the corresponding property will be -1.
target: {applicationFamily}/{environmentName}
GET /admin/v2.15/environments/usedstorage
Response
Returns a wrapped array of used storage objects.
{
"value":
[
{
"environmentType": string, // Environment type (for example, "Sandbox", "Production")
"environmentName": string, // Environment name, unique within an application family
"applicationFamily": string, // Family of the environment (for example, "BusinessCentral")
"databaseStorageInKilobytes": int // Used database storage in kilobytes
}
]
}
GET /admin/v2.15/environments/quotas
Response
Returns quotas object.
{
"environmentsCount":
{
"production": int, // Maximum allowed number of production environments
"sandbox": int // Maximum allowed number of sandbox environments
}
"storageInKilobytes":
{
"default": int, // Amount of storage allowed by default
"userLicenses": int, // Amount of storage allowed based on the number of user licenses
"additionalCapacity": int, // Amount of storage allowed based on purchased capacity add-ons
"total": int // Total amount of allowed storage
}
}
Get environment operations
INTRODUCED IN: API version 2.6
Gets the following operations that occurred on an environment.
GET /admin/v2.15/applications/{applicationType}/environments/{environmentName}/operations
Operation types
Data is returned for the following operation types:
Copy Endpoint
Create Endpoint
Delete Endpoint
EnvironmentAppHotfix1 App was hotfixed by using the App App Management API
Management API.
EnvironmentAppUpdate1 App was updated either by the Admin Update an App in Admin Center
Center or API update endpoint.
Update Endpoint
EnvironmentAppInstall1 App was installed by using the tenant's Extension Management Page
Extension Management page or the
API install endpoint. Install Endpoint
1 These operations are only supported with API version 2.6 and later. For these operations, the data returned is
the same as for Get App Operations, but in a different format.
2 These operations are only supported with API version 2.8 and later.
3 These operations are only supported with API version 2.9 and later.
4 These operations are only supported with API version 2.10 and later.
5 These operations are only supported with API version 2.11 and later.
6 These operations are only supported with API version 2.12 and later.
Route Parameters
applicationType - Family of the environment's application (for example, "BusinessCentral")
"value": [
{
"id": "552d3cb2-144e-4195-9a92-1043c4f483e9", // Id of the operation used for tracking
"type": "environmentAppInstall", // Type of operation
"status": "succeeded", // Status of operation (enum | "Queued", "Scheduled", "Running", "Succeeded",
"Failed", "Canceled", "Skipped")
"aadTenantId": "5633d4a2-6d53-4254-868f-b8d70eefed7a", // AAD tenant ID for which the operation was
executed
"createdOn": "2021-03-22T15:45:46.537Z", // Date and time the request was created
"errorMessage": "", // Error message for failed operations
"parameters": { // Additional parameters for the operation, specific to every operation type
"appId": "1bb96677-5112-4566-b742-12eebbb9a058",
"targetAppVersion": "17.0.3.0",
"countryCode": "US",
"allowPreviewVersion": true,
"ignoreUpgradeWindow": true,
"acceptIsvEula": true,
"allowDependencyUpdate": true,
"environmentName": "Production",
"environmentType": "Production",
"productFamily": "BusinessCentral"
}
},
{
"id": "5fe4ac38-a523-4c1f-80db-acd2cf848c09",
"type": "environmentRename",
"status": "succeeded",
"aadTenantId": "5633d4a2-6d53-4254-868f-b8d70eefed7a",
"createdOn": "2021-03-16T18:57:36.223Z",
"startedOn": "2021-03-16T18:57:39.053Z",
"completedOn": "2021-03-16T18:57:47.867Z",
"createdBy": "",
"errorMessage": "",
"parameters": {
"oldEnvironmentName": "Production",
"newEnvironmentName": "Production-deprecated",
"environmentName": "Production",
"environmentType": "Production",
"productFamily": "BusinessCentral"
}
}
]
}
"environmentName" , "environmentType" , and "productFamily" are only included in version 2.7 and later.
GET /admin/v2.15/applications/{applicationType}/environments/operations
Operation types
See Operation Types.
Route Parameters
applicationType - Family of the environment's application (for example, "BusinessCentral")
Response
Example 200 OK response:
"value": [
{
"id": "552d3cb2-144e-4195-9a92-1043c4f483e9", // Id of the operation used for tracking
"type": "environmentAppInstall", // Type of operation
"status": "succeeded", // Status of operation (enum | "Queued", "Scheduled", "Running", "Succeeded",
"Failed", "Canceled", "Skipped")
"aadTenantId": "5633d4a2-6d53-4254-868f-b8d70eefed7a", // AAD tenant ID for which the operation was
executed
"createdOn": "2021-03-22T15:45:46.537Z", // Date and time the request was created
"errorMessage": "", // Error message for failed operations
"parameters": { // Additional parameters for the operation, specific to every operation type
"appId": "1bb96677-5112-4566-b742-12eebbb9a058",
"targetAppVersion": "17.0.3.0",
"countryCode": "US",
"allowPreviewVersion": true,
"ignoreUpgradeWindow": true,
"acceptIsvEula": true,
"allowDependencyUpdate": true,
"environmentName": "Sandbox",
"environmentType": "Sandbox",
"productFamily": "BusinessCentral"
}
},
{
"id": "5fe4ac38-a523-4c1f-80db-acd2cf848c09",
"type": "environmentRename",
"status": "succeeded",
"aadTenantId": "5633d4a2-6d53-4254-868f-b8d70eefed7a",
"createdOn": "2021-03-16T18:57:36.223Z",
"startedOn": "2021-03-16T18:57:39.053Z",
"completedOn": "2021-03-16T18:57:47.867Z",
"createdBy": "",
"errorMessage": "",
"parameters": {
"oldEnvironmentName": "Production",
"newEnvironmentName": "Production-deprecated",
"environmentName": "Production",
"environmentType": "Production",
"productFamily": "BusinessCentral"
}
}
]
}
See Also
The Business Central Administration Center API
Manage Apps
Managing Production and Sandbox Environments in the Admin Center
Microsoft Dynamics 365 Business Central Server Administration Tool
Environment Database Export
2/6/2023 • 3 minutes to read • Edit Online
Allows for the export of an environment's Azure database. Databases are exported to an Azure Storage account
provided by you. There is a limit to the number of exports that can be done within a month as shown by the
'metrics' endpoint below.
Required In-Product Permissions for Exporting an Environment Database
To use the exports endpoint, you must have the D365 BACKUP/RESTORE permission set assigned to your
Business Central user account or authorized AAD App.
GET /admin/v2.15/exports/applications/{applicationFamily}/environments/{environmentName}/metrics
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
Response
Returns the metrics around the current month's database exports.
{
"exportsPerMonth": int, // The total number of allowed exports of the targeted environment every month.
"exportsRemainingThisMonth": int, // The number of exports remaining for the targeted environment that can
be performed this month.
}
target: {applicationFamily}/{environmentName}
Content-Type: application/json
POST /admin/v2.15/exports/applications/{applicationFamily}/environments/{environmentName}
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
Body
{
"storageAccountSasUri": string, // An Azure SAS uri pointing at the Azure storage account where the
database will be exported to. The uri must have (Read | Write | Create | Delete) permissions
"container": string, // The name of the container that will be created by the process to store the
exported database.
"blob": string, // The name of the blob within the container that the database will be exported to.
Databases are exported in the .bacpac format so a filename ending with the '.bacpac' suffix is typical.
}
target: {applicationFamily}/{environmentName}
requestBodyRequired - the request body must be provided
exportFailed - the export failed because the target environment's version was too old, it wasn't a production
environment, the requesting tenant is a trial, the calling user doesn't have permissions to export, or the quota of
allowed exports has been used up
POST /admin/v2.15/exports/history?start={startTime}&end={endTime}
Query parameters
startTime - datetime // The start of the export history entry time window to query endTime - datetime // The
end of the export history entry time window to query
Response
Returns a detailed list of the database exports that occurred within the provided timeframe of the start and
end query parameters
{
"applicationType": string, // Family of the environment (for example, "BusinessCentral")
"applicationVersion": string, // The version of the environment's application at the time of the export.
"blob": string, // The name of the blob that the environment's database was exported to.
"container": string, // The name of the Azure storage account container that the environment's database
was exported within.
"country": string, // The country code of the environment.
"environmentName": string, // The name of the environment that was exported.
"storageAccount": string, // The name of the Azure storage account that the environent's database was
exported to.
"time": dateTime, // The time that the environment's database was exported.
"user": string // The user who initiated the export process.
}
NOTE
All datetime values are in UTC
See Also
The Business Central Administration Center API Manage Apps Microsoft Dynamics 365 Business Central Server
Administration Tool
Environment Outage Reporting
2/6/2023 • 3 minutes to read • Edit Online
Enables the ability to report that an environment isn't accessible and may require attention
GET /admin/v2.13/support/outageTypes
Response
Returns a list with information about the supported outage types for reporting
{
"value": [
{
"outageType": string, // The identifier of the outage type.
"name": string, // A displayable name for the outage type.
"description": string, // A displayable description for the outage type.
}]
}
GET /admin/v2.15/support/outageTypes/{outageType}/outageQuestions
Response
Returns the list of question metadata for the provided outage type
{
"value": [
{
"sequence": int, // The order in which the question should be answered
"parentId": int, // The identifier of a toggle question whose value indicates if this question should
be shown. that is if the parent value is 'true' then this question should also be answered
"id": string, // The unique identifier of the question
"defaultValue": string, // The default value of the question if it has no value
"questionType": string, // (enum | "None", "Toggle", "TextField", "DateTime")
"questionText": string, // The question's text to display
"required": bool, // Indicates if the question must have a value
"onText": string, // Toggle type only - display text for when the question is toggled to 'true'
"offText": string, // Toggle type only - display text for when the question is toggled to 'false'
"multiline": bool // Indicates if the value is intended to contain multi-line text
}]
}
GET /admin/v2.15/support/reportedoutages
Response
Returns the list of outages reported across all environments for the calling tenant
{
"value": [
{
"TenantId": string, // The id of the tenant who reported the outage.
"EnvironmentId": string, // The id of the environment that was reported to have been unavailable.
"CreatedDate": dateTime, // The date that the report was created.
"State": string, // The current state of the outage report.
"MsaasTicketId": string, // The identifier of the MSaaS ticket that is associated with the outage
report.
"IcmTicketId": string, // The identifier of the IcM ticket that is associated with the outage report.
"AppVersion": string, // The version of the environment's application at the time of the outage
report.
"PlatformVersion": string, // The version of the environment's platform at the time of the outage
report.
"OutageType": string, // The category of the reported outage.
}]
}
Report Outage
Initiates an outage report indicating that an environment isn't accessible
Content-Type: application/json
POST /admin/v2.15/support/applications/{applicationFamily}/environments/{environmentName}/reportoutage
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
Body
{
"outageType": string, // The category of the outage being reported.
"outageQuestionAnswers": [{ // The collection of answers to the questions associated with the outage type.
"id": string, // The identifier of the question being answered.
"answer": string // The answered value of the question.
}],
("contact": string), // (Optional) - The name of the person whose to contact with updates on the outage
report
("email": string), // (Optional) - An email to contact with updates on the outage report
("phone": string), // (Optional) - A phone number to contact with updates on the outage report
("appVersion": string), // (Optional) - If known, the version of the targeted environment's application
("platformVersion": string) //(Optional) - If known, the version of the targeted environment's platform
}
Response
Returns information about the created outage report
{
"creationStatus": string, // The status of the request to create an outage report. (enum | "Unknown",
"Created", "UpdatedExisting", "Error")
"msaasCaseNumber": string, // The identifier of the MSaaS ticket that is associated with the outage
report.
}
See Also
The Business Central Administration Center API
Manage Apps
Microsoft Dynamics 365 Business Central Server Administration Tool
Environment Settings
2/6/2023 • 6 minutes to read • Edit Online
Allows you to manage environment-specific settings such as the AppInsights key or the update window.
GET /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/settings/upgrade
Route Parameters
applicationFamily - Family of the environment's application as is. (for example "BusinessCentral")
environmentName - Name of the targeted environment
Response
Returns the environment's update settings, or "null" if none exist
{
"preferredStartTime": string, // Start of environment update window in 24h format (HH:mm). Supported by
API version 2.13 and later only.
"preferredEndTime": string, // End of environment update window in 24h format (HH:mm). Supported by API
version 2.13 and later only.
"timeZoneId": string, // Windows time zone identifier. Supported by API version 2.13 and later only.
"preferredStartTimeUtc": datetime, // Start of an environment's update window, expressed as an UTC
timestamp
"preferredEndTimeUtc": datetime // End of an environment's update window, expressed as an UTC timestamp
}
NOTE
The UTC values identify the current or next immediate occurrence of the update window. For instance, when the request is
issued, if the current time is within the update window defined for the environment, then preferredStartTimeUtc will
identify an instant in the past, and preferredEndTimeUtc will identify an instant in the future. Otherwise, both the start
and end times will identify instants in the future. For a static, deterministic set of values that uniquely identify the
definition of the update window for a given environment, refer to the preferredStartTime , preferredEndTime , and
timeZoneId values.
target: {applicationFamily}/{environmentName}
Response
Returns a wrapped array of time zones.
{
"value":
[
{
"id": string, // Time zone identifier (for example, "Romance Standard Time")
"displayName": string, // Display name of the time zone (for example, "(UTC+01:00) Brussels,
Copenhagen, Madrid, Paris")
"currentUtcOffset": string, // Offset from UTC, expressed as a time span with +/-HH:mm format (for
example, "+01:00", "-09:00")
"supportsDaylightSavingTime": boolean, // Indicates whether the time zone supports daylight saving
time rules
"isCurrentlyDaylightSavingTime": boolean, // Indicates whether daylight saving time is in effect for
the given time zone, at the instant the request is issued
}
]
}
Content-Type: application/json
PUT /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/settings/upgrade
Route Parameters
applicationFamily - Family of the environment's application as is. (for example "BusinessCentral")
environmentName - Name of the targeted environment
Body
With API version 2.13 and later, there are two different parameter sets for defining the update window: the wall-
time + timezone parameter set and the UTC parameter set. Consumers can provide either parameter set, but not
both. Earlier API versions only support the UTC parameter set.
The wall-time + timezone parameter set identifies the clock time (or "real time")—expressed in 24-hour
format, like "22:00" for 10:00 PM or "07:30" for 7:30 AM—for a given time zone. The time zone ID must be a
valid Windows time zone identifier, for example, "Romance Standard Time" or "Pacific Standard Time".
The UTC parameter set identifies the start and end times in Coordinated Universal Time.
NOTE
If the UTC parameter set is used when modifying the update window settings and the country of the environment
supports multiple time zones, the time zone shown on the Environment Details page in the admin center will be reset to
the default time zone for the country, which may not always be desirable. We recommend to use the new parameter set
when consuming API v2.13 and later.
Example with wall-time + timezone parameter set (supported only by API v2.13 and later):
{
{
"preferredStartTimeUtc": datetime, // Start of environment update window
"preferredEndTimeUtc": datetime, // End of environment update window
}
Response
Returns the updated settings
{
"preferredStartTimeUtc": datetime, // Start of environment update window
"preferredEndTimeUtc": datetime, // End of environment update window
}
NOTE
The date components of the values are ignored, only the time components are used.
target: {applicationFamily}/{environmentName}
- invalidRange: - the targeted logical range is invalid in some way
target: "Preferred Upgrade Window" - the specified window is too small
requestBodyRequired - the request body must be provided
ScheduledUpgradeConstraintViolation - the update window conflicts with the current update date that's set for
the environment. Either the update would occur outside the allowed update date range or, if the update date is
today, the update window is in the past. Adjust the update window or change the update date.
IMPORTANT
This process requires a restart to the environment, which is triggered automatically when you call this API. Plan to do this
during non-working hours to avoid disruptions.
Content-Type: application/json
PUT /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/settings/appinsightskey
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
Body
{
"key": string, // The Application Insights key for the environment
}
target: {applicationFamily}/{environmentName}
requestBodyRequired - the request body must be provided
cannotSetAppInsightsKey - the targeted environment's status isn't 'Active'
GET
/admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/settings/securitygroupaccess
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
Response
If the group exists in Azure AD graph:
{
"id": "796d9c99-80e4-479c-8544-e745ffd18150",
"displayName": "Security group 1"
}
{
"id": "796d9c99-80e4-479c-8544-e745ffd18150",
"displayName": ""
}
Content-Type: application/json
POST
/admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/settings/securitygroupaccess
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
Body
{
"Value": GUID, // The object Id of the Azure AD group, "11111111-aaaa-2222-bbbb-222222222222"
}
Response
Returns 200 if successful, or 404 if the group doesn't exist in Azure AD.
DELETE
/admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/settings/securitygroupaccess
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
GET
/admin/v2.12/applications/{applicationFamily}/environments/{environmentName}/settings/accesswithm365licenses
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
Response
{
"enabled": true/false
}
Content-Type: application/json
POSThttps://api.businesscentral.dynamics.com/admin/v2.12/applications/{applicationFamily}/environments/{envi
ronmentName}/settings/accesswithm365licenses
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
Body
{
"enabled":"true"
}
Response
Returns 200 if successful.
See Also
The Business Central Administration Center API
Manage Apps
Microsoft Dynamics 365 Business Central Server Administration Tool
Notifications (API)
2/6/2023 • 2 minutes to read • Edit Online
Notifications are sent to the recipient email addresses set up for the tenant. For example, notifications are sent
for update availability, successful updates, update failures, and extension validations.
GET /admin/v2.15/settings/notification/recipients
Response
Returns a wrapped array of recipients.
{
"value":
[
{
"id": GUID, // Unique identifier of the recipient
"email": string, // Email address of the recipient
"name": string // Full name of the recipient
}
]
}
Content-Type: application/json
PUT /admin/v2.15/settings/notification/recipients
Body
{
"email": string, // Email address of the recipient
"name": string // Full name of the recipient
}
Response
Returns the newly created recipient.
{
"id": GUID, // Unique identifier of the recipient
"email": string, // Email address of the recipient
"name": string // Full name of the recipient
}
DELETE /admin/v2.15/settings/notification/recipients/{id}
Route Parameters
id - The unique identifier of the notification recipient to delete.
GET /admin/v2.15/settings/notification
Response
Returns the notification settings.
{
"aadTenantId": GUID, // AAD Tenant ID of the caller
"recipients": [
{
"id": GUID, // Unique identifier of the recipient
"email": string, // Email address of the recipient
"name": string // Full name of the recipient
}
]
}
Allows for the management of scheduled updates such as rescheduling the update to a run on or after a specific
date within a provided range.
GET /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/upgrade
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
Response
Returns information about the scheduled update for that environment.
{
"environmentName": string, // The name of the targeted environment.
"applicationFamily": string, // Family of the environment (for example, "BusinessCentral")
"sourceVersion": string, // The current version of the environment's application.
"targetVersion": string, // The version of the application that the environment will update to.
"canTenantSelectDate": boolean, // Indicates if a new update date can be selected.
"didTenantSelectDate": boolean, // Indicates if the tenant has selected the current date for the update.
"earliestSelectableUpgradeDate": datetime, // Specifies the earliest date that can be chosen for the
update.
"latestSelectableUpgradeDate": datetime, // Specifies the latest date that can be chosen for the update.
"upgradeDate": datetime, // The currently selected scheduled date of the update.
"updateStatus": string, // The current status of the environment's update. (enum | "Scheduled" or
"Running")
"ignoreUpgradeWindow": boolean, // Indicates if the environment's update window will be ignored
"isActive": boolean, // Indicates if the update is activated and is scheduled to occur.
}
Reschedule Update
Reschedule an update, if able.
Content-Type: application/json
PUT /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/upgrade
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
Body
{
"runOn": datetime, // Sets the date that the upgrade should be run on.
"ignoreUpgradeWindow": boolean // Specifies if the upgrade window for the environment should be respected.
}
See Also
The Business Central Administration Center API
Manage Apps
Microsoft Dynamics 365 Business Central Server Administration Tool
Session Management
2/6/2023 • 2 minutes to read • Edit Online
GET /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/sessions
Response
{
value: [
{
environmentName: string,
applicationFamily: string,
sessionId: int,
userId: string,
clientType: string,
logOnDate: string,
entryPointOperation: string,
entryPointObjectName: string,
entryPointObjectId: string,
entryPointObjectType: string,
currentObjectName: string,
currentObjectId: int,
currentObjectType: string,
currentOperationDuration: long
}
,...
]
}
GET /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/sessions/{sessionId}
Response
{
environmentName: string,
applicationFamily: string,
sessionId: int,
userId: string,
clientType: string,
logOnDate: string,
entryPointOperation: string,
entryPointObjectName: string,
entryPointObjectId: string,
entryPointObjectType: string,
currentObjectName: string,
currentObjectId: int,
currentObjectType: string,
currentOperationDuration: long
}
DELETE /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/sessions/{sessionId}
See Also
The Business Central Administration Center API
Manage Apps
Microsoft Dynamics 365 Business Central Server Administration Tool
Support Settings
2/6/2023 • 2 minutes to read • Edit Online
Allows for the management of support settings, such as changing the contact, for a specific environment
GET /admin/v2.15/support/applications/{applicationFamily}/environments/{environmentName}/supportcontact
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
Response
Returns information about the support contact for that environment.
{
"name": string, // The name of the support contact.
"email": string, // The email address of the support contact.
"url": string, // A freeform url for additional support contact information such as a support website.
}
Content-Type: application/json
PUT /admin/v2.15/support/applications/{applicationFamily}/environments/{environmentName}/supportcontact
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
Body
{
"name": string, // The name of the support contact.
"email": string, // The email address of the support contact.
"url": string, // A freeform url for additional support contact information such as a support website.
}
Response
Returns the newly updated support contact information.
{
"name": string, // The name of the support contact.
"email": string, // The email address of the support contact.
"url": string // A freeform url for additional support contact information such as a support website.
}
See Also
The Business Central Administration Center API
Manage Apps
Microsoft Dynamics 365 Business Central Server Administration Tool
Telemetry (API)
2/6/2023 • 2 minutes to read • Edit Online
Telemetry includes the top-level AL events and any returned errors logged from the service. These events can
provide necessary information and errors that can be used to troubleshoot issues happening in the tenant's
environment.
GET /admin/v2.15/applications/{applicationFamily}/environments/{environmentName}/telemetry?startDateUtc=
{start}&endDateUtc={end}&logCategory={cat}
Route Parameters
applicationFamily - Family of the environment's application (for example, "BusinessCentral")
environmentName - Name of the targeted environment
Query parameters
start : datetime // The start of the telemetry entry time window to query
end : datetime // The end of the telemetry entry time window to query
cat : (All or 0) // Category of telemetry to query
Response
Returns the telemetry logs and with data column headers.
{
"queryColumns": [
{
"name": string, // Column display name
"ordinal": int, // Index of the column in the data set
"dataType": ( string or 0 | numeric or 1 | datetime or 2 )
"expectations": (none or 0 | wide or 1) // Flags enum value
}
],
"queryResults": object[][] // Raw query data results
}
See Also
The Business Central Administration Center API
Manage Apps
Microsoft Dynamics 365 Business Central Server Administration Tool
Licensing in Dynamics 365 Business Central
2/6/2023 • 7 minutes to read • Edit Online
Business Central licenses can only be purchased through CSP. Microsoft offers several types of paid licenses for
business users:
Essential
Premium
Team Member
External Accountant
Microsoft also offers read-only access to Business Central through Microsoft 365 licenses, as an addition to
Premium or Essentials plans
Prospects and customers can also subscribe for an evaluation version by using self-service sign-up, also known
as the viral trial. This subscription comes with 10,000 licenses, and partners can use such viral trials to let
prospects explore Business Central using non-production companies. For more information, see Preparing
Demonstration Environments of Dynamics 365 Business Central.
IMPORTANT
Specifically for businesses who want to convert a 30-day trial company into their actual production company, the first
user who signs into Business Central after the license was applied to their tenant must be a user with this license
assigned. This way, the 30-day trial ends, and any trial-related notifications disappear so that users can use Business
Central to do work.
If an administrator is the first person to sign in after the license was applied to the tenant and to users, then the trial will
continue until it expires.
Business Central online doesn't use the classic Dynamics NAV license files (.flf). Instead, permissions are
generated based on entitlements.
Behind the scenes, the Entitlements table defines license permissions per object. Entitlements are grouped in
the Entitlement Set table, and then each entitlement set is associated with one of the four Azure Active
Directory (Azure AD) service plans.
This condition means that when a user purchases, for example, an Essential license and tries to sign in to
Business Central, we retrieve the user's service plan (in this case Essential) from Azure AD. Then, we load the
corresponding entitlements as license permissions.
NOTE
For more information about the different types of licenses and how licensing works in Business Central, see the Dynamics
365 Licensing Guide, which you can download from https://go.microsoft.com/fwlink/?LinkId=866544.
Reassigning licenses
The licensing terms in the Online Services Terms document don't allow temporary assignment of a license that
belongs to one user to another user.
Most, but not all, licenses can be reassigned. Except as permitted in this paragraph or in the Online Service-
specific Terms, the customer can't reassign a license on a short-term basis, meaning within 90 days of the latest
assignment. The customer can reassign a license on a short-term basis to cover a user's absence or the
unavailability of a device that is out of service. Reassignment of a license for any other purpose must be
permanent. When a customer reassigns a license from one device or user to another, they must block access and
remove any related software from the former device or from the former user's device.
Device licenses
The Dynamics 365 Business Central Device license allows multiple users to simultaneously use a device that is
covered by the license. For example, it might be a point of sales, shop floor, or warehouse device. When you've
purchased many device licenses, up to that number of users assigned to the Dynamics 365 Business Central
Device Users group can sign in at the same time. For more information, see the Microsoft Dynamics 365
Business Central Licensing Guide. The guide is available for download on the Business Central website.
Your company's Microsoft 365 administrator or Microsoft partner can create the Dynamics 365 Business Central
Device Users group and add device users as members in the Microsoft 365 Admin Center or on the Azure
portal.
Device user limitations
Users with the Device license can't perform the following tasks in Business Central:
Set up jobs to run as scheduled tasks in the job queue. Device users are concurrent users and, therefore,
we can't ensure that the involved user is present in the system when a task is executed, which is required.
A device user can't be the first user to sign in. A user of type Administrator, Full User, or External
Accountant must be the first to sign in so they can set up Business Central. For more information, see
Administration of Business Central Online.
To create the Dynamics 365 Business Central Device Users group
1. In the Microsoft 365 Admin Center, go to the Groups page.
2. Choose the Add a group action.
3. On the Choose a group type page, choose the Security option, and then choose the Add action.
4. On the Basics page, enter Dynamics 365 Business Central Device Users as the name of the group.
NOTE
The name of the group must be spelled in English exactly as shown in step 4, even if you are using another
language. If you have copied the name of the group from a document, such as a PDF, verify that the name does
not contain extra spaces.
NOTE
You can also create a group of type Microsoft 365. For more information, see Compare Groups
NOTE
You do not need to assign a Business Central license to users that are members of the Dynamics 365 Business Central
Device Users group.
See Also
Get Started as a Reseller of Business Central Online
Deployment of Dynamics 365 Business Central
Working with Sandboxes and Entitlements
Embed App Overview
Entitlements and Permission Sets Overview
2/6/2023 • 5 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
Business Central uses two main concepts for defining access to functionality: Entitlements and permissions.
Entitlements describe which objects in Business Central a customer is entitled to use according to the
license that they purchased from Microsoft or according to the Azure Active Directory role that they have
assigned in Microsoft 365 Admin Center, such as Global Administrator. Entitlements are only used in the
online version of Business Central.
Permissions describe which objects an administrator or a partner has given the user.
Permission sets combine objects permissions in logical groups (or sets), which can then be assigned to
the users explicitly or through a user group.
For more information about assigning licenses, see Licensing in Dynamics 365 Business Central. For more
information about how to create and assign permissions, see Assign Permissions to Users and Groups.
NOTE
In the current version of Dynamics 365 Business Central entitlements can only be included with Microsoft apps (enforced
by the AppSource cop rules and the technical validation checks that we run for the apps submitted to AppSource). These
objects will become available for the ISV apps when we introduce ability to monetize AppSource apps in one of our future
releases.
Upgrade considerations
Starting with Business Central 2021 release wave 1 (v18.0), the Business Central demo database, which is
shipped with our on-premises installation, doesn't contain any data in the Permission Set and Permission
tables in the application database. Instead, the System permission sets and permissions are provided as AL
objects of type PermissionSet and PermissionSetExtension , included with Microsoft apps.
The application database tables that used to store the entitlements won't contain any data either, because
entitlements are now defined as AL objects.
Business Central server configuration file (CustomSettings.config) includes a setting that allows on-premises
administrators to decide whether they want to continue using the permissions defined as data or as AL objects:
The default value for this setting is true , meaning that the server will be retrieving all System permission sets
and permissions from the AL objects of type PermissionSet and PermissionSetExtension . With the value for this
setting set to true , the permissions data, in case it is still present in the application database, will be
disregarded.
It's not possible to customize the System permission sets and permissions used in the online version of
Business Central. End-users can only copy these types to new permission sets, which they can then adjust to
their needs. For more information, see Assign Permissions to Users and Group.
In the on-premises version of Business Central, even though it's not recommended, the partners can customize
the permission sets and permissions shipped in the application database. In this case, as for any upgrade before,
the changes in Microsoft permissions should be merged with the customized permissions by partners during
upgrade.
Although starting with Business Central 2021 release wave 1 (v.18.0), System permissions are no longer
shipped as data in the application database, the partners can use the same procedure as before to export the
new permissions that are defined using AL objects. The new permission sets and permissions can be exported
into XML file by running XMLport 9171 Import/Export Permission Sets, making it possible to compare and
merge the customized permission sets in your old database with the newly shipped permission sets. Find more
details, see Export and Import Permission Sets and Permissions.
How to upgrade permission sets
When upgrading to version 18, first decide whether you want to use the permissions defined as data or switch
to permissions defined as AL objects. Then, follow the guidelines at Upgrading Permission Sets for details on
how to do the upgrade.
See Also
Get Started with AL
Entitlement Object
PermissionSet Object
PermissionSet Extension Object
Special Permission Sets
2/6/2023 • 2 minutes to read • Edit Online
The following permission sets have special definitions that you should be aware of as you implement
permissions and security for Business Central users.
SUPER Can read, use, update, and delete all data and all application
objects in the scope of your license. Business Central
requires that at least one user is assigned this permission set
in each database.
SUPER (DATA) Can read, use, update, and delete all data in the scope of
your license. You typically assign this permission set to an
accounting manager who needs to work with all data but
doesn't need to change Business Central.
BASIC Grants Read access to almost all application tables and all
system tables.
D365 BASIC Grants Read access to almost all application tables and all
system tables.
SYSTEM APP - BASIC Grants access to most features of the system application and
is required for login to Business Central.
SYSTEM APP - ADMIN Grants full permissions to all features of the System
Application.
See Also
Removing Elements from the User Interface According to Permissions
Enabling Upcoming Features Ahead of Time
2/6/2023 • 9 minutes to read • Edit Online
New capabilities are added to Business Central in major updates and minor updates. Some new features can be
enabled ahead of time on sandbox and production environments. Learn how you as an administrator can turn
on new features using the Feature Management page.
IMPORTANT
The projected timeline for a feature is subject to change (see Microsoft policy).
1. Sign in to your environment and navigate to the Feature Management page, or use this link:
https://businesscentral.dynamics.com/?page=2610.
2. If the page isn't editable, choose the Edit List action.
3. For the feature you want to turn on, in the Enabled for field, choose All users .
As soon as you enable the feature, any user who signs in to that environment experiences the change. You won't
necessarily experience the change yourself until you sign out and sign in again, or start a new session.
TIP
Try out the feature for yourself without enabling it for all users by choosing the Tr y it out link. This will open a new
browser tab with the feature enabled for that session. Any new sessions in your browser will also have the feature
temporarily turned on. To stop trying the feature, close your browser window or sign out.
If you manage multiple environments, such as several sandboxes, new features can be enabled in some of these
environments and not in other environments. It can be tricky to keep track of what is enabled where in such
scenarios, but the Feature Management page always shows what is enabled in a given environment.
NOTE
When you choose to enable an irreversible feature, a warning dialog that describes the consequences is displayed. Choose
the Yes action to turn on the feature in that environment.
Starting with version 19.1, when you create a copy of an environment, any irreversible features that were turned
on are also available in the copy.
NOTE
For a feature that requires data update, data is created based on the data for the existing feature. The data for the
existing feature may remain available, however, it is not synchronized with data for the new feature. Therefore, we
recommend that you use one feature or the other, but not both.
The Microsoft commercial marketplace offers a wide variety of apps from Microsoft and our partners that
extend the value of Business Central. As a Microsoft partner, you can save yourself, and your customers, a bit of
legwork by using the Recommended Apps extension to curate a list of apps that are right for your customers'
businesses. Recommended Apps is a per-tenant extension (PTE), which means that you can make collections
unique for each customer, or build collections specifically for certain types of businesses or industries and then
reuse the collections when you're on-boarding those types of customers. For example, you can create one
collection for customers who work in finance, and another for customers in the retail space. For more
information, see Maintain AppSource Apps and Per-Tenant Extensions in Business Central Online.
M ET H O D DESC RIP T IO N
Inser tApp Add information about the apps from AppSource to the
Recommended Apps table. When adding new apps, you can
simply paste the URL for the app from AppSource for the
AppSourceUrl parameter, and Business Central will add the
relevant parts to the other parameters. However, you must
manually complete the Short Description ,
Long Description , and Recommended By parameters.
GetApp Get information from AppSource about the apps that are
already added to the Recommended Apps table.
UpdateApp Update the information about the apps that are already
added to the Recommended Apps table.
RefreshImage Update the logo for the app. When you insert an app, the
image is downloaded automatically. Use if the logo has
changed.
M ET H O D DESC RIP T IO N
DeleteApp Delete an app from the collection. You provide the app ID.
GetAppURL Get the URL for a specific app. You provide the app ID.
See Also
Onboarding experiences in Business Central
Get the Outlook add-ins for the business inbox
2/6/2023 • 2 minutes to read • Edit Online
Business Central supports integration with Outlook so that users can complete Business Central business tasks
from their Outlook inbox.
Overview
The two add-ins for Business Central provide the following capabilities:
Contact insights
The add-in provides users with information from Business Central about their contacts in Outlook emails
and calendar appointments. It also enables users to create and send Business Central business
documents, such sales quotes and invoices to a contact. To support these tasks, the add-in adds actions to
the Outlook ribbon, in the Business Central group.
Create and view documents
When a business document is sent as an email, the add-in provides a direct link from email to the actual
business document in Business Central. The add-in adds a Document Links action in the email header,
which a user can select to display the document.
The processes for deploying the add-ins are different for Business Central online and on-premises, though the
add-ins are the same. So choose the right section to read from here on - use the links to the right to easily
navigate between the main sections.
See Also
Using Business Central as your Business Inbox in Outlook
Set Up the Add-Ins for Outlook with Business Central on-premises
Deployment of Business Central on-premises
Using Business Central as your Business Inbox in Outlook
Preparing Your Network for the Excel Add-In
2/6/2023 • 2 minutes to read • Edit Online
As the administrator of Business Central online or on-premises, you can deploy an add-in so that users can work
with their Business Central data in the Excel desktop app. This article includes information that helps
administrators configure advanced device and network settings for the Excel add-in for Business Central when
your network requirements block the add-in.
NOTE
Your API endpoint URL can be different from these default values. For example, if your environment is based on a vertical
solution by Fabrikam, your API endpoint is https://fabrikam.api.bc.dynamics.com . These vertical solutions have API
endpoints that are based on the format of ApplicationName .api.bc.dynamics.com. You can check if an environment uses
such a URL in the Business Central Administration Center.
See also
Setting up the Excel Add-In for Editing Business Central Data
Administration of Business Central Online
Managing an Business Central Embed App in Microsoft Lifecycle Services
Setting up App Key Vaults for Business Central
Online
2/6/2023 • 3 minutes to read • Edit Online
AppSource apps for Business Central can be developed to get secrets from Azure Keys Vaults. The app key vault
feature is readily available for use on the service by all App Source apps. However, there are some onboarding
tasks required.
IMPORTANT
With Business Central online, App key vaults can only be used with AppSource apps. They're not supported with per-
tenant extensions.
TIP
You must also specify secrets in a key vault if you deploy Business Central as part of the Embed App program. Especially if
you must support the Outlook add-in, in which case you must specify secrets for
TEMPORARYDOCUMENTSTORAGEACCOUNT and TEMPORARYDOCUMENTSTORAGEKEY.
For more information about developing extensions with key vaults, see Using Key Vault Secrets in Business
Central Extensions.
Import-Module AzureAD
Connect-AzureAD
Grant the key vault reader application permission to your key vaults
The next task is to grant the key vault reader application permission to read secrets from your key vaults. The
steps in this task are done from the Azure portal.
1. Open the key vault in the portal.
2. Select Access policies , then Add Access Policy .
3. Set Secret Permissions to Get .
4. Choose Select principal , and on the right, search for either the application (client) ID 7e97dcfb-bcdd-
426e-8f0a-96439602627a or the display name Dynamics 365 Business Central ISV Key Vault
Reader .
5. Select Add , then Save .
See Also
Security Considerations With App Key Vaults
Monitoring and Troubleshooting App Key Vaults
Configuring Business Central Server
Deploying a Tenant Customization
2/6/2023 • 3 minutes to read • Edit Online
When you have finished developing and testing your tenant customization, you must deploy the extension (.app
file) containing the customization to your customer’s production tenant. You must be able to log into the
customer’s tenant as a user with permissions to the Extension Management page to complete the
deployment.
Use the Upload Extension action to deploy the extension. The extension can be deployed for the current
version or for the next version of the service. In most cases it is sufficient to select the current version, unless
you have developed the extension specifically for the next version.
NOTE
When you deploy an .app file for the next version, the extension will be queued up to be deployed as part of the
customer’s tenant being upgraded to the next version. You can typically use this in a situation where you have built an
upgrade of the extension to work with the next version.
The extension you are deploying could be the initial release of the customization or an upgrade to a previous
version. You must use the same steps for uploading a new extension or an extension upgrade. The service will
determine if the extension needs to be upgraded based on the extension’s app ID and version.
If you have successfully deployed an extension to a tenant, and then recompile the extension’s source code
without updating version number, this generates a new extension package file with a new package ID. If you try
to upload this new extension package file to a different tenant, the upload will fail with the error similar to
An extension with same App ID and version has already been uploaded. Resolve and deploy again. . Similarly, if an
extension failed to deploy, and you try to upload a new extension package with the same version number, the
upload will fail as well.
See Also
Get Started with AL
AL Development Environment
FAQ for Developing in AL
Using Designer
Upgrading Per-Tenant Extensions that Conflicts with
Other Extensions
2/6/2023 • 4 minutes to read • Edit Online
In AL, all top-level objects are declared in the same global namespace. The extensions installed in an
environment cannot have the same top-level object declared multiple times or controls, fields, or dataitems with
the same name defined multiple times in the same logical object. This means that a table extension, for example,
cannot add a field with the same name as a field in the extended table. This topic shows how to upgrade an
extension which declares a table or a field that conflicts with a table or a field declared by another extension.
table 10 MyTable {}
table 20 MyTable {}
Extension A and Extension B cannot be installed in the same environment because the two tables have the
same name. An error will be raised when the installation of the second extension is attempted and the
installation will fail.
table 10 MyTable
{
field(1; MyField; Integer){}
}
Then Extension B will fail to compile because the field in the table extension has the same name as the field in
the base table. Publishing Extension B will fail with a compilation error.
In general, it is recommended using affixes for your object and element names to prevent this type of conflicts.
For more information, see Prefix and suffix for naming in extensions.
Example
To make the issue more concrete, the following example illustrates how this problem can manifest itself and
how to resolve it. In a Business Central environment running on Business Central 2020 release wave 1, update
16.5 (version 16.5), a per-tenant extension, named MyExtension by Contoso version 1.0.0.0 contains the
following table extension:
The table extension adds the field Shipping Agent Ser vice Code to the Sales Cr.Memo Header table
defined in the Base Application extension by Microsoft.
In Business Central 2020 release wave 2 (version 17.0), Microsoft enhances the table Sales Cr.Memo Header
by adding the following field:
The service will then attempt to upgrade the environment from version 16.5 to version 17.0 of the product.
During the upgrade process, the per-tenant extension will be recompiled against the latest version of the Base
Application . The compilation will fail with an error message similar to:
"A member of type Field with name "Shipping Agent Service Code" is already defined in Table "Sales Cr.Memo
Header" by the extension "Base Application by Microsoft (17.0.0.0)".
The service will now dismiss the upgrade of the environment and an email will be sent to the administrator
registered in the Tenant Administration Center containing the above error message.
The first reaction may be to modify the per-tenant extension, remove the conflicting field, and then try to upload
version 1.1.0.0 to the service. This will, however, fail with an error message similar to:
"Per-tenant extension "MyExtension" version 1.0.0.0 by "Contoso" failed to synchronize the database schema.".
This error message is raised because the system does not allow implicitly removing or renaming schema
elements such as tables and table fields. To upgrade the environment, it is necessary to forcefully remove the
conflicting field by following these steps:
1. Create a sandbox.
Because the following steps can lead to data-loss, it is recommended that the steps are first performed in a
sandbox environment created as a copy from the production environment. For more information, see Create
a new environment.
2. Export data using RapidStart.
Start by backing up the data contained in the tables or table extensions declared by the extension using
RapidStart. Use other mechanisms to backup the data, but the main point is to backup data to an external
storage system.
3. Uninstall the extension.
Uninstall the extension and select the option to delete the extension's data and schema. Using this option will
delete the tables and fields contributed by the table extension and the environment will delete any trace of
the extension.
4. Remove the field from the extension.
Create version 2.0.0.0 of the extension that does not contain the field which conflicts with the one from the
"Base Application". Deploy this version of the extension to the environment.
5. Import the data.
Import the data that has been backed up from the rapid start package or the external storage system used in
step 2.
6. Upgrade the environment.
At this point, the conflict is resolved and you should be able to update the environment. Schedule an update
for the sandbox and ensure it is successfully updated. If upgrade fails, troubleshoot the issue.
Once the sandbox environment has been successfully updated to the next release, steps 2-6 on the production
environment must be replicated. Before doing so, ensure that the customer will not be impacted by the changes
and clearly communicate a maintenance window in which the work will be performed.
See Also
Upgrading AppSource Apps in Production
Upgrading AppSource Apps in Production
2/6/2023 • 2 minutes to read • Edit Online
When an updated version of an AppSource app becomes the active version in the Dynamics 365 Business
Central service, tenants do not automatically get this updated version. This upgrade must be done manually by
getting the latest version of the app in AppSource.
NOTE
An alternative, is to use the Admin Center, where you can also manage the upgrade, given that you have the right
permissions. For more information, see Managing Apps.
See Also
Developing Extensions
Get Started with AL
How to: Publish and Install an Extension
Set Up Company Configuration Packages
2/6/2023 • 10 minutes to read • Edit Online
As you grow your business as a reseller of Business Central, you will likely come to rely on a set of company
types that you use with most of your Business Central prospects. You can streamline your implementation
process by turning these types into configuration packages that are available for reuse.
After you have set up a company in Business Central that suits your needs, you can create a configuration
package that contains relevant setup data from this company. You can then use it when you create a new
company that is to be configured in the same way.
To facilitate the import of master data, such as customer and vendor information, you can use configuration
templates. Configuration templates contain a set of default settings that are automatically assigned to the
records imported into Business Central. Configuration templates are an alternative to the cloud migration tools
that you can use to migrate customer data from supported products. For more information, see Migrate On-
Premises Data to Business Central Online.
TIP
Use these capabilities to scale your business as a reseller. Most of the relevant pages apply to both Business Central online
and on-premises. However, some processes rely on access to the underlying database and are too complex to use for
Business Central online. For Business Central on-premises, you probably want to use Windows PowerShell to help you
deploy. For more information, see Administration of Business Central On-Premises and Administration of Business Central
Online, respectively.
Configuration packages
By default, Business Central online comes with one configuration package for Microsoft's default application,
including local functionality. You can copy that and make relevant changes in the copy.
Many of our reselling partners create a configuration package for each functional area. For example, create a
package for the manufacturing functionality and another for sales. That lets you apply and set up new areas in a
company as you need them.
We recommend that you create configuration packages with most of the setup tables already filled in, so that
only a few settings must be tweaked for each customer. For example, when you create a new company, the No.
Series and the No. Series Line tables are filled in with a set of number series and starting numbers. The
corresponding No. Series fields in the setup tables are also filled in automatically. You do not have to do the
work of entering number series and other basic setup data. You can also manually change all default data that is
used with RapidStart Services by using the configuration worksheet.
Another approach would be to create a package that includes the tables that define setup, such as the following:
General Ledger Setup
General Posting Setup
VAT Posting Setup
Inventory Posting Setup
Purchases and Payables Setup
Sales and Receivables Setup
Warehouse Setup
Inventory Setup
Manufacturing Setup
Fixed Asset Setup
Marketing Setup
Service Setup
To see a complete list of setup tables in Business Central, choose the icon, enter Manual Setup , and then
choose the related link.
TIP
Optionally, use the configuration worksheet to gather together and categorize the information that you want to use to
configure a new company, and arrange tables in a logical way. Formatting in the worksheet is based on a simple hierarchy:
areas contain groups, which in turn contain tables. Areas and groups are optional but useful. You can then add the
worksheet lines to a new configuration package.
TIP
Take a look at the default configuration package for the demonstration company for inspiration for how to set up
the configuration.
a. Choose the Get Tables action. On the Get Config. Tables request page, specify the types of
tables that you want to add to the configuration, and set the relevant filters. Then choose the OK
button.
To exclude the configuration questionnaires, configuration templates, and configuration worksheet
tables from the package, select the Exclude Configuration Tables check box on the Config
Package Card page. Otherwise, these tables will be added to the list of package tables
automatically when you export the package.
b. To add related tables, choose the Get Related Tables action.
NOTE
Related tables will not be added with the Get Related Tables action if either of the following is true:
The relation is conditional.
Example: If you get related tables for the Customer table, then the Location table will not be added,
since it is only conditionally related to the Customer table, namely if the Location Code field in the
Customer table is filled in.
The related table is filtered.
Example: A field in the related table has a WHERE clause. The reason for this is that the involved
relations information is stored in the Field system table, which is not fully accessible to the application.
You must add such types of tables manually.
For each table, you can specify which fields to exclude, and you can modify the default processing
order for each field. Business Central checks if there are related fields that you must configure in
the Config. Package Fields page.
c. Optionally, for each table, modify which fields must be included in the package.
Select a table for which you want to specify field information, and on the Actions tab, in the Show
group, choose Fields .
To select just the fields you want to include, choose the Clear Included action. To add all fields,
choose the Set Included action.
To specify that the field data should not be validated, clear the Validate Field check box for the
field.
5. Assign the worksheet lines to an existing package.
a. Select the relevant lines, choose the Assign Package action, and then, in the Configuration
Packages page, choose the relevant package, or create a new one.
If a table is not already included in the package, it will now be added. The package code field on the
worksheet line will be filled in with the code of the package that the table is assigned to.
If you choose an existing package, you can see how many tables are already in the package by
reviewing the information in the No. of Tables field.
6. Optionally, create a questionnaire for the most frequently used setup tables so that you can get specific
information from your prospects and customers that will help you set up their Business Central.
a. On the Configuration Questionnaire page, add a new questionnaire, and then choose the
Questions Areas action.
b. In the Config. Question Area page, in the Table ID field, choose the ID of the table for which
you want to collect information. The Table Name field is automatically filled in.
c. Choose the Update Questions action. Each field in the table is added to the questionnaire with a
question mark following its caption in the Question field.
You can rephrase the question to make it clear that it is a question that should be answered. For
example, if a field is called Name , you could edit the related question to state What is the name of
the account. You can also provide guidance in the Reference field, including a URL to a page that
provides additional information for example.
You can also delete any questions that you do not want to include in the questionnaire.
NOTE
The Answer Option field describes the format that the answer to the question must meet, such as Code
or Text.
As needed, you can also define default answers in the Answer field. These values are used by default for
custom setup. However, the person filling in the questionnaire can modify and update the answer.
d. Repeat steps 2 and 3 for any additional areas that you want to add to the questionnaire, and then
return to the Configuration Questionnaire page.
Optionally, export the questionnaire to Excel. Then, you can use the Excel workbook to get answers
from your prospects and customers. There are worksheets for each of the question areas that have
been created for the questionnaire.
NOTE
You may encounter the following error when you run an English version of Excel, but have your regional
settings configured for a non-English language: Old format or invalid type library. To fix this error, make
sure that the language pack for the non-English language is installed.
7. Optionally, create configuration templates to make it easier to import master data, such as customers,
vendors, contacts, or items.
Use the built-in configuration templates, or create your own templates in the Configuration Templates
page. This is mainly useful if you're going to migrate customer data to Business Central on-premises and
then switch to the cloud. For more information, see Apply Company Configuration Packages.
You can export the templates as Excel workbooks so that you can work with customer data in Excel.
8. Export your package as a .rapidstart file, or export it to Excel.
The next time you're going to set up Business Central for a new customer, you can apply your configuration
packages and get started fast. For more information, see Apply Company Configuration Packages.
See Also
Apply Company Configuration Packages
Migrate On-Premises Data to Business Central Online
FAQ about Migrating to Business Central Online from On-Premises Solutions
Administration of Business Central Online
Administration of Business Central On-Premises
Get Started as a Reseller of Business Central Online
Onboarding experiences in Business Central
Apply Company Configuration Packages
2/6/2023 • 7 minutes to read • Edit Online
When you onboard a prospect, you can use configuration packages to set up Business Central according to your
best practices and their requirements. Apply the relevant configuration packages to an empty company in the
customer's tenant. Use the questionnaires to tweak things for individual customers of yours. Optionally, use
configuration templates to import existing customer data.
Start by setting up a company in a sandbox so that users can practice before they start using Business Central in
production.
If the customer needs more than one company in Business Central, you can copy commonly used values from
an existing company to a new one, as long as both companies are in the same tenant. For example, if you have a
standard list of symptom codes that is common to all your service management implementations, you can copy
the codes easily from one company to another. You can do this from the Configuration Worksheet page.
NOTE
In general, validation of the configuration questionnaire is a manual process. However, there are checks for regional
formatting inconsistencies. In addition, you will get errors if the structure of your Business Central database does not
match the structure of the migration database.
1. On the Configuration Questionnaire page, select the relevant questionnaire, and then choose the
Question Areas action.
2. Open the relevant question area.
3. For each question, validate that the value in the Answer field corresponds to the format provided in the
Answer Option field. For example, validate that the address of a company is in text format.
4. If you find errors, you can troubleshoot and make corrections in Excel by exporting the questionnaire, and
then importing it again. Alternatively, you can correct errors directly in Business Central as you review the
answers on the Config. Question Area page.
5. Repeat these steps for each question area.
When you have completed your validation, the data is ready to be applied to the database.
To apply answers from the configuration questionnaire
After you have imported and validated information from a configuration questionnaire, you can transfer, or
apply the setup data to the corresponding tables in the Business Central database.
1. Choose the icon, enter Configuration Questionnaire , and then choose the related link. The Config.
Questionnaire page opens.
2. Select a configuration questionnaire from the list, and then choose the Edit List action.
3. You can apply answers in one of two ways.
To apply the whole questionnaire, choose the Apply Answers action.
To apply answers for a specific Question Area only, choose the Question Areas action, select a Question
Area in the list, and then choose the Apply Answers action.
To verify that answers have been applied successfully
1. Check setup pages for the various functional areas of Business Central. To locate the page, choose the icon,
enter the name of the setup page, and then choose the related link.
2. Verify that the fields have been populated with the correct data from the various question areas in the
configuration questionnaire.
You have now configured setup with the customer’s business information and rules.
To import customer data
1. Open the Configuration Worksheet page or the Configuration Package page and import the
customer's master data.
In the No. of Package Errors field, see if there are any errors reported. If there are, drill down to see the
errors. The Config. Package Records page opens.
a. Choose the Show Error action. You will receive an error such as the following: XX is not a valid
option. Valid options are: XX. Choose the OK button.
b. To apply the mapping that you have set up, choose the Apply Data action.
2. Validate the migration
a. On the Migration Over view page, review the No. of Migration Errors field to see whether any
errors occurred during import.
b. If there are errors, select the migration table, and then, on the Tables tab, choose the Errors action.
The Invalid check box is selected for each record that has an error.
c. To review errors, select a line, and then choose the Show Error action.
The Error Text field contains the reason for the error. The Field Caption field contains the caption of the
field that contains the error.
4. To correct an error or otherwise make an update, on the Migration Over view page, choose the
Migration Record action, and then, on the Migration Record page, correct the record with the error.
Now, you have master data in place. Next, you add the opening balances. The following steps describe
how to create journal lines for G/L accounts, but the same apply to creating journal lines for customers,
vendors, and items.
3. Choose the Create G/L Acct. Journal Lines action.
4. Fill in the Options FastTab as appropriate, and set filters as needed. For example, in the Journal
Template field, enter a name.
5. Choose the OK button. The records are now in the journal, but the amounts are empty.
6. Export the journal table to Excel and manually enter the posting and balancing account information from
the legacy data.
7. Import and apply the table information into the new company. The journal lines are ready for posting.
8. In the configuration worksheet, select the journal line table, and then choose the Database Data action.
9. Review the information, and then choose the Post action.
10. Repeat the steps to import and post any other opening balances.
IMPORTANT
Specifically for opening balances for bank accounts, do not follow the steps in this article to post directly to the G/L
accounts that are associated with the relevant bank accounts. For more information, see Set Up Bank Accounts.
See Also
Set Up Company Configuration Packages
Migrate On-Premises Data to Business Central Online
FAQ about Migrating to Business Central Online from On-Premises Solutions
Administration of Business Central Online
Administration of Business Central On-Premises Get Started as a Reseller of Business Central Online
Onboarding experiences in Business Central
Trials and Sign-ups for Business Central Online
2/6/2023 • 5 minutes to read • Edit Online
As a reselling partner, you can invite customers and prospects to sign up for any number of Dynamics 365 apps,
including Business Central online and partner solutions based on Business Central, using the same account ID.
These apps will run side-by-side with each other, will use different URLs, and will be displayed as separate tiles
on the home.dynamics.com portal.
This means that you can show prospects a preview of what you are offering based on trials of Business Central
and other Dynamics 365 apps.
Adjust the onboarding checklist to fit your solution, and provide in-app tours for key experiences. For more
information, see Onboarding experiences in Business Central.
C A N B E USED F O R
SC EN A RIO T RIA L P ERIO D C A N B E EXT EN DED P RO DUC T IO N
At any point during their trial experience, when they are ready, you can convert their trial to a paid subscription
using the Partner Center dashboard. For more information, see Converting trials to paid subscriptions in the
Partner Center content.
Dynamics 365 Business Central Premium Trial
In the Partner Center, you can find a special license type called the Dynamics 365 Business Central
Premium Trial license, which is a very different way to give a prospect or an existing customer a trial
experience using their own data. If you assigned the Dynamics 365 Business Central Premium Trial license
to a customer's account in the Partner Center, then that also expires after 30 days. You cannot extend the
Premium trial, but you can add one more Premium trial license to give the customer an extra 30 days of trial.
But when the second Premium trial expires, then the customer must either convert their trial to a paid
subscription, or they must sign up for the viral trial.
For more information, see Offer your customers trials of Microsoft products in the Partner Center
documentation. If you have technical difficulties assigning this license, contact Partner Center support. For more
information, see Report problems with Partner Center.
Cau t i on
Make sure you understand the limitations of this type of trial, before you offer it to a prospect or customer. It is
easy to convert this type of trial to a paid subscription, but if the prospect needs more than 30 days to decide, or
if they want to add more than 25 users, then the viral trial is probably a better fit for them.
Extending trials
An organization can sign up for a free trial of Business Central. When they first sign up for Business Central, they
get access to an evaluation version that does not include all capabilities in Business Central. They can then
switch to the 30 day trial experience to enable all capabilities.
However, sometimes a 30 day trial is not enough to decide if they want to buy Business Central. In that case,
they can extend their trial with an additional 30 days. For more information, see Need More Time to Decide
Whether to Subscribe? in the business functionality content for Business Central.
NOTE
If you are a reselling partner, we recommend that you set up demo environments for prospects that need longer time to
decide if they want to buy Business Central. You can also use demo environments to help customers train their
employees, for example. Using the 30 days trials for training should be limited to just that short period. However, demo
environments cannot be used for production. For more information, see Preparing Demonstration Environments.
If the prospect wants to extend the trial further than those 30 days, they must contact a partner. The partner can
extend it another 30 days if the delegated administrator signs into the prospect's Business Central and runs the
Extend Trial Period guide.
After those additional 30 days, the prospect must either purchase Business Central or abandon Business Central.
At this point, they will have had up to 90 days with the trial experience.
TIP
As a reselling partner, you can suggest your prospects sign up for a trial, but you can also help set up a customized
demonstration environment based on a sandbox environment or a trial environment. In both cases, you can easily add or
remove functionality based on your prospects' expectations. For more information, see Preparing Demonstration
Environments.
See Also
Onboarding experiences in Business Central
Help your customers get started
Get Started as a Reseller of Business Central Online
Embed App Overview
Major Updates and Minor Updates for Business Central Online
Onboarding experiences in Business Central
2/6/2023 • 2 minutes to read • Edit Online
Setting up Business Central for a customer usually involves manual setup from the partners' side. Often this
setup time is spent on basic settings that do not provide additional value to the specific customer but are more
generic and address the customer's industry or type of business. This is costly for the customer and can be a
bottleneck for you as a partner.
Microsoft provides tools you can use to help speed up this process and enable the customer to more easily learn
how to use the product and get to productive usage faster. This will save costs on the customer side and free up
your consultants' time.
The onboarding framework in Business Central presents all users with a consistent onboarding experience when
it comes to an introduction to the product itself. Partners can still use any other methodology that they prefer,
but the tools in the onboarding framework provides a native experience.
See also
Get Users Started with the Checklist
Onboard New Users with the Welcome Banner
Teaching tips and in-app tours for onboarding users
User Assistance Model
Extend and Collaborate on the Help
Migrate On-Premises Data to Business Central Online
Onboard New Users with the Welcome Banner
2/6/2023 • 2 minutes to read • Edit Online
When a user signs in to a new company for the first time, Business Central shows a welcome banner that
provides a clear call-to-action.
The purpose of the banner is to give users a warm and personal welcome, reduce noise, provide a clear call to
action to the get started tasks, without blocking users that wish to explore the product first.
The welcome banner works slightly different in CRONUS evaluation companies and in non-evaluation
companies, including My Company, because the banner serves different purposes in evaluation and non-
evaluation companies. The following sections outline the differences.
IMPORTANT
The Business Manager Evaluation role was created specifically for the design of the CRONUS evaluation experience. The
experience that is tied to this role through page customization or other directly impacted experiences may change from
release to release, unlike other code-related changes that are goverened by our breaking change rules.
We recommend that you build your own evaluation and demo experiences on another role if you want to make sure that
your scenarios are not impacted by these changes. For example, elements on the Business Manager Role Center has been
hidden for the Business Manager Evaluation role through page customization that is saved to the Business Manager
Evaluation role. More changes for the Role Center or other pages may come in the future for the Business Manager
Evaluation role based on Microsoft's need to pivot the CRONUS evaluation experience from the My Company experience.
The welcome banner in My Company and other non-evaluation
companies
In My Company and other non-evaluation companies, the welcome banner serves the purpose of letting the
customer self-serve the last-mile setup of Business Central. Accordingly, the checklist tasks are more focused on
guiding the user through various elements of setup. Consider how you structure the checklist for your
customers with the goal of getting them set up and onboarded as fast as possible.
For more information, see the Get Users Started with the Checklist article.
See also
Get Users Started with the Checklist
Teaching tips and in-app tours for onboarding users
Onboarding experiences in Business Central
Get Users Started with the Checklist
2/6/2023 • 6 minutes to read • Edit Online
When the user hits Get star ted on their Home page, a checklist is revealed inside the banner. The checklist
provides users with an overview of their onboarding activities, while allowing them to learn and explore at their
own pace. The checklist serves as a platform for surfacing page tours, guiding users in the product interface, and
teaching users how to use the app in context. The checklist provides a sense of progression, nudging users to
complete onboarding activities. Users can navigate between the tasks of the checklist at their own pace.
Checklist tasks can point to pages or objects in Business Central or point to external URLs. Read more about the
checklist content in the Prerequisites for creating checklist items section.
As the user progresses through the checklist by either completing or skipping the steps, the banner title and
status indication will change accordingly to nudge and encourage users to finish. At any point, the user can
minimize the banner by hitting X and resume when ready. The following illustration shows the checklist with the
suggested setup and learning material.
The checklist provides an overview of the tasks to complete as well as a detailed description of the ongoing task.
The following illustration shows a Business Central Home page with a collapsed banner, which indicates the
completion progress as well as providing a clear call-to-action to resume with the checklist activities.
NOTE
The checklist has different purposes in evaluation and non-evaluation companies. Consider this when you add content to
the checklist. For more information, see Onboard New Users with the Welcome Banner].
ID NAME P URP O SE
The spotlight tour suppresses teaching tips on the page and immediately calls out Teams and Excel
integration features as shown in the following illustration.
Video
Records of type Video enables the user to watch a video provided by a custom URL. The video will play
in a window inside Business Central. Consider how you can utilize video to explain a feature or capability.
Video is normally used in a sales/evaluation scenario but could also be used for training purposes in an
onboarding case. The following illustration shows a video player that is started from the checklist.
Application Feature
Records of type Application Feature enables a checklist task to open any page inside Business Central.
Similar to Manual Setup this opens a page and will display a page tour if any is defined.
Checklist items can be based on records in the Guided Experience Item table, which means that before you
surface a task on the checklist, you must first add it to Guided Experience Item .
To insert a record in the Guided Experience Item table use the façade functions in the Guided Experience
codeunit:
InsertManualSetup
InsertAssistedSetup
InsertLearnLink
InsertTour
InsertSpotlightTour
InsertVideo
InsertApplicationFeature
For example, let's say that you have the page My ISV Solution Setup where the user can configure your app.
You want to invite the business manager to access this page from the checklist. In this example, you must insert
a new record in the Guided Experience Item table with the type Manual Setup and provide the metadata as
data (title, descriptions, and so on) as described below.
After having created this record, it can now be referenced from and inserted into a checklist.
Best practices for checklist content creation
Do:
Keep the list short (preferably 6 items or less) to avoid a scrollbar and to ensure a successful start for
users.
Keep checklist titles and descriptions short and to the point.
When writing the description, it's good practice to include the benefit of doing the task. But be brief.
TIP
If the task points to a page that comes from the manual setup list, the Shor tTitleChecklist is picked from there. Those
titles consist of nouns such as User permissions .
If the task points to wizards that comes from the assisted setup list, the LongerTitleCard is picked from there. Those
titles usually contain a verb such as Update users .
Don't:
Don't overwhelm the user with a long list of checklist tasks
Don't use too long titles as they're harder to understand and space becomes an issue.
Maximum character UX guideline
Checklist: Shor tTitleChecklist : Max 34 characters before truncation.
Checklist: LongerTitleCard : Max 53 characters before truncation.
Checklist: CardDescription: Max 180 characters before truncation
Client truncation limits
Checklist: Shor tTitleChecklist : Max 34 characters before truncation.
Checklist: LongerTitleCard : Max 53 characters before truncation.
Checklist: CardDescription: A scrollbar appears if the description renders as more than 4 lines.
Auto completion settings and time estimates
Add support for auto-completion when possible, such as for wizards, as this automatically makes the
checklist move to the next task and provides the user with a good sense of progress.
Provide a realistic time stamp of the estimated completion time and strive for tasks that take less than 5
minutes to complete.
See also
Teaching tips and in-app tours for onboarding users
Onboarding experiences in Business Central
Teaching tips and in-app tours for onboarding users
2/6/2023 • 9 minutes to read • Edit Online
A key element in educating users about Business Central pages and concepts is the tour. A tour is a sequence of
teaching tips.
Teaching tips can be defined at the page level, the page teaching tip, and be followed by teaching tips at the
control level, the control teaching tips. Both types of teaching tips are defined by the .AL properties AboutTitle
and AboutText , and an extension can overwrite teaching tips in the default version.
The following illustration shows how choosing the page title will reopen the teaching tip so that the user can
retake the tour.
How to write page teaching tips
There are different rules for teaching tips for lists versus cards and documents.
L IST PA GE W IT H T EA C H IN G T IP C A RD PA GE W IT H T EA C H IN G T IP
What can I do on this page in general? What can I do on this page with this particular field
or action?
Is there a related entity I should know about?
What is the desired outcome of the task in this page?
The title for a list page teaching tip will typically use
the plural form, such as About sales invoices The title for a card or document page teaching tip will
typically be [entity name] + details, such as About
sales invoice details
T EA C H IN G T IP P O IN T IN G TO A N IN P UT F IEL D T EA C H IN G T IP P O IN T IN G TO A N A C T IO N
AboutTitle: Who you are selling to Content example for the Post action:
AboutText: This can be an existing customer, or you can AboutTitle: When all is set, you post
register a new from here. Customers can have special prices AboutText: After entering the sales lines and other
and discounts that are automatically used when you enter information, you post the invoice to make it count. After
the sales lines. posting, the sales invoice is moved to the Posted Sales
Invoices list.
The teaching tip can point to a field that may or may With multiple similar actions,such as Post and Post
not have data. & New , call out the simplest version only.
A control teaching tip can explain an important Avoid action language that tells users to do
value's meaning, such as what leaving the field blank something that isn't active during the tour. Don't say:
does. Now post the invoice. Instead, explain what to be
aware of when posting.
Avoid stating the obvious and avoid action language
that tells users to do something that isn't active
during the tour. For example, don't say Enter the
customer name here. Instead, explain what to be
aware of when adding a customer.
You can add teaching tips for FactBoxes just like pages by using the AboutTitle and AboutText properties is AL.
Adding teaching tips to FactBoxes
Teaching tips are supported on all page types that are supported in FactBoxes, including pages that display cues.
Specifically, you can add teaching tips to following elements:
On the part control that contains the page or cue.
The page or cue that is included in the part control.
Controls, like fields, on the page or cue.
When adding teaching tips, consider the following limitations:
You can't add teaching tips to actions or control add-ins in FactBoxes.
For FactBox teaching tips to activate, the hosting page must have a page teaching tip. The page doesn't need
any control teaching tips.
How FactBox teaching tips fit into tours
The teaching tips for FactBoxes become part of the tour on the hosting page. For more information, see Teaching
tips flow.
2022 release wave 1 adds support for rich text formatting for teaching tips. In this section, we take a look at the
rules and guidelines to follow when using rich text in teaching tips, such as bold, italic, or links.
Bold
Bolded text can call out the most important points, such as
Page names, such as Customer Card
Key features, such as Search
Field names, such as Customer
Keyboard shortcuts, such as Alt+Q
Best practices for use of bolded text
Use bolded text sparsely to avoid "shouting".
If a page name or key feature is title cased, it might be a candidate. However, consider if using bold is
needed to help understanding the message.
Consider the difference between a page name such as the **Posted Sales Invoices** list (bolded and
capitalized page name) as opposed to what the list contains such as the list of posted invoices (not
capitalized and not bolded).
If the feature is already mentioned in the title, consider if it's necessary to highlight the word again in the
body text. Bolding a word once in a tip is usually enough.
Italics
Italic text can be used to bring attention to key terms or field values, such as the following:
Key term, such as general ledger
Field value, such as Closed
TO O LT IP P O IN T IN G AT A F IEL D C A P T IO N T EA C H IN G T IP P O IN T IN G TO A F IEL D
Every field and action has a tooltip. Only the most important fields/actions have a
teaching tip.
Answers the question What is this?
Answers the question What can I do with this field or
Relevant for everything since every field/action has a action?
definition.
Isn't relevant for every field/action.
For more information about tooltips, see Help users get unblocked.
See also
Get Users Started with the Checklist
Guidelines for tooltip text
Onboarding experiences in Business Central
AboutTitle Property
AboutText Property
Pivot onboarding based on sign-up context
2/6/2023 • 2 minutes to read • Edit Online
You can create onboarding experiences that depend on where the Business Central sign-up originated. This
origin is defined as the sign-up context , which is available in version 20.3 and later.
Business Central passes this sign-up context from the browser URL to the application where it can be processed
by AL code. The sign-up context is visible to apps that want to react to the sign-up context to vary the
functionality according to the context.
Let's look at an example where a sign-up is triggered by a user on the Shopify administration page. Shopify
users can choose to sign up to Business Central after they installed the Business Central app on Shopify. The
Business Central sign-up flow is triggered, and the sign-up context is passed along to Business Central by the
client and exposed to AL for apps to consume.
_%3D1%26signupContext%3D%7B%22name%22%3A%22shopify%22%7D_
The encoded characters will end up resolving to a URL such as the this one:
https://businesscentral.dynamics.com/?redirectedFromSignup=1&ScenarioId=signup&signupContext={name:shopify}
Business Central recognizes the sign-up context parameter and stores the key-value pairs in a system table. The
key-value pairs are then parsed by the Business Central application and added to a database table, Signup
Context Values , for consumption.
During the sign-in process, an event is triggered that allows subscribing apps to read the Signup Context
Values table at an appropriate moment to run code that modifies the user experience where needed based on
the context.
IMPORTANT
Only sign-up contexts that are known to the Business Central application, created by Microsoft, will be parsed and
transferred from the system table to the app table. At this moment we do not recommend partners to attempt to use
the sign-up context.
See also
Onboarding experiences in Business Central
Recommend Apps
2/6/2023 • 2 minutes to read • Edit Online
The Microsoft commercial marketplace offers a wide variety of apps from Microsoft and our partners that
extend the value of Business Central. As a Microsoft partner, you can save yourself, and your customers, a bit of
legwork by using the Recommended Apps extension to curate a list of apps that are right for your customers'
businesses. Recommended Apps is a per-tenant extension (PTE), which means that you can make collections
unique for each customer, or build collections specifically for certain types of businesses or industries and then
reuse the collections when you're on-boarding those types of customers. For example, you can create one
collection for customers who work in finance, and another for customers in the retail space. For more
information, see Maintain AppSource Apps and Per-Tenant Extensions in Business Central Online.
M ET H O D DESC RIP T IO N
Inser tApp Add information about the apps from AppSource to the
Recommended Apps table. When adding new apps, you can
simply paste the URL for the app from AppSource for the
AppSourceUrl parameter, and Business Central will add the
relevant parts to the other parameters. However, you must
manually complete the Short Description ,
Long Description , and Recommended By parameters.
GetApp Get information from AppSource about the apps that are
already added to the Recommended Apps table.
UpdateApp Update the information about the apps that are already
added to the Recommended Apps table.
RefreshImage Update the logo for the app. When you insert an app, the
image is downloaded automatically. Use if the logo has
changed.
M ET H O D DESC RIP T IO N
DeleteApp Delete an app from the collection. You provide the app ID.
GetAppURL Get the URL for a specific app. You provide the app ID.
See Also
Onboarding experiences in Business Central
Monitoring and Analyzing Telemetry
2/6/2023 • 6 minutes to read • Edit Online
Business Central emits telemetry data for various activities and operations on environments and
apps/extensions. Monitoring telemetry gives you a look at the activities and general health of your
environments/apps, so you can diagnose problems and analyze operations that affect performance. Azure
Application Insights is a service hosted within Azure that gathers telemetry data for analysis and presentation.
Whether running Business Central online or on-premises, you can set your tenants up to send telemetry to
Azure Application Insights.
Available telemetry
Currently, Business Central offers telemetry on the following operations:
EXT EN SIO N M O RE
A REA DESC RIP T IO N O N L IN E O N - P REM ISES SUP P O RT IN F O RM AT IO N
This signal is only emitted to the Application Insights resource that's specified in the extension.
2
Introduced in Business Central 2020 release wave 1, version 16.3. For extension telemetry, this signal was
introduced in 2020 release wave 2, version 17.1.
3
Introduced in Business Central 2020 release wave 1, version 17.1. For extension telemetry, this signal was
introduced in 2021 release wave 1, version 18.1.
4
Enable Telemetry
To send telemetry data to Azure Application Insights, you must have an Application Insights resource in Azure.
Once you have the Azure Application Insights resource, you can start to configure your environments and
apps/extensions to send telemetry data to it. Learn more at Enable Sending Telemetry to Application Insights.
NOTE
For apps/extensions, see Sending Extension Telemetry to Azure Application Insights.
See also
Telemetry Event IDs
Enable Sending Telemetry to Application Insights
Working with Administration Tools
Business Central Administration Center
Managing Environments
Managing Tenant Notifications
Introduction to Automation APIs
LogMessage Method
Available telemetry
2/6/2023 • 13 minutes to read • Edit Online
In Application Insights, telemetry from Business Central is logged into the traces or pageview tables.
Telemetry by area
Currently, Business Central offers telemetry on the following operations:
EXT EN SIO N M O RE
A REA DESC RIP T IO N O N L IN E O N - P REM ISES SUP P O RT IN F O RM AT IO N
This signal is only emitted to the Application Insights resource that's specified in the extension.
2
Introduced in Business Central 2020 release wave 1, version 16.3. For extension telemetry, this signal was
introduced in 2020 release wave 2, version 17.1.
3
Introduced in Business Central 2020 release wave 1, version 17.1. For extension telemetry, this signal was
introduced in 2021 release wave 1, version 18.1.
4
Telemetry by Event Id
The following tables list the Ids of Business Central telemetry events that are emitted into Azure Application
Insights.
Application events
EVEN T ID A REA M ESSA GE
Client events
EVEN T ID A REA M ESSA GE
Lifecycle events
EVEN T ID A REA M ESSA GE
Runtime events
EVEN T ID A REA M ESSA GE
RT0020 Web service key request Authentication with Web Service Key
succeeded: {endpoint}
RT0021 Web service key request Authentication with Web Service Key
failed: {endpoint}
See also
Telemetry Event IDs
Enable Sending Telemetry to Application Insights
Enable Environment Telemetry
2/6/2023 • 5 minutes to read • Edit Online
This article describes how to set up sending telemetry data to Azure Application Insights for Business Central
online and on-premises environments.
NOTE
For app/extension telemetry, see Sending Extension Telemetry to Azure Application Insights.
IMPORTANT
In Business Central 2020 release wave 2 (v17) and earlier, don't use an Azure Application Insights resource in
Germany regions, such as (Europe) Germany West Central or (Europe) Germany Nor th . If you do, traces
from Business Central might not be recorded in Application Insights. The mitigation is to create an Azure
Application Insights resource in a region outside of Germany. Then, when the relevant time comes, move the
resource to the preferred region.
The Azure Application Insights resource can be in any Azure tenant that is accessible to your organization.
For example, a delegated administrator from the reselling partner is the person analyzing the telemetry.
But this person might not have access rights the customer's Azure instance. This scenario enables the
partner to send the telemetry to their own Azure Application Insights instance.
TIP
You can use the same Azure Application Insights resource for multiple tenants and their different environments.
NOTE
Transition to using connection strings for data ingestion in Application Insights by 31 March 2025 . On
31 March 2025, technical support for instrumentation key–based global ingestion in the Application
Insights feature of Azure Monitor will end. After that date, your Azure Application Insights resources will
continue to receive data, but Microsoft no longer provide updates or customer support for
instrumentation key–based global ingestion.
IMPORTANT
The next steps require a restart to the environment, which is triggered automatically at the end of this procedure.
Plan to do this during non-working hours to avoid disruptions.
2. On the Environment page, the Application Insights Key field shows if the environment already uses
application insights.
To enable telemetry, choose the Define caption, and then, in the Set Application Insights Key pane,
choose the Enable application insights field and enter the instrumentation key in the
Instrumentation Key field.
NOTE
In version 15 and 16, to enable telemetry, choose the Application Insights Key action, and then specify the
instrumentation key.
or
If you use the same Azure Application Insights resource for multiple environments, consider also using the
AadTenantId parameter to distinguish tenants in telemetry.
For on-premises Docker sandbox environments
If you're using the BcContainerHelper module, specify the Azure Application Insights instrumentation key when
you create the container. The key is used on the server instance for a single-tenant container. For a multi-tenant
container, it's used on the default tenant.
New-BcContainer `
-accept_eula `
-updateHosts `
-artifactUrl (Get-BCArtifactUrl -country us) `
-applicationInsightsKey "11111111-2222-3333-4444-555555555555"
You can specify the same or another key when creating more tenants:
.
To assign or change the telemetry ID, choose Set field to random GUID > OK .
To clear the telemetry ID, choose Set field to null GUID > OK .
NOTE
We recommend that a telemetry ID is assigned to all users to make it possible to troubleshoot situations that happened
in the past using telemetry.
Cleaning up settings
If the Azure Application Insights resource is tied to your partner account, and you end the relationship with a
customer where you have set up telemetry based on your account's instrumentation key, you must remove the
instrumentation key while you still have access to that customer's Business Central administration center.
It is also considered good practice to change all user telemetry IDs at the end of the relationship with the
customer. This will remove traceability to users for all data in the Azure Application Insights resource.
See Also
Sending Extension Telemetry to Azure Application Insights
Monitoring Long Running SQL Queries
Environment Telemetry
Monitoring and Analyzing With Telemetry
Controlling Telemetry Cost
2/6/2023 • 4 minutes to read • Edit Online
Azure Application Insights is billed based on the volume of telemetry data your application sends (data
ingestion) and how long time you want data to be available (data retention).
Check the Azure Application Insights documentation for up-to-date information on pricing:
https://azure.microsoft.com/pricing/details/monitor/.
Similarly, you can see the data distribution of different environments in your Azure Application Insights
resource, by running the KQL queries below.
// 30 day overview of data ingestion by environment in your Application Insights resource
let lookback = 30d ;
union traces, pageViews
| where timestamp > ago(lookback)
| extend aadTenantId = tostring( customDimensions.aadTenantId )
, environmentName = tostring( customDimensions.environmentName )
| summarize count() by aadTenantId, environmentName
| project aadTenantId, environmentName, count_
| order by aadTenantId, environmentName
See also
Telemetry overview
Enabling telemetry
Available telemetry
Analyze and Monitor Telemetry with Power BI
2/6/2023 • 13 minutes to read • Edit Online
To make it simple to analyze Business Central telemetry, we've developed two Power BI apps available from
Microsoft AppSource. One app is for telemetry on environments. The other one is for telemetry on
apps/extensions (the telemetry defined in app.json). Both apps are free and open source but requires Power BI
pro licenses to use.
To open the app, from the navigation pane, select Apps > Dynamics 365 Business Central Usage .
By default, the app shows sample data in the reports. This sample data enables you to demo the app to
prospective customers without having to show data from existing customers.
App on App Telemetry
To install or update the app for app telemetry, go to https://aka.ms/bctelemetry-isv-app and select Get it now .
You'll first have to sign in to Microsoft AppSource using your Power BI account name and password, if you aren't
already signed in. Follow the online instructions to get the app installed in Power BI.
Once installed, the Dynamics 365 Business Central App Usage app appears under Apps in Power BI. A
workspace with the same name is also installed for configuring the app.
To open the app, from the navigation pane, select Apps > Dynamics 365 Business Central App Usage .
By default, the app shows sample data in the reports. This sample data enables you to demo the app to
prospective customers without having to show data from existing customers.
TIP
You can install the Power BI apps more than once. Just go to the install link for the app and select Get it now again.
When prompted, choose Install another copy of the app into a new workspace .
3. On the Connect to Dynamics 365 Business Central Usage page, fill in the Application Insights
application id with the ID you copied from the previous step. In the Lookback period box, select the
number of days back in time you want to show.
Other information on the page is optional. For more information, see Configure the app.
4. Select Next and wait while your credentials are checked.
5. Select Sign in and connect , then enter a valid name and password for accessing the Application
Insights resource, if asked.
NOTE
Keep the Authentication method set to OAuth2 . If you get the error The OAuth authentication method isn't
supported for this data source, check if the application ID is correct; that's usually the root cause for that error.
NOTE
Once you connect to an Application Insights resource, You can't change the app back to show the sample data. If you
want to see the sample data, install the app again.
NOTE
If you turn off scheduled refresh and go back to the app, it will remove the Application ID and you have to enter it again.
In the following table, you'll find examples of scenarios for each persona where the app might be of help.
P ERSO N A SC EN A RIO H O W T H E P O W ER B I A P P C A N H EL P
Account Manager Prospective customer has concerns The Power BI app comes with sample
that online solutions are a blackbox. data when you install it. If questions
pop up, show them what kind of
insights the app offers and that they
can get access to the app if they find it
useful. Focus on the Usage report
unless the customer wants to see
some of the more technical reports
(that is, Errors, Performance, or
Administration). If the customer has a
representative from IT, then show
them the Administration report.
Account Manager Plan new activities with an existing Most of the pages in the Usage report
customer. can help drive conversations with the
customer on how to get more value
from their Business Central
investment. For example, look at the
Page views, Reports, and Feature
Usage pages to check whether the
customer is using the functionality
they set out to when starting the
project. Lack of data typically means
lack of usage.
Account Manager Get existing customers excited about Go to the Usage report and open the
reporting with Excel layouts. Reports page to check whether the
customer is using the Excel layouts
(you can filter on the layout type). If
they are, then it's good. Maybe you
can follow up with training or PoCs on
Power Query and maybe also start
working differently with the customer
on reporting. With Excel layouts, some
reports only need a developer for the
AL report object, then the
customer/end users can do most/all of
the layout in Excel. If the customer isn't
using Excel layouts yet, show them the
power of Business Central reports with
Excel layouts and a bit of Power Query
in Excel.
P ERSO N A SC EN A RIO H O W T H E P O W ER B I A P P C A N H EL P
Product Owner Which features in our apps or per- Make sure that apps/extensions have
tenant extensions are being used and enabled telemetry in the app manifest
how often? (app.json). Use the Feature Telemetry
AL system module to equip your app
with usage telemetry. Consider having
separate Power BI apps for
apps/extensions and environments.
Once you have data in telemetry, then
go to the Usage report and visit the
pages Page views, 'Reports', and
Feature Usage. This gives you an
overview of the pages/reports/features
that users use in your app. You can
filter the results down to
publisher/app.
Project manager We need a way to track progress on Go to the Usage report and visit the
User Acceptance Testing (UAT) efforts Page views, Reports, and Feature
Usage pages to see what users are
doing in Business Central. Consider
sharing the app with the customer to
enable them to do the follow-ups
internally based on data.
Project manager We want a smooth go-live for the Use the Error dashboard in the Error
customer. report to drive errors to zero before
go-live. Monitor the dashboard in the
first weeks after go-live. Consider
sharing the app with the customer so
status meetings and follow-ups can be
based on data.
Project manager Business Central online only: We want Look at the Deprecated features page
to check if the customer will get in the Usage report to see if the
broken integrations when they get customer is still using web service keys
updated to version 20.0 or 21.0 (basic auth) for integrations. If you see
any data here, work with the customer
on a mitigation plan to move
integrations to OAuth.
Supporter Customer calls and says that Go to the Administration report, find
"something changed since Friday of the All changes page and filter to a
last week." period in time that overlaps with
"Friday of last week." There are various
changes that a customer can report,
such as data, UI, business logic,
performance, stability, and so on.
Depending on the reported change,
you might get lucky that one of the
lifecycle events for environments,
extensions, companies, or indexes can
explain the root cause of the changed
behavior. Otherwise, you can dig
further into the issue with the app
using KQL queries, or simply by
reaching out to the code owner.
Supporter Customer complains that some users Go to the Error report and investigate
can't sign in. the Login Errors page.
P ERSO N A SC EN A RIO H O W T H E P O W ER B I A P P C A N H EL P
Supporter Customer complains that users get Go to the Error report and investigate
lots of errors when using the system. the Error Dialogs, Permission Errors,
and Feature Errors pages. You can filter
pages by Extension Publisher to learn
which code path the error is coming
from.
Supporter Customer experiences many locking Use the Database Deadlocks page in
issues. the Error report to examine deadlocks.
Use the Database Lock Timeouts page
in the Performance report to examine
lock time-outs. Use the Long running
SQL queries page (filter SQL Statement
to "UPDLOCK") to investigate SQL
queries that take locks.
See also
Telemetry overview
Enabling telemetry
Available telemetry
Analyze Telemetry with KQL
Analyze and Monitor Telemetry with KQL
2/6/2023 • 2 minutes to read • Edit Online
Telemetry from Business Central is stored in Azure Application Insights in the tables traces and pageViews. The
language used to query data in Azure Application Insights is Kusto Query Language (KQL). This article has
information and links to resources to get started learning about the KQL language. As a simple example, follow
these steps:
1. In the Azure portal, open your Application Insights resource.
2. In the Monitoring menu, select Logs .
3. On the New Quer y tab, enter the following to get the last 100 traces:
traces
| where timestamp > ago(7d) // look back 7 days
| take 100 // only take 100 rows
| project timestamp, message, customDimensions // only choose these three columns
| sort by timestamp desc // show the most recent data first
NOTE
The 8000 character limit is governed by the Application Insights API.
See also
Telemetry overview
Enabling telemetry
Available telemetry
Analyze Telemetry with Power BI
Alert on Telemetry
2/6/2023 • 3 minutes to read • Edit Online
If something happens in your environment or app that you need to act on, you can set up a system that sends
you an alert. Azure Application Insights makes it easy to define such alerts.
You can use the following tools to define and set up alerts on telemetry events:
Azure Application Insights Alerts
Azure Logic Apps
Power Automate
All three approaches need a Kusto (KQL) query to define the alerting condition.
TIP
Samples of alerting queries are shared by Microsoft and third parties on the Business Central BCTech repository on
GitHub. You can also share your alerting queries with the community on GitHub.
NOTE
Samples of custom notifications and automations are shared by Microsoft and third parties on the Business Central
BCTech repository on GitHub. You can also share your Application Insights Alerts and Automations with the community
on GitHub.
The samples below can help getting started with customization and automation using Application Insights.
IMPORTANT
Deploying a Logic App to Azure also creates the API Connection Resources necessary to authenticate certain actions in
the Logic Apps.
After deploying the Logic App, navigate to the created API Connection Resources in the Azure Portal to authenticate
them. The Application Insights API Connection Resource can be authenticated using the Application ID and an API Key.
These can be found and generated on the API Access page of the Azure Application Insights resource in the Azure Portal.
If you have already have API Connection Resources deployed in the selected Resource Group for the connections needed
to run the Logic App you can reuse them by entering the same resource name before deploying the Logic App.
Example - Run an alerting query every "n" days and send an email
This Logic App runs every number of days (specified in app deployment). It lists all updates made available to
environments that emit telemetry to the specified Application Insights resource during the period.
Administrators can use this app to replace email notifications they'd receive for environments when set up as
notification recipient.
Example - Run an alerting query every "n" minutes and send a message to Teams
This Logic App queries Application Insights every number of minutes (specified in app deployment). It notifies a
user (also specified in deployment) of any deleted environments in Microsoft Teams. The action that sends the
notification in Teams can be updated to notify a Channel or Group Chat instead.
See also
Telemetry overview
Enabling telemetry
Available telemetry
Available telemetry areas
2/6/2023 • 3 minutes to read • Edit Online
In Application Insights, telemetry from Business Central is logged into the traces or pageview tables.
Currently, Business Central offers telemetry on the following operations:
EXT EN SIO N M O RE
A REA DESC RIP T IO N O N L IN E O N - P REM ISES SUP P O RT IN F O RM AT IO N
This signal is only emitted to the Application Insights resource that's specified in the extension.
2
Introduced in Business Central 2020 release wave 1, version 16.3. For extension telemetry, this signal was
introduced in 2020 release wave 2, version 17.1.
3
Introduced in Business Central 2020 release wave 1, version 17.1. For extension telemetry, this signal was
introduced in 2021 release wave 1, version 18.1.
4
See also
Telemetry Event IDs
Enable Sending Telemetry to Application Insights
Analyzing AppSource Submission Validation Trace
Telemetry
2/6/2023 • 10 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1, version 18.4, and later
When you submit an app to AppSource using Partner Center, it starts an automated validation process. This
technical validation process ensures the extensions in the app meet the technical requirements for going live. It
goes through many of the same checks described in technical validation.
If an app's set up for it, telemetry traces are emitted to and recorded in Application Insights. The data provides
details about the success or failure of different phases of the validation. For more information about setting up
telemetry for an app, see Sending Extension Telemetry to Azure Application Insights.
NOTE
In order to start analyzing your validation results, use this troubleshooting guide Dynamics 365 Business Central
Troubleshooting Guide (TSG) - AppSource Submission Results (SaaS).
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0028
countryRegions Lists the localized versions (markets) of the app that will be
validated, like US or DK .
severity Information
versions Lists the Business Central release versions that the app will
be validated against, like 19.0 or 18.4
eventId LC0038
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0030
extensions Specifies the extensions that are part of the submission and
will be validated. Select the arrow to expand the dimension
to see the details about each extension.
severity Information
version Specifies the Business Central release versions that the app
will be validated against, like 19.0 or 18.4 .
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0032
severity Information
version Specifies the Business Central release that the extension will
be validated against, like 19.0 or 18.4 .
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0034
countryRegion Specifies the localized version of the app that was validated.
diagnosticSeverity Error
diagnosticSourcePath Specifies the path to the file where the diagnostic was
reported.
severity Error
version Specifies the Business Central release that the extension was
validated against, like 19.0 or 18.4 .
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0033
countryRegion Specifies the localized version of the app that was validated.
severity Information
version Specifies the Business Central release that the extension was
validated against, like 19.0 or 18.4 .
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0037
countryRegion Specifies the localized version of the app that was validated.
severity Error
version Specifies the Business Central release that the extension was
validated against, like 19.0 or 18.4 .
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0031
countryRegion Specifies the localized version of the app that was validated.
DIM EN SIO N DESC RIP T IO N O R VA L UE
severity Information
version Specifies the Business Central release that the app was
validated against, like 19.0 or 18.4 .
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0036
countryRegion Specifies the localized version of the app that was validated.
severity Error
version Specifies the Business Central release that the app was
validated against, like 19.0 or 18.4 .
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0029
countryRegions Lists the localized versions (markets) of the app that were
validated, like US or DK .
severity Information
versions Lists the Business Central release that the app was validated
against, like 19.0 or 18.4 .
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0035
DIM EN SIO N DESC RIP T IO N O R VA L UE
countryRegions Lists the localized versions (markets) of the app that were
validated, like US or DK .
severity Error
versions Lists the Business Central releases that the app was
validated against, like 19.0 or 18.4 .
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Prepare a Configuration Package in the Business Central
Analyzing App Key Vault Secret Trace Telemetry
2/6/2023 • 6 minutes to read • Edit Online
App key vault telemetry gathers information about the acquisition of secrets in Azure Key Vaults by extensions
at runtime. For an overview of app key vaults and secrets, see Using App Key Vaults with Business Central
Extensions.
The app key vault secret process has two operations: initialization and retrieval. The telemetry data provides
information about the success or failure for each of these operations. There are various conditions that cause a
failure. The failure messages provide insight into the cause of the failure, helping you identify, troubleshoot, and
resolve issues.
Initialization
Initialization is the first stage. It verifies the configuration of the app key vault provider in the extension and on
the service. This stage is initiated by the TryInitializeFromCurrentApp method call in the extension code. Some
conditions that cause failures in this stage include:
The extension doesn't specify a key vault in it's app.json file.
The Azure Key Vault Client Identity settings are incorrect. For example, it could be that the application (client)
ID that you specified for the key vault reader application in Azure is wrong.
The Business Central Server lacks permission to the private key of the Azure Key Vault client certificate.
Retrieval
Retrieval is the second stage, and occurs after a successful initialization. In this stage, the service tries to get a
secret from a specified key vault. This stage is initiated by the GetSecret method call in the extension code.
Some conditions that cause failures include:
The secret name requested by the extension is doesn't exist or isn't valid.
The key vault doesn't exist.
The application ID doesn't have permission to read from the key vault.
For more information about using key vault secrets with extensions, see App Key Vaults with Business Central
Extensions.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
alObjectName Specifies the name of the AL object that was run by request.
clientType Specifies the type of client that executed the request, such as
Background or Web . For a list of the client types, see
ClientType Option Type.
eventId RT0014
keyVaultUrls Specifies the DNS name of the Azure key vault that was used
in the request. The keyVaultUris are specified in the app.json
file of the extension.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
alObjectName Specifies the name of the AL object that was run by request.
eventId RT0015
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
alObjectName Specifies the name of the AL object that was run by request.
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
eventId RT0016
keyVaultUrl Specifies the DNS name of the Azure key vault that was used
in the request. The keyVaultUris are specified in the app.json
file of the extension.
message App Key Vault secret retrieval failed from key vault
'{keyVaultUri}'.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
alObjectName Specifies the name of the AL object that was run by request.
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
eventId RT0017
keyVaultUrl Specifies the DNS name of the Azure key vault that was used
in the request. The keyVaultUris are specified in the app.json
file of the extension.
See also
App Key Vaults with Business Central Extensions
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Authorization Trace Telemetry
2/6/2023 • 11 minutes to read • Edit Online
Authorization telemetry provides information about the authorization of users (or services) when trying to sign
in to Business Central. This telemetry data can help you identify problems a user (or a service) might experience
when signing in.
Authorization signals are emitted in two stages of sign-in. The first stage is the initial authorization, before the
CompanyOpen trigger is run. In this stage, the system verifies that the user account is enabled in the tenant and
has the correct entitlements. The telemetry data includes:
Success or failure of the sign-in attempt
Reason for failure
Type of user (such as normal, administrator, or delegated user)
Whether the user belongs to the tenant or is an invited user
The next stage occurs after a successful authorization attempt, when trying to open the company (that is, when
the CompanyOpen trigger run). The telemetry data indicates whether the company opened successfully or failed
(for some reason).
NOTE
Business Central 2020 release wave 1, version 16.1, introduces changes to some operation_Name and message
dimension values. The differences from earlier versions are indicated in the following sections.
AuthorizationSucceeded(PreOpenCompany)
Occurs when a user has been successfully authorized. This data is not emitted for on-premises environments.
General dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
authorizationStatus Succeeded
eventId RT0003
guestUser true indicates that the user is a guest user on the tenant.
false indicates the user belongs to the tenant.
UserType
VA L UE DESC RIP T IO N SEE M O RE
Normal user Indicates that the user is a normal user Create Users According to Licenses
in the tenant, based on the license.
NOTE
The client type is not known when the server emits the pre-open company events (RT0001 and RT0003). You need to join
to data for the events RT0002/RT0004 if you need both userType and clientType.
AuthorizationFailed(PreOpenCompany)
Occurs when a user sign-in has failed authorization. This data is not emitted for on-premises environments.
General dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
authorizationStatus Failed
guestUser true indicates that the user is a guest user on the tenant.
false indicates the user belongs to the tenant.
eventId RT0001
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
authorizationStatus Success
clientType Specifies the type of client that opened the session, such as
Background or Web . For a list of the client types, see
ClientType Option Type.
eventId RT0004
result Success
serverExecutionTime Specifies the amount of time it took the server to open the
company. The time has the format hh:mm:ss.sssssss.
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements**.
** From telemetrySchemaVersion 0.6 and onwards, this value also includes the CompanyOpen operation.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
authorizationStatus Failed
companyName Specifies the name of the company that the user tried to
open.
eventId RT0002
TIP
A good starting point is to look at the Effective Permissions that the user has on the company. You can do this from
the user card by selecting Effective Permissions and setting the Company to the company in question.
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Company Lifecycle Trace Telemetry
2/6/2023 • 11 minutes to read • Edit Online
Company created
Occurs when the company has been successfully created.
General dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
eventId LC0001
result Success
serverExecutionTime Specifies the amount of time it took the server to create the
company. The time has the format hh:mm:ss.sssssss.
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
severityLevel 2
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
eventId LC0002
result Failure
serverExecutionTime Specifies the amount of time it took the server create the
company before being canceled. The time has the format
hh:mm:ss.sssssss.
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
eventId LC0003
failureReason Specifies the exception that indicates the cause of the failure.
result Failure
serverExecutionTime Specifies the amount of time it took the server create the
company before it failed. The time has the format
hh:mm:ss.sssssss.
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
Company copied
Occurs when a company has been copied from another company successfully.
General dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 2
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
eventId LC0004
result Success
serverExecutionTime Specifies the amount of time it took the server to copy the
company. The time has the format hh:mm:ss.sssssss.
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 2
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0005
result Failure
DIM EN SIO N DESC RIP T IO N O R VA L UE
serverExecutionTime Specifies the amount of time it took the server to copy the
company. The time has the format hh:mm:ss.sssssss.
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
eventId LC0006
failureReason Specifies the exception that indicates the cause of the failure.
result Failure
serverExecutionTime Specifies the amount of time on the server. The time has the
format hh:mm:ss.sssssss.
Company deleted
Occurs when a company has been deleted successfully.
General dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
eventId LC0007
result Success
serverExecutionTime Specifies the amount of time it took on server. The time has
the format hh:mm:ss.sssssss.
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
severityLevel 2
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
eventId LC0008
result Failure
serverExecutionTime Specifies the amount of time it took on server. The time has
the format hh:mm:ss.sssssss.
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
eventId LC0009
result Failed
serverExecutionTime Specifies the amount of time it took on server. The time has
the format hh:mm:ss.sssssss.
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Configuration Package Telemetry
2/6/2023 • 3 minutes to read • Edit Online
APPLIES TO: Business Central 2020 release wave 2, version 17.2, and later
Configuration package telemetry gathers data about the following operations on configuration packages:
Export
Import
Apply
Delete
For information about working with configuration packages, see Prepare a Configuration Package in the
Business Central Application Help.
alCategory RapidStar t
alDataClassification SystemMetadata
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type. Added in version 20.0.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E3F
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E3G
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E3H
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E3I
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E3N
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E3O
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E3P
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Prepare a Configuration Package in the Business Central
Analyzing Database Deadlock Telemetry
2/6/2023 • 2 minutes to read • Edit Online
IMPORTANT
For Business Central on-premises, you must turn on the EnableDeadlockMonitoring setting of the Business Central Server
instance to collect the telemetry. For more information, see Configuring Business Central Server.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId RT0028
alObjectId Specifies the ID of the AL object that ran the transaction that
was victim of the deadlock.
DIM EN SIO N DESC RIP T IO N O R VA L UE
alObjectName Specifies the name of the AL object that ran the transaction
that was victim of the deadlock.
alObjectName Specifies the name of the AL object that ran the transaction
that victim of the deadlock.
alObjectType Specifies the type of the AL object that ran the transaction
that was victim of the deadlock, such as a page or report.
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
extensionId Specifies the AppID of the extension that was involved in the
deadlock.
extensionName Specifies the name of the extension that was involved in the
deadlock.
sqlServerSessionId Specifies the ID of the SQL server session that was the victim
of the deadlock.
sqlStatement Specifies the SQL statement that was the victim of in the
deadlock.
See also
Monitoring and Analyzing Telemetry
Database Lock Timeout Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Database Lock Timeout Trace Telemetry
2/6/2023 • 5 minutes to read • Edit Online
NOTE
In later versions of Business Central on-premises, the Business Central Server includes the
EnableLockTimeoutMonitoring setting. Use this setting to turn database lock timeout telemetry on or off. By default, it
is off. For more information, see Configuring Business Central Server.
TIP
When analyzing database lock timeout telemetry, it's useful to look at combined data from the Database lock timed
out event and Database lock snapshot events. You can combine data from different events by using joins in your
Kusto queries. For an example, see LockTimeouts.kql in the Microsoft/BCTech repository on GitHub. For more general
information about using joins, see Joins in Azure Monitor log queries in the Microsoft Azure documentation.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
eventId RT0012
extensionId Specifies the AppID of the extension that was involved in the
lock.
extensionName Specifies the name of the extension that was involved in the
lock.
sqlServerSessionId Specifies the ID of the SQL server session that requested the
lock.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId RT0013
extensionId Specifies the AppID of the extension that was involved in the
lock.
extensionName Specifies the name of the extension that was involved in the
lock.
sqlLockRequestStatus Specifies the current status of the lock, which can be one of
the following values:
CNVRT - means that the lock is transitioning from
another mode, but the conversion is blocked by
another process that holds a lock with a conflicting
mode.
GRANT - means that the lock is active.
WAIT - means that the lock is blocked by another
process that holds a lock with a conflicting mode.
sqlServerSessionId Specifies the ID of the SQL server session that requested the
lock.
sqlTableName Specifies the name of table on which the lock was held.
APPLIES TO: Business Central 2022 release wave 1, version 20.0, and later
The database performance can also be analyzed by checking the information at Database Wait Statistics . You
can see how many queries got delayed because of different wait types along with their wait times. The wait
types give you an idea about the resources or operations that are responsible for the slow performance.
For more information about wait statistics in optimizing database and application performance, see Database
Wait Statistics in Dynamics 365 Business Central.
NOTE
The wait times aren't live. These statistics show the wait times for the queries which are completed from the time the
database was started or when it was reset.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId RT0025
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId RT0026
databaseSignalWaitTimeInMs Specifies the time difference between when the query was
signaled to wait and when it starts to process.
databaseStartedDuration Specifies the date and time when the database was started.
databaseWaitTimeInMs Specifies the total wait time for a wait category including the
databaseSignalWaitTimeInMs.
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Performance for Developers
How to work with a performance problem
Analyzing Email Trace Telemetry
2/6/2023 • 2 minutes to read • Edit Online
APPLIES TO: Business Central 2020 release wave 2, update 17.2, and later
Email telemetry gathers data about the following operations:
An email was sent successfully
An attempt to send an email failed
Before you can collect this data, you'll have to set up email. For more information, see Set Up Email in the
Business Central application help.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
alCategory Email
alDataClassification SystemMetadata
alObjectType CodeUnit
eventId AL0000CTV
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
alCategory Email
alDataClassification SystemMetadata
alObjectType CodeUnit
eventId AL0000CTP
TIP
You can also view failed emails in the Email Outbox page in the Business Central client.
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Environment Lifecycle Trace Telemetry
2/6/2023 • 64 minutes to read • Edit Online
Environment lifecycle telemetry gathers data about the success or failure of the following environment-related
operations:
Update an environment
Start/stop/restart an environment
Copy an environment
Point-in-time restore an environment
Move an environment to a difference Azure Active Directory (AAD) tenant
Cancel a session from the Business Central admin center
Export the environment database
Change the environment configuration
Delete an environment
Rename an environment
Telemetry is also gathered on the following data update events:
Data upgrade started
Data upgrade succeeded
Data upgrade failed
Data upgrade recovery succeeded
Data upgrade recovery failed
Failed operations result in a trace log entry that includes a reason for the failure.
Custom dimensions available in all events
The following dimensions are available in all events described below and aren't included in the individual event
documentation:
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0100
registeredForUpdateOnOrAfterDateUtc Specifies the date and time (shown in UTC), registered in the
Business Central admin center, from which an update can be
scheduled.
updatePeriodEndDateUtc Specifies the end date and time of the update period (shown
in UTC).
updatePeriodStartDateUtc Specifies the start date and time of the update period
(shown in UTC).
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0101
registeredForUpdateOnOrAfterDateUtc Specifies the date and time (shown in UTC), registered in the
Business Central admin center, from which an update can be
scheduled.
updateDateSelectedByPartner Boolean value (True or False). Set to True if the update date
was chosen by the partner in the admin center.
updatePeriodEndDateUtc Specifies the end date and time of the update period (shown
in UTC).
updatePeriodStartDateUtc Specifies the start date and time of the update period
(shown in UTC).
updateWindowEndTimeUtc Specifies the end date and time of the update window
(shown in UTC).
updateWindowStartTimeUtc Specifies the start date and time of the update window
(shown in UTC).
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0102
registeredForUpdateOnOrAfterDateUtc Specifies the date and time (shown in UTC), registered in the
Business Central admin center, from which an update can be
scheduled.
updatePeriodEndDateUtc Specifies the end date and time of the update period (shown
in UTC).
updatePeriodStartDateUtc Specifies the start date and time of the update period
(shown in UTC).
updateWindowEndTimeUtc Specifies the end date and time of the update window
(shown in UTC).
updateWindowStartTimeUtc Specifies the start date and time of the update window
(shown in UTC).
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0103
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0104
registeredForUpdateOnOrAfterDateUtc Specifies the date and time (shown in UTC), registered in the
Business Central admin center, from which an update can be
scheduled.
updatePeriodEndDateUtc Specifies the end date and time of the update period (shown
in UTC).
updatePeriodStartDateUtc Specifies the start date and time of the update period
(shown in UTC).
updateWindowEndTimeUtc Specifies the end date and time of the update window
(shown in UTC).
updateWindowStartTimeUtc Specifies the start date and time of the update window
(shown in UTC).
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0105
registeredForUpdateOnOrAfterDateUtc Specifies the date and time (shown in UTC), registered in the
Business Central admin center, from which an update can be
scheduled.
remainingTimeInUpdateWindow The time from the start of the operation until the end of the
registered update window.
updatePeriodEndDateUtc Specifies the end date and time of the update period (shown
in UTC).
updatePeriodStartDateUtc Specifies the start date and time of the update period
(shown in UTC).
updateWindowEndTimeUtc Specifies the end date and time of the update window
(shown in UTC).
updateWindowStartTimeUtc Specifies the start date and time of the update window
(shown in UTC).
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0106
registeredForUpdateOnOrAfterDateUtc Specifies the date and time (shown in UTC), registered in the
Business Central admin center, from which an update can be
scheduled.
updatePeriodEndDateUtc Specifies the end date and time of the update period (shown
in UTC).
updatePeriodStartDateUtc Specifies the start date and time of the update period
(shown in UTC).
updateWindowEndTimeUtc Specifies the end date and time of the update window
(shown in UTC).
updateWindowStartTimeUtc Specifies the start date and time of the update window
(shown in UTC).
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0107
failureCode Specifies code that describes the type of error that blocks
the update, such as PteCompilation .
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
registeredForUpdateOnOrAfterDateUtc Specifies the date and time (shown in UTC), registered in the
Business Central admin center, from which an update can be
scheduled.
updatePeriodEndDateUtc Specifies the end date and time of the update period (shown
in UTC).
updatePeriodStartDateUtc Specifies the start date and time of the update period
(shown in UTC).
updateWindowEndTimeUtc Specifies the end date and time of the update window
(shown in UTC).
updateWindowStartTimeUtc Specifies the start date and time of the update window
(shown in UTC).
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0110
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0111
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0112
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0113
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0114
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0115
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0116
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0117
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0118
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0119
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0120
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0121
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0122
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0123
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0124
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0125
pointInTimeUtc Specifies the point in time (in UTC) to which the environment
should be restored to.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0126
pointInTimeUtc Specifies the point in time (in UTC) to which the environment
should be restored to.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0127
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
pointInTimeUtc Specifies the point in time (in UTC) to which the environment
should be restored to.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0128
pointInTimeUtc Specifies the point in time (in UTC) to which the environment
should be restored to.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0129
pointInTimeUtc Specifies the point in time (in UTC) to which the environment
should be restored to.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0130
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
pointInTimeUtc Specifies the point in time (in UTC) to which the environment
should be restored to.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0131
registeredForMoveDateUtc Specifies the date and time (in UTC) registered by Microsoft
Support on which the operation should happen.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0132
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
registeredForMoveDateUtc Specifies the date and time (in UTC) registered by Microsoft
Support on which the operation should happen.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0133
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0134
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0135
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0136
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0137
DIM EN SIO N DESC RIP T IO N O R VA L UE
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0138
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
blobUrl Specifies the URL of the blob where the database export file
will be saved.
eventId LC0139
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
blobUrl Specifies the URL of the blob where the database export file
will be saved.
eventId LC0140
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
blobUrl Specifies the URL of the blob where the database export file
will be saved.
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0141
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0142
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0143
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0144
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0145
DIM EN SIO N DESC RIP T IO N O R VA L UE
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0146
newUpdateWindowStartTimeUtc The start time (in UTC) for the new update window.
newUpdateWindowEndTimeUtc The end time (in UTC) for the new update window.
oldUpdateWindowStartTimeUtc The start time (in UTC) for the old update window.
oldUpdateWindowEndTimeUtc The end time (in UTC) for the old update window.
Environment update window modification failed
Occurs when a update window failed to be updated.
General dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0147
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
newUpdateWindowStartTimeUtc The start time (in UTC) for the new update window.
newUpdateWindowEndTimeUtc The end time (in UTC) for the new update window.
oldUpdateWindowStartTimeUtc The start time (in UTC) for the old update window.
oldUpdateWindowEndTimeUtc The end time (in UTC) for the old update window.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0149
Environment deleted
Occurs when the environment was successfully deleted.
General dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0150
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0151
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0152
Environment renamed
Occurs when the environment was successfully renamed.
General dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0153
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0154
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0155
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0156
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0157
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0158
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0159
DIM EN SIO N DESC RIP T IO N O R VA L UE
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0160
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0175
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0176
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0177
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0178
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId LC0179
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Error Message Quality Telemetry
2/6/2023 • 2 minutes to read • Edit Online
APPLIES TO: > APPLIES TO: Business Central 2022 release wave 1 and later
When a user gets an error message while working in the application, the message includes a yes or no question
as to whether the message was helpful, similar to the following illustration:
If a user selects either Yes or No , a signal is emitted and recorded in Application Insights. This information can
help partners and developers get insight into error messages that users find hard to understand. They can then
follow up with the customer to help out.
This voting feature appears on all error messages that are thrown by calls to the Error(String) and
Error(ErrorInfo) methods.
Custom dimensions
The following table explains the custom dimensions included in the trace.
eventId CL0002
appName Specifies the name of the extension that threw the error.
appVersion Specifies the version of the extension that threw the error.
userFeedback Specifies what the user voted, which can be either Yes or
No .
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Error Method Telemetry
2/6/2023 • 2 minutes to read • Edit Online
When a user gets an error dialog while working in Business Central, a telemetry signal is emitted, which can be
logged in an Application Insights resource.
This telemetry data let's you identify and analyze calls to the ERROR method from AL code. You can also set up
alerts in Azure Monitor to get notified if many users experience errors.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId RT0030
alErrorMessage The error string defined in error method and displayed in the
client.
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
companyName The display name of the Business Central company that was
used at time of execution
failureReason Dialog means the error was the result of an error method
call in AL. Errors thrown by the platform have other reasons,
like MetadataNotFound.
aadTenantId The Azure Active Directory (Azure AD) tenant ID that's used
for Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
See also
Upgrading Extensions
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Dialog.Error Method
Dialog.Error Method
Analyzing Extension Lifecycle Trace Telemetry
2/6/2023 • 42 minutes to read • Edit Online
INTRODUCED IN: Business Central 2020 release wave 1, version 16.3. Extension-level support introduced in
2020 release wave 2, version 17.1.
Extension lifecycle telemetry gathers data about the success or failure of the following extension-related
operations:
Compiling an extension
Synchronizing an extension
Publishing an extension
Installing an extension
Updating an extension
Uninstalling an extension
Unpublishing an extension
Failed operations result in a trace log entry that includes a reason for the failure.
Traces are recorded for operations started initiated from any of the following components, depending whether
you have Business Central online or on-premises:
C O M P O N EN T O N L IN E O N - P REM ISES
NOTE
For some operations, you might experience that certain custom dimensions aren't available. The reason is that custom
dimensions are added to the signal gradually, as the information is retrieved. If the operation fails before the custom
dimension is retrieved, it isn't included in the result. For example, if you try to uninstall an extension using the Ininstall-
NAVApp cmdlet, and the specified extension name is wrong, the operation fails. In this case, the extensionid and
extensionVersion will be excluded from the results.
ENVIRONMENT/SERVER TRACES
The traces in this section are recorded for extensions that are published to the environment/server in the tenant
scope only.
For on-premises, it includes extensions that are published by running the Publish-NAVApp cmdlet with
the -Scope Tenant parameter.
For online, it includes per-tenant extensions uploaded from the Extension Management page in the
client. It doesn't include Microsoft extensions or AppSource extensions.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0020
result Success
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0021
result Failure
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0014
result Success
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0015
result Failure
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0018
result Success
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0019
result Failure
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
TENANT TRACES
The traces in this section are recorded for synchronizing, installing and updating extensions on a tenant.
Synchronizing extensions
For on-premises, data for this operation is recorded when an extension is synchronized by using
the Sync-NAVApp cmdlet.
For online, data is recorded when an extension is installed from the Extension Management
page in the client. Or, when upgraded from the Manage Apps page in the Business Central
administration center.
Installing and uninstalling extensions
For on-premises, data for these operations is recorded when an extension is installed or
uninstalled by using the Install-NAVApp cmdlet or Uninstall-NAVApp cmdlet. Or, when an
extension is installed or uninstalled from the Extension Management page in the client.
For online, data for these operations is recorded when an extension is installed or uninstalled from
the Extension Management page in the client.
Updating an extension
For on-premises, data for this operation is recorded when an extension is upgraded by using the
Start-NAVAppDataUpgrade cmdlet.
For online, data is recorded when an extension is updated from the Manage Apps page in the
Business Central administration center.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0012
result Success
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0013
result Failure
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0056
result Failure
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0010
result Success
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0026
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0011
failureReason Specifies the error that occurred when the extension was
installed.
result Failed
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0016
result Success
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0027
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0017
DIM EN SIO N DESC RIP T IO N O R VA L UE
failureReason Specifies the error that occurred when the extension was
uninstalled.
result Failure
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
NOTE
Data is also recorded for any upgrade code that was run. For more information, see Analyzing Extension Update Trace
Telemetry.
General dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0022
extensionCulture Specifies the language version for which the extension that
was upgraded. The value is a language culture name, such as
en-US or da-DK . If a language wasn't specified when the
extension was installed, then en-US is used by default.
result Success
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
NOTE
Data is also recorded for any upgrade code that was run. For more information, see Analyzing Extension Update Trace
Telemetry.
General dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0023
extensionCulture Specifies the language version for which the extension that
was upgraded. The value is a language culture name, such as
en-US or da-DK . If a language wasn't specified when the
extension was installed, then en-US is used by default.
result Failure
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
The traces in this section are emitted by the Business Central control plane service during the installation or
update operation of an extension/app. Theses traces compliment the tenant traces described above and help
you identify the origin or cause of the extension's installation or update. The traces are recorded when:
The extension is explicitly installed or updated
The extension is installed or updated because an extension that's dependant on it was installed or updated.
A hotfix is applied to the extension by Microsoft or ISV embed partner.
The following table illustrates the traces you can expect to see with the installation or update of an extension, in
the order that they'll occur. The trace messages have been simplified for illustration purposes.
Environment app version install Environment app version update Control plane
scheduled scheduled
Environment app version install Environment app version update Control plane
started started
Environment app version installed Environment app version updated Control plane
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0161
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0162
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0163
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0164
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0165
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0166
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0167
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0168
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0169
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0170
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0171
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0173
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0174
failureReason Specifies the reason for the failure. Use this for
troubleshooting.
runAfterDateUtc Specifies the date and time (in UTC) after which the hotfix
can be applied.
See also
Upgrading Extensions
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Extension Update Telemetry
2/6/2023 • 4 minutes to read • Edit Online
INTRODUCED IN: Exception telemetry was introduced in Business Central 2020 release wave 1, version 16.2.
Upgrade tag telemetry was introduced in Business Central 2021 release wave 1, version 18.1.
Extension upgrade telemetry gathers information about operations that can occur during extension upgrades:
Upgrade code failures
The telemetry provides information about exceptions that are thrown by code run by upgrade codeunits.
The trace events include the following information:
The codeunit that threw the exception.
AL stack trace.
Exception message.
Upgrade tag usage
The telemetry provides information about calls to the AL methods HasUpgradeTag and SetUpgradeTag
from upgrade codeunits. These methods are provided by codeunit 9999 Upgrade Tag in the System
Application extension. Upgrade tags are used to control when upgrade code is run. For more information,
see Using upgrade tags to control upgrade code. This data can help you identify, troubleshoot, and
resolve issues in upgrade code.
The telemetry helps you troubleshoot and resolve code issues that block the data upgrade of per-tenant and
AppSource extensions.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId RT0010
companyName The display name of the Business Central company that was
used at time of execution
failureReason The exception that was thrown by the upgrade code. Some
exception messages can contain customer data. As a
precaution, Business Central only emits information that's
classified as SystemMetadata. Exception messages that
contain other data classifications, like customer data, aren't
shown. Instead, the following message is shown: "Message
not shown because the NavBaseException(string, Exception,
bool) constructor was used."
failureType DataUpdate
aadTenantId The Azure Active Directory (Azure AD) tenant ID that's used
for Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000EJ9
alCategory ALUpgrade
alCompanyName The display name of the Business Central company that was
used at time of execution
alDataClassification OrganizationIdentifiableInformation
alObjectId 9996
alExecutionContext The context that the upgrade code was running in. The
dimension has the following values:
Install indicates the code was run during the
installation of the extension.
Upgrade indicates the code was run during the
upgrade of the extension.
Normal indicates the code was run by an operation
other than extension installation or upgrade. For
example, when a new company was added.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000EJA
alCategory ALUpgrade
alCompanyName The display name of the Business Central company that was
used at time of execution
alDataClassification OrganizationIdentifiableInformation
alObjectId 9996
alExecutionContext The context that the upgrade code was running in. The
dimension has the following values:
Install indicates the code was run during the
installation of the extension.
Upgrade indicates the code was run during the
upgrade of the extension.
Normal indicates the code was run by an operation
other than extension installation or upgrade. For
example, when a new company was added.
See also
Upgrading Extensions
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Feature Telemetry
2/6/2023 • 3 minutes to read • Edit Online
The Telemetry AL module simplifies the way you monitor the health of your solution and the uptake of
application features. There are multiple benefits of using the module compared to sending telemetry via
Session.LogMessage . For example:
NOTE
Tracking the uptake status of a feature may make database transactions. If LogUptake is called from within a try
function, the PerformWriteTransactionsInASeparateSession parameter should be set to True .
Calling LogUptake when the uptake state is Undiscovered resets the uptake state of the feature. The telemetry
from this call will be used to calculate the values in the uptake funnel of the feature.
Log uptake
If a feature logs uptake, there should be calls to register the Discovered , Set up , and Used states. The
following list describes the current convention for registering uptake states:
Discovered should be registered when pages related to the given feature are opened (or when a user looks
for information about a feature).
Set up should be registered when the user performed a set up for the feature (usually right after a record in
a table related to the feature is added or updated).
Used should be registered when a user attempts to use the feature (note the difference with LogUsage,
which should be called only if the feature is used successfully).
If LogUptake is called from a try function, the PerformWriteTransactionsInASeparateSession parameter should be
set to true .
General dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
alCategory FeatureTelemetr y .
See Also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Feature Telemetry sample
Analyzing Field Monitoring Telemetry
2/6/2023 • 3 minutes to read • Edit Online
APPLIES TO: Business Central 2020 release wave 2 (update 17.1) and later
Keeping sensitive data secure and private is a core concern for most businesses. To add a layer of security, you
can monitor important fields when someone changes a value. For example, you might want to know if someone
changes your company's IBAN number.
To gather this data, you'll have to start field monitoring and specify the fields that you want to monitor. For more
information, see Auditing Changes in Business Central - Monitoring Sensitive Fields in the Application help.
Telemetry is then logged for the following operations:
When field monitoring is stopped or started
When a field is added or removed for monitoring (only in version 18.0 and later)
When a field value is changed
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000DD3
alObjectId 1392
alObjectType CodeUnit
alDataClassification SystemMetadata
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000CTE
alFieldCaption Specifies the name of the field that was changed. This
dimension is called "alfieldCaption" before version 18.0.
alFieldNumber Specifies the ID of the field that was changed. This dimension
was introduced in version 18.0.
alTableCaption Specifies the name of the table that includes the changed
field. This dimension is called "altableCaption" before version
18.0.
alTableNumber Specifies the ID of the table that includes the changed field.
This dimension was introduced in version 18.0.
alObjectId 1367
alObjectType CodeUnit
NOTE
Changes to fields in the following tables are always logged:
Fields in the Field Monitoring Setup table. Many of the fields are included on the Field Monitoring Setup page.
Fields in the Change Log Setup (Field) table. Many of the fields are included on the Field Monitoring
Worksheet page.
The Contact Email field in the User table.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000EMW
alFieldCaption Specifies the name of the field that was added or removed.
alTableCaption Specifies the name of the table that includes the added or
removed field.
alObjectId 1367
alObjectType CodeUnit
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Job Queue Lifecycle Trace Telemetry
2/6/2023 • 5 minutes to read • Edit Online
APPLIES TO: Business Central 2020 release wave 2, version 17.2, and later
Job queue lifecycle telemetry gathers data about the following operations:
A job queue entry was enqueued.
A job queue entry was started.
A job queue entry finished. Provides information as to whether it was successful or failed.
For information about creating and managing job queue entries, see Use Job Queues to Schedule Tasks in the
Business Central application help.
severityLevel 1
Custom dimensions
The following table explains custom dimensions that are specific to this trace.
eventId AL0000E24
alJobQueueIsRecurring Specifies whether the job queue is recurring. Yes indicates it's
recurring. No indicates it's not recurring.
alJobQueueObjectId Specifies the ID of the object that the job queue entry runs.
alJobQueueObjectType Specifies the type of the object that the job queue entry
runs, for example Repor t or Codeunit .
Error
Information if the job queue entry fails to be sent to the queue.
General dimensions
severityLevel 2
Custom dimensions
The following table explains custom dimensions that are specific to this trace.
eventId AL0000FNY
Success
Information if the job queue entry was successfully sent to the queue.
General dimensions
severityLevel 1
Custom dimensions
The following table explains custom dimensions that are specific to this trace.
eventId AL0000E24
severityLevel 1
Custom dimensions
The following table explains custom dimensions that are specific to this trace.
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E25
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E26
alJobQueueExecutionTimeInMs Specifies how many milliseconds it took to run the job queue
entry.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E26
severityLevel 2
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000HE7
alCategory AL JobQueueEntries
alJobQueueEarliestStartDateTime Specifies the earliest start date/time for the job queue entry.
alJobQueueObjectId Specifies the ID of the object that the job queue entry runs.
alJobQueueObjectType Specifies the type of the object that the job queue entry
runs, for example Repor t or Codeunit .
alJobQueueStackTrace Specifies the AL stack trace of the job queue entry. This
dimension was introduced in version 20.5.
alObjectType CodeUnit
extensionName Specifies the name of the extension that contains the object
run by the job queue entry.
extensionId Specifies the ID of the extension that contains the object run
by the job queue entry.
Event IDs
The following table describes the event IDs that are currently emitted.
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Use Job Queues to Schedule Tasks
Analyzing Long Running AL Methods Telemetry
2/6/2023 • 3 minutes to read • Edit Online
> APPLIES TO: Business Central 2020 release wave 2 and later, version 17.1. Available in extension telemetry
starting with version 18.1.
The Business Central Server server will emit telemetry about the execution time of long running AL methods,
including the time spent in the database. The signal also includes a breakdown of how much time each event
subscriber added to the total time. As a partner, this data gives you insight into bad performing code and
enables you to troubleshoot performance issues caused by extensions.
NOTE
To collect this telemetry for Business Central on-premises, the AL Function Timing and AL Function Logging
Threshold - Application Insights settings must be configured on the Business Central Server instance. For more
information, see Configuring Business Central Server. With Business Central online, this telemetry is enabled with a
specific threshold on a case-by-case basis by the service.
General dimensions
The following table explains the general dimensions included in the trace. The table lists the dimensions that are
specific to Business Central.
severityLevel 2
CustomDimensions
This table describes the different dimensions of a Operation exceeded time threshold (AL method)
operation.
C O L UM N ( K EY ) DESC RIP T IO N O R VA L UE
companyName The display name of the Business Central company that was
used at time of execution.
eventId RT0018
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Monitoring and Analyzing Long Running SQL Queries On-Premises
The Business Central Administration Center
Analyzing Long Running Operation (SQL Query)
Telemetry
2/6/2023 • 5 minutes to read • Edit Online
Any SQL query that takes longer than 750 milliseconds to execute will be sent to your Azure Application Insights
resource. This enables you to focus on tuning SQL queries that take too long to execute (maybe one or more
tables miss an index or maybe some filters are missing). It also reduces the ingestion of data into the Azure
Application Insights resource to save cost of having telemetry.
If you want to capture all SQL queries for a short period of time for a given session, you can enable Additional
logging from the Help & Suppor t page. This lets you analyze queries that take a short time to run but happen
very frequently. For Business Central online, additional logging is available on production environments running
version 17.4 or later. For Business Central on-premises, additional logging is available on environments running
version 18.6 or later.
NOTE
With Business Central on-premises, you can change the threshold that defines long running queries. For more
information, see Defining Long Running SQL Queries Threshold.
There are multiple reasons that affect the time it takes SQL queries to run. For example, the database could be
waiting for a lock to be released. Or, the database is executing an operation that does badly because of missing
indexes. Sometimes you can look at the SQL statement that was generated by the code to see what caused the
delay. This information is found in the CustomDimension data, specifically the AL Stack Trace column.
C O L UM N DESC RIP T IO N O R VA L UE
timestamp Specifies the date and time that the long running query
event occurred, such as 2019-08-20T07:23:07.9996696Z
itemType trace
session_Id Specifies the GUID of the client session. When a client makes
a connection to the Business Central Server instance, a
session is created and assigned an ID.
CustomDimensions
This table describes the different dimensions of a Long Running Operation (SQL Quer y) operation.
C O L UM N ( K EY ) DESC RIP T IO N O R VA L UE
alObjectType The type of the AL object that executed the SQL statement
alObjectName The name of the AL object that executed the SQL statement
companyName The display name of the Business Central company that was
used at time of execution.
eventId RT0005
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web. For a list of the client types, see
ClientType Option Type.
alObjectId The type of the AL object that executed the SQL statement.
component Specifies the Business Central Server instance name and the
platform version.
longRunningThreshold Specifies the amount of time that an SQL query can run
before a warning event is recorded. The value has the format
hh:mm:ss.sssssss.
sqlStatement Specifies the SQL statement that was executed for the long
running query. The value is limited to 8192 characters. If the
value exceeds 8192 characters, it will be truncated in manner
that still provides the most pertinent information.
C O L UM N ( K EY ) DESC RIP T IO N O R VA L UE
** From telemetrySchemaVersion 0.6 and onwards, this value also includes the CompanyOpen operation.
Example
The following code snippet shows an example of the CustomDimensions.
{"extensionVersion":"16.0.10962.0","telemetrySchemaVersion":"0.3","componentVersion":"15.0.40494.0","environmentType":"Production","environmentName":"Production","
Application","alObjectType":"Report","alObjectName":"Suggest Worksheet Lines","alStackTrace":"AppObjectType: Report\r\n AppObjectId: 840\r\n AL CallStack: \"Sugges
(Report 840).DeleteEntries line 10 - Base Application by Microsoft\r\n\"Suggest Worksheet Lines\"(Report 840).\"Cash Flow Forecast - OnPostDataItem\"(Trigger) line
Application by Microsoft\r\n\"Cash Flow Management\"(CodeUnit 841).UpdateCashFlowForecast line 32 - Base Application by Microsoft\r\n\"Cash Flow Forecast Update\"(
842).OnRun(Trigger) line 18 - Base Application by Microsoft\r\n\"Job Queue Start Codeunit\"(CodeUnit 449).OnRun(Trigger) line 11 - Base Application by Microsoft\r\
Dispatcher\"(CodeUnit 448).HandleRequest line 30 - Base Application by Microsoft\r\n\"Job Queue Dispatcher\"(CodeUnit 448).OnRun(Trigger) line 19 - Base Applicatio
Microsoft","companyName":"CRONUS USA, Inc.","extensionId":"437dbf0e-84ff-417a-965d-ed2bb9650972","aadTenantId":"8ca62103-8877-486d-88e2-
9a91303abfc6","clientType":"Background","alObjectId":"840","component":"Dynamics 365 Business Central Server","executionTime":"00:00:05.7470000","sqlStatement":"DE
\"SQLDATABASE\".dbo.\"CURRENTCOMPANY$Cash Flow Forecast Entry$437dbf0e-84ff-417a-965d-ed2bb9650972\" WHERE (\"Cash Flow Forecast No_\"=@0)"}
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Monitoring and Analyzing Long Running SQL Queries On-Premises
The Business Central Administration Center
Analyzing Page View Telemetry
2/6/2023 • 5 minutes to read • Edit Online
INTRODUCED IN: Business Central 2020 release wave 1, version 16.3. Available in extension telemetry from
version 18.0. Available in on-premises environments from version 21.0.
Page view telemetry gathers data about the pages that users open in the Business Central client. Each page view
tells you how long it took to open the page, information about the user's environment, and more.
Use the data to gather statistics about system usage and also troubleshoot performance issues caused by the
users' environments.
NOTE
In Application Insights, telemetry about page views is logged to the pageViews table and not the traces table like other
Business Central traces. This also means that you can use the built-in pages in the Usage feature of the Application
Insights to investigate how users interact with the Business Central environment. For more information, see Usage
analysis with Application Insights.
alObjectName Specifies the name of the page object that was opened.
alObjectType Page
appId Specifies the ID of the extension that the page belongs to.
appName Specifies the name of the extension that the page belongs
to.
appVersion Specifies the version of the extension that the page belongs
to.
clientType Specifies the type of client that opened the page such as
Background or Web . For a list of the client types, see
ClientType Option Type.
companyName The display name of the Business Central company that was
used when the page opened.
designerLevel Specifies the design level in which the page was opened. This
dimension provides additional insight when the hostType
dimension is Designer .
None
The page wasn't opened in a design mode. This value
is shown when the hostType dimension is a value
other than Designer
Personalization
The page opened in the personalizing mode for
tailoring the page in the user's workspace only. See
Personalize Your Workspace.
Configuration
The page opened in customizing mode for tailoring
the page for all users of a specific profile. See
Customizing Pages for Profiles.
Development
The page opened in design mode for developing and
modifying the page from the client for all users. See
Using Designer.
Inspector
The page opened in page inspection mode for
viewing page information like source table, source
extension, and filters. See Inspecting Pages.
All - the page was opened in the personalization,
configuration, development, and inspector modes.
deviceScreenResolution Specifies the display resolution of the device that opened the
page. The value is given as {width}×{height}, with the units in
pixels. For example, 1024×768 means the width is 1024
pixels and the height is 768 pixels.
eventID CL0001 (note that this is different from other signals where
the dimension is called eventId)
expandedFastTabs Specifies the FastTabs on the page that were expanded when
the page opened.
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Permission Changes Trace Telemetry
2/6/2023 • 4 minutes to read • Edit Online
APPLIES TO: Business Central 2020 release wave 2, version 17.2, and later
Permission changes telemetry gathers data about the following operations on permission sets:
A user-defined permission set was added or removed
A link between a user-defined permission set and system permission set was added or removed
A permission set was assigned to or removed from a user or user group
For information about managing permission sets, see Assign Permissions to Users and Groups.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E2A
alCategory AL PermissionSet
alDataClassification SystemMetadata
alObjectType CodeUnit
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E2B
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E28
alSourcePermissionSetId Specifies the ID of the system permission set that was copied
to create the user-defined permission set.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E29
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E2C
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E2D
alPermissionSetId Specifies the ID of the permission set that was removed from
the user.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E2E
alUserGroupId Specifies the ID of the user group that the permission set
was assigned to.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000E2F
alPermissionSetId Specifies the ID of the permission set that was removed from
the user group.
alUserGroupId Specifies the ID of the user group that the permission set
was removed from.
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Permission Dependency Cycle Trace
Telemetry
2/6/2023 • 2 minutes to read • Edit Online
A permission dependency cycle occurs when a permission set depends on itself, which can happen when you
build permissions sets that include other permission sets. For example, suppose you create a permission set Y
that includes permission set X. If you then try modify permission set X to include permission set Y, you'll create a
dependency cycle. When you create a permission dependency cycle in the Business Central client, you'll get an
error similar to the following message:
The permission set [XX] has a circular reference on path [XX]->[YY]->[XX].
This telemetry data let's you identify and analyze permission problems that users may experience in Business
Central.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId RT0032
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
alObjectType The type of the AL object that the user was trying to access,
like a table or page.
clientType Specifies the type of client that opened the session, such as
Background or Web . For a list of the client types, see
ClientType Option Type.
DIM EN SIO N DESC RIP T IO N O R VA L UE
permissionArea The area that the dependency cycle is related to. Possible
values include: System , Entitlement , Company , Object
.
See also
Composing Permission Sets
Upgrading Extensions
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Permission Error Trace Telemetry
2/6/2023 • 2 minutes to read • Edit Online
When a user gets an error dialog about lack of permissions while working in Business Central, a telemetry
signal is emitted. This signal can be logged in an Application Insights resource.
This telemetry data let's you identify and analyze permission problems that users may experience in Business
Central.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId RT0031
aadTenantId The Azure Active Directory (Azure AD) tenant ID that's used
for Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
alObjectType The type of the AL object that the user was trying to access,
like a table or page.
clientType The type of client that executed the SQL Statement, such as
Background or Web . For a list of the client types, see
ClientType Option Type.
companyName The display name of the Business Central company that was
used at time of execution
permissionArea The area that the permission error is related to. Possible
values include: System , Entitlement , Company , Object
.
permissionType The permission that the operation requires, but the user
lacks. Possible values: Delete , Execute , Insert ,
Modify , Read , Undefined
See also
Upgrading Extensions
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Profile Configuration Lifecycle Telemetry
2/6/2023 • 7 minutes to read • Edit Online
APPLIES TO: Business Central 2022 release wave 2, version 21.0, and later
From the Business Central Web client, users can do various operations on profiles, like, import/export, create,
copy, and remove. To learn more about these operations, see Manage User Profiles and Customize Pages for
Profiles.
Business Central emits telemetry signals for these operations, which you can collect using an Application
Insights resource. As a partner or consultant, this information gives you insight into what the service does with
the profiles and page customizations you provide.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0046
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements during the operation.
result Success
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0047
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0048
force Species whether the Force flag was set, allowing to export
profiles even with compilation errors.
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements during the operation.
result Success
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0049
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0050
newProfileId Specifies the ID of the new profile that was created from a
copy.
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements during the operation.
result Success
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0051
newProfileId Specifies the ID of the new profile that was created from a
copy.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0052
Profile removed
Occurs when a profile was deleted.
General dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 2
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0053
severityLevel 2
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0054
severityLevel 2
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0055
Next steps
Use this telemetry data to determine how the users are working with the profiles that you provide in extensions.
Then, make changes to better suit the users needs as you see fit.
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Report Telemetry
2/6/2023 • 12 minutes to read • Edit Online
Report telemetry gathers data about which reports are run on the environment. It provides information about
whether the report succeeded, failed, or was canceled. For each report, it tells you how long it ran, how many
SQL statements it executed, and how many rows it consumed.
You use this data to gather statistics on report usage or to help identify slow-running reports.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
alObjectName Specifies the name of the report object that was run.
alObjectType Repor t .
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
eventId RT0006
extensionId Specifies the appID of the extension that the report object
belongs to.
extensionName Specifies the name of the extension that the report object
belongs to.
extensionVersion Specifies the version of the extension that the report object
belongs to.
reportAction Specifies the action that was done on the report. See
reportAction. This dimension was added in version 20.0.
result Success
DIM EN SIO N DESC RIP T IO N O R VA L UE
sqlDatabaseAccessIntent Specifies the database access intent used to read data for
the report, such as ReadOnly , or ReadWrite . This
dimension was added in version 19.1.
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements[1].
1From telemetrySchemaVersion 0.6 and onwards, this value also includes the CompanyOpen operation.
reportAction
The reportAction dimension shows actions taken to generate a report. The action can be taken from the report
request page, for example, from the Send To menu, or from AL code.
VA L UE DESC RIP T IO N
None There were no results from the request page, for example,
the user canceled.
Preview The user selected to preview the report from the request
page.
Schedule The user selected to schedule the report from the request
page.
Download The user downloaded the report as a file from the request
page.
Parameters Parameters and filters were collected from the request page
without rendering the output.
documentFormat
The documentFormat dimension shows the output of the generated report as a result of the report action. The
action can be taken from the report request page, for example, from the Send To menu, or from AL code.
VA L UE DESC RIP T IO N
Excel The output was a .xlsx file type that included the layout and
dataset.
ExcelDataset The output was a .xlsx file type that contained the dataset
only.
ProcessingOnly The action was for processing report without any kind of
layout.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
alObjectName Specifies the name of the report object that was run.
alObjectType Repor t .
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
eventId RT0006
extensionId Specifies the appID of the extension that the report object
belongs to.
extensionName Specifies the name of the extension that the report object
belongs to.
extensionVersion Specifies the version of the extension that the report object
belongs to.
reportAction Specifies the action that was done on the report. See
reportAction. This dimension was added in version 20.0.
result Specifies the title of the exception that was thrown, such as
NavNCLDialogException .
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
message Specifies the reason why the report was canceled. See
Analyzing cancellation messages section for details.
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 2
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
alObjectName Specifies the name of the report object that was run.
alObjectType Repor t .
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
eventId RT0007
extensionId Specifies the appID of the extension that the report object
belongs to.
extensionName Specifies the name of the extension that the report object
belongs to.
DIM EN SIO N DESC RIP T IO N O R VA L UE
extensionVersion Specifies the version of the extension that the report object
belongs to.
NOTE
The service evaluates cancellation events in a specific order, and the evaluation is done every five seconds. For more
information, see Report Generation and Cancellation Flow.
severityLevel 2
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
alObjectName Specifies the name of the report object that was run.
alObjectType Repor t .
clientType Specifies the type of client that executed the SQL Statement,
such as Background or Web . For a list of the client types,
see ClientType Option Type.
eventId RT0011
extensionId Specifies the appID of the extension that the report object
belongs to.
extensionName Specifies the name of the extension that the report object
belongs to.
extensionPublisher Specifies the name of the extension publisher that the report
object belongs to.
DIM EN SIO N DESC RIP T IO N O R VA L UE
extensionVersion Specifies the version of the extension that the report object
belongs to.
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Retention Policy Trace Telemetry
2/6/2023 • 4 minutes to read • Edit Online
APPLIES TO: Business Central 2020 release wave 2, update 17.1 and later
Administrators define retention policies to specify how frequently they want Business Central to delete outdated
data in tables that contain log entries and archived records. For example, cleaning up log entries makes it easier
to work with the data that's relevant. Policies can include all data in the tables that is past the expiration date. Or
you can add filter criteria to include only certain expired data in the policy.
To gather this telemetry data, you'll have to set up retention policies on tables that contain log entries and
archived records. For more information, see Define Retention Policies in the Application help.
Telemetry is then logged for the following operations:
A table is added to the list of allowed tables
An error occurs when adding a new retention policy
A retention policy is enabled
A retention policy is applied, either manually or automatically
Data is deleted because of a retention policy
The first retention policy is enabled on a table in a company
The last retention policy is removed in a company
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000D3L
alCategory Specifies the aspect of the retention policy that created the
log entry. For example, it can be related to setup, the
retention period, and when the policy was applied. Some of
the values are: Retention Policy - Setup , Retention
Policy - Apply , Retention Policy - Schedule , Retention
Policy - Allowed Tables .
alDataClassification SystemMetadata
alObjectType Codeunit
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000D6H
alTableName Specifies the name of the table from which the records were
deleted.
alTableNo Specifies the ID of the table from which the records were
deleted.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000D6I
DIM EN SIO N DESC RIP T IO N O R VA L UE
alTableName Specifies the name of the table the retention policy was
enabled on.
alTableNo Specifies the ID of the table that the retention policy was
enabled on.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId AL0000D6J
alTableName Specifies the name of the table from which the records were
deleted.
alTableNo Specifies the ID of the table from which the records were
deleted.
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Stopped Session Telemetry
2/6/2023 • 2 minutes to read • Edit Online
In Business Central, a background session is session without a UI that runs a specified codeunit. Background
sessions are started and stopped by calling the StartSession and StopSession methods from AL. With Business
Central online, sessions can be stopped by using the admin center, which indirectly calls the StopSession
method. For more information, see Managing Sessions.
With Application Insights, you can record when sessions are stopped, either by direct calls to the StopSession
method or from the admin center.
operation_Name StopSessionOperation
severityLevel 1
CustomDimensions
The following table describes the most relevant custom dimensions of the trace.
C O L UM N DESC RIP T IO N O R VA L UE
eventId RT0029
alObjectName* The name of the object that called the StopSession method
to cancel the session
alObjectType* The type of the object, like codeunit or page, called by the
StopSession method to cancel the session
clientType The type of client that called the Stop Session method such
as Background , WebClient , or ManagementClient .
ManagementClient indicates that the session was
canceled from the Business Central admin center. For a list of
the client types, see ClientType Option Type.
companyName* The name of the company that was open during the session
extensionName The name of the extension that included the code that called
the StopSession method.
stoppingSessionIsAdmin Indicates whether the session that was stopped was running
as an administrator
aadTenantId The Azure Active Directory (Azure AD) tenant ID that's used
for Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Monitoring and Analyzing Long Running SQL Queries On-Premises
The Business Central Administration Center
Analyzing Table Index Trace Telemetry
2/6/2023 • 3 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1, version 18.0 and later
The table index trace gathers data when a index is added to, modified, or removed from a base table by a table
extension.
In AL, an index is defined by a key, which can include one or more table fields. A key in a table extension object
can include either fields from the base table or fields from the table extension object itself. A key that includes
base tables fields is added as an index on the base table in the SQL database. For more information, see Table
Keys.
This signal is emitted when a table extension object is installed or upgraded on a tenant, and it does one of the
following operations:
Adds an index to the base table
Changes an existing index on the base table, for example, it adds or removes fields
Removes an existing index from the base table
Index enabled
Occurs when an index was added or modified on the base table by key in a table extension object.
General dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0024
alObjectName Specifies the name of table that the index was added or
changed.
keyFields Specifies the table fields that are included in the index.
keyName Specifies the name of the index that was added or changed.
Index disabled
Occurs when an index was removed from the base table by table extension object.
General dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0025
alObjectId Specifies the ID of table that the index was removed from.
alObjectName Specifies the name of table that the index was removed
from.
extensionName Specifies the name of the extension that removed the index.
keyFields Specifies the table fields that are included in the index.
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Task Scheduler Telemetry
2/6/2023 • 9 minutes to read • Edit Online
Task scheduler telemetry gathers information about the execution of scheduled tasks. The data gives insight into
what happens in background sessions that are coming from scheduled tasks. It provides information that let's
you troubleshoot failures. The data can also help you determine whether tasks would be better scheduled for off
hours to limit the load on the service.
For an overview of task scheduler to understand the flow related to these traces, see Task Scheduler.
NOTE
In this article, main codeunit refers to the codeunit that's run by the TaskScheduler.CreateTask method.
Each scheduled task is assigned a unique identifier (ID), which is included in each trace related to the task. Using
the ID makes it easy to query the flow of a task.
Task created
Occurs when a task was created by a TaskScheduler.CreateTask method call in AL code.
General dimensions
The following table explains the general dimensions of this trace.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0040
isReady Specifies whether the task was in the the ready state when
created. True indicates that the task is in the ready state.
False indicates that the task isn't in the ready state.
notBefore Specifies the earliest date and time the task was scheduled
to run.
DIM EN SIO N DESC RIP T IO N O R VA L UE
timeout Specifies the timeout that was set on the task. If a task takes
longer to complete than the specified time, it's canceled. The
time has the format hh:mm:ss.sssssss.
Task ready
Occurs when a task is set to the ready state by TaskScheduler.SetTaskReady method call in AL code. A task can't
be run until it's in the ready state.
General dimensions
The following table explains the general dimensions of this trace.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0041
isReady True
notBefore Specifies the earliest date and time that was scheduled to
run.
timeout Specifies the timeout that was set on the task. If a task takes
longer to complete than the specified time, it's canceled. The
time has the format hh:mm:ss.sssssss.
Task removed
Occurs when a task is deleted by a TaskScheduler.CancelTask method call in AL code.
General dimensions
The following table explains the general dimensions of this trace.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0042
isReady Specifies whether the task was in the ready state when
removed. True indicates that the task was in the ready state.
False indicates that the task wasn't in the ready state.
notBefore Specifies the earliest date and time that was scheduled to
run.
DIM EN SIO N DESC RIP T IO N O R VA L UE
timeout Specifies the timeout that was set on the task. The time has
the format hh:mm:ss.sssssss.
Task canceled
Occurs when the execution of a task's main or failure codeunit is canceled by the service or by a user.
For example, the service cancels a task when:
It takes longer to complete than the specified timeout. The timeout is specified on the task when it's created.
Or if no timeout is specified, then the default timeout of the service is used. For online, the default task
timeout is 12 hours. For on-premises, the default timeout is specified by the Default Task Scheduler
Session Timeout setting on the Business Central Server instance.
The Session.StopSession method was called from AL code.
Users can cancel a task a couple ways. For example, with Business Central online, they can use the Business
Central admin center. With on-premises, they can run the the Remove-NAVSession cmdlet.
General dimensions
The following table explains the general dimensions of this trace.
Main codeunit
Task {taskId} main codeunit {codeunitObjectId}
canceled. It will not be retried and the failure
codeunit {failureCodeunitObjectId} will be run.
Reason: Exception is not retriable.
Failure codeunit
Task {taskId} failure codeunit
{failureCodeunitObjectId} canceled. It will not be
retried. Reason: Exception is not retriable.
severityLevel 2
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0044
isReady True
notBefore Specifies the earliest date and time to the task was
scheduled to run.
DIM EN SIO N DESC RIP T IO N O R VA L UE
result Canceled
serverExecutionTime Specifies the amount of time it took the server to run the
codeunit. The time has the format hh:mm:ss.sssssss.
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements before the task was canceled.
timeout Specifies the timeout that was set on the task. The time has
the format hh:mm:ss.sssssss.
totalTime Specifies the amount of time it took before the task was
canceled. The time has the format hh:mm:ss.sssssss.
Task failed
Occurs when the execution of task's main codeunit or failure codeunit fails because of an exception.
General dimensions
The following table explains the general dimensions of this trace.
Main codeunit
Task {taskId} main codeunit {codeunitObjectId}
failed. It will not be retried and the failure codeunit
{failureCodeunitObjectId} will be run. Reason:
Exception is not retriable.
Failure codeunit
Task {taskId} failure codeunit {codeunitObjectId}
failed. It will not be retried. Reason: Exception is not
retriable.
severityLevel 3
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0045
notBefore Specifies the earliest date and time that was scheduled to
run.
DIM EN SIO N DESC RIP T IO N O R VA L UE
result Failure
serverExecutionTime Specifies the amount of time it took the server to run the
codeunit. The time has the format hh:mm:ss.sssssss.
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements before the task failed.
timeout Specifies the timeout that was set on the task. The time has
the format hh:mm:ss.sssssss.
Task completed
Occurs when the execution of a task's main codeunit or failure codeunit succeeds with no errors.
Note that there is no event emitted for task started. You can infer the task-start time by subtracting the totalTime
from the task completed timestamp.
General dimensions
The following table explains the general dimensions of this trace.
severityLevel 1
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
eventId LC0043
DIM EN SIO N DESC RIP T IO N O R VA L UE
notBefore Specifies the earliest date and time that was scheduled to
run.
result Success
serverExecutionTime Specifies the amount of time it took the server to run the
codeunit. The time has the format hh:mm:ss.sssssss.
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.
timeout Specifies the timeout that was set on the task. The time has
the format hh:mm:ss.sssssss.
totalTime Specifies the amount of time it took to run the codeunit. The
time has the format hh:mm:ss.sssssss.
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing User Checklist Telemetry
2/6/2023 • 2 minutes to read • Edit Online
User checklist telemetry gathers data about state changes for the checklists presented to users when
onboarding to Business Central. For more information about checklists, see Get Users Started with the Checklist.
Custom dimensions
DIM EN SIO N DESC RIP T IO N O R VA L UE
aadTenantId Specifies the Azure Active Directory (AAD) tenant ID used for
Azure AD authentication. For on-premises, if you aren't
using Azure AD authentication, this value is common .
eventId AL0000EIQ
alOldStatus The old status of the checklist, for example Not Star ted or
In progress .
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Verbose Telemetry
2/6/2023 • 2 minutes to read • Edit Online
Business Central users can temporarily set up their environment to emit more verbose telemetry by going to
the Help and Suppor t page in the client and selecting Additional Logging . They'll typically only do this
when asked by a partner or support representative to help troubleshoot problems. This additional logging will
continue for 15 minutes or until the user closes the browser or signs out of Business Central—then it's turned
off
A telemetry trace is recorded whenever additional logging is turned on or off.
For information about enabling additional logging, see Resources for Help and Support.
severityLevel 3
Custom dimensions
The following table explains the custom dimensions included in the trace.
eventId RT0023
severityLevel 3
Custom dimensions
The following table explains the custom dimensions included in the trace.
eventId RT0024
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Web Service Access Key Telemetry
2/6/2023 • 3 minutes to read • Edit Online
APPLIES TO: Business Central 2020 release wave 2, version 17.3, and later
The Business Central emits telemetry data about the success or failure of authenticating web service access keys
on web service requests.
IMPORTANT
Starting October, 2022, the use of access keys (Basic Auth) for web service authentication is deprecated and not
supported in Business Central online. We recommend that you use OAuth2 instead. For more information, see Using
OAuth to Authorize Business Central Web Services.
As a partner or customer, this data lets you monitor the use of web service access keys on your environments in
preparation for the deprecation of the feature.
For information about web service access keys, see How to use an Access Key for SOAP and OData Web Service
Authentication.
severityLevel 1
Custom dimensions
The following table explains the custom dimensions included in the trace.
authenticationStatus Succeeded
endpoint Specifies the endpoint for the request. Private and sensitive
information is omitted from the endpoint.
eventId RT0020
severityLevel 3
Custom dimensions
The following table explains the custom dimensions included in the trace.
authenticationStatus Failed
endpoint Specifies the endpoint for the request. Private and sensitive
information is omitted from the endpoint.
eventId RT0021
failureReason Specifies the exception that was thrown by the server. Some
exception messages can contain customer data. As a
precaution, Business Central only emits information that's
classified as SystemMetadata. Exception messages that
contain other data classifications, like customer data, are not
shown. Instead, the following message is shown: "Message
not shown because the NavBaseException(string, Exception,
bool) constructor was used."
Example trace
The following code snippet is a CustomDimensions example:
{"component":"Dynamics 365 Business Central
Server","category":"Api","AadTenantId":"common","environmentType":"Production","Component":"Dynamics 365 Business Central
Server","AL Object Id":"0","alObjectId":"0","Telemetry schema
version":"0.1","telemetrySchemaVersion":"0.1","authenticationType":"NavUserPassword","componentVersion":"17.0.15855.0","Component
version":"17.0.15855.0","eventId":"RT0020","endpoint":"BC170/ODataV4/Company()/purchaseDocumentLines","deprecatedKeys":"Company
name, AL Object Id, AL Object type, AL Object name, AL Stack trace, Client type, Extension name, Extension App Id, Extension
version, Telemetry schema version, Component, Component version, Telemetry schema version, AadTenantId, Environment name,
Environment type","aadTenantId":"common","Environment type":"Production","authenticationStatus":"Succeeded"}
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Analyzing Incoming Web Services Request
Telemetry
2/6/2023 • 5 minutes to read • Edit Online
Web services telemetry gathers data about SOAP, OData, and API requests through the service. It provides
information like the request's endpoint, time to complete, the SQL statements run, and more.
General dimensions
The following table explains the general dimensions included in an incoming Web Ser vices Call trace. The
table lists the dimensions that are specific to Business Central.
severityLevel 1
Custom dimensions
The following table explains the custom dimensions included in a Web Ser vices Call trace.
alObjectName Specifies the name of the AL object that was run by the
request.[1]
alObjectType Specifies the type of the AL object that was run by the
request.[1]
eventId RT0008
sqlRowsRead Specifies the number of table rows that were read by the
SQL statements.[1] [2]
1
1
This dimension isn't relevant for $metadata calls, like https://localhost:7048/BC/ODataV4/$metadata , so it won't
be in the trace.
2
From telemetrySchemaVersion 0.6 and onwards, this value also includes the CompanyOpen operation.
C O N DIT IO N A N A LY SIS
A web service request results in a long running SQL query Adjust or fine-tune code.
Web service requests to a specific endpoint read more rows Consider adding filtering to limit the rows that are read.
than requests to the other endpoints
Fewer API type requests compared with other types With SOAP and OData requests to UI pages, computation
resources are used on UI elements that aren't relevant.
Instead of exposing normal pages as web service endpoints,
use the built-in API pages. API pages are optimized for this
scenario.
High number of requests to endpoints that include Power BI This condition may indicate excessive Power BI integration.
See also
Monitoring and Analyzing Telemetry Enable Sending Telemetry to Application Insights
Writing efficient Web Services API Limits
Analyzing Outgoing Web Service Request
Telemetry
2/6/2023 • 4 minutes to read • Edit Online
Outgoing web service request telemetry gathers data about outgoing web service requests sent using the AL
HTTPClient module. As a partner, the data gives you insight into the execution time and failures that happen in
external services that your environment and extensions depend on. Use the data to monitor environments for
performance issues caused by external services, and be more proactive in preventing issues from occurring.
General dimensions
The following table explains the general dimensions included in an outgoing Web Ser vices Call (Outgoing)
trace. The table lists the dimensions that are specific to Business Central.
severityLevel 1
Custom dimensions
The following table explains the custom dimensions included in a Web Ser vices Call trace.
alHttpTimeout Specifies the timeout defined for the request. The timeout is
the time to wait before a request gets canceled. The value
has the format hh:mm:ss.
alObjectName Specifies the name of the AL object that made the request.
alObjectType Specifies the type of the AL object that made the request.
eventId RT0019
extensionId Specifies the appID of the extension that made the request.
extensionName Specifies the name of the extension that made the request.
extensionVersion Specifies the version of the extension that made the request.
DIM EN SIO N DESC RIP T IO N O R VA L UE
httpStatusCode Specifies the http status code returned when a request has
completed. This dimension further indicates whether request
succeeded or not, and why. Use it to verify whether there
was an issue with a request even though the request was
logged as successful. The dimension displays one of the
following values:
200
OK. The request succeeded.
404
Not found. The given endpoint wasn't valid.
In the case of a failure, the reason for the underlying issue
could be network connectivity, DNS failure, server certificate
validation or timeout. The Business Central Server does not
know which if these it might be.
Example trace
The following code snippet is a CustomDimensions example:
{"Telemetry schema version":"0.2","telemetrySchemaVersion":"0.2","Component version":"17.0.15765.0","Environment type":"Production","componentVersion":"17.0.15765.0","Env
AL Object Id, AL Object type, AL Object name, AL Stack trace, Client type, Extension name, Extension App Id, Extension version, Telemetry schema version, Component, Compo
version":"17.0.15821.0","extensionVersion":"17.0.15821.0","Extension App Id":"11111111-aaaa-2222-bbbb-333333333333","aadTenantId":"afbb64dc-bc88-43a3-9153-dd9d2fde08e6","
type":"CodeUnit","Extension name":"Base Application","AL Object name":"My Codeunit","component":"Dynamics 365 Business Central Server","companyName":"CRONUS USA, Inc.","e
Codeunit","alObjectType":"CodeUnit","extensionId":"11111111-aaaa-2222-bbbb-
333333333333","eventId":"RT0019","httpMethod":"GET","serverExecutionTime":"00:00:00.1971767","totalTime":"00:00:00.1971767","endpoint":"https://mycorp.dynamics.com/api/di
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Telemetry Event IDs in Application Insights
2/6/2023 • 10 minutes to read • Edit Online
The following tables list the Ids of Business Central telemetry trace events that are emitted into Azure
Application Insights.
Application events
EVEN T ID A REA M ESSA GE
Client events
EVEN T ID A REA M ESSA GE
Lifecycle events
EVEN T ID A REA M ESSA GE
Runtime events
EVEN T ID A REA M ESSA GE
RT0020 Web service key request Authentication with Web Service Key
succeeded: {endpoint}
RT0021 Web service key request Authentication with Web Service Key
failed: {endpoint}
See also
Monitoring and Analyzing Telemetry
Enable Sending Telemetry to Application Insights
Managing Technical Support
2/6/2023 • 14 minutes to read • Edit Online
When users report a problem with Business Central, superusers or the internal administrator can often find a
solution. The internal administrator can find technical information in the Help and Suppor t page, and they can
then escalate relevant issues to the reselling partner.
The reselling partner can sign in to their customer's Business Central as the delegated admin for
troubleshooting. Sometimes, they create a sandbox environment based on production data or troubleshooting.
Both internal administrators and their partner can use the Business Central administration center to manage
environments, updates, and troubleshooting.
Internal administrators
The internal administrator can work with users to identify solutions or workarounds, such as missing setup,
missing permissions, and other issues. If users aren't sure if things aren't working as intended, they can check
the Help and Learn content for the intended behavior. For more technical problems, administrators can find
information in the Help and Suppor t page to help with this investigation. For more information, see the
Finding technical information section.
As the tenant admin, you can check the Microsoft 365 admin center for incidents. For more information, see the
Monitor service health section.
Internal administrators can also create sandbox environments for deeper troubleshooting, for example, before
they decide to contact their partner for technical support. The partner must have specified their support contact
details in the Help and Suppor t page.
Delegated administrators
Each Business Central customer has a partner who assists with technical support when requested by the internal
administrator. As the partner, you must have specified support contact details in the Help and Suppor t page.
For more information, see Configuring the support experience.
IMPORTANT
You must have set up users in your own tenant in Partner Center as either Admin agent or Helpdesk agent, and they
must have delegated administration privileges in your customer's Business Central to support the customer. For more
information, see Delegated Administrator Access to Business Central Online.
The delegated administrator can access the customer's Business Central for further troubleshooting. They can
also use the Business Central administration center to analyze telemetry, create a sandbox environment for
debugging or step-by-step reproduction, for example.
If the partner can't find a solution, they can request support from Microsoft. For more information, see the
Escalating support issues to Microsoft section.
Extend trials
Another task for a delegated admin is to help with extending trials. For more information, see Business Central
Trials and Subscriptions.
Cleaning up settings
If you end the relationship with a customer, you must remove certain settings while you still have access to that
customer's Business Central administration center. Consider the following settings:
Support contact details
For more information, see To supply your support contact information in the administration center.
Notification recipients
For more information, see Tenant Notifications.
Application Insights key (if the partner had set up Application Insights)
For more information, see Environment Telemetry in the Business Central administration center.
Also in the Help and Suppor t page, users can see support contact information, if the partner has provided this
information. For more information, see To supply your support contact information in the administration center.
The Help and Suppor t page also shows which version of Business Central, the specific environment is on.
For Business Central online, a user can enable more logging and then perform the operation that is causing
problems. The more telemetry is sent to Application Insights where you can do further troubleshooting, either
as part of a support case, or before you submit a support request. In both scenarios, the more details about the
problematic operation will lead to a quicker resolution.
For Business Central online, internal and delegated administrators also have access to this information in the
Business Central administration center. You can use the Business Central administration center to easily navigate
to the different environments in a tenant, and you can create sandbox environments that can help troubleshoot
any issues reported by users. For more information, see The Business Central Administration Center.
Azure Active Directory tenant
When the internal administrator wants to contact the partner for support, then the Help and Suppor t page
encourages them to include information about their Azure Active Directory tenant ID in the email. This
information is shown in the Troubleshooting section at the bottom of the Help and Suppor t page.
The delegated administrator can use that to identify the tenant in the Partner Center and in the Business Central
administration center for troubleshooting.
Version
You can use the information about which version the tenant is on to help you troubleshoot the issue that the
customer has reported, for example. This information is also listed in the Troubleshooting section of the Help
and Suppor t page. For more information, see Version numbers in Business Central.
Last known error
The link behind the sentence View the last known error will find and show the most recent error message that
was generated by the application code. This includes errors from field validation, posting routines, and other
code behind business functionality.
The information that you can get from this link includes the following:
Text
This is the error message that the user sees, either in a dialog window or next to a user interface element
that can't render, for example.
Code
This is the code snippet that threw the error.
Callstack
This shows how the error was triggered.
Object
This shows information about the runtime objects.
The link can't open errors that were generated by the platform. If you suspect that the issue is caused by the
platform, try to reproduce the error in a sandbox environment before you contact Microsoft for support. For
more information, see Create a new environment.
TIP
If your users complain of a confusing error message such as Sorry, we just updated this page. Please close and reopen.,
then you can often find the underlying problem either in this last known error, or by analyzing telemetry in the Business
Central administration center. For example, in the case of the Sorry, we just updated this page. Please close and reopen.
message, the underlying problem is often that two users are trying to modify the same data. So if both users open the
same sales order, and both change a field, then one of them will see the Sorry, we just updated this page. Please close and
reopen. message, because Business Central saves changes as soon as you move to the next field or close the page.
TIP
In the Power Platform Admin Center, use the See solutions button to find potential guidance or workarounds. Based on
your search keywords, links to suggested content are shown on the Solutions tab.
NOTE
The internal administrator cannot contact Microsoft directly. If you are an internal admin and suspect that something is
wrong with your Business Central, you must contact your partner for next steps.
TIP
Alternatively, you can use customer-specific URLs such as
https://admin.powerplatform.microsoft.com/account/login/[customer tenant ID] .
Your company must be registered as a Microsoft partner, and it must have the Advanced Support for Partners
(ASfP) or Premier support plan. Your service account manager can get you more information about getting the
ASfP. If you already have a support plan, the Technical Benefits tab in the Partner Center lists the contract ID and
access ID that you must specify when you submit a new support request on behalf of your customer. If you're
not sure how to find the information, the service account manager can get the information for you.
NOTE
Outages are frustrating but rare. If your customer reports that they cannot access Business Central at all, help them test
their connection and other potential local problems. For more information, see the Report Customer Outages section
here, and also bookmark the article How do I check my online service health? in the Power Platform administration
content.
To start the process of submitting a new support request from the Business Central administration center
1. On the Environments tab of the Business Central administration center, choose the relevant
environment to open the environment details.
2. In the Suppor t menu, choose New Suppor t Request .
A new browser tab opens so that you can submit the support request in the Power Platform Admin
Center.
You are automatically logged in with information about your customer's tenant. Create a new support
request and fill in the fields as appropriate.
TIP
Use the See solutions button to find potential guidance or workarounds. Based on your search keywords, links
to suggested content are shown on the Solutions tab.
You can find most of the necessary information in the Business Central administration center, including the
tenant ID and the Business Central version numbers. For more information, see View solutions or enter a
support request through the new support center in the Power Platform administration content.
IMPORTANT
Your company must be registered as a Microsoft partner, and it must have the Advanced Support for Partners (ASfP) or
Premier support plan. Your service account manager can get you more information about getting the ASfP. If you already
have a support plan, the Technical Benefits tab in the Partner Center lists the contract ID and access ID that you must
specify when you submit a new support request on behalf of your customer. If you're not sure how to find the
information, the service account manager can get the information for you.
The support person can be a member of the Helpdesk agent group in the customer's Azure AD tenant or a
global administrator. For more information, see Delegated Admin Access to Business Central Online.
Microsoft Support will keep you updated on the status of your support request. You can also see the status in
the Power Platform Admin Center. For more information, see Power Platform Admin Center.
To start the process of submitting a new support request from the Partner Center
You can also start the process from the Partner Center. Choose the customer you want to open a case on, and
then follow the support request work flow. You're automatically redirected to the Power Platform admin center
in the context of the customer's tenant.
However, you might need information from the Business Central administration center, which is why we
recommend that route. For more information, see Report problems on behalf of a customer in the Partner
Center content.
See also
How to check service health
Inspecting and Troubleshooting Pages
The Business Central Administration Center
Technical Support for Business Central
Provide technical support (Microsoft Partner Center)
Escalate Support Issues to Microsoft
Deployment Overview
Administration as a partner
Administration of Business Central Online
Administration of Business Central On-Premises
Escalate Support Issues to Microsoft
2/6/2023 • 3 minutes to read • Edit Online
It might happen that a Business Central online customer runs into a technical problem that the partner cannot
resolve. In those cases, the delegated admin can use the Partner Center or the Business Central administration
center to submit a support request to Microsoft.
NOTE
The internal administrator cannot contact Microsoft directly. If you are an internal admin and suspect that something is
wrong with your Business Central online, you can use the Business Central administration center to troubleshoot. To go
further than that, you must contact your partner for next steps.
TIP
Alternatively, you can use customer-specific URLs such as
https://admin.powerplatform.microsoft.com/account/login/[customer tenant ID] .
Your company must be registered as a Microsoft partner, and it must have the Advanced Support for Partners
(ASfP) or Premier support plan. Your service account manager can get you more information about getting the
ASfP. If you already have a support plan, the Technical Benefits tab in the Partner Center lists the contract ID and
access ID that you must specify when you submit a new support request on behalf of your customer. If you're
not sure how to find the information, the service account manager can get the information for you.
You can find most of the necessary information in the Business Central administration center, including the
tenant ID and the Business Central version numbers. For more information, see View solutions or enter a
support request through the new support center in the Power Platform administration content.
IMPORTANT
Your company must be registered as a Microsoft partner, and it must have the Advanced Support for Partners (ASfP) or
Premier support plan. Your service account manager can get you more information about getting the ASfP. If you already
have a support plan, the Technical Benefits tab in the Partner Center lists the contract ID and access ID that you must
specify when you submit a new support request on behalf of your customer. If you're not sure how to find the
information, the service account manager can get the information for you.
The support person can be a member of the Helpdesk agent group in the customer's Azure AD tenant or a
global administrator. For more information, see Delegated Admin Access to Business Central Online.
Microsoft Support will keep you updated on the status of your support request. You can also see the status in
the Power Platform Admin Center. For more information, see Power Platform Admin Center.
See Also
Report Customer Outages
Managing Technical Support
Inspecting and Troubleshooting Pages
The Business Central Administration Center
Technical Support for Business Central
Provide technical support (Microsoft Partner Center)
Deployment Overview
Administration as a partner
Administration of Business Central Online
Administration of Business Central On-Premises
Report Customer Outages
2/6/2023 • 2 minutes to read • Edit Online
When a customer has a situation where no users can sign in to Business Central, the admin must take
immediate action. Outages are frustrating but rare. Make sure that the users are not unable to sign in due to
problems with their network connection, for example. For more information, see How do I check my online
service health? in the Power Platform administration content.
Internal and delegated administrators can report this outage to Microsoft by using the Repor t Production
Outage action for the relevant production environment in the Business Central administration center. This
action creates a support ticket for Microsoft with all the information that is needed to begin steps to resolve the
issue.
NOTE
This option is not available in sandbox environments.
To report an outage
1. On the Environments tab of the Business Central administration center, choose the relevant
environment to open the environment details.
2. In the action ribbon, choose Suppor t , and then choose Repor t Production Outage .
3. In the Repor t Production Outage pane, choose the outage type:
Unable to sign in (all users)
Cannot access API/Web Service
4. Enter your name, email address, and phone number. This information will be included in the support
ticket.
5. Choose Next .
6. In the next pane, provide details about the outage, including which browsers users have tried to sign in
with, any companies that you can sign into, and errors and correlation IDs. This information will be
included in the support ticket.
7. Finally, add the date and time when the outage began. This information will also flow to the support
ticket.
8. Choose the consent checkbox, and then choose Repor t .
A support request ticket is then created, and you will see a dialog box with the ticket ID. You can then monitor
progress in the Repor ted Outages section. From there, you can access the tickets in the Partner Center. For
more information, see the Microsoft Partner Center documentation.
See Also
Escalating Support Issues to Microsoft
Managing Technical Support
Inspecting and Troubleshooting Pages
The Business Central Administration Center
Technical Support for Business Central
Provide technical support (Microsoft Partner Center)
Deployment Overview
Administration as a partner
Administration of Business Central Online
Administration of Business Central On-Premises
Performance Profiler Overview
2/6/2023 • 2 minutes to read • Edit Online
If a business process takes longer than expected, your administrator can use the Performance Profiler page to
record a snapshot of the process. While recording, the profiler monitors all of the apps that are involved in the
process. These include first-party apps from Microsoft, such as the Base Application and System Application, and
any third-party apps that you have installed. Identifying where the holdup is can make it easier to go to the
correct support organization or, if you have developers in-house, fix the problem yourself. For more information,
see Viewing technical information.
After you record a snapshot you'll get two types of insights:
The Active Apps chart shows how much faster the process could be if you remove each app.
The Time Spent chart shows how many milliseconds each app took to complete its part. This chart is
available if you turn on the Show technical information toggle.
You can use the App Name and App Publisher actions to filter the charts, for example, to view the
performance of apps from a particular publisher.
TIP
It's a good idea to open the Performance Profiler page in a separate browser window while you record a process. That
makes it easier to return to the profiler to stop the recording. To open the page in a new window, choose the icon in
the upper right of the page.
FA ST TA B DESC RIP T IO N
Time Spent by Application Object This FastTab shows the objects, such as pages, codeunits,
and tables, that were involved in the process. The interesting
things here are the Time Spent and Samples columns. The
Time Spent column focuses on the object, and shows how
long it was active during the recording. The Samples column
shows the number of times that the profiler sampled the
performance of the object.
Call Tree The Self Time and Total Time columns show where time is
spent in the code. The Self Time column shows the amount
of time spent in the method only, and excludes calls out of
the method. The Total Time field is the Self Time amount
plus calls out of the method.
See Also
Managing Technical Support
Escalate support issues to Microsoft
Debugging
Snapshot Debugging
Introduction to automation APIs
2/6/2023 • 5 minutes to read • Edit Online
Automation APIs provide capability for automating company setup through APIs. Once the tenants have been
created, the automation APIs can be used, in order to hydrate the tenant - to bring the tenant up to a desired
state. Usually this involves creating a new company on the tenant, running RapidStart packages, installing
extensions, adding users to user groups and assigning permission sets to users.
Delegated admin credentials and Dynamics 365 Business Central users with permissions, can call the APIs.
IMPORTANT
For delegated admin access, you must add the Azure Active Directory (Azure AD) application to the AdminAgents
group. If the Azure AD application is not added, the consent flow will show an error such as Need pre-consent. For more
information, see Pre-consent your app for all your customers in the Graph documentation.
Automation APIs are placed in the microsoft/automation API namespace. In all the examples below, parameters
are marked in parenthesis {} . Make sure that only valid parameters are passed.
Create a company
To create a company, an automationCompany endpoint is available. To create a Company issue a POST request
as shown in the following example.
POST https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/automationCompanies
Authorization: Bearer {token}
Content-type: application/json
{
"name": "CRONUS",
"displayName": "CRONUS",
"businessProfileId": ""
}
The {companyId} must be the ID of an valid company on the tenant. Issue a GET automationCompany request to
fetch existing companies.
NOTE
The company which is created will not be initialized.
In the response, status for the import and apply status will be shown, as well as information about the
RapidStart package.
Insert RapidStart
First step is to create the configuration package, by issuing a POST configurationPackages in the Dynamics 365
Business Central tenant. Once the configuration package is created, the RapidStart package can be uploaded.
See the example below.
POST https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/configurationPackages
PATCH https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/configurationPackages({packageId})/file('{SAMPLE}
')/content
POST https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/configurationPackages({packageId})/Microsoft.NAV.
import
When the RapidStart package is imported it can applied with a POST on bound action Microsoft.NAV.apply.
POST https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/configurationPackages({packageId})/Microsoft.NAV.
apply
PATCH https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})
Content-type: application/json
If-Match:*
{
"state": "Enabled",
"expiryDate": "2035-01-01T21:03:53.444Z"
}
POST https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userGroupMembers
To retrieve the list of user groups issue a GET userGroups. This will return the information that you need for the
payload above.
Assigning permission sets is identical to adding users to user groups. GET permissionSet returns information
about the available permission sets. To assign a permissionSet issue a POST userPermission as shown in the
following example.
POST https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userPermissions
Removing the permissionSet from the user is done by issuing a DELETE userPermissions on the users entity.
Get new users from Office 365
To get new users from Office 365, two bound actions on the users endpoint can be used:
Microsoft.NAV.getNewUsersFromOffice365 and Microsoft.NAV.getNewUsersFromOffice365Async . Both actions retrieve
new users or new user information from the Office 365 portal but former one is designed for delegated admins
and it runs synchronous and latter one schedules a background job which makes it asynchronous.
Microsoft.NAV.getNewUsersFromOffice365Async returns a link to the scheduled job where you can track the
progress. You can also track the progress by issuing a GET scheduledJobs on the users entity. Note that existing,
unchanged users will not be updated with these actions.
Handling tenant extensions
Add-on extensions which are already published to the tenant can be installed and uninstalled. Per-tenant
extensions can be uploaded and installed. To get the list of all extensions on the tenant, issue a GET extensions.
This will return the packageId needed for installing and uninstalling extensions.
Installing and uninstalling published add-on extensions
There are three bound actions available on the extensions endpoint: Microsoft.NAV.install ,
Microsoft.NAV.uninstall and Microsoft.NAV.uninstallAndDeleteExtensionData .
Issue a POST extension using the bound actions. See the example below.
POST https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/2.0/companies({companyId})/extensions({packageId})/Microsoft.NAV.install
NOTE
Installing per-tenant extensions using Automation APIs is only possible in SaaS.
POST https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/extensionUpload
NOTE
Schedule in the body can be "Current version", "Next minor version" or "Next major version".
NOTE
Schema Sync Mode in the body can be "Add" or "Force Sync".
Install extension
Once extension file is uploaded, the extension needs to be installed by issuing a POST on the bound action
Microsoft.NAV.upload.
POST https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/extensionUpload({extensionUploadId})/Microsoft.NA
V.upload
Uninstalling the extension can be done through the bound action Microsoft.NAV.uninstall, as with the add-on
extensions. The bound action Microsoft.NAV.uninstallAndDeleteExtensionData can be used to delete the tables
that contain data owned by the extension on uninstall. This action cannot be undone.
Monitoring extension installation progress
To view ongoing extension installation status, issue GET extensionDeploymentStatus as shown in the following
example.
GET https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/extensionDeploymentStatus
See Also
Automation company
Company
Configuration package
Extension
Extension deployment status
Extension upload
Permission set
Profile
Scheduled job
User
User group
User group member
User group permission
User permission
automationCompany resource type
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the automationCompany resource.
{
"id": "GUID",
"name": "string",
"evaluationCompany": "boolean",
"displayName": "string",
"businessProfileId": "string"
}
See Also
GET automationCompany
DELETE automationCompany
POST automationCompany
PATCH automationCompany
Get automationCompany
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of an automation company object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET /microsoft/automation/v2.0/companies({companyId})/automationCompanies({automationCompanyId})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and an automationCompany object in the
response body.
Example
Request
Here is an example of the request.
GET https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/automationCompanies({automationCompanyId})
Response
Here is an example of the response.
NOTE
The response object shown here may be truncated for brevity. All of the properties will be returned from an actual call.
{
"id": "3496bbf8-fcae-4e48-a4f8-cb17c27de0b3",
"name": "CRONUS USA, Inc.",
"evaluationCompany": true,
"displayName": "CRONUS USA, Inc.",
"businessProfileId": ""
}
See Also
Tips for working with the APIs
automationCompany
Delete automationCompany
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
DELETE /microsoft/automation/v2.0/companies({companyId})/automationCompanies({automationCompanyId})
Request headers
H EA DER VA L UE
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
automationCompany , the automationCompany will
not be updated.
Request body
Do not supply a request body for this method.
Response
If successful, this method returns 204 No Content response code and deletes the automationCompany. It does
not return anything in the response body.
Example
Request
Here is an example of the request.
DELETE https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/automationCompanies({automationCompanyId})
Response
Here is an example of the response.
See Also
Tips for working with the APIs
automationCompany
Create automationCompany
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
POST /microsoft/automation/v2.0/companies({companyId})/automationCompanies
Request headers
H EA DER VA L UE
Content-Type application/json
Request body
In the request body, supply a JSON representation of a automationCompany object.
Response
If successful, this method returns 201 Created response code and a automationCompany object in the
response body.
Example
Request
Here is an example of the request.
POST https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/automationCompanies
Content-type: application/json
{
"name": "CRONUS",
"evaluationCompany": false,
"displayName": "CRONUS",
"businessProfileId": ""
}
See Also
Tips for working with the APIs
automationCompany
Update automationCompany
2/6/2023 • 2 minutes to read • Edit Online
Updates the properties of an automation company object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
PATCH /microsoft/automation/v2.0/companies({{companyid}})/automationCompanies({automationCompanyId})
Request headers
H EA DER VA L UE
Content-Type application/json
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
automationCompany , the automation company will
not be updated.
Request body
In the request body, supply the values for relevant fields that should be updated. Existing properties that are not
included in the request body will maintain their previous values or be recalculated based on changes to other
property values. For best performance you shouldn't include existing values that haven't changed.
Response
If successful, this method returns a 200 OK response code and an updated **automationCompany ** object in
the response body.
Example
Request
Here is an example of the request.
PATCH https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/automationCompanies({automationCompanyId})
Content-type: application/json
If-Match:*
{
"displayName": "My Company",
}
Response
Here is an example of the response.
NOTE
The response object shown here may be truncated for brevity. All of the properties will be returned from an actual call.
{
"id": "2b8ea70b-1384-448d-b3d7-1d26c41f3cec",
"name": "CRONUS USA, Inc.",
"evaluationCompany": false,
"displayName": "My Company",
"businessProfileId": ""
}
See Also
Tips for working with the APIs
automationCompany
company resource type (automation)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Navigation
N AVIGAT IO N RET URN T Y P E DESC RIP T IO N
JSON representation
Here is a JSON representation of the company resource.
{
"id": "GUID",
"systemVersion": "string",
"name": "string",
"displayName": "string",
"businessProfileId": "string",
"systemCreatedAt": "datetime",
"systemCreatedBy": "GUID",
"systemModifiedAt": "datetime",
"systemModifiedBy": "GUID"
}
See Also
GET company
Get company
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a company object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET /microsoft/automation/v2.0/companies
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a company object in the response body.
Example
Request
Here is an example of the request.
Response
Here is an example of the response.
NOTE
The response object shown here may be truncated for brevity. All of the properties will be returned from an actual call.
{
"id": "3496bbf8-fcae-4e48-a4f8-cb17c27de0b3",
"systemVersion": "24012",
"name": "CRONUS USA, Inc.",
"displayName": "CRONUS USA, Inc.",
"businessProfileId": ""
}
See Also
Tips for working with the APIs
company
configurationPackage resource type
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Bound Actions
The configurationPackage resource type offers a bound action called import which imports the corresponding
configurationPackage batch. This is illustrated in the following example:
POST https://<server address>:<server API port>/<server instance
name>/api/microsoft/automation/v2.0/companies({id})/configurationPackages({id})/Microsoft.NAV.import
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the configurationPackage resource.
{
"id": "GUID",
"code": "string",
"packageName": "string",
"languageId": "integer",
"productVersion": "string",
"processingOrder": "integer",
"excludeConfigurationTables": "boolean",
"numberOfTables": "integer",
"numberOfRecords": "integer",
"numberOfErrors": "integer",
"importStatus": "string",
"importError": "string",
"applyStatus": "string",
"applyError": "string"
}
See Also
GET configurationPackage
DELETE configurationPackage
POST configurationPackage
PATCH configurationPackage
Get configurationPackage
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a configuration package object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET /microsoft/automation/v2.0/companies({companyId})/configurationPackages
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a configurationPackage object in the response
body.
Example
Request
Here is an example of the request.
GET https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/configurationPackages({packageId})
Response
Here is an example of the response.
NOTE
The response object shown here may be truncated for brevity. All of the properties will be returned from an actual call.
{
"id": "b6d25c66-f33d-eb11-846f-0022482037e2",
"code": "MyRSPackage",
"packageName": "SAMPLE",
"languageId": 0,
"productVersion": "",
"processingOrder": 0,
"excludeConfigurationTables": false,
"numberOfTables": 12,
"numberOfRecords": 3,
"numberOfErrors": 3,
"importStatus": "Completed",
"applyStatus": "Completed",
"applyError": "",
"importError": ""
}
See Also
Tips for working with the APIs
configurationPackage
Delete configurationPackage
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
DELETE /microsoft/automation/v2.0/companies({companyId})/configurationPackages({packageId})
Request headers
H EA DER VA L UE
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
configurationPackage , the configurationPackage will
not be updated.
Request body
Do not supply a request body for this method.
Response
If successful, this method returns 204 No Content response code and deletes the configurationPackage. It does
not return anything in the response body.
Example
Request
Here is an example of the request.
DELETE https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/configurationPackages({packageId})
Response
Here is an example of the response.
See Also
Tips for working with the APIs
configurationPackage
Create configurationPackage
2/6/2023 • 2 minutes to read • Edit Online
Bound Actions
A C T IO N S RET URN T Y P E DESC RIP T IO N
HTTP requests
Replace the URL prefix for Business Central depending on environment following the guideline.
Insert configurationPackage
POST /microsoft/automation/v2.0/companies({companyId})/configurationPackages
Content-type: application/json
{
"code":"YourPackageCode",
"packageName": "YourPackageName"
}
Response
If successful, this method returns 201 Created response code and a configurationPackage object in the
response body.
Request headers
H EA DER VA L UE
Content-Type application/json
Request body
In the request body, supply a JSON representation of a configurationPackage object.
Import configurationPackage
POST
/microsoft/automation/v2.0/companies({companyId})/configurationPackages({packageId})/Microsoft.NAV.import
Apply configurationPackage
POST
/microsoft/automation/v2.0/companies({companyId})/configurationPackages({packageId})/Microsoft.NAV.apply
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns 204 No Content response code.
Example
Request
Here is an example of the request.
POST https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/configurationPackages
Content-type: application/json
{
"code":"YourPackageCode",
"packageName": "YourPackageName"
}
Response
Here is an example of the response.
NOTE
The response object shown here may be truncated for brevity. All of the properties will be returned from an actual call.
Updates the properties of a configuration package object for Dynamics 365 Business Central.
HTTP request
Upload RapidStart package
PATCH
/microsoft/automation/v2.0/companies({companyId})/configurationPackages({packageId})/file('{packageCode}')/c
ontent
Content-type: application/octet-stream
Body: binary content of the RapidStart package
Request headers
H EA DER VA L UE
Content-Type application/json
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
configurationPackage , the configuration package will
not be updated.
Request body
In the request body, supply the values for relevant fields that should be updated. Existing properties that are not
included in the request body will maintain their previous values or be recalculated based on changes to other
property values. For best performance you shouldn't include existing values that haven't changed.
Response
If successful, this method returns a 204 No Content .
Example
Request
Here is an example of the request.
PATCH https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/configurationPackages({packageId})/file('{package
Code}')/content
Authorization : Bearer {token}
Content-type : application/octet-stream
If-Match:*
Body: binary stream
See Also
Tips for working with the APIs
configurationPackage
extension resource type
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Bound Actions
The extension resource type offers a bound action called install which installs the corresponding extension
batch. This is illustrated in the following example:
POST https://<server address>:<server API port>/<server instance
name>/api/v2.0/companies({id})/extensions({id})/Microsoft.NAV.install
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the extension resource.
{
"packageId": "GUID",
"id": "GUID",
"displayName": "string",
"publisher": "string",
"versionMajor": "integer",
"versionMinor": "integer",
"versionBuild": "integer",
"versionRevision": "integer",
"isInstalled": "boolean",
"publishedAs": "string"
}
See Also
GET extension
Get extension
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of an extension object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET /microsoft/automation/v2.0/companies({companyid})/extensions({packageId})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and an extension object in the response body.
Example
Request
Here is an example of the request.
GET https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/extensions({packageId})
Response
Here is an example of the response.
NOTE
The response object shown here may be truncated for brevity. All of the properties will be returned from an actual call.
{
"packageId": "3252be43-93d6-4d6a-b603-cdc0f0f32a9e",
"id": "3d5b2137-efeb-4014-8489-41d37f8fd4c3",
"displayName": "Late Payment Prediction",
"publisher": "Microsoft",
"versionMajor": 18,
"versionMinor": 0,
"scope": 0,
"isInstalled": true
}
See Also
Tips for working with the APIs
extension
extensionDeploymentStatus resource type
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the extensionDeploymentStatus resource.
{
"operationID": "GUID",
"name": "string",
"publisher": "string",
"operationType": "string",
"status": "string",
"schedule": "string",
"appVersion": "string",
"startedOn": "datetime"
}
See Also
GET extensionDeploymentStatus
Get extensionDeploymentStatus
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of an extension deployment status object for Dynamics 365 Business
Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET /microsoft/automation/v2.0/companies({companyId})/extensionDeploymentStatus
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and an extensionDeploymentStatus object in the
response body.
Example
Request
Here is an example of the request.
GET https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/extensionDeploymentStatus
Response
Here is an example of the response.
NOTE
The response object shown here may be truncated for brevity. All of the properties will be returned from an actual call.
{
"operationID": "138fb013-1ebd-4e65-a333-420631e67344",
"name": "VeryNiceApp",
"publisher": "Default publisher",
"operationType": "Upload",
"status": "Completed",
"schedule": "Immediate",
"appVersion": "1.0.0.0",
"startedOn": "2018-08-23T09:07:04.387Z"
}
See Also
Tips for working with the APIs
extensionDeploymentStatus
extensionUpload resource type
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Bound Actions
The extensionUpload resource type offers a bound action called upload which uploads the corresponding
extensionUpload batch. This is illustrated in the following example:
POST https://<server address>:<server API port>/<server instance
name>/api/microsoft/automation/v2.0/companies({id})/extensionUpload({id})/Microsoft.NAV.upload
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the extensionUpload resource.
{
"systemId": "GUID",
"schedule": "string",
"schemaSyncMode": "string",
"extensionContent": "stream"
}
See Also
GET extensionUpload
POST extensionUpload
PATCH extensionUpload
Get extensionUpload
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of an extension upload object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET /microsoft/automation/v2.0/companies({companyId})/extensionUpload({extensionUploadId})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and an extensionUpload object in the response
body.
Example
Request
Here is an example of the request.
GET https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/extensionUpload({extensionUploadId})
{
"systemId" : "f99be650-07ce-45df-a285-3afe69a953eb",
"schedule" : "Next major version",
"schemaSyncMode": "Add",
"extensionContent" : ""
}
Schedule in the body can be "Current version", "Next minor version", or "Next major version". Schema Sync
Mode in the body can be "Add" or "Force Sync".
See Also
Tips for working with the APIs
extensionUpload
Create extensionUpload
2/6/2023 • 2 minutes to read • Edit Online
Bound Actions
A C T IO N S RET URN T Y P E DESC RIP T IO N
HTTP requests
Replace the URL prefix for Business Central depending on environment following the guideline.
Insert extensionUpload
POST /microsoft/automation/v2.0/companies({companyId})/extensionUpload
Request headers
H EA DER VA L UE
Content-Type application/json
Request body
In the request body, supply a JSON representation of a extensionUpload object.
Response
If successful, this method returns 201 Created response code and a extensionUpload object in the response
body.
Upload extensionUpload
POST
/microsoft/automation/v2.0/companies({companyId})/extensionUpload({extensionUploadId})/Microsoft.NAV.upload
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns 204 No Content response code.
Example
Request
Here is an example of the request.
POST https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/extensionUpload
Content-type: application/json
{
"schedule" : "Current version",
"schemaSyncMode": "Add"
}
See Also
Tips for working with the APIs
extensionUpload
Update extensionUpload
2/6/2023 • 2 minutes to read • Edit Online
Updates the properties of an extension upload object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
PATCH /microsoft/automation/v2.0/companies({companyId})/extensionUpload({extensionUploadId})/content
Content-type: application/octet-stream
Body: binary content of the extension
Request headers
H EA DER VA L UE
Content-Type application/octet-stream
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
extensionUpload , the extension upload will not be
updated.
Request body
In the request body, supply the values for relevant fields that should be updated. Existing properties that are not
included in the request body will maintain their previous values or be recalculated based on changes to other
property values. For best performance you shouldn't include existing values that haven't changed.
Response
If successful, this method returns a 204 No Content .
Example
Request Here is an example of the request.
PATCH https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/extensionUpload({extensionUploadId})/content
Authorization : Bearer {token}
Content-type : application/octet-stream
If-Match:-*
Body: binary stream
See Also
Tips for working with the APIs
extensionUpload
permissionSet resource type
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the permissionSet resource.
{
"scope": "string",
"appId": "GUID",
"id": "string",
"displayName": "string",
"extensionName": "string"
}
See Also
GET permissionSet
Get permissionSet
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a permission set object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET /microsoft/automation/v2.0/companies({companyId})/permissionSets
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a permissionSet object in the response body.
Example
Request
Here is an example of the request.
GET https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/permissionSets
Response
Here is an example of the response.
NOTE
The response object shown here may be truncated for brevity. All of the properties will be returned from an actual call.
{
"id": "D365 ACC. PAYABLE",
"scope": "System",
"appID": "00000000-0000-0000-0000-000000000000",
"displayName": "Dynamics 365 Accounts payable",
"extensionName": ""
}
See Also
Tips for working with the APIs
permissionSet
scheduledJob resource type
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the scheduledJob resource.
{
"id": "GUID",
"category": "string",
"status": "string",
"description": "string",
"errorMessage": "string"
}
See Also
GET scheduledJob
Get scheduledJob
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a scheduled job object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET /microsoft/automation/v2.0/companies({companyId})/scheduledJobs({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a scheduledJob object in the response body.
Example
Request
Here is an example of the request.
GET https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/scheduledJobs({id})
{
"id" : "26066f96-8775-eb11-bb56-000d3a298ab3",
"category" : "APIUSERJOB",
"status" : "In Progress",
"description" : "Create new users from Azure AD API job",
"errorMessage" : ""
}
See Also
Tips for working with the APIs
scheduledJob
user resource type
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Bound Actions
The user resource type offers a bound action called getNewUsersFromOffice365 which retrieves new users or new
user information from the Office 365 portal. Note that existing, unchanged users will not be updated. This is
illustrated in the following example:
POST https://<server address>:<server API port>/<server instance
name>/api/microsoft/automation/v2.0/companies({id})/users({id})/Microsoft.NAV.createNewUsersFromAzureAD
The response has a reference to the scheduled job to track the progress of the scheduled background job; the
response code is 201.
Navigation
N AVIGAT IO N RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the user resource.
{
"userSecurityId": "GUID",
"userName": "string",
"displayName": "string",
"state": "string",
"expiryDate": "datetime"
}
See Also
GET user
PATCH user
Get user
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of an user object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET /microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and an user object in the response body.
Example
Request
Here is an example of the request.
GET https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyid})/users({userSecurityId})
Response
Here is an example of the response.
NOTE
The response object shown here may be truncated for brevity. All of the properties will be returned from an actual call.
{
"userSecurityId": "82ae94d5-3445-47de-8668-714b5113a9c2",
"userName": "JOE",
"displayName": "JOE JONES",
"state": "Enabled",
"expiryDate": "0001-01-01T00:00:00Z"
}
See Also
Tips for working with the APIs
user
Update user
2/6/2023 • 2 minutes to read • Edit Online
Updates the properties of an user object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
PATCH /microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})
Request headers
H EA DER VA L UE
Content-Type application/json
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the user , the
user will not be updated.
Request body
In the request body, supply the values for relevant fields that should be updated. Existing properties that are not
included in the request body will maintain their previous values or be recalculated based on changes to other
property values. For best performance you shouldn't include existing values that haven't changed.
Response
If successful, this method returns a 200 OK response code and an updated **user ** object in the response
body.
Example
Request
Here is an example of the request.
PATCH https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})
Content-type: application/json
If-Match:*
{
"state": "Enabled",
"expiryDate": "2035-01-01T21:03:53.444Z"
}
See Also
Tips for working with the APIs
user
userGroup resource type
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Navigation
N AVIGAT IO N RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
{
"id": "GUID",
"code": "string",
"displayName": "string",
"defaultProfileID": "string",
"assignToAllNewUsers": "boolean"
}
See Also
GET userGroup
DELETE userGroup
POST userGroup
PATCH userGroup
Get userGroup
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of an user group object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET /microsoft/automation/v2.0/companies({companyId})/userGroups({userGroupId})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and an userGroup object in the response body.
Example
Request
Here is an example of the request.
GET https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/userGroups({userGroupId})
{
"id": "d38a92e2-9d74-eb11-bb5c-00155df3a615",
"code": "D365 ACCOUNTANTS",
"displayName": "Dynamics 365 for Accountants",
"defaultProfileID": "ACCOUNTANT PORTAL",
"assignToAllNewUsers": false
}
See Also
Tips for working with the APIs
userGroup
Create userGroup
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
POST /microsoft/automation/v2.0/companies({companyId})/userGroups
Request headers
H EA DER VA L UE
Content-Type application/json
Request body
In the request body, supply a JSON representation of a userGroup object.
Response
If successful, this method returns 201 Created response code and a userGroup object in the response body.
Example
Request
Here is an example of the request.
POST https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/userGroups
Content-type: application/json
{
"code": "NEW USER GROUP",
"displayName": "New User Group",
"defaultProfileID": "ACCOUNTANT"
}
See Also
Tips for working with the APIs
userGroup
Delete userGroup
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
DELETE /microsoft/automation/v2.0/companies({companyId})/userGroups({userGroupId})
Request headers
H EA DER VA L UE
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
userGroup , the userGroup will not be updated.
Request body
Do not supply a request body for this method.
Response
If successful, this method returns 204 No Content response code and deletes the userGroup. It does not return
anything in the response body.
Example
Request
Here is an example of the request.
DELETE https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/userGroups({userGroupId})
Response
Here is an example of the response.
See Also
Tips for working with the APIs
userGroup
Update userGroup
2/6/2023 • 2 minutes to read • Edit Online
Updates the properties of an user group object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
PATCH /microsoft/automation/v2.0/companies({companyId})/userGroups({userGroupId})
Request headers
H EA DER VA L UE
Content-Type application/json
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
userGroup , the user group will not be updated.
Request body
In the request body, supply the values for relevant fields that should be updated. Existing properties that are not
included in the request body will maintain their previous values or be recalculated based on changes to other
property values. For best performance you shouldn't include existing values that haven't changed.
Response
If successful, this method returns a 200 OK response code and an updated userGroup object in the response
body.
Example
Request
Here is an example of the request.
PATCH https:///microsoft/automation/{apiVersion}/companies({companyId})/userGroups({userGroupId})
Content-type: application/json
{
"displayName" : "YourUserGroupName"
}
See Also
Tips for working with the APIs
userGroup
userGroupMember resource type
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Navigation
N AVIGAT IO N RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the userGroupMember resource.
{
"id": "GUID",
"userSecurityId": "GUID",
"code": "string",
"displayName": "string",
"companyName": "string"
}
See Also
GET userGroupMember
DELETE userGroupMember
POST userGroupMember
PATCH userGroupMember
Get userGroupMember
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of an user group member object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET
/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userGroupMembers({userGroupMemberI
d})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and an userGroupMember object in the response
body.
Example
Request
Here is an example of the request.
GET https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userGroupMembers({userGro
upMemberId})
Response
Here is an example of the response.
NOTE
The response object shown here may be truncated for brevity. All of the properties will be returned from an actual call.
{
"id": "d38a92e2-9d74-eb11-bb5c-00155df3a615",
"code": "D365 BUS PREMIUM",
"userSecurityId": "7ae30772-481f-4895-a042-98f36e280680",
"companyName": "CRONUS USA, Inc.",
"displayName": "D365 Premium Business Access"
}
See Also
Tips for working with the APIs
userGroupMember
Delete userGroupMember
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
DELETE
/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userGroupMembers({userGroupMemberI
d})
Request headers
H EA DER VA L UE
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
userGroupMember , the userGroupMember will not be
updated.
Request body
Do not supply a request body for this method.
Response
If successful, this method returns 204 No Content response code and deletes the userGroupMember. It does not
return anything in the response body.
Example
Request
Here is an example of the request.
DELETE https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userGroupMembers({userGro
upMemberId})
If-Match:*
Response
Here is an example of the response.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
POST /microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userGroupMembers
Request headers
H EA DER VA L UE
Content-Type application/json
Request body
In the request body, supply a JSON representation of a userGroupMember object.
Response
If successful, this method returns 201 Created response code and a userGroupMember object in the response
body.
Example
Request
Here is an example of the request.
POST https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userGroupMembers
Content-Type:application/json
{
"id": "d38a92e2-9d74-eb11-bb5c-00155df3a615",
"code": "D365 EXT. ACCOUNTANT",
"companyName" :"CRONUS USA, Inc."
}
Response
Here is an example of the response.
NOTE
The response object shown here may be truncated for brevity. All of the properties will be returned from an actual call.
{
"id": "d38a92e2-9d74-eb11-bb5c-00155df3a615",
"code": "D365 EXT. ACCOUNTANT",
"userSecurityId": "7ae30772-481f-4895-a042-98f36e280680",
"companyName": "CRONUS USA, Inc.",
"displayName": ""
}
See Also
Tips for working with the APIs
userGroupMember
Update userGroupMember
2/6/2023 • 2 minutes to read • Edit Online
Updates the properties of an user group member object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
PATCH
/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userGroupMembers({userGroupMemberI
d})
Request headers
H EA DER VA L UE
Content-Type application/json
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
userGroupMember , the user group member will not be
updated.
Request body
In the request body, supply the values for relevant fields that should be updated. Existing properties that are not
included in the request body will maintain their previous values or be recalculated based on changes to other
property values. For best performance you shouldn't include existing values that haven't changed.
Response
If successful, this method returns a 200 OK response code and an updated **userGroupMember ** object in the
response body.
Example
Request
Here is an example of the request.
PATCH https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userGroupMembers({userGro
upMemberId})
Content-type: application/json
{
"displayName": "YourDisplayName"
}
HTTP/1.1 200 OK
Content-type: application/json
{
"id": "d38a92e2-9d74-eb11-bb5c-00155df3a615",
"code": "D365 BUS PREMIUM",
"userSecurityId": "7ae30772-481f-4895-a042-98f36e280680",
"companyName": "CRONUS USA, Inc.",
"displayName": "YourDisplayName"
}
See Also
Tips for working with the APIs
userGroupMember
userPermission resource type
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Navigation
N AVIGAT IO N RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the userPermission resource.
{
"id": "GUID",
"userSecurityId": "GUID",
"roleId": "string",
"displayName": "string",
"company": "string",
"appId": "GUID",
"extensionName": "string",
"scope": "string"
}
See Also
GET userPermission
DELETE userPermission
POST userPermission
PATCH userPermission
Get userPermission
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of an user permission object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userPermissions({userPermissionId}
)
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and an userPermission object in the response body.
Example
Request
Here is an example of the request.
GET https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userPermissions({userPerm
issionId})
Response
Here is an example of the response.
NOTE
The response object shown here may be truncated for brevity. All of the properties will be returned from an actual call.
{
"id": "d38a92e2-9d74-eb11-bb5c-00155df3a615",
"userSecurityId": "a0ad6d24-99b7-440e-a26d-9a86840c2056",
"roleId": "SUPER",
"company": "",
"scope": "System",
"appId": "00000000-0000-0000-0000-000000000000",
"displayName": "This role has all permissions.",
"extensionName": ""
See Also
Tips for working with the APIs
userPermission
Delete userPermission
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
DELETE
/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userPermissions({userPermissionId}
)
Request headers
H EA DER VA L UE
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
userPermission , the userPermission will not be updated.
Request body
Do not supply a request body for this method.
Response
If successful, this method returns 204 No Content response code and deletes the userPermission. It does not
return anything in the response body.
Example
Request
Here is an example of the request.
DELETE https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userPermissions({userPerm
issionId})
If-Match:*
Response
Here is an example of the response.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
POST /microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userPermissions
Request headers
H EA DER VA L UE
Content-Type application/json
Request body
In the request body, supply a JSON representation of a userPermission object.
Response
If successful, this method returns 201 Created response code and a userPermission object in the response
body.
Example
Request
Here is an example of the request.
POST https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userPermissions
Content-Type:application/json
{
"roleId": "SECURITY",
"company" : "CRONUS"
}
Response
Here is an example of the response.
NOTE
The response object shown here may be truncated for brevity. All of the properties will be returned from an actual call.
{
"id": "d38a92e2-9d74-eb11-bb5c-00155df3a615",
"userSecurityId": "82ae94d5-3445-47de-8668-714b5113a9c2",
"roleId": "SECURITY",
"company": "CRONUS",
"scope": "System",
"appID": "00000000-0000-0000-0000-000000000000",
"displayName": "",
"extensionName": ""
}
See Also
Tips for working with the APIs
userPermission
Update userPermission
2/6/2023 • 2 minutes to read • Edit Online
Updates the properties of an user permission object for Dynamics 365 Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
PATCH
/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userPermissions({userPermissionId}
)
Request headers
H EA DER VA L UE
Content-Type application/json
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
userPermission , the user permission will not be updated.
Request body
In the request body, supply the values for relevant fields that should be updated. Existing properties that are not
included in the request body will maintain their previous values or be recalculated based on changes to other
property values. For best performance you shouldn't include existing values that haven't changed.
Response
If successful, this method returns a 200 OK response code and an updated **userPermission ** object in the
response body.
Example
Request
Here is an example of the request.
PATCH https://api.businesscentral.dynamics.com/v2.0/{environment
name}/api/microsoft/automation/v2.0/companies({companyId})/users({userSecurityId})/userPermissions({userPerm
issionId})
Content-type: application/json
{
"userSecurityId": "82ae94d5-3445-47de-8668-714b5113a9c2",
"roleId": "SECURITY",
}
Response
Here is an example of the response.
NOTE
The response object shown here may be truncated for brevity. All of the properties will be returned from an actual call.
{
"id": "d38a92e2-9d74-eb11-bb5c-00155df3a615",
"userSecurityId": "82ae94d5-3445-47de-8668-714b5113a9c2",
"roleId": "SECURITY",
"company": "",
"scope": "System",
"appID": "00000000-0000-0000-0000-000000000000",
"displayName": "",
"extensionName": ""
}
See Also
Tips for working with the APIs
userPermission
The Business Central Admin Center API
2/6/2023 • 7 minutes to read • Edit Online
The Business Central administration center API enables administrators to programmatically do administrative
tasks for a Business Central tenant. With the API, administrators can, for example:
Query and work with production and sandbox environments for the tenant.
Set up administrative notifications.
View telemetry for events on the tenant.
For more information about administrative capabilities, see The Business Central Administration Center. This
article describes the API contracts for these administrative capabilities.
IMPORTANT
For delegated admin access, you must add the Azure Active Directory (Azure AD) application to the AdminAgents
group. If the Azure AD application is not added, the consent flow will show an error such as Need pre-consent. For more
information, see Pre-consent your app for all your customers in the Graph documentation.
Location
The Business Central administration center API is located at the following URL:
https://api.businesscentral.dynamics.com.
The Business Central administration center API supports authentication using AAD Apps.
1. Sign in to the Azure portal.
2. Register an application for Business Central administration center in your Azure Active Directory tenant.
Follow the general guidelines at Register your application with your Azure Active Directory tenant.
When you add an application to an Azure AD tenant, you must specify the following information:
Redirect URI Optional. You can grant consent from the Azure portal if
left empty.
When completed, an Over view displays in the portal for the new application.
3. Create a client secret for the registered application as follows:
a. Select Cer tificates & secrets > New client secret .
b. Add a description, select a duration, and select Add .
NOTE
Copy the secret's value for use in your client application code. This secret value is never displayed again after you
leave this page.
For the latest guidelines about adding client secrets in Azure AD, see Add credentials in the Azure
documentation.
NOTE
Copy the Application (client) ID of the registered app. You'll need this later. You can get this value from the Over view
page.
NOTE
If you intent to use the same AAD App with the Automation API and Business Central Web Services you can also
grant API.ReadWrite.All and Automation.ReadWrite.All permissions. Learn more here.
5. (optional) Grant admin consent on each permission by selecting it in the list, then selecting Grant admin
consent for <tenant name> . This step isn't required if you'll be granting consent from the Business
Central administration center. It is possible to grant consent from this page only for your own current
tenant. This works for single-tenant apps, but for multi-tenant apps you have to grant consent for each
tenant from that tenant's Azure AD portal or the Business Central administration center
6. Go to the Business Central administration center and navigate to the 'Authorized AAD Apps' page. Paste
the Application (client) ID of your app in the form to authorize an app.
7. If not already completed in step 5 you can grant consent for your app from the 'Authorized AAD Apps'
page in the Business Central administration center.
Note: There might be a short delay until the Granted status is visible in the TAC UI after refreshing.
8. (optional) Some operations in the Business Central administration center API require that the app has a
permissions assigned in the environment in addition to the authorization in the Business Central
administration center. Follow the instructions in Task 2 here to assign permissions.
NOTE
Learn more about permissions required for App Management operations here and learn more about permissions
required for Database Exports here.
NOTE
In the PowerShell example above, the guid specified to acquire the token (996def3d-b36c-4153-8607-a6fd3c01b89f) is
the resource ID of Business Central. The example gets the client credential using the app secret, but the recommended
way would be to rely on X.509 certificates.
# @name auth
POST https://login.microsoftonline.com/{{tenantId}}/oauth2/v2.0/token HTTP/1.1
Content-type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id={{clientId}}
&client_secret={{clientSecret}}
&scope={{scope}}
# @name GetEnvironments
GET {{url}}/applications/BusinessCentral/environments HTTP/1.1
Authorization: {{accessHeader}}
NOTE
If Dynamics 365 Business Central doesn't show up in search, it's because the tenant doesn't have any
knowledge of Dynamics 365 Business Central. To make it visible, an easy way is to register for a free trial for
Dynamics 365 Business Central with a user from the directory.
6. Make a note of both the Application ID and the Redirect URI . They'll be needed later.
Getting an access token with Authorization Code Flow
HTTP requests sent to the Business Central administration center API must include the Authorization HTTP
header, and the value must be an access token.
The following examples show how to obtain such a token using PowerShell. Using C# is straightforward.
PowerShell example without prompt:
$cred = [Microsoft.IdentityModel.Clients.ActiveDirectory.UserPasswordCredential]::new($UserName,
$Password)
$ctx =
[Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext]::new("https://login.windows.net/$Ten
antName")
$token =
[Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions]::AcquireToke
nAsync($ctx, "https://api.businesscentral.dynamics.com", <Application ID>,
$cred).GetAwaiter().GetResult().AccessToken
$ctx =
[Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext]::new("https://login.windows.net/$ten
antName")
$redirectUri = New-Object -TypeName System.Uri -ArgumentList <Redirect URL>
$platformParameters = New-Object -TypeName
Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters -ArgumentList
([Microsoft.IdentityModel.Clients.ActiveDirectory.PromptBehavior]::Always)
$token = $ctx.AcquireTokenAsync("https://api.businesscentral.dynamics.com", <Application ID>,
$redirectUri, $platformParameters).GetAwaiter().GetResult().AccessToken
Error Format
If an error occurs during the execution of an API method, it will respond back with an error object. While the
specifics of any error will vary from endpoint to endpoint and by the error, the error object returned should
adhere to the following structure. When an error occurs that doesn't fit this structure, it typically indicates that
an error occurred in sending the request or during authentication of the request. For example, it could be that
the API hasn't yet received the request.
Error Response Object:
{
"code": string, // A stable error code describing the type an nature of the error. Ex: EnvironmentNotFound
"message": string, // A message with a readable description of the error and cause. Intended to assist with
debugging or troubleshooting the API, it's not intended to be displayed.
("target": string), // Optional - Provides information about what part of a request caused the error. Ex:
The name of a property on the request body.
("extensionData": {...}), // Optional - A key/value dictionary object containing additional information
about the error.
("clientError": [ // Optional - A nested list of error objects containing more details about the error
encountered. For instance, this may be used if multiple errors are encountered to list them all out.
{
"code": string,
"message": string,
"target": string,
"extensionData": {...},
"clientError": [...]
})
]
}
Cloud Migration APIs provide capability for automating the cloud migration process end-to-end by using APIs.
You will be able to complete the setup, move the data, and track the progress, trigger upgrade if needed and
switch off the cloud migration.
The main endpoint for the API is:
https://api.businesscentral.dynamics.com/v2.0/79dbd222-0f30-42a6-9f25-
3164d21b269a/Production/api/microsoft/cloudMigration/v1.0/companies
POST https://api.businesscentral.dynamics.com/v2.0/{aadTenantID}/{environment
name}/api/microsoft/cloudMigration/v1.0/companies({companyId})/setupCloudMigration
Authorization: Bearer {token}
Content-type: application/json
Body:
{
"productId":"{ProductID}",
"sqlServerType":"{SqlServerType}",
"sqlConnectionString":"{SqlConnectionString}"
}
{
"id":"{SetupRecordId}",
"productId":"{ProductID}",
"sqlServerType":"{SqlServerType}",
"sqlConnectionString":"{SqlConnectionString}"
"runtimeName":"{RuntimeName}",
"runtimeKey":"{RuntimeKey}"
}
If you are migrating from Azure SQL you can skip next step:
If you are migrating from SQLServer, you should take the runtimeKey value and install and connect Microsoft
Integration Runtime by using this key. Then you need to issue a PATCH request such as the following:
PATCH https://api.businesscentral.dynamics.com/v2.0/{aadTenantID}/{environment
name}/api/microsoft/cloudMigration/v1.0/companies({companyId})/setupCloudMigration({SetupRecordId})
Authorization: Bearer {token}
Content-type: application/json
If-Match: etag
Body:
{
"productId":"{ProductID}",
"sqlServerType":"{SqlServerType}",
"sqlConnectionString":"{SqlConnectionString}",
"runtimeName":"{RuntimeName}"
}
To complete the setup for both SQL and Azure SQL hosted databases invoke:
POST https://api.businesscentral.dynamics.com/v2.0/{aadTenantID}/{environment
name}/api/microsoft/cloudMigration/v1.0/companies({companyId})/setupCloudMigration({SetupRecordId})/
Microsoft.NAV.completeSetup
GET https://api.businesscentral.dynamics.com/v2.0/{aadTenantID}/{environment
name}/api/microsoft/cloudMigration/v1.0/companies({companyId})/cloudMigrationCompanies
Authorization: Bearer {token}
To include the company into the cloud migration you should issue following request:
PATCH https://api.businesscentral.dynamics.com/v2.0/{aadTenantID}/{environment
name}/api/microsoft/cloudMigration/v1.0/companies({companyId})/cloudMigrationCompanies ({CompanyId})
Authorization: Bearer {token}
Content-type: application/json
If-Match: etag
{
"replicate": true
}
To exclude the company, issue the same request with a false value.
Once the companies are marked for replication you can create them by running the following request:
POST https://api.businesscentral.dynamics.com/v2.0/{aadTenantID}/{environment
name}/api/microsoft/cloudMigration/v1.0/companies({companyId})/cloudMigrationCompanies({AnyCompanyId})
/Microsoft.NAV.createCompaniesMarkedForReplication
DELETE and POST are not allowed against this API; it is not possible to create or delete entities on this API.
GET https://api.businesscentral.dynamics.com/v2.0/{aadTenantID}/{environment
name}/api/microsoft/cloudMigration/v1.0/companies({companyId})/cloudMigrationStatus
Authorization: Bearer {token}
{
"id": "679c8aa5-16a9-ec11-80f1-002248334988",
"runId": "79090ce4-404d-4274-829a-a3b18e99006c",
"startTime": "2022-03-21T12:57:17Z",
"endTime": "2022-03-21T12:58:48.35Z",
"replicationType": "Normal",
"status": "Completed",
"source": "Dynamics 365 Business Central earlier versions",
"details": "Cloud migration setup completed.",
"tablesSuccessful": 0,
"tablesFailed": 0,
"tablesRemaining": 0
}
To start the replication find the cloudMigrationStatus with last endTime and invoke the following command:
POST https://api.businesscentral.dynamics.com/v2.0/{aadTenantID}/{environment
name}/api/microsoft/cloudMigration/v1.0/companies({companyId})/cloudMigrationStatus ({LastStatusId})
/Microsoft.NAV.runReplication
Authorization: Bearer {token}
POST https://api.businesscentral.dynamics.com/v2.0/{aadTenantID}/{environment
name}/api/microsoft/cloudMigration/v1.0/companies({companyId})/cloudMigrationStatus ({LastStatusId})
/Microsoft.NAV.refreshStatus
Authorization: Bearer {token}
POST https://api.businesscentral.dynamics.com/v2.0/{aadTenantID}/{environment
name}/api/microsoft/cloudMigration/v1.0/companies({companyId})/cloudMigrationStatus ({LastStatusId})
/Microsoft.NAV.runDataUpgrade
Authorization: Bearer {token}
See also
Endpoints for the APIs.
cloudMigrationCompany resource type
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see guideline.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Bound Actions
The cloudMigrationCompany resource type offers two bound actions:
The first bound action is called createCompaniesMarkedForReplication which create companies marked for
replications the corresponding cloudMigrationCompany batch. This is illustrated in the following example:
CREATECOMPANIESMARKEDFORREPLICATION https://<server address>:<server API port>/<server instance
name>/api/v1.0/companies({id})/cloudMigrationCompanys({id})/Microsoft.NAV.createCompaniesMarkedForReplication
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the cloudMigrationCompany resource.
{
"id": "GUID",
"name": "string",
"replicate": "boolean",
"displayName": "string",
"estimatedSize": "decimal",
"status": "string",
"created": "boolean"
}
See Also
GET cloudMigrationCompany
PATCH cloudMigrationCompany
Get cloudMigrationCompanies
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a cloud migration company object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/cloudMigrationCompanies({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a cloudMigrationCompany object in the
response body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v1.0/companies({id})/cloudMigrationCompanies({id})
Response
Here is an example of the response.
{
"id" : "",
"name" : "",
"replicate" : "",
"displayName" : "",
"estimatedSize" : "",
"status" : "",
"created" : ""
}
See Also
Tips for working with the APIs
cloudMigrationCompany
PATCH cloudMigrationCompany
Update cloudMigrationCompanies
2/6/2023 • 2 minutes to read • Edit Online
Updates the properties of a cloud migration company object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline..
PATCH businesscentralPrefix/companies({id})/cloudMigrationCompanies({id})
Request headers
H EA DER VA L UE
Content-Type application/json
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
cloudMigrationCompany , the cloud migration
company will not be updated.
Request body
In the request body, supply the values for relevant fields that should be updated. Existing properties that are not
included in the request body will maintain their previous values or be recalculated based on changes to other
property values. For best performance you shouldn't include existing values that haven't changed.
Response
If successful, this method returns a 200 OK response code and an updated cloudMigrationCompany object in
the response body.
Example
Request
Here is an example of the request.
PATCH https://{businesscentralPrefix}/api/v1.0/companies({id})/cloudMigrationCompanies({id})
Content-type: application/json
{
"id" : ,
"name" :
}
Response
Here is an example of the response.
HTTP/1.1 200 OK
Content-type: application/json
{
"id" : ,
"name" : ,
"replicate" : ,
"displayName" : ,
"estimatedSize" : ,
"status" : ,
"created" :
}
See Also
Tips for working with the APIs
cloudMigrationCompany
GET cloudMigrationCompany
cloudMigrationStatus resource type
2/6/2023 • 2 minutes to read • Edit Online
Represents a status record of the cloud migration in Business Central. It is used to start replication, start the data
upgrade, disable the cloud migration, and to track the overall status.
NOTE
For information about enabling APIs for Business Central see guideline.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Bound Actions
The cloudMigrationStatus resource type offers a bound action called disableReplication which disable
replications the corresponding cloudMigrationStatus batch. This is illustrated in the following example:
DISABLEREPLICATION https://<server address>:<server API port>/<server instance
name>/api/v1.0/companies({id})/cloudMigrationStatus({id})/Microsoft.NAV.disableReplication
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the cloudMigrationStatus resource.
{
"id": "GUID",
"runId": "string",
"startTime": "datetime",
"endTime": "datetime",
"replicationType": "string",
"status": "string",
"source": "string",
"details": "string",
"tablesSuccessful": "integer",
"tablesFailed": "integer",
"tablesRemaining": "integer"
}
See Also
GET cloudMigrationStatus
Get cloudMigrationStatus
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a cloud migration status object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline..
GET businesscentralPrefix/companies({id})/cloudMigrationStatus({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a cloudMigrationStatus object in the response
body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v1.0/companies({id})/cloudMigrationStatus({id})
Response
Here is an example of the response.
{
"id" : "",
"runId" : "",
"startTime" : "",
"endTime" : "",
"replicationType" : "",
"status" : "",
"source" : "",
"details" : "",
"tablesSuccessful" : "",
"tablesFailed" : "",
"tablesRemaining" : ""
}
See Also
Tips for working with the APIs
cloudMigrationStatus
cloudMigrationStatusDetail resource type
2/6/2023 • 2 minutes to read • Edit Online
Represents a cloud migration status detail in Business Central that is giving more information about the status
of the table that is under cloud migration.
NOTE
For information about enabling APIs for Business Central see guideline.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Navigation
N AVIGAT IO N RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the cloudMigrationStatusDetail resource.
{
"id": "GUID",
"runId": "string",
"companyName": "string",
"tableName": "string",
"status": "string",
"recordsCopied": "integer",
"totalRecords": "integer",
"errors": "string"
}
See Also
GET cloudMigrationStatusDetail
Get cloudMigrationStatusDetails
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a cloud migration status detail object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline..
GET businesscentralPrefix/companies({id})/cloudMigrationStatusDetails({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a cloudMigrationStatusDetail object in the
response body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v1.0/companies({id})/cloudMigrationStatusDetails({id})
Response
Here is an example of the response.
{
"id" : "",
"runId" : "",
"companyName" : "",
"tableName" : "",
"status" : "",
"recordsCopied" : "",
"totalRecords" : "",
"errors" : ""
}
See Also
Tips for working with the APIs
cloudMigrationStatusDetail
company resource type
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see guideline.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Navigation
N AVIGAT IO N RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the company resource.
{
"id": "GUID",
"systemVersion": "string",
"name": "string",
"displayName": "string",
"businessProfileId": "string",
"systemCreatedAt": "datetime",
"systemCreatedBy": "GUID",
"systemModifiedAt": "datetime",
"systemModifiedBy": "GUID"
}
See Also
GET company
Get companies
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a company object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline..
GET businesscentralPrefix/companies({id})/companies({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a company object in the response body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v1.0/companies({id})/companies({id})
Response
Here is an example of the response.
{
"id" : "",
"systemVersion" : "",
"name" : "",
"displayName" : "",
"businessProfileId" : "",
"systemCreatedAt" : "",
"systemCreatedBy" : "",
"systemModifiedAt" : "",
"systemModifiedBy" : ""
}
See Also
Tips for working with the APIs
company
setupCloudMigration resource type
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see guideline.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Bound Actions
The setupCloudMigration resource type offers a bound action called completeSetup which complete setups the
corresponding setupCloudMigration batch. This is illustrated in the following example:
COMPLETESETUP https://<server address>:<server API port>/<server instance
name>/api/v1.0/companies({id})/setupCloudMigrations({id})/Microsoft.NAV.completeSetup
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the setupCloudMigration resource.
{
"id": "GUID",
"productId": "string",
"sqlServerType": "string",
"sqlConnectionString": "string",
"runtimeName": "string",
"runtimeKey": "string"
}
See Also
GET setupCloudMigration
POST setupCloudMigration
PATCH setupCloudMigration
Get setupCloudMigrations
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a setup cloud migration object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline..
GET businesscentralPrefix/companies({id})/setupCloudMigrations({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a setupCloudMigration object in the response
body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v1.0/companies({id})/setupCloudMigrations({id})
Response
Here is an example of the response.
{
"id" : "",
"productId" : "",
"sqlServerType" : "",
"sqlConnectionString" : "",
"runtimeName" : "",
"runtimeKey" : ""
}
See Also
Tips for working with the APIs
setupCloudMigration
POST setupCloudMigration
PATCH setupCloudMigration
Create setupCloudMigrations
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline..
POST businesscentralPrefix/companies({id})/setupCloudMigrations({id})
Request headers
H EA DER VA L UE
Content-Type application/json
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
setupCloudMigration , the setupCloudMigration will
not be updated.
Request body
In the request body, supply a JSON representation of a setupCloudMigration object.
Response
If successful, this method returns 201 Created response code and a setupCloudMigration object in the
response body.
Example
Request
Here is an example of the request.
POST https://{businesscentralPrefix}/api/v1.0/companies({id})/setupCloudMigrations({id})
Content-type: application/json
{
"id" : "",
"productId" : "",
"sqlServerType" : "",
"sqlConnectionString" : "",
"runtimeName" : "",
"runtimeKey" : ""
}
Response
Here is an example of the response.
See Also
Tips for working with the APIs
setupCloudMigration
GET setupCloudMigration
PATCH setupCloudMigration
Update setupCloudMigrations
2/6/2023 • 2 minutes to read • Edit Online
Updates the properties of a setup cloud migration object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline..
PATCH businesscentralPrefix/companies({id})/setupCloudMigrations({id})
Request headers
H EA DER VA L UE
Content-Type application/json
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
setupCloudMigration , the setup cloud migration will
not be updated.
Request body
In the request body, supply the values for relevant fields that should be updated. Existing properties that are not
included in the request body will maintain their previous values or be recalculated based on changes to other
property values. For best performance you shouldn't include existing values that haven't changed.
Response
If successful, this method returns a 200 OK response code and an updated setupCloudMigration object in the
response body.
Example
Request
Here is an example of the request.
PATCH https://{businesscentralPrefix}/api/v1.0/companies({id})/setupCloudMigrations({id})
Content-type: application/json
{
"id" : ,
"productId" :
}
Response
Here is an example of the response.
HTTP/1.1 200 OK
Content-type: application/json
{
"id" : ,
"productId" : ,
"sqlServerType" : ,
"sqlConnectionString" : ,
"runtimeName" : ,
"runtimeKey" :
}
See Also
Tips for working with the APIs
setupCloudMigration
GET setupCloudMigration
POST setupCloudMigration
sourceProductType resource type
2/6/2023 • 2 minutes to read • Edit Online
Represents a source product type in Business Central that can be used for cloud migration. The values can be
used for setupCloudMigration to indicate from which source product to migrate from.
NOTE
For information about enabling APIs for Business Central see guideline.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the sourceProductType resource.
{
"id": "string",
"displayName": "string"
}
See Also
GET sourceProductType
Get sourceProductTypes
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a source product type object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline..
GET businesscentralPrefix/companies({id})/sourceProductTypes({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a sourceProductType object in the response
body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v1.0/companies({id})/sourceProductTypes({id})
Response
Here is an example of the response.
{
"id" : "",
"displayName" : ""
}
See Also
Tips for working with the APIs
sourceProductType
subscriptions resource type
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see guideline.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the subscriptions resource.
{
"subscriptionId": "string",
"notificationUrl": "string",
"resource": "string",
"userId": "GUID",
"lastModifiedDateTime": "datetime",
"clientState": "string",
"expirationDateTime": "datetime",
"systemCreatedAt": "datetime",
"systemCreatedBy": "GUID",
"systemModifiedAt": "datetime",
"systemModifiedBy": "GUID"
}
See Also
GET subscriptions
DELETE subscriptions
POST subscriptions
PATCH subscriptions
Get subscriptions
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a subscriptions object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline..
GET businesscentralPrefix/companies({id})/subscriptions({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a subscriptions object in the response body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v1.0/companies({id})/subscriptions({id})
Response
Here is an example of the response.
{
"subscriptionId" : "",
"notificationUrl" : "",
"resource" : "",
"userId" : "",
"lastModifiedDateTime" : "",
"clientState" : "",
"expirationDateTime" : "",
"systemCreatedAt" : "",
"systemCreatedBy" : "",
"systemModifiedAt" : "",
"systemModifiedBy" : ""
}
See Also
Tips for working with the APIs
subscriptions
DELETE subscriptions
POST subscriptions
PATCH subscriptions
Delete subscriptions
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replaces the URL prefix for Business Central depending on environment following the guideline..
DELETE businesscentralPrefix/companies({id})/subscriptions({id})
Request headers
H EA DER VA L UE
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
subscriptions , the subscriptions will not be updated.
Request body
Do not supply a request body for this method.
Response
If successful, this method returns 204 No Content response code and deletes the subscriptions . It does not
return anything in the response body.
Example
Request
Here is an example of the request.
DELETE https://{businesscentralPrefix}/api/v1.0/companies({id})/subscriptions({id})
Response
Here is an example of the response.
See Also
Tips for working with the APIs
subscriptions
GET subscriptions
POST subscriptions
PATCH subscriptions
Create subscriptions
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline..
POST businesscentralPrefix/companies({id})/subscriptions({id})
Request headers
H EA DER VA L UE
Content-Type application/json
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
subscriptions , the subscriptions will not be updated.
Request body
In the request body, supply a JSON representation of a subscriptions object.
Response
If successful, this method returns 201 Created response code and a subscriptions object in the response body.
Example
Request
Here is an example of the request.
POST https://{businesscentralPrefix}/api/v1.0/companies({id})/subscriptions({id})
Content-type: application/json
{
"subscriptionId" : "",
"notificationUrl" : "",
"resource" : "",
"userId" : "",
"lastModifiedDateTime" : "",
"clientState" : "",
"expirationDateTime" : "",
"systemCreatedAt" : "",
"systemCreatedBy" : "",
"systemModifiedAt" : "",
"systemModifiedBy" : ""
}
Response
Here is an example of the response.
See Also
Tips for working with the APIs
subscriptions
GET subscriptions
DELETE subscriptions
PATCH subscriptions
Update subscriptions
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline..
PATCH businesscentralPrefix/companies({id})/subscriptions({id})
Request headers
H EA DER VA L UE
Content-Type application/json
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
subscriptions , the subscriptions will not be updated.
Request body
In the request body, supply the values for relevant fields that should be updated. Existing properties that are not
included in the request body will maintain their previous values or be recalculated based on changes to other
property values. For best performance you shouldn't include existing values that haven't changed.
Response
If successful, this method returns a 200 OK response code and an updated subscriptions object in the
response body.
Example
Request
Here is an example of the request.
PATCH https://{businesscentralPrefix}/api/v1.0/companies({id})/subscriptions({id})
Content-type: application/json
{
"subscriptionId" : ,
"notificationUrl" :
}
Response
Here is an example of the response.
HTTP/1.1 200 OK
Content-type: application/json
{
"subscriptionId" : ,
"notificationUrl" : ,
"resource" : ,
"userId" : ,
"lastModifiedDateTime" : ,
"clientState" : ,
"expirationDateTime" : ,
"systemCreatedAt" : ,
"systemCreatedBy" : ,
"systemModifiedAt" : ,
"systemModifiedBy" :
}
See Also
Tips for working with the APIs
subscriptions
GET subscriptions
DELETE subscriptions
POST subscriptions
tableMapping resource type
2/6/2023 • 2 minutes to read • Edit Online
Represents a table mapping in Business Central that can be used to include custom tables or tables that are not
included in the cloud migration out of the box. If you provide a table mapping the source table will be copied to
the destination table during cloud migration.
NOTE
For information about enabling APIs for Business Central see guideline.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Bound Actions
The tableMapping resource type offers a bound action called deleteAllForExtension which delete all for
extensions the corresponding tableMapping batch. This is illustrated in the following example:
DELETEALLFOREXTENSION https://<server address>:<server API port>/<server instance
name>/api/v1.0/companies({id})/tableMappings({id})/Microsoft.NAV.deleteAllForExtension
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the tableMapping resource.
{
"id": "GUID",
"tableId": "integer",
"tableName": "string",
"sourceTableName": "string",
"extensionName": "string"
}
See Also
GET tableMapping
DELETE tableMapping
POST tableMapping
PATCH tableMapping
Get tableMappings
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a table mapping object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline..
GET businesscentralPrefix/companies({id})/tableMappings({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a tableMapping object in the response body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v1.0/companies({id})/tableMappings({id})
Response
Here is an example of the response.
{
"id" : "",
"tableId" : "",
"tableName" : "",
"sourceTableName" : "",
"extensionName" : ""
}
See Also
Tips for working with the APIs
tableMapping
DELETE tableMapping
POST tableMapping
PATCH tableMapping
Delete tableMappings
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replaces the URL prefix for Business Central depending on environment following the guideline..
DELETE businesscentralPrefix/companies({id})/tableMappings({id})
Request headers
H EA DER VA L UE
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
tableMapping , the tableMapping will not be updated.
Request body
Do not supply a request body for this method.
Response
If successful, this method returns 204 No Content response code and deletes the tableMapping . It does not
return anything in the response body.
Example
Request
Here is an example of the request.
DELETE https://{businesscentralPrefix}/api/v1.0/companies({id})/tableMappings({id})
Response
Here is an example of the response.
See Also
Tips for working with the APIs
tableMapping
GET tableMapping
POST tableMapping
PATCH tableMapping
Create tableMappings
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline..
POST businesscentralPrefix/companies({id})/tableMappings({id})
Request headers
H EA DER VA L UE
Content-Type application/json
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
tableMapping , the tableMapping will not be updated.
Request body
In the request body, supply a JSON representation of a tableMapping object.
Response
If successful, this method returns 201 Created response code and a tableMapping object in the response body.
Example
Request
Here is an example of the request.
POST https://{businesscentralPrefix}/api/v1.0/companies({id})/tableMappings({id})
Content-type: application/json
{
"id" : "",
"tableId" : "",
"tableName" : "",
"sourceTableName" : "",
"extensionName" : ""
}
Response
Here is an example of the response.
HTTP/1.1 201 Created
Content-type: application/json
{
"id" : "",
"tableId" : "",
"tableName" : "",
"sourceTableName" : "",
"extensionName" : ""
}
See Also
Tips for working with the APIs
tableMapping
GET tableMapping
DELETE tableMapping
PATCH tableMapping
Update tableMappings
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline..
PATCH businesscentralPrefix/companies({id})/tableMappings({id})
Request headers
H EA DER VA L UE
Content-Type application/json
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
tableMapping , the table mapping will not be updated.
Request body
In the request body, supply the values for relevant fields that should be updated. Existing properties that are not
included in the request body will maintain their previous values or be recalculated based on changes to other
property values. For best performance you shouldn't include existing values that haven't changed.
Response
If successful, this method returns a 200 OK response code and an updated tableMapping object in the
response body.
Example
Request
Here is an example of the request.
PATCH https://{businesscentralPrefix}/api/v1.0/companies({id})/tableMappings({id})
Content-type: application/json
{
"id" : ,
"tableId" :
}
Response
Here is an example of the response.
HTTP/1.1 200 OK
Content-type: application/json
{
"id" : ,
"tableId" : ,
"tableName" : ,
"sourceTableName" : ,
"extensionName" :
}
See Also
Tips for working with the APIs
tableMapping
GET tableMapping
DELETE tableMapping
POST tableMapping
accountingPeriod resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
startingDate date
endingDate date
newFiscalYear boolean
fiscalYearStartDate date
fiscalYearEndDate date
closed boolean
JSON representation
Here is a JSON representation of the accountingPeriod resource.
{
"id": "GUID",
"displayName": "string",
"startingDate": "date",
"endingDate": "date",
"newFiscalYear": "boolean",
"fiscalYearStartDate": "date",
"fiscalYearEndDate": "date",
"closed": "boolean",
"lastModifiedDateTime": "datetime"
}
See Also
GET accountingPeriod
Get accountingPeriods (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of an accounting period object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/accountingPeriods({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and an accountingPeriod object in the response
body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/accountingPeriods({id})
Response
Here is an example of the response.
{
"id" : "",
"displayName" : "",
"startingDate" : "",
"endingDate" : "",
"newFiscalYear" : "",
"fiscalYearStartDate" : "",
"fiscalYearEndDate" : "",
"closed" : "",
"lastModifiedDateTime" : ""
}
See Also
Tips for working with the APIs
accountingPeriod
businessUnit resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Navigation
N AVIGAT IO N RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
startingDate date
endingDate date
JSON representation
Here is a JSON representation of the businessUnit resource.
{
"id": "GUID",
"code": "string",
"startingDate": "date",
"endingDate": "date",
"lastModifiedDateTime": "datetime"
}
See Also
GET businessUnit
Get businessUnits (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a business unit object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/businessUnits({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a businessUnit object in the response body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/businessUnits({id})
Response
Here is an example of the response.
{
"id" : "",
"code" : "",
"startingDate" : "",
"endingDate" : "",
"lastModifiedDateTime" : ""
}
See Also
Tips for working with the APIs
businessUnit
company resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Navigation
N AVIGAT IO N RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
timestamp int64
JSON representation
Here is a JSON representation of the company resource.
{
"id": "GUID",
"systemVersion": "string",
"timestamp": "int64",
"name": "string",
"displayName": "string",
"businessProfileId": "string",
"systemCreatedAt": "datetime",
"systemCreatedBy": "GUID",
"systemModifiedAt": "datetime",
"systemModifiedBy": "GUID"
}
See Also
GET company
Get companies (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a company object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/companies({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a company object in the response body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/companies({id})
Response
Here is an example of the response.
{
"id" : "",
"systemVersion" : "",
"timestamp" : "",
"name" : "",
"displayName" : "",
"businessProfileId" : "",
"systemCreatedAt" : "",
"systemCreatedBy" : "",
"systemModifiedAt" : "",
"systemModifiedBy" : ""
}
See Also
Tips for working with the APIs
company
customer resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
type string
salespersonCode string
creditLimit decimal
JSON representation
Here is a JSON representation of the customer resource.
{
"id": "GUID",
"number": "string",
"displayName": "string",
"type": "string",
"city": "string",
"state": "string",
"country": "string",
"postalCode": "string",
"salespersonCode": "string",
"balanceDue": "decimal",
"creditLimit": "decimal",
"currencyCode": "string",
"blocked": "string",
"lastModifiedDateTime": "datetime"
}
See Also
GET customer
Get customers (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a customer object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/customers({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a customer object in the response body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/customers({id})
Response
Here is an example of the response.
{
"id" : "",
"number" : "",
"displayName" : "",
"type" : "",
"city" : "",
"state" : "",
"country" : "",
"postalCode" : "",
"salespersonCode" : "",
"balanceDue" : "",
"creditLimit" : "",
"currencyCode" : "",
"blocked" : "",
"lastModifiedDateTime" : ""
}
See Also
Tips for working with the APIs
customer
customerLedgerEntry resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
balancingAccountType string
open boolean
dimensionSetID integer
amountLocalCurrency decimal
debitAmountLocalCurrency decimal
creditAmountLocalCurrency decimal
JSON representation
Here is a JSON representation of the customerLedgerEntry resource.
{
"entryNumber": "integer",
"documentType": "string",
"description": "string",
"postingDate": "date",
"documentNumber": "string",
"externalDocumentNumber": "string",
"balancingAccountNumber": "string",
"balancingAccountType": "string",
"customerNumber": "string",
"open": "boolean",
"dimensionSetID": "integer",
"currencyCode": "string",
"lastModifiedDateTime": "datetime",
"amount": "decimal",
"debitAmount": "decimal",
"creditAmount": "decimal",
"amountLocalCurrency": "decimal",
"debitAmountLocalCurrency": "decimal",
"creditAmountLocalCurrency": "decimal"
}
See Also
GET customerLedgerEntry
Get customerLedgerEntries (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a customer ledger entry object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/customerLedgerEntries({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a customerLedgerEntr y object in the response
body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/customerLedgerEntries({id})
Response
Here is an example of the response.
{
"entryNumber" : "",
"documentType" : "",
"description" : "",
"postingDate" : "",
"documentNumber" : "",
"externalDocumentNumber" : "",
"balancingAccountNumber" : "",
"balancingAccountType" : "",
"customerNumber" : "",
"open" : "",
"dimensionSetID" : "",
"currencyCode" : "",
"lastModifiedDateTime" : "",
"amount" : "",
"debitAmount" : "",
"creditAmount" : "",
"amountLocalCurrency" : "",
"debitAmountLocalCurrency" : "",
"creditAmountLocalCurrency" : ""
}
See Also
Tips for working with the APIs
customerLedgerEntry
detailedCustomerLedgerEntry resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
entryType string
amountLocalCurrency decimal
debitAmountLocalCurrency decimal
creditAmountLocalCurrency decimal
initialEntryGLobalDim1 string
initialEntryGLobalDim2 string
JSON representation
Here is a JSON representation of the detailedCustomerLedgerEntry resource.
{
"entryNumber": "integer",
"entryType": "string",
"customerNumber": "string",
"amount": "decimal",
"debitAmount": "decimal",
"creditAmount": "decimal",
"amountLocalCurrency": "decimal",
"debitAmountLocalCurrency": "decimal",
"creditAmountLocalCurrency": "decimal",
"initialEntryGLobalDim1": "string",
"initialEntryGLobalDim2": "string",
"postingDate": "date",
"currencyCode": "string",
"lastModifiedDateTime": "datetime"
}
See Also
GET detailedCustomerLedgerEntry
Get detailedCustomerLedgerEntries (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a detailed customer ledger entry object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/detailedCustomerLedgerEntries({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a detailedCustomerLedgerEntr y object in the
response body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/detailedCustomerLedgerEntries({id})
Response
Here is an example of the response.
{
"entryNumber" : "",
"entryType" : "",
"customerNumber" : "",
"amount" : "",
"debitAmount" : "",
"creditAmount" : "",
"amountLocalCurrency" : "",
"debitAmountLocalCurrency" : "",
"creditAmountLocalCurrency" : "",
"initialEntryGLobalDim1" : "",
"initialEntryGLobalDim2" : "",
"postingDate" : "",
"currencyCode" : "",
"lastModifiedDateTime" : ""
}
See Also
Tips for working with the APIs
detailedCustomerLedgerEntry
detailedVendorLedgerEntry resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
entryType string
amountLocalCurrency decimal
debitAmountLocalCurrency decimal
creditAmountLocalCurrency decimal
initialEntryGLobalDim1 string
initialEntryGLobalDim2 string
JSON representation
Here is a JSON representation of the detailedVendorLedgerEntry resource.
{
"entryNumber": "integer",
"entryType": "string",
"vendorNumber": "string",
"amount": "decimal",
"debitAmount": "decimal",
"creditAmount": "decimal",
"amountLocalCurrency": "decimal",
"debitAmountLocalCurrency": "decimal",
"creditAmountLocalCurrency": "decimal",
"initialEntryGLobalDim1": "string",
"initialEntryGLobalDim2": "string",
"postingDate": "date",
"currencyCode": "string",
"lastModifiedDateTime": "datetime"
}
See Also
GET detailedVendorLedgerEntry
Get detailedVendorLedgerEntries (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a detailed vendor ledger entry object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/detailedVendorLedgerEntries({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a detailedVendorLedgerEntr y object in the
response body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/detailedVendorLedgerEntries({id})
Response
Here is an example of the response.
{
"entryNumber" : "",
"entryType" : "",
"vendorNumber" : "",
"amount" : "",
"debitAmount" : "",
"creditAmount" : "",
"amountLocalCurrency" : "",
"debitAmountLocalCurrency" : "",
"creditAmountLocalCurrency" : "",
"initialEntryGLobalDim1" : "",
"initialEntryGLobalDim2" : "",
"postingDate" : "",
"currencyCode" : "",
"lastModifiedDateTime" : ""
}
See Also
Tips for working with the APIs
detailedVendorLedgerEntry
dimensionSetEntry resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Navigation
N AVIGAT IO N RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
setId integer
dimensionDisplayName string
dimensionValueDisplayName string
dimensionValueId integer
JSON representation
Here is a JSON representation of the dimensionSetEntry resource.
{
"id": "GUID",
"setId": "integer",
"dimensionCode": "string",
"dimensionDisplayName": "string",
"dimensionValueCode": "string",
"dimensionValueDisplayName": "string",
"dimensionValueId": "integer",
"lastModifiedDateTime": "datetime"
}
See Also
GET dimensionSetEntry
Get dimensionSetEntries (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a dimension set entry object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/dimensionSetEntries({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a dimensionSetEntr y object in the response
body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/dimensionSetEntries({id})
Response
Here is an example of the response.
{
"id" : "",
"setId" : "",
"dimensionCode" : "",
"dimensionDisplayName" : "",
"dimensionValueCode" : "",
"dimensionValueDisplayName" : "",
"dimensionValueId" : "",
"lastModifiedDateTime" : ""
}
See Also
Tips for working with the APIs
dimensionSetEntry
dimensionValue resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Navigation
N AVIGAT IO N RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
dimensionValueName string
dimensionValueId integer
dimensionValueType string
consolidationCode string
P RO P ERT Y TYPE DESC RIP T IO N
globalDimensionNumber integer
JSON representation
Here is a JSON representation of the dimensionValue resource.
{
"id": "GUID",
"dimensionCode": "string",
"dimensionValueCode": "string",
"dimensionValueName": "string",
"dimensionValueId": "integer",
"dimensionValueType": "string",
"blocked": "boolean",
"indentation": "integer",
"consolidationCode": "string",
"globalDimensionNumber": "integer",
"lastModifiedDateTime": "datetime"
}
See Also
GET dimensionValue
Get dimensionValues (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a dimension value object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/dimensionValues({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a dimensionValue object in the response body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/dimensionValues({id})
Response
Here is an example of the response.
{
"id" : "",
"dimensionCode" : "",
"dimensionValueCode" : "",
"dimensionValueName" : "",
"dimensionValueId" : "",
"dimensionValueType" : "",
"blocked" : "",
"indentation" : "",
"consolidationCode" : "",
"globalDimensionNumber" : "",
"lastModifiedDateTime" : ""
}
See Also
Tips for working with the APIs
dimensionValue
generalBudgetEntry resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
number integer
budgetName string
businessUnitCode string
accountNo string
generalLedgerAccountNumber string
dimensionSetID integer
globalDimension1Code string
globalDimension2Code string
budgetDimension1Code string
P RO P ERT Y TYPE DESC RIP T IO N
budgetDimension2Code string
budgetDimension3Code string
budgetDimension4Code string
JSON representation
Here is a JSON representation of the generalBudgetEntry resource.
{
"id": "GUID",
"number": "integer",
"description": "string",
"budgetName": "string",
"businessUnitCode": "string",
"date": "date",
"accountNo": "string",
"amount": "decimal",
"generalLedgerAccountNumber": "string",
"dimensionSetID": "integer",
"globalDimension1Code": "string",
"globalDimension2Code": "string",
"budgetDimension1Code": "string",
"budgetDimension2Code": "string",
"budgetDimension3Code": "string",
"budgetDimension4Code": "string",
"lastModifiedDateTime": "datetime"
}
See Also
GET generalBudgetEntry
Get generalBudgetEntries (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a general budget entry object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/generalBudgetEntries({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a generalBudgetEntr y object in the response
body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/generalBudgetEntries({id})
Response
Here is an example of the response.
{
"id" : "",
"number" : "",
"description" : "",
"budgetName" : "",
"businessUnitCode" : "",
"date" : "",
"accountNo" : "",
"amount" : "",
"generalLedgerAccountNumber" : "",
"dimensionSetID" : "",
"globalDimension1Code" : "",
"globalDimension2Code" : "",
"budgetDimension1Code" : "",
"budgetDimension2Code" : "",
"budgetDimension3Code" : "",
"budgetDimension4Code" : "",
"lastModifiedDateTime" : ""
}
See Also
Tips for working with the APIs
generalBudgetEntry
generalLedgerAccount resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Navigation
N AVIGAT IO N RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
accountName string
accountCategory string
accountSubcategoryEntryNumber integer
accountSubcategoryDescription string
incomeBalance string
budgetFilter string
businessUnitFilter string
parentAccountNumber string
JSON representation
Here is a JSON representation of the generalLedgerAccount resource.
{
"id": "GUID",
"accountNumber": "string",
"accountName": "string",
"accountType": "string",
"accountCategory": "string",
"accountSubcategoryEntryNumber": "integer",
"accountSubcategoryDescription": "string",
"indentation": "integer",
"netChange": "decimal",
"incomeBalance": "string",
"budgetFilter": "string",
"businessUnitFilter": "string",
"parentAccountNumber": "string",
"lastModifiedDateTime": "datetime"
}
See Also
GET generalLedgerAccount
Get generalLedgerAccounts (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a general ledger account object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/generalLedgerAccounts({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a generalLedgerAccount object in the
response body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/generalLedgerAccounts({id})
Response
Here is an example of the response.
{
"id" : "",
"accountNumber" : "",
"accountName" : "",
"accountType" : "",
"accountCategory" : "",
"accountSubcategoryEntryNumber" : "",
"accountSubcategoryDescription" : "",
"indentation" : "",
"netChange" : "",
"incomeBalance" : "",
"budgetFilter" : "",
"businessUnitFilter" : "",
"parentAccountNumber" : "",
"lastModifiedDateTime" : ""
}
See Also
Tips for working with the APIs
generalLedgerAccount
generalLedgerBudgets resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
budgetDimension1Code string
budgetDimension2Code string
budgetDimension3Code string
budgetDimension4Code string
JSON representation
Here is a JSON representation of the generalLedgerBudgets resource.
{
"id": "GUID",
"displayName": "string",
"description": "string",
"blocked": "boolean",
"budgetDimension1Code": "string",
"budgetDimension2Code": "string",
"budgetDimension3Code": "string",
"budgetDimension4Code": "string",
"lastModifiedDateTime": "datetime"
}
See Also
GET generalLedgerBudgets
Get generalLedgerBudgets (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a general ledger budgets object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/generalLedgerBudgets({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a generalLedgerBudgets object in the
response body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/generalLedgerBudgets({id})
Response
Here is an example of the response.
{
"id" : "",
"displayName" : "",
"description" : "",
"blocked" : "",
"budgetDimension1Code" : "",
"budgetDimension2Code" : "",
"budgetDimension3Code" : "",
"budgetDimension4Code" : "",
"lastModifiedDateTime" : ""
}
See Also
Tips for working with the APIs
generalLedgerBudgets
generalLedgerEntry resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
number integer
businessUnitCode string
reveresd boolean
sourceType string
sourceNumber string
sourceCode string
P RO P ERT Y TYPE DESC RIP T IO N
vatAmount decimal
additionalCurrencyAmount decimal
dimensionSetID integer
globalDimension1Code string
globalDimension2Code string
JSON representation
Here is a JSON representation of the generalLedgerEntry resource.
{
"id": "GUID",
"number": "integer",
"description": "string",
"postingDate": "date",
"accountNumber": "string",
"businessUnitCode": "string",
"reveresd": "boolean",
"documentNumber": "string",
"externalDocumentNumber": "string",
"sourceType": "string",
"sourceNumber": "string",
"sourceCode": "string",
"amount": "decimal",
"debitAmount": "decimal",
"creditAmount": "decimal",
"vatAmount": "decimal",
"additionalCurrencyAmount": "decimal",
"dimensionSetID": "integer",
"globalDimension1Code": "string",
"globalDimension2Code": "string",
"lastModifiedDateTime": "datetime"
}
See Also
GET generalLedgerEntry
Get generalLedgerEntries (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a general ledger entry object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/generalLedgerEntries({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a generalLedgerEntr y object in the response
body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/generalLedgerEntries({id})
Response
Here is an example of the response.
{
"id" : "",
"number" : "",
"description" : "",
"postingDate" : "",
"accountNumber" : "",
"businessUnitCode" : "",
"reveresd" : "",
"documentNumber" : "",
"externalDocumentNumber" : "",
"sourceType" : "",
"sourceNumber" : "",
"sourceCode" : "",
"amount" : "",
"debitAmount" : "",
"creditAmount" : "",
"vatAmount" : "",
"additionalCurrencyAmount" : "",
"dimensionSetID" : "",
"globalDimension1Code" : "",
"globalDimension2Code" : "",
"lastModifiedDateTime" : ""
}
See Also
Tips for working with the APIs
generalLedgerEntry
subscriptions resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
timestamp int64
JSON representation
Here is a JSON representation of the subscriptions resource.
{
"subscriptionId": "string",
"notificationUrl": "string",
"resource": "string",
"timestamp": "int64",
"userId": "GUID",
"lastModifiedDateTime": "datetime",
"clientState": "string",
"expirationDateTime": "datetime",
"systemCreatedAt": "datetime",
"systemCreatedBy": "GUID",
"systemModifiedAt": "datetime",
"systemModifiedBy": "GUID"
}
See Also
GET subscriptions DELETE subscriptions POST subscriptions PATCH subscriptions
Get subscriptions (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a subscriptions object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/subscriptions({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a subscriptions object in the response body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/subscriptions({id})
Response
Here is an example of the response.
{
"subscriptionId" : "",
"notificationUrl" : "",
"resource" : "",
"timestamp" : "",
"userId" : "",
"lastModifiedDateTime" : "",
"clientState" : "",
"expirationDateTime" : "",
"systemCreatedAt" : "",
"systemCreatedBy" : "",
"systemModifiedAt" : "",
"systemModifiedBy" : ""
}
See Also
Tips for working with the APIs
subscriptions
DELETE subscriptions
POST subscriptions
PATCH subscriptions
Delete subscriptions (Beta)
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replaces the URL prefix for Business Central depending on environment following the guideline.
DELETE businesscentralPrefix/companies({id})/subscriptions({id})
Request headers
H EA DER VA L UE
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
subscriptions , the subscriptions will not be updated.
Request body
Do not supply a request body for this method.
Response
If successful, this method returns 204 No Content response code and deletes the subscriptions . It does not
return anything in the response body.
Example
Request
Here is an example of the request.
DELETE https://{businesscentralPrefix}/api/v2.0/companies({id})/subscriptions({id})
Response
Here is an example of the response.
See Also
Tips for working with the APIs
subscriptions
GET subscriptions
POST subscriptions
PATCH subscriptions
Create subscriptions (Beta)
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
POST businesscentralPrefix/companies({id})/subscriptions({id})
Request headers
H EA DER VA L UE
Content-Type application/json
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
subscriptions , the subscriptions will not be updated.
Request body
In the request body, supply a JSON representation of a subscriptions object.
Response
If successful, this method returns 201 Created response code and a subscriptions object in the response body.
Example
Request
Here is an example of the request.
POST https://{businesscentralPrefix}/api/v2.0/companies({id})/subscriptions({id})
Content-type: application/json
{
"subscriptionId" : "",
"notificationUrl" : "",
"resource" : "",
"timestamp" : "",
"userId" : "",
"lastModifiedDateTime" : "",
"clientState" : "",
"expirationDateTime" : "",
"systemCreatedAt" : "",
"systemCreatedBy" : "",
"systemModifiedAt" : "",
"systemModifiedBy" : ""
}
Response
Here is an example of the response.
See Also
Tips for working with the APIs
subscriptions
GET subscriptions
DELETE subscriptions
PATCH subscriptions
Update subscriptions (Beta)
2/6/2023 • 2 minutes to read • Edit Online
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
PATCH businesscentralPrefix/companies({id})/subscriptions({id})
Request headers
H EA DER VA L UE
Content-Type application/json
If-Match Required. When this request header is included and the eTag
provided does not match the current tag on the
subscriptions , the subscriptions will not be updated.
Request body
In the request body, supply the values for relevant fields that should be updated. Existing properties that are not
included in the request body will maintain their previous values or be recalculated based on changes to other
property values. For best performance you shouldn't include existing values that haven't changed.
Response
If successful, this method returns a 200 OK response code and an updated subscriptions object in the
response body.
Example
Request
Here is an example of the request.
PATCH https://{businesscentralPrefix}/api/v2.0/companies({id})/subscriptions({id})
Content-type: application/json
{
"subscriptionId" : ,
"notificationUrl" :
}
Response
Here is an example of the response.
HTTP/1.1 200 OK
Content-type: application/json
{
"subscriptionId" : ,
"notificationUrl" : ,
"resource" : ,
"timestamp" : ,
"userId" : ,
"lastModifiedDateTime" : ,
"clientState" : ,
"expirationDateTime" : ,
"systemCreatedAt" : ,
"systemCreatedBy" : ,
"systemModifiedAt" : ,
"systemModifiedBy" :
}
See Also
Tips for working with the APIs
subscriptions
GET subscriptions
DELETE subscriptions
POST subscriptions
vendor resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
JSON representation
Here is a JSON representation of the vendor resource.
{
"id": "GUID",
"number": "string",
"displayName": "string",
"city": "string",
"state": "string",
"country": "string",
"postalCode": "string",
"currencyCode": "string",
"paymentTermsId": "GUID",
"paymentMethodId": "GUID",
"taxLiable": "boolean",
"blocked": "string",
"balance": "decimal",
"lastModifiedDateTime": "datetime"
}
See Also
GET vendor
Get vendors (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a vendor object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/vendors({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a vendor object in the response body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/vendors({id})
Response
Here is an example of the response.
{
"id" : "",
"number" : "",
"displayName" : "",
"city" : "",
"state" : "",
"country" : "",
"postalCode" : "",
"currencyCode" : "",
"paymentTermsId" : "",
"paymentMethodId" : "",
"taxLiable" : "",
"blocked" : "",
"balance" : "",
"lastModifiedDateTime" : ""
}
See Also
Tips for working with the APIs
vendor
vendorLedgerEntry resource type (Beta)
2/6/2023 • 2 minutes to read • Edit Online
NOTE
For information about enabling APIs for Business Central see Enabling the APIs for Dynamics 365 Business Central.
Methods
M ET H O D RET URN T Y P E DESC RIP T IO N
Properties
P RO P ERT Y TYPE DESC RIP T IO N
balancingAccountType string
open boolean
dimensionSetID integer
amountLocalCurrency decimal
debitAmountLocalCurrency decimal
creditAmountLocalCurrency decimal
JSON representation
Here is a JSON representation of the vendorLedgerEntry resource.
{
"entryNumber": "integer",
"documentType": "string",
"description": "string",
"postingDate": "date",
"documentNumber": "string",
"externalDocumentNumber": "string",
"balancingAccountNumber": "string",
"balancingAccountType": "string",
"vendorNumber": "string",
"open": "boolean",
"dimensionSetID": "integer",
"currencyCode": "string",
"lastModifiedDateTime": "datetime",
"amount": "decimal",
"debitAmount": "decimal",
"creditAmount": "decimal",
"amountLocalCurrency": "decimal",
"debitAmountLocalCurrency": "decimal",
"creditAmountLocalCurrency": "decimal"
}
See Also
GET vendorLedgerEntry
Get vendorLedgerEntries (Beta)
2/6/2023 • 2 minutes to read • Edit Online
Retrieves the properties and relationships of a vendor ledger entry object for Business Central.
HTTP request
Replace the URL prefix for Business Central depending on environment following the guideline.
GET businesscentralPrefix/companies({id})/vendorLedgerEntries({id})
Request headers
H EA DER VA L UE
Request body
Do not supply a request body for this method.
Response
If successful, this method returns a 200 OK response code and a vendorLedgerEntr y object in the response
body.
Example
Request
Here is an example of the request.
GET https://{businesscentralPrefix}/api/v2.0/companies({id})/vendorLedgerEntries({id})
Response
Here is an example of the response.
{
"entryNumber" : "",
"documentType" : "",
"description" : "",
"postingDate" : "",
"documentNumber" : "",
"externalDocumentNumber" : "",
"balancingAccountNumber" : "",
"balancingAccountType" : "",
"vendorNumber" : "",
"open" : "",
"dimensionSetID" : "",
"currencyCode" : "",
"lastModifiedDateTime" : "",
"amount" : "",
"debitAmount" : "",
"creditAmount" : "",
"amountLocalCurrency" : "",
"debitAmountLocalCurrency" : "",
"creditAmountLocalCurrency" : ""
}
See Also
Tips for working with the APIs
vendorLedgerEntry
Migrate On-Premises Data to Business Central
Online
2/6/2023 • 24 minutes to read • Edit Online
Organizations that run their workloads on-premises but are looking to move to the cloud can easily migrate to
Business Central online. By moving to the cloud, users get the benefits of cloud scenarios such as Machine
Learning, Power BI, Power Automate, and others to drive suggested actions.
If you're not already familiar with Business Central online, take a look here.
TIP
If you are currently on a version of Dynamics NAV, you must upgrade to Business Central on-premises, and then switch to
Business Central online. For more information, see Upgrading from Dynamics NAV to Business Central online.
If a customer is coming from another product, you can use configuration packages and templates to migrate
their data to Business Central on-premises, and then use the cloud migration tool to switch to Business Central
online. For more information, see Set Up Company Configuration Packages.
TIP
Customers coming from QuickBooks can use apps from Microsoft to move to Business Central online. For more
information, see Changing from a QuickBooks App to Dynamics 365 Business Central.
Prerequisites
The customer must have a Business Central online tenant
The person who runs the migration must be signed in as an administrator of the Microsoft 365 tenant
and Business Central online
The on-premises solution must be on the list of supported migration paths
If the solution is based on an older version of the on-premises product, upgrade to the latest
supported version
The on-premises database must be ready
The on-premises solution must use SQL Server 2016 SP1 or later
The database must have compatibility level 130 or higher
Update statistics and reorganize indexes on all tables on the source database
This will ensure that the migration runs as fast as possible. For more information, see the
documentation for sp_updatestats (Transact-SQL) and Resolve index fragmentation by
reorganizing or rebuilding indexes.
At least one user has SUPER permissions in the target company in Business Central online.
This is the only user who can make changes in Business Central online. All users that don't have SUPER
permissions will be automatically reassigned to the intelligent cloud user group. This will limit them to
read-only access to data in Business Central online. For more information, se the Business Central
permission sets section.
Consider reducing the amount of data that you migrate.
You can migrate the data that you want to take with you to the cloud. If you need more storage than the
default 80 GB, you can buy additional environments or additional storage capacity. We recommend that
you consider reducing the amount of data that you migrate so that it is less than 30 GB in each migration
run. For example, reduce the number of companies that you are migrating data for, or delete outdated
data in tables that contain log entries and archived records. Also, review how you can manage database
capacity in a Business Central online environment.
You can specify which companies to include in the migration in the assisted setup guide, and you can
view the migration status of each company in the Cloud Migration Management page.
If you want to add more companies after the first selection of companies, you can add more companies in
the Cloud Migration Management page in Business Central online. For more information, see Run the
tool multiple times. But use the Capacity section of the Business Central administration center to keep
track of how much data you migrate.
TIP
On page 9035 Data Administration , you can find reports that are used to compress or cleanup the data. In
earlier Business Central versions, the page may not be present. However, most reports can be found using Search
.
In certain cases, the customer wants to migrate large amounts of data. For large source databases, we
recommend deploying the source database to an Azure SQL Database, and then setting up cloud
migration from Azure SQL source instead of the on-premise SQL Server. This eliminates the need to
install and maintain self-hosted integration runtime on-premise, and ensures much faster data
replication.
Deploying to Azure SQL can be an easy and quick process if done in SQL Server Management Studio
connected to the on-premise database. Follow the Deploy Database to Microsoft Azure SQL
Database wizard, which you find in the Tasks context menu on the database. When prompted to choose
a service tier for the new Azure SQL database, remember that the lowest configurations may not be
adequate for migrating large amounts of data. Consider the right balance between performance and
price that would be preferable in your case. The database service tier can be tuned later in Azure Portal.
We continually work on improving and optimizing the migration tool for larger database sizes. For
example, customers can buy more environments, and they can buy extra storage. For more information,
see Managing Capacity. If more assistance is required, contact support as described in Escalating support
issues to Microsoft.
There are no firm limits on the size of the database, the number of daily transactions, or the number of
users that can migrate from on-premises to Business Central online.
To help you test the migration, you can migrate data to the target production environment, and then
create a sandbox environment based on this production environment. For Business Central on-premises,
first use the data replication step in the production environment, and then run the data upgrade step in
the sandbox environment for safe testing before you run the data upgrade step in the production
environment.
IMPORTANT
Only run the data migration into a single environment. Don't reuse the same on-premises database for multiple
data migrations—restore a fresh backup of the database. You have the option of migrating to a sandbox, copying
to another sandbox, and testing upgrade there. If successful, you can then copy the upgraded sandbox to the
production environment and delete all other environments.
Plan the switch to use Business Central online for production carefully to not start until migration is
complete
IMPORTANT
Do not set up cloud migration for a production environment that is already in use for business. You risk that the
migration process overwrites data that is needed to run the business. Even if your migration targets a different
company in that environment, you risk that the upgrade overwrites data that is shared across companies in the
target environment.
Schedule the migration to not conflict with an update of Business Central online
If you set up cloud migration for an environment, the environment cannot be upgraded. If you want to
upgrade the environment, you must disable cloud migration. If you want to move more companies, set
up cloud migration again once the upgrade is complete. By separating upgrade from cloud migration, we
remove the risk of potentially corrupting data if the upgrade touches tables with records in both migrated
and non-migrated companies. Upgrade the target environment first, then migrate.
Install the migration apps in Business Central
In the Business Central administration center, open the environment that you intend to migrate your data
to, and then choose the Apps action. Make sure that these apps have the latest updates installed:
Intelligent Cloud Base
Business Central Intelligent Cloud
IMPORTANT
In Business Central online, install, publish, or upgrade the Intelligent Cloud Base extension first, and then the
product-specific extension or extensions.
If you're migrating from an earlier supported version of Business Central, you must also make sure that
the following apps are updated:
Business Central Cloud Migration – Previous Release
Business Central Cloud Migration – Previous Release [code for your country-specific version]
Also, at the end of the upgrade, you must make sure that the applicationVersion field in the
ndo$tenantdatabaseproperty table is set to the right version. If the field is blank, or if it's set to an older
version than the migration tool supports, the migration can't run. For more information, see Post-
upgrade tasks.
If you're migrating from Dynamics GP, make sure that the following apps are installed and updated:
Dynamics GP Intelligent Cloud
Dynamics GP History SmartLists
IMPORTANT
Migrating from Dynamics GP using the Cloud Migration Setup assisted setup guide is currently only
supported for the following markets:
United States
Canada
United Kingdom
Australia
If you want to migrate from another product, check the marketplace for an app to help.
Test extensions
It's highly recommended that you test the impact of any extension in a sandbox environment before
having it installed in your production environment in Business Central online to help avoid any data
failures or untended consequences.
End-to-end process
You manage cloud migration from Business Central online. But the on-premises solution remains the operative
environment until you complete the migration. Do not set up cloud migration for a production environment that
is already in use for business. You risk that the migration process overwrites data that is needed to run the
business. Even if your migration targets a different company in that environment, you risk that the upgrade
overwrites data that is shared across companies in the target environment.
Any existing data in Business Central online will be overwritten with data from your on-premises solution, or
source, once the data migration process is run.
If you don't want data in Business Central online to be overwritten, don't configure the connection. The only
exception is when you migrate from Business Central on-premises current version because you can run the
migration tool multiple times in that specific scenario.
If your data source is Business Central on-premises, several stored procedures will be added to the SQL Server
instance that you define. These stored procedures are required to migrate data from your SQL Server database
to the Azure SQL server associated with your Business Central tenant.
The main steps in a migration process are:
1. Have a target environment with a paid subscription
2. Determine which data to migrate
For Business Central on-premises, determine which companies to migrate and the number of
migration runs to use to migrate the required data
For Dynamics GP, you can use the migration process to move historical data to Azure Data Lake
For Dynamics NAV, upgrade to Business Central on-premises first, and then migrate
3. Migrate data, using the Cloud Migration Setup assisted setup guide in Business Central online
4. Test the result of the migration
5. Set up users, permissions, and other configurations in Business Central online
6. Stop using the on-premises solution, switch off the migration, and tell users to start using Business
Central online for daily business
TIP
Meanwhile, users can train themselves in how to work in Business Central using a sandbox environment and the free
training modules on Microsoft Learn.
Migrate data
Data migration is the process of securely migrating data from an on-premises SQL Server instance (or Azure
SQL) to Business Central online. The process uses the Azure Data Factory (ADF) to migrate the data between
databases directly, meaning it doesn't look at any permissions within the applications you're transferring data
between, only SQL permissions.
Data is migrated table by table, and success and failures are tracked for each table. If a table fails to migrate, the
error will be captured, and the migration moves on to the next table until completed. Tables will fail to migrate if
they can't be found, or if the schema doesn't match between the cloud and the on-premises tables.
The initial data migration time can vary depending on factors such as the amount of data to migrate, your SQL
Server configuration, and your connection speeds. The initial migration will take the longest amount of time to
complete because all data is migrating. After the initial migration, only changes in data will be migrated, so each
iteration runs more quickly. You don't need to run the migration process more than once if you don't want to.
However, if you're running the migration while users are still using the on-premises system, you must run at
least one more migration in order to ensure all data was moved to the cloud before you start transacting in
Business Central online.
IMPORTANT
Do not set up cloud migration for a production environment that is already in use for business. You risk that the
migration process overwrites data that is needed to run the business. Even if your migration targets a different company
in that environment, you risk that the upgrade overwrites data that is shared across companies in the target
environment.
IMPORTANT
You must be signed in as an administrator of the Microsoft 365 tenant as well as Business Central online.
If the user running this flow is a delegated administrator, they must receive approval from a licensed user with
either the Essentials or the Premium license and SUPER permissions in order to run the cloud migration. In this
case, the Data Migration Setup guide will display an extra step, where the delegated administrator can copy
the auto-generated approval link and send it to the licensed user for approval. Once the licensed user has
approved the request, the delegated administrator can continue with the setup of the cloud migration and
perform all other steps required to complete that process. The licensed user can always revoke the permission
to run the migration by choosing the same approval link that was shared by the delegated administrator, or
from the Cloud Migration Approval page.
TIP
We recommend that you start the migration by running the assisted setup from a company other than the company that
you are migrating data to. For example, sign into the demonstration company, CRONUS, and start the process there. This
way, you can make sure that all users are logged out of the original company and the target company. This is especially
important when you migrate from Business Central on-premises current version because you can run the migration tool
multiple times.
IMPORTANT
Do not set up cloud migration for a production environment that is already in use for business. You risk that the
migration process overwrites data that is needed to run the business. Even if your migration targets a different company
in that environment, you risk that the upgrade overwrites data that is shared across companies in the target
environment.
Once the setup guide is complete and data migration is activated, the initial data migration ready to be run from
the Cloud Migration Management page whenever you want. Go to Manage the Migration.
TIP
You can migrate the data that you want to take with you to the cloud. If you need more storage than the default 80 GB,
you can buy additional environments or additional storage capacity. We recommend that you consider reducing the
amount of data that you migrate so that it is less than 30 GB in each migration run. For example, reduce the number of
companies that you are migrating data for, or delete outdated data in tables that contain log entries and archived records.
Also, review how you can manage database capacity in a Business Central online environment.
IMPORTANT
Azure SQL Managed Instance is not supported.
IMPORTANT
In the second connection string format, don't forget to add the space in User Id parameter as it's mandatory and
can throw an error if it's missing.
The SQL connection string is passed to Azure Data Factory (ADF), where it's encrypted and delivered to
your Self-Hosted Integration Runtime and used to communicate with your SQL Server instance during
the data migration process.
Integration runtime name
If your SQL connection is SQL Server, you must specify the runtime service that will be used to replicate
the data from the defined source to Business Central online. The integration runtime must be running on
the machine that holds the SQL Server database. If you don't already have a runtime service, leave the
field empty, and then choose the Next button.
If you leave the Integration runtime name field empty, a new page appears from where you can
download the self-hosted integration runtime that you must install. Follow the instructions on the page.
Hover over a field to read a short description.
Once you choose Next , a new pipeline will be created in the Azure service. This takes less than a minute to
complete, in most cases. If you want to test your SQL string, open the Microsoft Integration Runtime
Configuration Manager , and then choose the Diagnostics menu option. From there, you can test to see if
the connection is good.
A C T IO N DESC RIP T IO N
A C T IO N DESC RIP T IO N
Run Migration Now Choose this action to start the data migration manually. The
migration can also be used for subsequent runs after the
initial migration. On subsequent runs, the migration tool will
only migrate changes that have happened since the previous
migration was run. Change tracking is used to identify what
data should be moved in those subsequent runs. However,
the migration tool can't run if the target environment is
being upgraded. In that case, you must disable cloud
migration, upgrade, and then set up cloud migration again.
Run Data Upgrade Now Choose this action to upgrade data, such as if you're
migrating data from an earlier version to the latest version
of Business Central.
Reset Cloud Data You may run into instances where you need to reset your
cloud data. This option will clear all data in your cloud tenant
and enable you to start over with data migration. Only run
this process if you want to start the migration process all
over from the beginning. If you need to clear data in your
cloud tenant, and you have connectivity issues that persist
for more than 7 days, you must contact customer support.
They'll create a ticket to have your tenant data cleared. Only
run this process if you want to start the data migration all
over and bring all data from on-premises to your cloud
tenant.
Reset Runtime Service Key If at any time you suspect that your Self-Hosted Integration
Runtime key is no longer secure, you can choose this option
to regenerate a new key. A new key will be generated for
you and automatically be updated in the Self-Host
Integration Runtime service.
Disable Cloud Migration Opens a guide that helps you through a checklist of
instructions to disable the cloud migration configuration.
Use the guide when you've migrated the data that you want
to migrate, or when you want to upgrade the target
environment. Once the steps in this process are complete,
you can use your Business Central online tenant as your
primary solution, or you can upgrade the environment.
Check for Update If there have been changes to the migration service, we'll
publish the new service. This action will check to see if a new
service has been published. The check will display the version
of the service you're currently running and then also display
the latest service published. Then, you can choose to update
your solution. We recommend that you update the solution
if a newer version has been published.
A C T IO N DESC RIP T IO N
Select Companies to Migrate If your database contains more than one company, use this
action to specify which company or companies to run a
migration for. For example, you're migrating a large database
with multiple companies, so you break down the migration
in several runs by including one or a few companies in each
migration run. You can see the estimated size of each
company
Define User Mappings This option is available when you sign in to a particular
company that has been migrated. This action should be
done in one of the companies you've migrated. This action
gives you a list of the users that were in your on-premises
environment, and then gives you a list of your Microsoft 365
users, so that you can map the two together. This process
renames the Name field on the User Card to match the
user name in your on-premises solution. It isn't a required
step, but if you use some of the processes in Business
Central that work with the user name, such as time sheets,
you may want to map users. Time sheets are visible based
on the user name you're logged in as in Business Central.
Map users only once for each migration. If you run the
mapping twice or more, you might run into conflicts.
Setup Checklist When you're ready to use your Business Central online
tenant as your main system, the tables that weren't
migrated must be set up or defined as needed. The checklist
page shows recommended steps to complete your migration
to the cloud.
Azure Data Lake This option is available if the Business Central online tenant
is connected to Dynamics GP. For more information, see
Migrate Dynamics GP to Azure Data Lake.
TIP
We recommend that you take a backup of the target environment so that you can easily restore the environment to a
specific state and time, should you want to.
TIP
If you are using Business Central on-premises, the same setup guide is also available in your on-premises solution. You
will automatically be redirected to your Business Central online to continue the configuration process.
Cau t i on
If you have mapped users in the first run of the cloud migration setup guide, then do not choose the Define
User Mappings action again in subsequent runs.
NOTE
Before you configure a connection from on-premises to Business Central online, make sure that at least one user in each
company is assigned SUPER permissions.
Users that are reassigned to the Intelligent Cloud user group will have access to read ALL data by default. If you
need to further restrict what data a user should be able to read, the SUPER user may create new user groups
and permissions sets and assign users accordingly. It's highly recommended to create any new permissions sets
from a copy of the Intelligent Cloud permission set and then take away permissions you don't want users to
have.
WARNING
If you grant insert, modify or delete permissions to any resource in the application that was set to read-only, it could have
a negative impact on the data in Business Central online. If this occurs, you may have to clear all your data and rerun a
full migration to correct this.
Company initialization
When a company is created in Business Central, it must be initialized to ensure it's accessible and functional for
everyone who needs to use it. If you're familiar with Dynamics NAV, then you're used to this step happening
automatically during the upgrade process, for example. But it's not quite the same with Business Central online.
When a migration run completes, you're prompted to view a list of non-initialized companies so that you can
start the initialization. You can choose to mark a company as already initialized, such as if it was initialized in an
earlier migration run. Technically, the initialization runs as a scheduled task in the job queue, and the status is
automatically updated in the list of companies when a task completes.
NOTE
When you schedule an initialization in the Hybrid Companies list, we recommend not using the company until its
initialized. The setup data could be missing, which might cause problems.
NOTE
The amount of time the migration will take to complete depends on the amount of data, your SQL configuration, and
your connection speed. Subsequent migrations will complete more quickly because only changed data is migrating.
IMPORTANT
If you set up cloud migration for an environment, the environment cannot be upgraded. If you want to upgrade the
environment, you must disable cloud migration. If you want to move more companies, set up cloud migration again once
the upgrade is complete. By separating upgrade from cloud migration, we remove the risk of potentially corrupting data if
the upgrade touches tables with records in both migrated and non-migrated companies. Upgrade the target environment
first, then migrate.
See also
FAQ about Migrating to the Cloud from On-Premises Solutions
Migrate to Business Central Online from Business Central On-premises
Migrate Dynamics GP Data to the Cloud
Upgrading from Dynamics NAV to Business Central Online
Managing Capacity
Migrate to Business Central Online from Business
Central On-premises
2/6/2023 • 5 minutes to read • Edit Online
The end-to-end process is described here. In this article, we talk about background information and things to
take into consideration.
The migration from Business Central on-premises is in two separate steps:
Data replication
This step starts when you run the Set up Cloud Migration assisted setup guide in Business Central
online. At the end of the process, you have a copy of the on-premises data in the relevant environment in
Business Central online so that you can verify if the migration went well or not. The migration task has
the status Upgrade Pending in the Cloud Migration Management page, and you can rerun the
migration multiple times if you want to.
For example, you've run the assisted setup guide from a test company in a sandbox environment because
you worry that many extensions might be problematic. Once the data has been replicated to the sandbox
environment, you can use the troubleshooting tools in the Business Central administration center, for
example.
Data upgrade
This step starts when you choose the Run Data Upgrade Now action in the Cloud Migration
Management page in Business Central online for the specific environment.
Once you have chosen this action, both the Run Migration Now and the Run Data Upgrade Now action can
no longer be used for this company in the environment. If the upgrade has failed, an automatic point-in-time
restore is run to revert the tenant to the point before upgrade. You can then fix the errors and try the upgrade
again. Alternatively, you can start the cloud migration in another environment, or you can restore the current
environment from a backup from a point in time before the data upgrade. Or, delete all companies in the current
environment and start the migration again.
If you want to migrate more companies, disable the migration, and start the setup again. Or, use the Select
Companies to Migrate action from Cloud Migration Management page.
TIP
The migration from Business Central on-premises is in two separate steps, which gives you better options to test the
migration in a sandbox environment before you migrate to the final production environment.
In order to support data migration, tables and table extensions must specify if data from that table must be
migrated or not. By default, the ReplicateData property is set to Yes so that, by default, any extension that is
installed in the Business Central online environment will have all its tables migrated.
In certain circumstances, you may not want to migrate all data. Here are a few examples:
The extension is installed in the Business Central online environment but not in the Business Central on-
premises solution
In this case, Business Central will attempt to migrate the data but show a warning. Since the extension
isn't installed on-premises, any table related to that extension table won't migrate, and warning
notifications will appear in the cloud migration status page.
If you own the extension, we recommend that you set the ReplicateData property to No on the
extension tables. If you don't, and if you want data to migrate, install the extension in both Business
Central online and your on-premises solution. If you don't want data to migrate, uninstall the extension
from the Business Central online environment.
The extension references a base table
This can cause your base table to appear empty when you view data in your Business Central online
tenant. If that happens, uninstall the extension from your Business Central online tenant, and then run the
cloud migration process again.
Business Central will insert the default values and records into the table extensions automatically. If there
any problems, you can use the Repair Companion Table Records action on the Cloud Migration
Management page to insert the missing table extension records.
TIP
Use the Cloud Migration Management page to verify that data migrated correctly. For example, an extension extends
a table in the base application. In SQL Server, the table doesn't contain the data from the base app table for some reason.
In this example, the Cloud Migration Management page shows the table as not migrated, and the page that renders
the table is blank. The solution is to verify on-premises that the table with the table extension contains the same count of
records as the table for the base app table.
For more information, see FAQ about Migrating to Business Central Online from On-Premises Solutions and
Troubleshooting Cloud Migration.
NOTE
Currently, record links are not migrated because the links are associated with a user ID, and we do not migrate users from
the on-premises environment to the online tenant. You can choose to upvote this feature suggestion.
See also
Run the assisted setup guide
Migration On-premises Data to Business Central online
ReplicateData Property
Intelligent Insights with Business Central Online
Migrate Legacy Help to the Dynamics 365 Business Central Format
Upgrading from Dynamics NAV to Business Central Online
Important Information and Considerations for Before Upgrading to Dynamics 365 Business Central Spring 2019
Migrate Dynamics GP Data to the Cloud
2/6/2023 • 13 minutes to read • Edit Online
An assisted setup guide in Business Central can help you migrate data from Dynamics GP. You can migrate data
from Dynamics GP 2015 and later versions of Dynamics GP. For more information, see System requirements.
IMPORTANT
Migrating from Dynamics GP using the Cloud Migration Setup assisted setup guide is currently only supported for the
following markets: United States, Canada, United Kingdom, Australia.
The end-to-end process is described here. In this article, we talk about background information and things to
take into consideration.
As part of the Business Central 21.1 release, company settings for data migration have been moved from the
Cloud Migration Setup Wizard and placed in a new GP Company Migration Configuration page. This page
allows for improved ease of use by allowing you to make global settings for all companies selected to migrate
with the ability to update at a company level if necessary. You can access the GP Company Migration
Configuration page from Migration Management.
In addition to the GP Company Migration Configuration page you can select which modules you would like
migrated from GP to Business Central. You will be able to select from the following modules to migrate:
Accounts Payable, Accounts Receivable, Bank, Open Purchase Orders and Inventory.
Note: General Ledger information will always be migrated.
Dynamics GP data
Business Central update 21.1 adds a new page, GP Company Migration Configuration . Use this new page to
select the data you want migrated from Dynamics GP to Business Central. The page will automatically open after
you complete the Cloud Migration Setup wizard, but you can also open it from the Cloud Migration
Management page.
New options such as selecting what modules you want to migrate as well as if you only want to migrate master
data for specific modules are available. You can select the options at a global level, applying the options to all
companies selected to migrate or you can tweak options at a company level in the Per Company fast tab.
If you select to only migrate master data, records such as Accounts, Customer, Vendors and Items will migrate,
however no transactional information from GP will be migrated for the selected module.
When you migrate from Dynamics GP, the following information is migrated from Dynamics GP to Business
Central online:
1. Fiscal periods
The fiscal periods setup in Dynamics GP will be migrated to Business Central as accounting periods. Any
years marked as historical in Dynamics GP will come over to Business Central as open and will must be
closed in Business Central. If any adjustments need to be made to historical years after migrating, those
adjustments can be done before closing the year.
2. Chart of Accounts master records
The account number in Business Central will be mapped from the main account segment from Dynamics
GP. Remaining account segments are then defined as dimensions in Business Central. The GP Company
Migration Configuration asks the user to enter a segment for Global Dimension 1 and Global Dimension
2. If your chart of accounts in Dynamics GP has more than 2 segments outside of the main segment, the
other segments are automatically set up as shortcut dimensions (3-8). You can verify the setup in the
General Ledger Setup page in Business Central.
Let us look at an example of an account from Dynamics GP, using the year 2022 as an example:
A C C O UN T IN DY N A M IC S
GP Y EA R NAME A M O UN T
Period 1 250.00
Period 2 117.00
Period 3 340.00
Period 1 240.00
Period 2 102.00
Period 3 501.00
Period 1 490.00
Period 2 219.00
Period 3 841.00
The migration creates two accounts in Business Central, number 1100 and number 4000. New
dimensions are also added with the names 000, 00, and 01. General journal transactions are created as
follows:
The data migration generates dimensions on that account based on the different segments. User will see
a Department dimension with the values 000, 100, and 200, respectively. A second dimension, Division,
will show the values 00, 01, and 02, respectively.
Account summary transactions are generated and posted for open and history years that were set up in
Dynamics GP. The summary amounts are created based on the fiscal periods set up in Dynamics GP. In the
GP Company Migration Configuration page, you can select the oldest historical year you want migrated
to Business Central. For example, if 2019, 2020, and 2021 are historical years in Dynamics GP, you could
select that the oldest historical year you want migrated is 2020. Summary transactions for 2019 would
not be migrated to Business Central.
3. Customer master records and outstanding transactions from the Receivables module
In the GP Company Migration Configuration page, you can choose to migrate all customers from
Dynamics GP or only active customers. This allows you to not migrate over customers that have been
marked as inactive. We also have added bringing all addresses from the customer over into Business
Central. All of the addresses on the customer will be setup as shipping addresses in Business Central. That
will allow the end user to choose the address needed when entering transactions after the migration.
In the GP Company Migration Configuration page, you can also choose to migration posting accounts on
customer classes. If you choose this option, posting accounts defined on customer classes in Dynamics
GP will be migrated to Business Central as customer posting groups. If a customer is assigned to a
customer class in Dynamics GP, the customer will be assigned to the corresponding customer posting
group after migrating.
We also bring over outstanding receivables transactions. These transactions will be brought in with the
amount remaining in Dynamics GP. For example, if an invoice for $1000 was entered into Dynamics GP,
and it has been partially paid and has a remaining balance of $400, the new invoice created in Business
Central will be for $600 as that is the amount remaining to be paid. We bring over all transaction types
from Receivables Management.
4. Vendor master records and outstanding transactions from the Payables module
In the GP Company Migration Configuration page, you can choose to migrate all vendors from Dynamics
GP or only active vendors. This allows you to not migrate over vendors that have been marked as
inactive. We also have added bringing all addresses from the vendor over into Business Central. All
vendor addresses from the vendor are migrated to Business Central. The vendor's Remit To Address will
be the main address for the vendor. All other vendor addresses will be setup as Order addresses in
Business Central. That will allow the end user to choose the address needed when entering transactions
after the migration.
In the GP Company Migration Configuration page, you can also choose to migrate posting accounts on
vendor classes. If you choose this option, posting accounts defined on vendor classes in Dynamics GP will
be migrated to Business Central as vendor posting groups. If a vendor is assigned to a vendor class in
Dynamics GP, the vendor will be assigned to the corresponding vendor posting group after migrating.
Vendor EFT Bank information will be migrated to Business Central as Vendor Bank Accounts. If a Vendor's
Remit to address contains EFT Bank information in Dynamics GP, it will be migrated over as the Preferred
Bank Account Code on a vendor in Business Central.
We also bring over outstanding Payables transactions. These transactions will be brought in with the
amount remaining in Dynamics GP. For example, if an invoice for $1000 was entered into Dynamics GP,
and it has been partially paid and has a remaining balance of $400, the new invoice created in Business
Central will be for $600 as that is the amount remaining to be paid. We bring over all transaction types
from Payables Management.
You can also bring over Open Purchase Orders. When we migrate purchase orders, we are looking at the
items and the quantities remaining on those items to determine what we will bring over as an open
purchase order. If an item is fully received and invoiced that item will not migrate. By bringing over open
purchase orders, you do not have to enter outstanding transactions from the purchase order aspect.
5. Inventory items
Inventory is imported with the cost valuation method that is set in GP at the time the migration is run.
Location information as well as the quantity on hand for each time is migrated. If serial or lot information
is tracked on an item, that information is also migrated.
In the GP Company Migration Configuration page, you can choose to migrate posting accounts on item
classes. If you choose this option, posting accounts that are defined on item classes in Dynamics GP will
be migrated to Business Central as inventory posting groups. If an item is assigned to an item class in
Dynamics GP, the item will be assigned to the corresponding inventory posting group after migrating. If
you only want to migrate active items you can choose to exclude inactive items in the GP Company
Migration Configuration page. Additional, you can choose if you do not want to migrate discontinued
items.
6. Checkbook transaction and master data
You can choose to migrate all checkbooks from Dynamics GP or only active checkbooks. Unreconciled
bank transactions will be migrated to Business Central so that you can reconcile your checkbooks after
migrating. Any cash receipt that has been posted should also be deposited in GP before migrating, as
undeposited receipts will not migrate.
7. GP Historical Snapshot
In the GP Company Migration Configuration page you can select if you want to migrate historical
information from GP into Business Central. This data will be visible in listpages found under the
corresponding entities and navigating to GP Detail Snapshot. You can indicate if you want to migrate GL
detail, Receivables, Payables, Sales Order Processing, Purchase Order Receipts and Inventory transactions.
The data is stored in extension tables in Business Central. Data stored in those tables can be used in
Power BI reports, Power Apps or other 3rd party reporting tools. The tables containing the GP Historical
Snapshot data are as follows:
Hist. G/L Account
Hist. Gen. Journal Line
Hist. Payables Document
Hist. Receivables Document
Hist. Sales Trx. Header
Hist. Sales Trx. Line
Hist. Purchase Recv. Header
Hist. Purchase Recv. Line
Hist. Inventory Trx. Header
Hist. Inventory Trx. Line
You can limit the about of data migrated in the snapshot by entering the latest year in GP that you want
brought over. Enter this year in the Oldest GP Year field in the GP Company Migration Configuration
page.
The GP Historical Snapshot will run as a background process after the migration is complete. The status
of the GP Historical Snapshot data can be viewed in Fact boxes in the Cloud Migration Management page.
Diagnostics run
In the Cloud Migration Management page, you can create a diagnostics run to do more data
validation/verification before the migration is run so that you can decrease the risk of a failed migration.
The maximum field length is different in Dynamics GP (30) and Business Central (20), and the diagnostics run
checks for issues and shows warnings. The tool also checks item numbers to look for duplicates based on the
character limit, and it checks to make sure there are no blank posting accounts that are needed for posting of
transactions with the migration.
Here is an example of what you might see when you run a diagnostic run:
See also
Run the assisted setup guide
Compare Work in Dynamics GP to Business Central
Migrating On-Premises Data to Business Central Online
Troubleshooting Cloud Migration
FAQ about Migrating to Business Central Online from On-Premises Solutions
Important Information and Considerations for
Before Upgrading to Dynamics 365 Business Central
Spring 2019 and Later Versions
2/6/2023 • 5 minutes to read • Edit Online
Depending on which version you are upgrading from, and the degree to which your solution differs from the
standard version of Business Central, you may want to prepare your solution for the upgrade. This topic
provides important information and tips for things to consider when you prepare to upgrade to Business
Central.
NOTE
Upgrade your solution to Business Central Spring 2019 (version 14) or later, and then migrate to Business Central online.
Names of variables
Business Central introduces new methods and statements. If your solution includes variables where the name is
now used by a standard AL method or statement such as REGISTERTABLECONNECTION or FOREACH, you must
change the variables before you upgrade to Business Central. Alternatively, you can enclose the variable names
in quotation marks. If you do not, and you import an object that has this code in text format, you cannot compile
the object.
Upgrade codeunits
When you introduce changes to the database schema, Business Central will check if these changes are
destructive or not. If the database check indicates that the change may lead to data deletion, such as if you are
dropping a table column so that the contents of that column will be deleted, this is considered a destructive
change. You will be prompted to handle the situation using upgrade codeunits.
Company names
If a company name includes a special character, an error may display during the upgrade. In this context, special
characters include the following:
[~@#$%&*().!%-+/=?]
If you are going to upgrade a database where one or more company name includes a special character, we
recommend that you rename the company before you start the upgrade process. After the upgrade is
successfully finished, you can rename the company again.
See Also
Upgrading the Application Code
Upgrading the Data
Deprecated Fields, and Fields Marked as Obsolete
Define Migration Table Mappings
2/6/2023 • 4 minutes to read • Edit Online
Migration table mapping can be used to rename the table during the cloud migration or to move a subset of
fields to a different table or table extension. Before you start defining table mapping
TIP
You can use the Impor t and Expor t actions to import or export the definition done in the UI.
Design constraints
It's not possible to have multiple source tables mapping to the same destination (target) table. The destination
table must have a single on-premises source table.
For example, the following mappings together aren't supported:
SO URC E TA B L E DEST IN AT IO N TA B L E
Customer MyTable
MyTable MyTable
SO URC E TA B L E DEST IN AT IO N TA B L E
Customer Customer
Customer MyTable
This limitation also applies to tables that are automatically included into the replication, which means tables
enabled for cloud migration by the ReplicateData property. If these tables exist in the on-premises database,
they'll automatically be included in the clod migration. So, no table mappings can define these tables the
destination table.
F IEL DS VA L UE
Extension Names Set to the name of the extension that contains the table.
Table Name Set to the table in the extension. Setting these three
fields specifies the target table.
Source Table Name Enter the full name as it appears in SQL. The system will
parse the values.
AL table example:
[CRONUS COMPANY$ABC My Custom Table$437dbf0e-
84ff-417a-965d-ed2bb9650972]
. The GUID 437dbf0e-84ff-417a-965d-ed2bb9650972 is
the extension ID, which in this case is for base app.
The following figure illustrates an example of the Migrate Table Mappings page for an AL table:
Move a set of fields out of the main table to another table or table
extension
NOTE
This type of table mapping is only supported for cloud migrations from Business Central. Dynamics GP and SL don't
support table extensions.
For example, suppose that you've added two custom fields to the Customer table in Business Central on-
premises. You want to move these two custom fields to a table extension in Business Central online. If you define
a table extension mapping, then the engine will move a subset of fields to the table extension.
Prerequisite
Fields to be moved to a table extension must have the same name and type as in the source table in the
Business Central. If the name is different, the fields will be ignored by the engine, and won't be moved to
Business Central online.
Create the table mapping for moving fields
1. To create the table mapping, follow the same steps as in Scenario 1, except set the Target Table Type to
Table Extension .
2. If you're moving a table that is per-database table, clear the Data Per Company check box.
The following figure illustrates an example of the Migrate Table Mappings page for a C/AL table:
The GUID 437dbf0e-84ff-417a-965d-ed2bb9650972 is the extension ID, which in this case is for base app.
3. To set the target table, go to the Target Table section and set the Type to Table or Extension .
The list shows all the tables available for mapping to the target table. You can filter the list by setting an
extension in the Extension Name field.
4. Select all rows that you want to map to the target table.
The following figure illustrates an example of the Add Migrate Table Mappings page:
5. Close the page.
After closing the page, the multiple table mappings will be inserted. This step is useful when you want to
split a single source table into multiple table extensions.
See also
Migrate Data
FAQ about Migrating to Business Central Online
from On-Premises Solutions
2/6/2023 • 5 minutes to read • Edit Online
This section contains answers to frequently asked questions about migrating from on-premises solutions to
Business Central online.
TIP
Check the tips in this article if your organization is not yet ready to migrate to Business Central online but are thinking
hard about it. For more information about migration, see Migrate On-Premises Data to Business Central Online.
See also
Troubleshooting Cloud Migration
Migrating On-Premises Data to Business Central Online
Troubleshooting Cloud Migration
2/6/2023 • 8 minutes to read • Edit Online
In this article, you learn how to troubleshoot problems that you may experience with the cloud migration of
Business Central. For the cloud migration to work properly, there are certain requirements that must be met on
the online and on-premises databases. The following sections talk about these requirements, how you can check
them, and correct them as needed.
If your on-premises SQL Server instance is a supported version that allows you to change the compatibility
level, you can do so with the following query. If you're using a different version, you must upgrade your current
on-premises environment to meet the current SQL Server compatibility requirements. For more information,
see View or Change the Compatibility Level of a Database
NOTE
You may also get the following error when compatibility level isn't set to the expected value: A database operation failed
with the following error: Invalid length parameter passed to the LEFT or SUBSTRING function.
Migration user
Database: on-premises
Make sure that the database user that the Integration Runtime uses to connect to your database has access to
the database.
You can verify the database user, for example, by running the following command using Microsoft PowerShell
ISE.
Change tracking
Database: on-premises
Change tracking must be enabled on the database. It should be enabled automatically. However, if you see an
error like Change tracking is not enabled on table <number> during migration, you'll have to enable it
manually.
To enable change tracking on your database, run the following query:
ALTER DATABASE [YOUR DATABASE] SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON)
If a user has problems managing a cloud migration, like starting migration, initializing companies, or migrating
data from earlier versions, check that:
The user has a Business Central license (Essentials or Premium, depending on their solution). We recommend
using free Dynamics 365 Business Central Premium Trial subscription for this user.
The user is assigned the SUPER permission set.
Users without a license, such as internal administrators or delegated administrators, aren't allowed to run the
migration.
Ensure that you're running the latest, compatible version of Microsoft Integration Runtime (IR).
You can check for and download the latest version from the Microsoft Download Center.
When downloading and installing Integration Runtime, choose version 5 (IntegrationRuntime_5.x.x.x.msi)
only if your machine runs .NET Framework Runtime 4.7.2. Otherwise, or if in doubt, choose version 4
(IntegrationRuntime_4.x.x.x.msi).
IMPORTANT
Running Integration Runtime v5 on a machine that doesn't have .NET Framework Runtime 4.7.2 can cause
timeouts when connecting to the on-premise SQL Server, which will break the cloud migration setup.
Before you install a new Integration Runtime version, uninstall the old version. When you uninstall the
old version, choose to delete the user data (such as authentication key and data source credentials) when
prompted. Then, install the Integration Runtime again and connect it to the online environment using the
new authentication key.
If you get a "Failed to enable your replication." error when running theData Migration Setup assisted
setup, check the IR logs.
You view the logs by using the Microsoft Integration Runtime Configuration Manager , which was
installed on-premises as part of the IR installation. Launch Microsoft Integration Runtime
Configuration Manager , select the Diagnostics tab, then select View Logs action. You can also use
the Test Connection feature on the page to verify that your user can connect to the database.
Synchronization errors can sometimes occur because IR is installed on a laptop or desktop computer
where the hibernate feature is turned on.
The computer where IR is installed ideally shouldn't be switched off, go to sleep, or hibernate. If these
conditions happen, the IR may get into an error state. In this case, we recommend that you reinstall the IR
and turn off sleep hibernate on the computer.
Make sure the machine, which you use for hosting IR has plenty of memory (RAM) available. Migration
can be interrupted by your machine running out of memory, and you can find this issue described in the
IR log. To prevent this situation, avoid running too many migrations simultaneously using the same IR.
Every extra parallel migration slows down the overall progress considerably.
If you experience problems with Microsoft Integration Runtime, also see Troubleshoot self-hosted integration
runtime.
If you migrate several on-premises databases to several online environments, it's possible to reuse the
same IR for these migrations.
Once you've successfully connected and migrated data into one online environment, you can reuse the IR
for another environment. To reuse an IR, enter its name in Integration Runtime Name field of Data
Migration Setup assisted setup, instead of leaving the field blank.
Use a restored backup when migrating the same on-premises database to different online environments.
Cloud migration stores some data in the on-premises database. So using the same on-premises database
to migrate into another online environment can affect the next synchronization run. If you need to
migrate to several online environments, we recommend you make a backup of the on-premises database
before enabling the data migration. Then, restore the on-premises database to this backup before setting
up migration to another online environment.
Avoid running several migrations of the same on-premises database to different online environment at
the same time.
If you need to do this type of migration, then migrate data sequentially. First, migrate data into the online
environment and disable the migration. Then restore the on-premises database from backup and enable
the migration again by providing a connection string to this database. You can use the same Integration
Runtime and Authorization key.
Don't try to migrate data from several on-premises databases into the same online environment at the
same time.
For example, you may have two companies, where each company is in its own on-premises database. If
you need to do this type of migration, the migrate data sequentially. First, migrate data from one
database into the online environment and disable the migration. Then set up the migration in the same
online environment, provide a new connection string to the next on-premises database. You can use the
same Integration Runtime and Authorization key.
Product version
Database: online
When running the Data Migration Setup assisted setup, make sure to select the right product that you
want to migrate from. Depending on which Cloud Migration apps you've installed, the assisted setup will
let you choose from three options:
O P T IO N W H EN TO USE
Dynamics 365 Business Central current version Select this option if you're migrating from the Business
Central latest version.
Dynamics 365 Business Central earlier versions Select this option if you're migrating from an earlier
supported version. Currently, you can migrate to
Business Central online from the earlier versions 14
through 20. For an indication of compatibility across
minor versions, see here. You can also switch to online
from the current version (21).
When migrating data from Business Central, check the applicationVersion field in the
$ndo$tenantdatabaseproperty table. Set this field to the correct version in the SQL if it's blank or not up to
date. The migration code uses the field's value for the following reasons:
Verifies that you're migrating from a supported version
Verifies that you've selected the right product version in the Data Migration Setup assisted
setup, Dynamics 365 Business Central current version or Dynamics 365 Business
Central earlier versions .
Determines which upgrade code will be executed.
If that field is blank, the migration can't run.
Company names
The cloud migration process can become difficult if the names of the companies in Business Central on-
premises or Dynamics NAV include special characters or trailing spaces, for example. To test that the company
names are valid, run a query in the on-premises database such as the following:
SELECT *
FROM Company
Where ([Name] like '% ') or ([Name] like ' %' ) or ([Name] like '%' + Char(10) + '%') or ([Name ] like '%' +
Char(13) + '%') or ([Name ] like '%/%' )
Change the company name, run the migration, and then, when migration is complete, change the company
name in the target environment as appropriate.
If cloud migration has completed successfully, but pages in Business Central online aren't showing the expected
data, or there are duplicate record exceptions thrown for setup tables, it's most likely due to table extensions
missing records that are present in the base application.
For example, an extension extends a table in the base application. In SQL Server, the table doesn't contain the
data from the base app table for some reason. In this example, the Cloud Migration Management page
shows the table as not migrated, and the page that renders the table is blank. The solution is to verify on-
premises that the table with the table extension contains the same count of records as the table for the base app
table.
To fix this problem, go to the Cloud Migration Management page and run the Repair Companion Table
Records action to insert the missing table extension records.
When you've completed the migration, disable cloud migration by using the Disable Cloud Migration action
on the Cloud Migration Management page. This action properly disengages the synchronization and cleans
up the Azure Data Factory resources deployed for this migration.
IMPORTANT
Just uninstalling the cloud migration apps, even with the option to remove the data, won't disable the migration in the
same way. If you don't disable Cloud Migration , users will experience permission-related errors when they try to modify
records in the migrated companies.
See also
Migrating On-Premises Data to Business Central Online
Migrate to Business Central Online from Business Central On-premises
Migrate to Business Central Online from Dynamics GP
Upgrading from Dynamics NAV to Business Central Online
FAQ about Connecting to Business Central Online from On-Premises Solutions
Compare Work Processes in Dynamics GP to
Business Central
2/6/2023 • 2 minutes to read • Edit Online
Moving to Business Central from Dynamics GP can seem daunting, even for experienced users. To help people
quickly become productive, we're producing videos that demystify the experience by explaining the differences
and similarities in work processes.
TIP
The videos in this article probably seem a little small. To get a closer look, switch the video player to full screen view.
Pay vendors
This video compares the process of paying vendors in Dynamics GP and Business Central.
Extensions are a programming model where functionality is defined as an addition to existing objects and
defines how they're different or modify the behavior of the solution. This section explains how you can develop
extensions using the development environment for Dynamics 365 Business Central.
If you're new to building extensions, we recommend that you read this document to get an understanding of the
basics and terms you'll encounter while working. Next, follow the Get Started with AL to set up the tools.
TIP
If you are looking for the C/SIDE documentation, visit our Dynamics NAV library.
NOTE
A single .al file may contain multiple objects.
Table extension objects and page extension objects are used to add or override changes to table or page objects.
For example, consider a business that sells organic food, and the business wants to add two extra fields;
Organic and Local Produce in its existing item table. The business will use a table extension object to define
those extra fields. The table extension has made the newly added fields available for use in the item table. You
can store data in these fields and access them by code. You can then use the page extension object to display the
fields in the UI.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
You have several options for creating new objects with the AL Language extension for Visual Studio Code. For
more information about the objects that you can create for your extension, see AL Development Environment.
NOTE
For some users the Ctrl+F5 shortcut key may not work due to keyboard or other settings. If it doesn't work for you, run
your code by choosing Run Without Debugging from the Run menu in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
NOTE
If you have previous experience working with the C/SIDE development environment and need an overview of some of the
changes between the two development environments, see Differences in the Development Environments.
Designer
Designer works in the client and allows you to design pages using drag and drop components. Designer lets you
build extensions in the client itself by rearranging fields, adding fields, and previewing your changes in page
design. For more information, see Using Designer.
To start writing extensions for Dynamics 365 Business Central, you'll need a Business Central tenant, Visual
Studio Code, and the AL Language extension. Visual Studio Code is a cross-platform editor that you'll use for
coding and debugging.
NOTE
If you want to create a container-based sandbox, see Get started with the Container Sandbox Development Environment.
For information about which sandboxes you can choose, see Sandbox Environments for Dynamics 365 Business Central
Development.
IMPORTANT
It is not supported to publish an extension from Visual Studio Code with the same identifiers as an extension which is
already published to AppSource. Identifiers include the combination of appID and version or name, publisher, and version.
If you do publish such an extension, it can be removed at any time.
NOTE
If you want to change your configuration at a later point in time, you can choose the Add Configuration button
on the bottom right side, and then choose one of the available options.
NOTE
For some users the Ctrl+F5 shortcut key may not work due to keyboard or other settings. If it doesn't work for you, run
your code by choosing Run Without Debugging from the Run dropdown in Visual Studio Code.
You now have a HelloWorld sample that compiles and runs. The JSON files in the project are automatically
updated with the settings that allows you to press Ctrl+F5 to build and deploy the solution to Business Central.
For more information, see JSON Files.
Tips and tricks
Use Ctrl+Space to activate IntelliSense at any place in the code, which will help you identify possible
options.
Always use the .al extension on new files.
Use the built-in snippets for code by typing t and choose the desired snippet from the list.
Create objects within the right object ranges, see Object Ranges in Dynamics 365 Business Central.
Build and get inspired by our sample library on GitHub.
Use Ctrl+Shift+P and select AL: Clear credentials cache to clear the credentials cache if you want to
deploy against a different environment.
Use F2 to rename objects, types etc. For more information, see Keyboard Shortcuts.
AL configuration settings
Use the AL configuration settings to specify general preferences for working with AL projects. For more
information, see AL Language Extension Configuration.
Telemetry settings
By default, Visual Studio Code is set up with a telemetry system to make sure that data and errors are sent to
Microsoft. If you don't want to send telemetry data, you can change the telemetry.enableTelemetry setting from
true to false .
To modify the telemetry setting, press Ctrl+Shift+P in Visual Studio Code and choose User Settings , which
opens the settings.json file, and then add telemetry.enableTelemetry and set it to false like shown below.
"telemetry.enableTelemetry": false,
TIP
The settings.json file contains user and workspace settings, these options can be modified to suit your preference. If
you want to modify Visual Studio Code editor options and functional behavior settings, see User and Workspace Settings.
NOTE
The EXTEND. MGT. - ADMIN permission set was introduced in Business Central 2021 release wave 1 as a replacement
for the D365 EXTENSION MGT permission set in earlier versions.
Next steps
Now that you have the tools and the HelloWorld example up and running, you might want to create a small
sample app in AL. This walkthrough guides you to create an app adding objects, code, and publishing the app to
your tenant. For more information, see Building Your First Sample Extension With Extension Objects, Install
Code, and Upgrade Code.
See Also
AL Development Environment
FAQ for Developing in AL
Syntax
Building Your First Sample Extension With Extension Objects, Install Code, and Upgrade Code
AL Language Extension Configuration
XML Comments in Code
Building your first Sample Extension with Extension
Objects, Install Code, and Upgrade Code
2/6/2023 • 16 minutes to read • Edit Online
This walkthrough will guide you step by step to create a sample extension in AL. New objects and extension
objects will be added to the base application for a simple reward feature for customers. Every section of this
exercise includes code that serves for installing, customizing, or upgrading this sample extension. The final result
can be published and installed on your tenants.
Prerequisites
To complete this walkthrough, you'll need:
The Dynamics 365 Business Central tenant.
Visual Studio Code.
The AL Language extension for Visual Studio Code.
For more information on how to get started with your first extension for Dynamics 365 Business Central, see
Getting Started.
TIP
Type ttable followed by the Tab key. This snippet will create a basic layout for a table object.
fields
{
// The "Reward ID" field represents the unique identifier
// of the reward and can contain up to 30 Code characters.
field(1;"Reward ID";Code[30])
{
DataClassification = ToBeClassified;
}
// The "MaxValue" property sets the maximum value for the "Discount Percentage"
// field.
MaxValue = 100;
keys
{
// The field "Reward ID" is used as the primary key of this table.
key(PK;"Reward ID")
{
// Create a clustered index from this key.
Clustered = true;
}
}
}
TIP
Use the snippet tpage, Page to create the basic structure for the page object.
field(Description; Rec.Description)
{
ApplicationArea = All;
}
For more information about the types of pages in AL, see Pages Overview.
layout
{
area(content)
{
repeater(Rewards)
{
field("Reward ID"; Rec."Reward ID")
{
ApplicationArea = All;
ToolTip = 'Specifies the level of reward that the customer has at this point.';
}
field(Description; Rec.Description)
{
ApplicationArea = All;
}
After you've created the objects, update the startupObjectId in the launch.json file to 50102 , which is the ID of
the Reward List page and select the Ctrl+F5 shortcut to see the new page in your sandbox environment. You'll
be asked to sign in to your Business Central, if you haven't already done so.
TIP
Information about your sandbox environment and other environments is stored as configurations in the launch.json
file. For more information, see JSON Files.
Designer
Dynamics 365 Business Central Designer works in the browser and allows modifying the current page. It
enables users to add existing table fields, move fields around, or remove fields from the page. Users can make
changes to display the information they need, where they need it by using drag-and-drop components.
To show how Designer changes the design of a page, you begin by adding one field to the Reward table. This
field will be used later to exemplify the Designer's properties.
field(4;"Minimum Purchase";Decimal)
{
MinValue = 0;
DecimalPlaces = 2;
}
From this point, changes to the Reward Card page can be done either manually by adding the code below in
Visual Studio Code or by using Designer's functions to add the same field. Both ways lead to the same results,
but using Designer speeds up the process.
Using the F6 key shortcut in Visual Studio Code launches the browser and enters Designer. You can also use
Designer from the Business Central client, by selecting Designer .
NOTE
Every time you start designing, you create a new extension and the changes you make in Designer will apply to all users.
To add the same fields and customize the Reward Card page, follow the next steps:
Navigate to the Reward Card page by choosing + new .
Enter Designer mode from the UI and select More from the Designer bar.
Select Field from the Designer bar to show the list of available fields.
Drag the Minimum Purchase field from the list onto the page in the Reward group .
Choose the Reward in the group caption to enable the value to be edited. Change the caption to Info and
press Enter .
After making these adjustments, finish up your design by choosing Stop Designing , which allows you to name
the extension with an option to download code, and save the extension for the tenant. If you choose not to
download the code at the end, you can still pull the changes via the Alt+F6 key shortcut from Visual Studio
Code. You can also uninstall the extension from the Extension Management page. You can find the Extension
Management page by choosing the search icon and typing the page name.
For more information about Designer, see Designer.
TIP
Use the snippet ttableext to create a basic structure for the table extension object.
tableextension 50103 "Customer Ext" extends Customer
{
fields
{
field(50100;"Reward ID";Code[30])
{
// Set links to the "Reward ID" from the Reward table.
TableRelation = Reward."Reward ID";
// If the "Reward ID" changed and the new record is blocked, an error is thrown.
if (Rec."Reward ID" <> xRec."Reward ID") and
(Rec.Blocked <> Blocked::" ") then
begin
Error('Cannot update the rewards status of a blocked customer.')
end;
end;
}
}
}
NOTE
While running the code, you might get errors and warnings in Visual Studio Code. Those errors and warnings shouldn't
affect the output of this example exercise.
TIP
Use the shortcuts tpageext to create the basic structure for the page extension object.
pageextension 50104 "Customer Card Ext" extends "Customer Card"
{
layout
{
// The "addlast" construct adds the field control as the last control in the General
// group.
addlast(General)
{
field("Reward ID"; Rec."Reward ID")
{
ApplicationArea = All;
actions
{
// The "addfirst" construct will add the action as the first action
// in the Navigation group.
addfirst(Navigation)
{
action("Rewards")
{
ApplicationArea = All;
At this point, reward levels can be created and assigned to customers. To view recent changes in the code,
update the startupObjectId value in the launch.json file to 21 . Then, select the Ctrl+F5 key or Run Without
Debugging from the Run menu to open the page.
Help links
This sample app is relatively straightforward, but we want users of your app to be able to get help instantly and
learn more in the process of using it. Just like Business Central has Help readily available for users, you'll
configure your app to get context-sensitive links to Help, and then apply tooltips to the fields in your pages.
Configure context-sensitive links to Help
At an app level, you can specify where the Help for your functionality is published in the app.json file. Then, for
each page in your app, you specify a relevant Help file on your targeted website for that particular page. For
more information, see Configure Context-Sensitive Help.
Open the app.json file, and then change the value of the contextSensitiveHelpUrl property to point at the right
location on your website. In this example, you publish Help for your app at https://mysite.com/documentation .
"contextSensitiveHelpUrl": "https://mysite.com/documentation/",
Next, you set the ContextSensitiveHelpPage property in your app code for the Reward Card and Reward List
pages:
// The target Help topic is hosted on the website that is specified in the app.json file.
ContextSensitiveHelpPage = 'sales-rewards';
The following example shows the properties for the Reward List page after you've specified the context-
sensitive Help page.
// The target Help topic is hosted on the website that is specified in the app.json file.
ContextSensitiveHelpPage = 'sales-rewards';
...
Now, if you run your app, you can see the link to help article for Reward List page by pointing over Reward ID
and choosing Learn More . The URL of your targeted website is present in the Help section. You can specify the
same relative link for Reward Card , Reward List , and the customization of the Customer page, or you can
specify different targets. For more information, see Page-level configuration.
Add tooltips
To help users navigate the app interface without any confusion and to add more clarity on the app features, you
can use tooltips. Just like the base application of Dynamics 365 Business Central includes tooltips for all controls
and actions. For more information, see Help users get unblocked.
For this walkthrough, add the following tooltip to the properties of the Reward ID field on all three pages,
Reward Card, Reward List, and Customer Card ext:
ToolTip = 'Specifies the level of reward that the customer has at this point.';
Now, if you deploy the app, you'll be able to read the tooltip text for the Reward ID field, and if you choose the
Learn more link or press Ctrl+F1 , a new browser tab opens the equivalent of
https://mysite.com/documentation/sales-rewards .
Install code
After you have installed the extension, the Reward List page is empty. This is the result of the fact that the
Reward table is also empty. Data can be entered manually into the Reward table by creating new records from
the Reward List page. However, this task slows down the process, especially because the Reward table should
be initialized with a standard number of reward levels when the extension is installed. To solve this, install
codeunits can be used.
A codeunit is an object that can be used to encapsulate a set of related functionality represented by procedures
and variables. An install codeunit is a codeunit with the Subtype property set to Install. This codeunit provides a
set of triggers that are executed when a particular extension is installed for the first time or when it's reinstalled.
In this example, the following install codeunit initializes the Reward table with three records representing the
'GOLD', 'SILVER', and 'BRONZE' reward levels.
TIP
Use the shortcuts tcodeunit to create the basic structure for the codeunit.
codeunit 50105 RewardsInstallCode
{
// Set the codeunit to be an install codeunit.
Subtype = Install;
For more information about install code, see Writing Extension Install Code.
Upgrade code
When you upgrade an extension to a newer version, any modifications, which are required to support the
upgrade in the existing data must be written in an upgrade codeunit. In this example, the following upgrade
codeunit contains code that changes the BRONZE reward level to ALUMINUM level in customer records. The
upgrade codeunit will apply the changes when you run the Start-NAVAppDataUpgrade cmdlet in terminal.
IMPORTANT
Remember to increase the version number of the extension in the app.json file.
codeunit 50106 RewardsUpgradeCode
{
// An upgrade codeunit includes AL methods for synchronizing changes to a table definition
// in an application with the business data table in SQL Server and migrating existing
// data.
Subtype = Upgrade;
// If the code needs to be upgraded, the BRONZE reward level will be changed into the
// ALUMINUM reward level.
if Module.DataVersion.Major = 1 then begin
Reward.Get('BRONZE');
Reward.Rename('ALUMINUM');
Reward.Description := 'Aluminum Level';
Reward.Modify();
end;
end;
}
For more information about writing and running upgrade code, see Upgrading Extension.
"applicationInsightConnectionString":"<connection string>"
Conclusion
This walkthrough showed how an extension can be developed. The main AL objects and extension objects were
used to make a structure for reward levels, to store, view, and edit them. The Designer was introduced as an
alternative to modify visual components of page objects and to customize them directly from the web interface
instead of using code. Up to this point, the table and the page objects were empty, so, we added install codeunit
which initialized the Reward table with a standard number of reward levels when the extension was installed.
We also added an upgrade code section in this exercise to create a complete picture of all processes involved
when an extension is built. As a result, a user is enabled to assign one of the three reward levels to a customer
and to change this scenario by upgrading the version of the extension.
TIP
To try building a more advanced Customer Rewards sample extension, see Building an Advanced Sample Extension.
See Also
Developing Extensions
Get Started with AL
How to: Publish and Install an Extension
Converting Extensions V1 to Extensions V2
Configure Context-Sensitive Help
Sending Extension Telemetry to Azure Application Insights
Using Designer
2/6/2023 • 10 minutes to read • Edit Online
When developing extensions in the AL development environment, you have a wide range of possibilities.
Designer in Dynamics 365 Business Central complements the development experience in Visual Studio Code. It
provides an easy and convenient way to make immediate changes to your design by dragging and dropping the
components on the page.
IMPORTANT
Currently, Designer is only available from a Dynamics 365 Business Central sandbox.
Every time you start designing, you're effectively creating a new extension. Your changes are immediately visible to other
users in the sandbox environment.
Designer cannot be used by multiple users at the same time in sandboxes.
NOTE
Extensions created using Designer are removed when the sandbox environment is updated or relocated within our
service. Thus, you should not rely on using the sandbox environment as a source control for these Designer extensions.
Remember to frequently download and backup the Designer extension source. For more information, see Production and
Sandbox Environments.
Designer capabilities
Here's a quick overview of capabilities in Designer :
Move components fields, columns, cues, parts, actions, and action groups
Remove components fields, columns, cues, parts, actions, and action groups
Drag-and-drop components
In Designer, you design and modify the current page by using drag and drop components. You can display
existing table fields, move fields around, remove fields from the page, hide and move actions, and much more.
Working with fields
To add a field or column to a page, in the banner, choose Field . A pane to the right appears that lets you add
fields. Here, you can see all the fields that are available for the specific page. The fields displayed are based on
the underlying table or tables. The field can have a status of Placed , which means that the field already exists on
the page. A status of Ready means that the field doesn't exists on the page and can be added. To add a field,
drag and drop it to the preferred location.
If you want to remove a field or column, select the arrowhead indicator or on the component, and then
choose Remove .
You can edit the caption of a FastTab (FastTabs divide key information in separate groups and are arranged in
columns) by selecting the caption and start writing. A caption should provide a short and clear description. For
more information, see Field Arrangement on FastTabs
Show under "Show more" Sets the field so that it appears only Additional
when the user selects Show more .
Show when collapsed Sets the field to always display on the Promoted
page. The field is displayed regardless
the user selects Show more or Show
less . The fields will also display in the
header of the FastTab if the FastTab is
collapsed.
NOTE
Bookmarking is only available for pages and reports that are discoverable from Tell Me (search icon on top right). For
more information on how to make pages and reports searchable, see Adding Pages and Reports to Tell me.
This feature allows the user to efficiently create multiple links and group together the important or commonly
used links for a specific profile in the Role Center navigation bar. For more information about bookmarking, see
Bookmark a Link to a Page or Report on Your Role Center in the Business Central Application Help.
You can also move actions to reorder them in the navigation bar, or move them into groups or subgroups to
design the Navigation Menu.
NOTE
You cannot modify actions that are defined on pages that are shown in parts, such as in FactBoxes or embedded lists.
TIP
In Designer, to run an action as normal, select the action and press Ctrl+Click .
O P T IO N W H AT IT DO ES
Remove This option is available for the actions that are shown only in
a promoted category. Or actions that are shown in both,
promoted category and another action menu.
Hide This option is available for actions or action groups that are
currently shown only in an action menu (not in a promoted
category). Like Remove , choosing Hide will make the action
or action group disappear from the action bar in the client.
However, in Designer, the action or action group appears
dimmed.
Show This option appears if the action or action group has been
previously hidden (dimmed). Choosing this option will make
the action or action group appear in the action bar.
NOTE
It is important that the EXTEND. MGT. - ADMIN permission set does not have a company specified; otherwise the user
will not be able to access Designer.
NOTE
The EXTEND. MGT. - ADMIN permission set was introduced in Business Central 2021 release wave 1 as a replacement
for the D365 EXTENSION MGT permission set in earlier versions.
TIP
You can hide the Automation item from users, but not using designer. Learn more at Set Up Power Automate
Integration.
See Also
Developing Extensions
Get Started with AL
AL Development Environment
Keyboard Shortcuts
2/6/2023 • 2 minutes to read • Edit Online
The following table provides an overview of some of the shortcut key combinations that you can use when you
are working in Visual Studio Code. For a complete overview, see Key Bindings for Visual Studio Code.
Ctrl+Shift+B Package
F5 Publish
Ctrl+X Cut
Ctrl+C Copy
Ctrl+V Paste
F12 Go to definition
K EY B O A RD SH O RTC UT A C T IO N
K EY B O A RD SH O RTC UT A C T IO N
* (star) Expand one level for all nodes. Consecutive keystrokes will
expand to the next level.
See Also
Developing Extensions
Get Started with AL
AL Development Environment
The AL Formatter
2/6/2023 • 2 minutes to read • Edit Online
The AL Language extension offers users the option to automatically format their source code. This capability
increases the usability of the editor by allowing developers to instantly fix the indentation and formatting of
their code. The auto-formatter analyzes the syntax tree of the AL code that you're formatting. By using rules that
are based on the coding and style guidelines for AL, the auto-formatter then inserts and removes whitespace
from key points in the document to make it more readable.
NOTE
The rules used by the auto-formatter cannot be configured by the user. This limitation is present to allow for a uniform
style to be used throughout the community of AL developers.
To format a range, in an already opened project, open the document that you want to modify, select the specific
range to format, right-click, and select Format Selection . In the default configuration for Visual Studio Code,
the command can be run using the shortcut Ctrl+K , Ctrl+F .
See Also
AL Development Environment
AL Outline View
AL Code Actions
AL Outline View
2/6/2023 • 2 minutes to read • Edit Online
Working with the AL Language extension, you have access to the Outline view. The Outline view is a separate
section in the lower left corner, right under the Explorer view.
The Outline view is enabled by default and shows the symbol tree of the currently active cursor, it also allows
you to filter as you type. Double-clicking on any node makes your cursor jump to the selected definition or
keyword. The Outline view will also display any errors in your project for an easy review.
You manage the look and feel of the Outline view by defining settings that are all enabled by default. To modify
settings, press Ctrl+Shift+P , and then choose Preferences: Open Settings (UI) for workspace settings, or
choose Preferences: Open User Settings for user settings. Under Extensions , and AL Language
extension configuration you'll find the settings that are available for the AL Language extension for the
settings.json file.
See Also
AL Development Environment
AL Formatter
AL Code Navigation
2/6/2023 • 2 minutes to read • Edit Online
When you develop an AL extension, you may want to navigate around the source code frequently. To jump
around the code or to access the reference code, you use the Go To Definition feature in Visual Studio Code.
Go To Definition
The Go to Definition feature navigates to the source of a type and opens the result in a new tab. You can use
the F12 shortcut key or right-click and select the Go to Definition feature from the right-click menu. The Go
to Definition opens the source in the .dal format that contains the base application code. For example, the
base application code may contain table metadata and application methods. In the following illustration, the
Address type and the HasAddress type open the Customer.dal file and locate the reference code of those types
by using the Go To Definition feature.
With Go to Definition , you can step into the referenced code and set breakpoints on the external code and
base application code. For more information, see Debugging in AL.
You can always use Go to Definition on Dynamics 365 Business Central code. However, if you want to use it on
other extensions, the extension package that is now referenced, when originally published, must have the
includeSourceInSymbols property set to true . The includeSourceInSymbols property is one of the three options
inside the resourceExposurePolicy property. An example is, that if A is referencing B you can only use the Go To
Definition on types of B, if B, when it was published, had the includeSourceInSymbols flag set to true . For more
information, see Resource Exposure Policy Setting.
See Also
Developing Extensions in AL
JSON Files
Debugging in AL
AL Code Actions
AL Code Actions
2/6/2023 • 2 minutes to read • Edit Online
The AL Language extension can help users to fix issues in the code. Code Actions is a Visual Studio Code
feature that provides the user with possible corrective actions right next to an error or warning. If actions are
available, a light bulb appears next to the error or warning. When the user chooses the light bulb (or presses
Ctrl+.), a list of available code actions is presented. A code action can be applied to a single instance or a
broader scope depending on the type of action.
In AL Language extension, these code actions are available in the current version:
Multiple IF to CASE converting code action
Spell check code action
Interface implementer
Make method local
Use parenthesis for method call fix for instance, document, project, or workspace.
Fix explicit with statements
Fix implicit with statements
Fix old report layout and replace with rendering layout section
Fix for AW0013
Convert pages or page extensions to use the actionRef syntax for promoted actions on the action bar. Fix for
instance, document, project, or workspace. For more information, see Code action for actions.
Examples
The spell check code action is triggered on certain syntax errors:
The make method local action is triggered to fix the CodeCop Warning AA0207:
Code actions for promoted actions
Use the code action to convert legacy syntax for promoted actions to the actionref syntax, which is introduced
with Business Central 2022 release wave 2. In-client customizations, user personalization, and profile
configurations are automatically converted into the new syntax, so this is primarily applicable to DEV extensions.
The code action can apply to a single instance, the document, the project, or the workspace.
NOTE
For Designer extensions, use F6 to open Designer , which opens the page where the legacy syntax is used. Choose the
Lock symbol and use Unlock page to automatically convert the legacy syntax for the running code. Pressing Alt+F6 will
bring you back into Visual Studio Code, and show the converted actionref code.
See Also
AL Development Environment
AL Outline View
AL Formatter
Directives in AL
Object Ranges in Business Central
2/6/2023 • 2 minutes to read • Edit Online
When you develop an app for Business Central online, you must request an object range in terms of licensing.
Development for Business Central is done using Visual Studio Code with the AL Language extension.
There are currently two available ranges that you can request. Both have some characteristics to keep in mind:
RSP Object Range (ID range 1,000,000-69,999,999)
This object range is tied to the RSP Program details.
IMPORTANT
We currently advise new publishers to not request an RSP object range
IMPORTANT
We currently advise new publishers to request an app object range.
Currently, you can implement apps developed in both the RSP range and the app object range in Business
Central online and on-premises, as well as partner-hosted.
For more information, see Requesting an object range.
The following sections describe the different object ranges that you can find in the base application and
extensions.
0-49,999
This range is assigned to Business Central base app functionality and must not be used in extensions or
customizations.
50,000-99,999
This range is for customizations, and for test purposes. For Business Central online, a partner can develop an
extension tailored to the individual tenant to fit the needs. The partner will develop the extension either by using
a sandbox tenant or by obtaining a Docker image. Once the development is done, the extension can be deployed
to the individual tenant.
Also, use this range as part of training and similar, such as if you're using a sandbox tenant or a build of Business
Central on Docker.
100,000-999,999
The objects in this range are designed when the Microsoft team localizes Business Central for a specific country
or region. These objects can't be used by partners.
1,000,000-69,999,999
This object range is intended for the Registered Solution Program (RSP). The partner can choose to use this
range for developing extensions that can be used in Business Central online or on-premises. When used in
Business Central online, these extensions are obtained as apps from appsource.microsoft.com.
70,000,000-74,999,999
Partners can obtain IDs in this range for extensions for Business Central online. These extensions are obtained as
apps from appsource.microsoft.com.
For more information, see Get Started with Building Apps.
Download the Business Central licensing guide here.
See Also
Get Started with Building Apps
Get Started with AL
Blog Post
Differences in the Development Environments
2/6/2023 • 3 minutes to read • Edit Online
Coming from the Dynamics NAV development environment and C/SIDE, it's good to know about some
differences and optimizations between them. The following sections go through some of these changes, but it
isn't an exhaustive list.
TIP
A very useful tool working in Visual Studio Code is IntelliSense, which gives you a list of options in the current context. To
activate IntelliSense from anywhere in the code, press Ctrl+Space .
Data types
C / SIDE A L L A N GUA GE DEVELO P M EN T EN VIRO N M EN T
Dates are parsed based on culture settings. Locale independent and supports only: yyyy-mm-ddD .
Boolean values are expressed as yes /no . Boolean values are expressed as true /false .
For tables, integers can allow decimal values. For example, For tables, Min, Max, InitValue numbers with a fraction are
5.0 converts to an integer, 5.4 throws an error at runtime. expressed as decimal , thus they aren't a valid integer data
type.
The largest constant integer can be 999999999999999 . Transforms to 999'999'999'999'999.0 , a decimal value. In
AL, this can be expressed as 999999999999999.0 or
999999999999999L .
Syntax updates
C / SIDE A L L A N GUA GE DEVELO P M EN T EN VIRO N M EN T
The token for multilanguage comment is @@@. A multilanguage comment is marked with Comment .
AutoFormatExpr AutoFormatExpression
DataCaptionExpr DataCaptionExpression
Layout GridLayout
ProviderID Provider
NOTE
Property values are considered syntax elements; thus they must follow the standard AL escaping rules.
Multilanguage properties
With the introduction of .xliff files, the ML properties, such as CaptionML and TooltipML aren't used for this
translation method. Use the equivalent properties instead, such as Caption and Tooltip . Then, make sure the
manifest is set up to generate the /Translations folder and use the generated .xliff files for translations of the
extension. For more information, see Working with Translation Files.
Pages
The ActionContainer elements in AL have been renamed; the following table lists the renamed elements:
ActionItems Processing
ActivityButtons Sections
HomeItems Embedding
NewDocumentItems Creation
RelatedInformation Navigation
Reports Reporting
For instance, area(Sections) can be defined inside the actions section of the page.
Likewise, Container and ContainerTypeelements in C/SIDE are renamed to
area(Content|FactBoxes|RoleCenter) and can be defined inside the layout section of the page.
NOTE
For backward compatibility, we continue to support adding non-part pages as parts. It's a good idea to redesign your
page to only use Card part or List part, as we may remove support in a future update.
For syntax examples, see Page Object and Page Extension Object.
Naming
Controls, actions, and methods names must be unique on pages. In C/SIDE, you could create a Part control with
the same name as a method, which would give you an error at runtime. It's now prevented by disallowing
duplicates. Similarly, trigger and trigger event names are disallowed on matching application object
types. Likewise, actions and fields could have same names before, but that would have prevented page
testability access, and will now throw a compilation error.
NOTE
Name on Controls and Actions on Pages is mandatory now.
Property dependencies
For some properties to work, they require you to set another property. An example is PromotedCategory , which
requires that you've enabled the property Promoted . The following table lists some of the properties that have
this dependency.
PromotedCategory Promoted
PromotedIsBig Promoted
ValidateTableRelation TableRelation
SourceTableTemporary SourceTable
RunPageMode RunObject
Limited functionality
The InitValue property of type Duration isn't allowed in the AL Language development environment. The
InitValue of type DateTime is only allowed for the value 0DT .
See Also
Developing Extensions
Get Started with AL
AL Development Environment
Adding Help Links from Pages, Reports, and
XMLports
2/6/2023 • 2 minutes to read • Edit Online
When creating new pages, you can specify which Help file to open if the user selects the Learn more links in the
UI of Business Central.
The context-sensitive Help link is generated based on a configuration setting in the app.json file and the name
of the relevant Help file that you specify as part of the metadata for the page object. For more information, see
Configure Context-Sensitive Help.
Examples
The following examples show how you can specify the ContextSensitiveHelpPage property from new pages,
reports, and XMLports:
In all three examples, the ContextSensitiveHelpPage property is set to point at the same Help file. This is because
all three example objects support the same feature that is explained in the sales-rewards Help article. In your
app, you can choose to structure the Help differently.
See Also
Configure Context-Sensitive Help
Translating Base App Help
JSON Files
Page Object
Report Object
XMLport Object
Table Object
ContextSensitiveHelpPage Property
Working with Translation Files
2/6/2023 • 5 minutes to read • Edit Online
Dynamics 365 Business Central is multi-language enabled, which means that you can display the user interface
(UI) in different languages. In Dynamics 365 Business Central, this is done using XLIFF files, which is a
standardized format used for computer-based translations.
TIP
Optionally, use the Dynamics 365 Translation Service to get translations for your target languages. For more information,
see Translate user interface files.
NOTE
To submit an app to AppSource, you must use XLIFF translation files.
"features": [ "TranslationFile" ]
NOTE
If the Incremental Build setting is enabled in the AL Language extension configuration then all translations will be
ignored, even though the "features": [ "TranslationFile" ] setting is specified in the app.json file. For more
information, see AL Language Extension Configuration. The same is true when using RAD publishing, all translations will
also be ignored. For more information, see Work with Rapid Application Development.
Now, when you run the build command (Ctrl+Shift+B ) in Visual Studio Code, a \Translations folder will be
generated and populated with the .xlf file that contains all the labels, label properties, and report labels that
you're using in the extension. The generated .xlf file can now be translated.
IMPORTANT
The ML versions of properties are not included in the .xlf file:
CaptionML
ConstValueML
InstructionalTextML
OptionCaptionML
PromotedActionCategoriesML
RequestFilterHeadingML
ToolTipML
The TextConst Data Type is not included in the .xlf file either.
IMPORTANT
Make sure to rename the translation file before building the extension next time, as it'll be overwritten.
By setting the GenerateCaptions flag in the app.json file, you specify that you want to generate captions based
on the object name for pages, tables, reports, XMLports, request pages, and table fields. If the object already has
a Caption property set, that value will be used. For the table fields, the OptionCaption is used. The syntax is as
follows:
GenerateLockedTranslations
APPLIES TO: Business Central 2020 release wave 2 and later
By setting the GenerateLockedTranslationsflag in the app.json file, you specify that you want to generate
<trans-unit> elements for locked labels in the XLIFF file. The default behavior is that these elements aren't
generated. For more information, see JSON Files.
"features": [ "GenerateLockedTranslations" ]
Label syntax
The label syntax is shown in the example below for the Caption property:
Caption = 'Developer translation for %1', Comment = '%1 is extension name', locked = false, MaxLength=999;
NOTE
The comment , locked , and maxLength attributes are optional and the order is not enforced. For more information, see
Label Data Type.
var
a:Label'LabelText',Comment='Foo',MaxLength=999,Locked=true;
NOTE
You can have only one .xlf file per language. If you translate your extension to multiple languages, you must have a
translation file per language. There is no enforced naming on the file, but it's a good practice to name it
<extensionname>.<language>.xlf .
When the extension is built and published, you can change the language of Dynamics 365 Business Central to
view the UI in the translated language.
and it has <trans-unit id> for the page corresponding to Page 2931038265 - Property 2879900210 .
And if the following page extension of MyPage called MyPageExtension :
has <trans-unit id> for the page extension corresponding to PageExtension 1716690578 - Property 2879900210 ,
then if you want to change the caption on the page, you must use the ID Page 2931038265 - Property 2879900210 ,
which is the <trans-unit id> of the original property.
See Also
Working with labels
Working with multiple AL project folders within one workspace
JSON Files
Translate user interface files using the Dynamics 365 Translation Service
Instrumenting an Application for Telemetry
2/6/2023 • 2 minutes to read • Edit Online
This article describes how you can implement custom telemetry signals in your application for emitting
telemetry data. This data can then be collected and visualized for analyzing the application against the desired
business goals, troubleshooting, and more.
Telemetry overview
One aspect of event logging is the data collection about the working and deployment infrastructure of an
application to diagnose conditions and troubleshoot problems that affect its operation and performance. For
example, this type of event logging includes Business Central Server events and trace events like SQL and AL
method (function) traces.
Another aspect of logging is telemetry, which is the collection of data about how your application works in
production. Telemetry can tell you about specific activities that users perform within the application in the
production environment. Telemetry also helps troubleshooting in those instances where you aren't able to
reproduce the conditions experienced by the user or have no access to the user's environment. Telemetry can be
divided into different categories, like: telemetry for engineering, telemetry about the business, telemetry for
customers.
Extension developers
can specify whether
the signal is only sent
to the extension
publisher or also to
the VAR partner
telemetry resource.
NOTE
Using Application Insights is recommended.
See Also
Monitoring and Analyzing Telemetry
Monitoring Business Central Server Events
The SMB Opportunity for App Publishers
2/6/2023 • 3 minutes to read • Edit Online
Our mission is to empower every individual and every organization on the planet to achieve more. Particularly,
focusing on those 78 million small and mid-sized businesses (SMB) worldwide that passionately want more
resiliency in their tech intensity and their capability of transforming products and services to face the challenges
in the marketplace. To embrace the constant change and grow, every organization must have a business
application that breaks down the silos of data, processes, and workflow in their operations. This insight enables
employees to respond to daily challenges and opportunities with agility. Market research shows that the
business applications opportunity for software companies in the SMB space is predicted to be 51 billion dollars
by 2025. As a developer, you want to make sure you bet on the winning platform. The BizApps market growth in
this area is 17%; however Dynamics 365 platform growth is increasing at 47%!
Consultancy services
A large number of business users find it easy to buy consultancy services to research, deploy and manage apps.
Therefore, next to providing Apps, a publisher can also market consultancy services on Microsoft AppSource to
connect with buyers. The offered services could be assessments, briefings, workshops, proof of concepts, and
implementations. In general, the services are typically fixed in scope and duration. They're offered at a fixed price
or free, and have a defined outcome.
Here are a few examples of consultancy services provided by publishers:
Unified Commerce Readiness Intro: 1-Hr Assessment In this 1 hour assessment, LS Retail assesses how a
4-day engagement helps them with implementing their Unified Commerce Cloud solution based on
Microsoft Dynamics 365.
NAV-X Commission Mgt Gold 4-Hr Implementation In this 4 hour implementation workshop, NAV-X
supports the customers in implementing their commission management app.
Learn more about Consultancy Services.
See also
Get Started with Building Apps
Get Started with Building Apps
2/6/2023 • 8 minutes to read • Edit Online
Dynamics 365 Business Central is a business management solution that helps companies connect their services
and operations to streamline business processes, improve customer interactions and make better decisions.
With this modern business platform, you have the convenience to quickly tailor, extend, and build applications
so that they fit your specific needs with little to no code development.
Build a business app for a specific industry, process, or department such as HR, finance, marketing or
operations. Then, publish your app to the Microsoft commercial marketplace, where customers can find your
app, try it and get in touch with you. For more information, see What is the Microsoft commercial marketplace?.
Learn how you can become a Business Central app publisher in six steps in this article.
IMPORTANT
We currently advise new publishers to not request an RSP object range
IMPORTANT
We currently advise new publishers to request an app object range.
Currently, you can implement apps developed in both the RSP range and the app object range in Business
Central online and on-premises, as well as partner-hosted.
You can request an object range by downloading the object range request form here. After completion, send
them to your Regional Operational Center (ROC) for processing:
mbscon@microsoft.com if you're based in Europe, the Middle East, or Africa
mbsagree@microsoft.com if you're based in the Americas
mbslques@microsoft.com if you're based in the Asia Pacific region.
Downloading your development license file
After your Regional Operational Center has processed your Agreements and Object Range Request forms,
download your company's unique developer license from PartnerSource Business Center. Find it in the license
key configuration section under the developer tools section.
Register your unique prefix or suffix
In your extension, the name of each object must contain a prefix or suffix that is registered for your publisher
name. For more information about the use of affixes and the registration process, see Benefits and Guidelines
for using a Prefix or Suffix.
NOTE
If you have Microsoft 365, then your company most likely has Azure AD.
NOTE
To find out if your company has an Azure AD account, check with your system administrator.
2. Choose the settings icon in the top-right corner of the page, got to on account settings, and choose
user management .
3. Choose the grey ADD USERS button, and leave the default choice to Add existing users as-is. Now,
you can search for the user(s) that you want to add to Collaborate. To add them, you need to choose them
from the menu, and then choose the grey ADD SELECTED button.
4. You've successfully added your coworkers to Collaborate. Users can now sign in to Microsoft Collaborate
using the following link: aka.ms/Collaborate
Step 4 B: Getting access to the available builds and engagements
Once you've successfully registered on Microsoft Collaborate, Microsoft must assign you to the right programs,
and engagements before you can see the preview bits. Contact Dyn365BEP@microsoft.com and provide them
with information about the relevant users. the following table illustrates the type of information that you must
submit:
P UB L ISH ER DISP L AY W O RK A C C O UN T
NAME M P N ID F IRST N A M E L A ST N A M E EM A IL
After sending the email, expect a response from Microsoft within 1-2 business days.
See also
The SMB Opportunity for App Publishers
The Lifecycle of Apps and Extensions for Business Central
Update Lifecycle for AppSource Apps FAQ
Maintain AppSource Apps and Per-Tenant Extensions in Business Central Online
Microsoft Responsibilities for Apps on Business Central online
Marketing Validation Checklist
2/6/2023 • 3 minutes to read • Edit Online
The storefront details on AppSource are the first impression that prospects get regarding your offer. First
impressions last, so make sure to invest some time in developing the content on the storefront, so it gives a
good impression from the beginning. Failing to do so will jeopardize the hard work you put in, when developing
your offer, likely leaving the prospect confused or looking elsewhere. Accordingly, we recommend you put in the
time, effort and due diligence when developing this content.
You use Partner Center to submit your offer to AppSource. In the following, you can find information on all the
marketing-related items that you need to fill out in Partner Center prior to submitting your app to AppSource.
Follow this marketing validation checklist and get your app passed on the first submission.
Microsoft images Make sure not to use any Microsoft Read more
images (for example, the Business
Central icon or Dynamics 365 logo).
App type Read more about the types of apps Read more
you can submit to AppSource.
Properties
IT EM REQ UIREM EN T DETA IL S
Terms and conditions Outline the terms and conditions that Read more
the customer must accept before they
can use your offer.
Offer listing
IT EM REQ UIREM EN T DETA IL S
Offer name Enter a descriptive name for the offer. Read more
Products your app work with Add specific products that your app Read more
works with.
Privacy policy link The link to your offer’s privacy policy. Read more
Support link The link to your offer’s support page. Read more
Availability
IT EM REQ UIREM EN T DETA IL S
Markets (countries) Choose the markets that your app is Read more
available in (make sure that it
resembles the supported countries
paragraph in the description text).
Hide key The hide key is a token that is used to Read more
view the preview of your offer in
AppSource before going live.
Below you'll find a checklist of all requirements that you must meet before submitting an extension for
validation. You'll also find a description of how the Business Central Validation team is performing technical and
manual validation and how you can implement a validation pipeline to perform the same technical validation
yourself.
TIP
If you have questions around validation for your app, see Technical Validation FAQ for more information about who to
contact.
The app.json file has mandatory properties that you must Mandatory app.json properties
include. The 'name', 'publisher', and 'version' properties must
match the values set in your offer description. Here you can
also read more about dependency syntax and multiple
countries per a single app syntax.
Coding of Date must follow a specific format (no longer Use the format yyyymmddD . For example, 20170825D .
region-specific)
Remote services (including all Web services calls) can use Guidance on HTTP use
either HTTP or HTTPS. However, HTTP calls are only possible
by using the HttpRequest AL type.
Only JavaScript based Web client add-ins are supported. The Control Add-Ins
zipping process is handled automatically by the compiler.
Include the new AL controladdin type, JavaScript sources,
and build the app.
The .app file must be digitally signed. Sign an APP Package File
Set the application areas that apply to your controls. Failure Application Area guidance
to do so will result in the control not appearing in Dynamics
365 Business Central.
Permission set(s) must be created by your extension and Exporting Permission Sets
when marked, should give the user all setup and usage Managing Users and Permissions
abilities. A user must not be required to have SUPER
permissions for setup and usage of your extension.
REQ UIREM EN T EXA M P L E/ GUIDA N C E
Before submitting for validation, ensure that you can How to publish your app
publish/sync/install/uninstall/reinstall your extension. This
must be done in a Dynamics 365 Business Central
environment .
Thoroughly test your extension in a Dynamics 365 Business Testing Your Extension
Central environment.
Include the proper upgrade code allowing your app to Upgrading Extensions
successfully upgrade from version to version.
Pages and code units that are designed to be exposed as Web Services Usage
Web services must not generate any UI that would cause an
exception in the calling code.
You're required to register affixes for your publisher name Prefix/Suffix Guidelines
and to use them in your extension.
We strongly recommend you're using automated testing, Testing the Advanced Sample Extension
using the AL Test Toolkit. You aren't required to include the
test package with your extension.
You must use the Profile object to add profiles instead of Profile Object
inserting them into the Profiles table.
Use addfirst and addlast for placing your actions on Placing Actions and Controls
Business Central pages. This eliminates breaking your app
due to Business Central core changes.
The extension submitted must not be a runtime package. Creating Runtime Packages
The extension submitted must use translation files. Working with Translation Files
The extension submitted must specify the Application The Application manifest property is required in order to
manifest property. compute the minimum release of Business Central targeted
by your submission. For more information, see Computation
of Releases for Validation
IMPORTANT
It is recommended that all partners run the self-validation documented below before submitting apps for validation to
maximize chances of validation success.
1. The manifest of all extensions in the submission is validated. If any mandator y proper ties or required
proper ty values are missing, the submission is rejected..
2. The registration of affixes for the publisher name of all the extensions in the submission is validated. If the
publisher name does not have any registered affixes, the submission is rejected.
3. The signature of all extensions in the submission are validated. If any extension is not signed or its
signature is not valid, the submission is rejected.
4. The consistency of the main extension information (name, publisher, version) is validated against the offer
description. If any differences are noticed, the submission is rejected.
5. The extensions in the submission are validated. If any runtime packages are present, the submission is
rejected.
Once the extension has passed these first validation steps, the minimum release for your submission is
computed as described in Computation of Releases for Validation.
For each countr y and each release targeted by your submission, the following steps are run for each
extension in the submission:
1. If the extension with the same version has already been validated for the country, further validation for this
extension is skipped.
2. The set of dependencies for your extension is resolved. Any unresolved dependencies will cause the
submission to be rejected. If you include extensions created by Microsoft in your submission, it
will also be rejected.
NOTE
You are required to include the dependencies for your extension as part of your submission only if you are submitting a
newer version for them. If you do not include them in your submission, they will be downloaded automatically if they are
available in Business Central for the targeted countries/regions. If you are making your libraries available in new countries,
you should increase the version number.
3. The set of baselines for your extension is resolved by using the App Management API.
4. The extension is compiled against the set of dependencies resolved. If the compilation fails, the
submission is rejected.
5. The extension is tested against the resolved baselines using the AppSourceCop analyzer. If any violations or
breaking changes are identified, the submission is rejected.
6. If the runtime version of the extension is not suppor ted by the release targeted, the submission
is rejected.
If all extensions in the submission succeed the validation for each country and release without errors, the
submission is accepted..
All array parameters can also be specified as a comma-separated string. For more information, you can also
check this blog post Run-AlValidation and Run-AlCops.
Please include app and all library apps in both previousApps and apps and please include all countries on which
you want to validate.
NOTE
The Run-AlValidation cannot see whether the affixes to specify have been correctly registered with Microsoft using your
MPN ID and app publisher name, please make sure registration is in place.
IMPORTANT
The computer on which you run this command must have Docker and the latest BcContainerHelper PowerShell module
installed and be able to run Business Central on Docker.
If you are having issues with Business Central on Docker, you might be able to find help here:
https://freddysblog.com/2020/10/12/troubleshooting-business-central-on-docker.
You can use https://aka.ms/getbc?artifacturl=bcartifacts%2fsandbox%2f%2fus%2flatest to create an Azure VM, which has
all prerequisites installed to run Business Central on Docker.
NOTE
It is recommended that all partners set up DevOps processes to ensure that this validation process happens automatically
and regularly.
You can find resources for how to set up full plug-and-play DevOps processes using AL-Go for Github: https://aka.ms/AL-
Go.
NOTE
If multiple extensions are contained in your submission, the minimum release for the submission is the highest minimal
release computed for each of the extensions in the submission.
IMPORTANT
The minimum release computed for your submission also defines the availability in Business Central of all the extensions
in your submission.
For example, if the minimum release computed is 18.1, your extensions will be available starting from release 18.1.
Example
If your extension's manifest is defined as follows, the minimum release where your extension can be installed is
18.0 because the manifest requires the Application extension to be available with a version higher or equal to
18.0.0.0.
{
"application": "18.0.0.0",
}
See Also
Developing AL Language extensions
How to Make Compelling Videos
2/6/2023 • 9 minutes to read • Edit Online
Why use video? It's worth investing time and resources to create marketing videos for your app, it's taken
seriously in a business environment.
Choose the video format that is relevant for the audience that you
want to target
Video type 1: “Why” video
How to set up “Why” videos
Recommended length: 60-90 seconds
Purpose:
Your video should clearly communicate WHY prospects need to buy your solution now.
Focus:
Make sure the prospect is the hero of the story, not you or your company. Prospects aren't interested
in hearing about your company at this stage. They're simply trying to determine if what you offer is of
value to THEM.
Your video should speak to the principal challenges and goals of your core decision-maker persona.
Describe the desired end state they'll achieve by using your app.
A client/customer speaking about the benefits they received from your app is far more credible and
compelling than anyone from your organization.
Don’t only rely on “features” to acquire new customers.
How to speak to a WHY persona in a video
Target audience:
Owner/executive/leadership
They have limited time and financial resources as well as many competing priorities and resource
requirements
You need to elevate the discussion to a strategic level, where you highlight market share,
competitiveness, profitability, differentiation, revenue loss, and more.
Message:
The question you must answer beyond a doubt is WHY should they invest the time and money to buy
your app? What will they get out of it?
Why should they spend money on a new system now? Can’t they put it off?
The WHY messaging teaches people something and it's industry specific and results oriented, as well
as being memorable. It engages the emotional/limbic brain and leads to meaningful action.
Video tips
How to structure your video and practical things to keep in mind when producing videos
How to structure the flow in your video?
Gain immediate attention in the first 10 seconds of the video Stimulate curiosity by including a hook
phrase/comment that will elude to solving a pain point. Ask questions about the prospects’ core business
challenges or ask about something they would like to do but can’t accomplish today.
Highlight the prospects’ problems: Use an empathetic approach when describing their current situation and
demonstrate that you understand their current business challenges. They must relate to this if they're to
continue watching.
Give them new learning Teach them something they don’t know. Demonstrate you have expertise and
knowledge about their business or industry that they might not. Show you can offer strategic value to them.
Paint a picture of a desired outcome they would love to have or state they crave to experience. Highlight the
benefits, rewards, and value they'll enjoy after they purchase from you. Include both what it looks like and
how it will feel.
Prove what you’re saying is true Prospects don’t trust us when we say our products are great. Include
objective and credible proof in the form of data, charts, graphs, quotes, statistics, or testimonials as evidence
of your claims.
Ask them to take action. Include a call to action at the end of all videos. When viewers watch your videos,
they should feel inspired to take the next step towards purchasing. Tell them what to do next and include an
interactive link to the next step in the buying cycle. Use scarcity to compel them to action. Provide a time
limited offer or, for example, say it is “only for the first 20 customers”.
Practical things to keep in mind when producing and distributing your video
Does and don’t when producing your video
Don’t make the video too long As our attention span is 8 seconds the ideal length of video is 90 seconds
(minimum 30 seconds/maximum 2 minutes).
Add interactivity where possible Overlay text, charts, animation, questions etc. Visually call out key messages.
Make sure your audio is high quality.
Make your video easily shareable
Enable your video to be shared on multiple media. Track views and attention span. Observe and measure
viewer patterns so that you can learn from prospects’ actual behaviors and then improve future content.
How to make a good narrative that speak to the right persona in the right way?
Your narrative should have a beginning, middle, and end.
Lead with a story, not with your app or the technology.
Don’t turn your videos into a product pitch.
You’ll build more brand affinity and trust by shedding light on a problem your prospects care about
rather than by pitching your solutions to them directly.
The brain is on alert at the beginning of the video and at the end.
Make sure the first and last 10 seconds are compelling, memorable, and interesting.
Speak directly to a particular persona in the second person.
Don't talk about them in the third person, and avoid using terms like “our clients” and “companies”;
instead, use “you” language as often as possible.
Use many industry specific vocabulary, terminology, and visuals. If possible, film onsite at a
customer’s location rather than in your office or in a studio.
Speak to a particular persona:
Don't try to appeal to everyone at once, as you may not fully engage anyone with this approach.
Keep your delivery casual and authentic to instill trust. Speak directly to the prospect as if you were
having a fireside chat
The prospect should be the hero of the story, that is, don't speak about you and your company.
Ask rhetorical questions that stimulate pain and anxiety in your prospects in order to demonstrate that you
understand their business problems.
For example: Are your margins decreasing? Having cash flow problems because you can’t collect
payments sooner than 90 days? Had another large write-off? Lost an important customer recently
due to a late delivery?
Use visual and auditory language to help the prospect imagine a new possible future.
For example: “imagine seeing”, “picture yourself”, or “how would you like to hear your clients say…”
and so on.
Use contrast whenever possible.
Compare prospects’ experience now versus what it could be after the implementation of your
solution.
Call out your competitive differentiators while anchoring your solution in prospects’ minds so that
they can compare all others against the bar you set.
How to make a good narrative that speak to the right persona in the right way?
Where possible, use tangible, concrete language.
Include quantifiable proof in the form of data or visual pictures.
No vague claims like “transform your business with the cloud”. This is an emotionless statement.
Providing customer references and testimonials is much more compelling and effective than selling your
company or product yourself.
Let others speak for you. A customer testimonial video will always be more believable and compelling
than a video of you saying the same thing.
Surprise and delight them.
Use humor to make them smile. We take ourselves and our problems too seriously. Be warm,
memorable, and unique.
Technical Validation FAQ
2/6/2023 • 21 minutes to read • Edit Online
This article addresses some of the most frequently asked questions around validation of apps for AppSource
submission.
IMPORTANT
The minimum release computed for your submission also defines the availability in Business Central of all the extensions
in your submission.
For example, if the minimum release computed is 18.1, your extensions will be available starting from release 18.1.
NOTE
30 days before the release of a new Business Central major version, all submissions are validated against the upcoming
release. The apps in your submission must then be compatible with the upcoming release. The goal is to ensure that your
customers won't be blocked during the upgrade of their environment.
When you're adding new localizations in Business Central, these countries/regions can be added to Partner
Center before they're ready in Business Central. If you're targeting a country/region marked as 'Planned' in
Country/regional availability, depending on when your submission is processed, your apps might not be
uploaded to Business Central if the localization isn't yet ready in Business Central. Generally, it's possible to
upload apps for 'Planned' localizations a few weeks before they're officially released. When the localization
becomes available, if you're experiencing issues installing your apps, you should increase the version in the
app.json and submit the packages again in Partner Center. If you're using Azure Application Insights, you can
check whether the country/region was validated using this Troubleshooting Guide (TSG).
Against which baselines are my apps validated?
The service will verify that your extensions don't introduce breaking changes by comparing them to the latest
version available in AppSource for each country validated.
You can know which versions of your extensions were used as baseline during the breaking change validation
by enabling Azure Application Insights in your extension and running this Troubleshooting Guide (TSG).
IMPORTANT
As soon as your app has been uploaded to the AppSource marketplace, it will be used as a baseline during the technical
validation of your next submissions. As a consequence, you won't be allowed to perform breaking changes without
obsoleting the AL objects first and you won't be allowed to perform schema breaking changes; breaking changes on
tables or table extensions. This applies also if your extension isn't used by customers yet. You should then not submit your
app to the AppSource marketplace if you are still developing it and expect to change it in the near future.
NOTE
If some apps in your submission already have been uploaded to Business Central with the same version for some
countries/regions, then the app will not be validated again for these countries/regions.
IMPORTANT
If one or more libraries in your submission have their own offer, their listing(s) in the AppSource marketplace won't be
updated automatically. In order to keep the listing(s) in sync with the version of the app(s) uploaded to Business Central,
you should submit a submission for their related offer(s).
NOTE
If you include the dependencies of your extension as part of the submission, these dependency versions will be used
during the validation, even if there are higher versions already available in Business Central.
If you didn't include the dependencies for your app and they aren't available, your submission will fail during the
"Automated Application Validation" stage. Failing to find the dependencies for an extension results in error
messages with the diagnostic codes AVS0005 or AVS0101 .
If you receive an error with the diagnostic code AVS0107 and a message similar to
The extension 'MyApp' by 'MyPublisher' (version '1.2.3.4') has already been uploaded to Business Central for
the country/region 'US'
for one of your library apps, it means that you've already published another .app file for this extension to
Business Central as part of a previous submission. This can happen if you submit a .app file with different
content, or created by a different build (each .app file created has a specific build ID stamped, so building
multiple times the same project results in .app files with different build IDs). If this version of the library is
already available for all countries targeted by your submission, you can just remove the extension from the
submission. If you're making your library available in new countries, you should use the .app file that has
already been uploaded to Business Central or increase the version number in the manifest of the extension (the
app.json file).
My app failed at the "Automated application validation" stage, what do I do next?
At this stage, your extensions are validated to assess whether they meet the requirements specified in the
Technical Validation Checklist.
If this stage failed with an error message similar to
The validation of the submission failed for X out of Y tasks , you must investigate what has caused the error.
If you're using Azure Application Insights, information about the validation results is logged in Azure Application
Insights. You can also use this Troubleshooting Guide (TSG) in order to get started. If you're experiencing issues
with Azure Application Insights, refer to the dedicated section below.
If this stage failed with an error message similar to
The extension 'MyApp' by 'MyPublisher' (version '1.2.3.4') has already been uploaded to Business Central for
the country/region 'US'
, you must update the list of extensions submitted. For more information, see "When should I include my library
apps as part of my submission?".
If this stage failed with an error message similar to
The submission must target at least one existing country/region of Business Central , your submission doesn't
target any countries/regions currently available in Business Central. If your submission targets a country/region
marked as 'Planned' in Country/regional availability, you must wait for the localization to become available in
Business Central and resubmit your offer. Generally, it's possible to upload apps for new localizations, a few
weeks before they're made available to customers.
If this stage failed with an error message similar to
The extension 'MyApp' by 'MyPublisher' (version '1.2.3.4') contains inconsistent information about the
package id/name/publisher/version
, it means that something went wrong when the package included in your submission was built. In order to
mitigate the issue, you must rebuild the package and submit it again.
If this stage failed with an error message similar to
The App ID '<some-Guid>' is already used for Per-Tenant-Extensions in Business Central and cannot be used for
the AppSource extension with name 'MyApp' and publisher 'MyPublisher'
, this means that there exists one or many PTEs with the same App ID in the service. Since Business Central
doesn't support having AppSource apps and PTEs with the same App ID, it's then recommended to change the
ID of your extension before submitting it in Partner Center. For more information, see Moving a PTE to
AppSource. If the PTEs with that App ID aren't used in any customer environments anymore, you can create a
support case in Partner Center to request an exception.
If this stage failed with the following error message
Automated validation of the submission has failed. Please retry the operation and contact Partner Center
support if it fails again.
, you should create a new submission in Partner Center. If your submission fails again, you should create a
support case in Partner Center as documented in this article.
NOTE
Because the extensions in your submission are validated for each release and country/region targeted by the submissions,
the validation results can be really verbose and cannot always be displayed in their full length in Partner Center. The error
message will then end with ...(Truncated) . If that happens for your submission, you should either enable Azure
Application Insights in your extension, run the self-validation script, or fix the errors visible and iterate on your submission.
NOTE
Instead of writing your own queries, we recommend using the executable Azure Data Studio Troubleshooting Guide (TSG).
This guide contains queries that will process the signals for your submission and extract the important information.
IMPORTANT
The App ID is a critical part of the identity of apps in Business Central, and changing it is a breaking change for all
extensions depending on it. You should then not change the App ID of extensions which are installed for customers in
Business Central Online.
If you are submitting a new version of your extension with a different App ID for an existing offer, then this new
version will be considered as a different extension. This means that all extensions that depend on the extension
with the old app ID must be updated to reference the new App ID. If they are not updated, this will cause issues
such as customer environment upgrade failures which must be fixed within the required time period, see
Maintain AppSource Apps and Per-Tenant Extensions in Business Central Online. Since the app ID is part of how
data is stored in Business Central, this also means that you will have to migrate the data for all customers that
have the extension with the old App ID installed. Note that we do not provide tools for performing data
migration in SaaS, but you can create your own solution to export data from the old extension and re-import
the data after the extension change.
Is it possible to have multiple apps with the same App ID in AppSource?
Each unique codebase has one unique ID. If you have four apps in AppSource, you need to have four unique IDs
for these apps. Otherwise you'll get conflicts.
What if we already have an app on AppSource but we need to create the same app for another country; can
we then have the same app ID for two different apps targeting two different countries?
If they're different apps (different code), they should have different identity. Identity is used in, for example, app
management, dependencies, support cases, and telemetry. If reused across different apps, identity uniqueness is
lost. Another approach could be a common shared (internal/library) app across countries (with one app identity)
and localized functionality as extensions on top (with their own identity).
NOTE
The App ID is used as part of the URL of the offer listing and is used as a key to retrieve to customer review left on the
offer listing. Not preserving the App ID means that the offer URL will change and customer reviews will be lost.
IMPORTANT
If you're using Azure Application Insights, before opening a support case for a failure at the 'Automated application
validation', you must analyze the signals emitted in your Azure Application Insights storage. You can do so by using the
Troubleshooting Guide (TSG). When opening a support case, you must include the Kusto queries you used and the
diagnostic messages that you found. Including the results from the TSG is also recommended.
See also
Technical Validation Checklist
Guideline on Creating an Effective Sales Landing
Page for Your App
2/6/2023 • 10 minutes to read • Edit Online
App name & app logo Include a visual logo of your product
name and a one sentence positioning
statement.
Logo
The upper-left corner of the landing page is the most valuable section of the entire landing page.
Place your company logo in this location.
If you need help with formulating a positioning statement, try the value proposition generator located at here.
There should ideally be 5 or fewer choices; don't include more than seven options.
The menu text should state what the prospect gains if they select on the menu item
The text should be written from their perspective, not yours.
Recommended menu items:
How to Buy, Benefits Gained, Why Us, and Contact.
Include a headline question Get your prospects’ attention by “Struggling to manage your ingredient
asking them a compelling pain-based inventory and fretting over allergens?”
question that they can relate to.
Microsoft Dynamics 365 product Somewhere on the landing page, make Insert this paragraph: Microsoft
description sure you include the standard Dynamics 365 Business Central is a
Microsoft Dynamics 365 Business comprehensive business management
Central product description provided solution for small and medium-size
by Microsoft This is a requirement businesses (SMBs) that have outgrown
because your product is adding value their basic accounting software. From
to and building on this foundational day one, this new application makes
solution. ordering, selling, invoicing, and
reporting easier and faster. Dynamics
365 Business Central is deeply
integrated with Microsoft 365 and
includes built-in intelligence, so it's
easy to use and helps users make
better business decisions.
- Describe the most significant benefits - For example, “Save time and money
and rewards that your prospect will (benefits) by having a system that
realize after purchase. does all the tracking and calculations
for you (features).”
Messaging (Prove your claims) Include specific calls-to-action on your “Reduce how long it takes to set up
app page. your recipes in the morning from 1
hour to 10 minutes.”
Target market - If you support multiple countries or languages, this is a key selling feature. • Find a way to show
this visually.
This can be your free trial; a time-limited special price; a scheduled walk-through demonstration; and so on.
The words "free” and “save” are highly emotional words in the English language, so they should be used.
Use bright colors, such as orange, yellow, or red, to call attention to your buttons.
Button text should use benefit language rather than descriptive language.
For example, instead of “Download” write “Click here to start saving money now.”
Try not to send prospects away from your page – always have an embedded next step in your call to action
that brings them back to your landing page.
Messaging (Create a sense of Help your prospect gain a sense of Your bakery profitability will decrease
urgency by teaching the urgency to buy by teaching them one over the next five years due to an
prospects) thing about how they can be more increase of 3% in the cost of key
efficient or profitable now. inputs, such as wheat and sugar. Want
to know five key strategies that can
help you mitigate this challenge? Click
here to find out how to preserve your
profit margin
Show them how their performance in one key business area is below that of their competitors.
For an example you can provide a quick online self-assessment, a top-10 tips blog post, and much more.
Visual elements
Pictures (Differentiation Show them, don’t tell them Show the before and after state.
comparison images)
This is a visual image of how your prospects do things now versus how they'll be able to do it in the future.
You aren't telling them but showing them using a visual.
Compelling proof screenshots Visually demonstrate all the claims that Quickly and easily view inventory
you're making. items.
EL EM EN T DESC RIP T IO N
Videos (Tell your story using videos not text) Include as many videos as possible.
Videos have a much higher level of engagement and viewing time and convey much more than you can ever
say with words.
Include at least one customer testimonial video on your app landing page.
Your client should speak specifically about the pains they had before and the benefits they gained after, not
product features. It should be all about your customers, not you.
Include one product demonstration video.
See the video best practices https://aka.ms/ReadyToGo.
Elements that reduce anxiety and risk, while increasing trust
EL EM EN T DESC RIP T IO N
Customer testimonials Don’t sell your product; let your customers do that for you.
Social proof is more credible and trustworthy to prospects. The purpose of testimonials is to reduce the
buyer's anxiety and fear.
Your testimonials should answer the following questions:
“Will this work for my situation?”
“What benefit will I really get if I buy this?”
“Is this going to be too hard?”
“How long is this going to take?"
“Can I trust this company?”
EL EM EN T DESC RIP T IO N
Live chat Include live chat, with a photo of one of your team members
smiling at an appropriate time to increase conversion, such
as when a prospect selects the back button on your pricing
page.
SHORT lead capture form Include a lead capture form on your page.
Only ask for their name and email address, you can get the rest later.
Your forms shouldn't have more than four or five fields to fill out. You haven't yet earned the right or enough
trust to ask for too much information at this point.
Most lead capture forms are way too long, demanding, and intimidating, and have low completion rates.
NOTE
Nobody has the time or is willing to fill out an annoying form, which is of no value to them, especially if it is purely self-
serving from your standpoint.
EL EM EN T DESC RIP T IO N
Ideally, include a phone number and an email address with an employee photo.
This alone could double your conversion rate.
AppSource app page link & social Include a link back to your listing on Return to AppSource.
share AppSource, so the prospect can return
when ready.
Also, enable visitors to share and forward your app with others!
EL EM EN T DESC RIP T IO N
Close them! Add a get star ted button Include a specific call-to-action button with the option to
buy or try.
Get Started with C/SIDE and AL for On-Premises
2/6/2023 • 2 minutes to read • Edit Online
To get started with a mixed development environment of C/SIDE and AL, you must follow the steps below.
TIP
For information about which sandboxes you can choose, see Sandbox Environments for Dynamics 365 Business Central
Development.
NOTE
Build and get inspired by our sample library on GitHub.
See Also
AL Development Environment
FAQ for Developing in AL
Run C/SIDE and AL Side-by-Side
2/6/2023 • 3 minutes to read • Edit Online
Business Central on-premises supports development using C/SIDE, AL, and Designer side-by-side. When new
objects are added or changed in C/SIDE, these changes must be reflected in the symbol download in Visual
Studio Code using the AL Language extension. To enable this reflection, a command and argument called
generatesymbolreference has been added to finsql.exe and you can run it as illustrated below.
For example:
TIP
The finsql.exe includes several parameters that you can set to suit your environment. For more information, see Using the
Development Environment from the Command Prompt.
This is a lengthy operation. When you run the command, the console returns to an empty command prompt,
and doesn't display or provide any indication about the status of the run. However, the finsql.exe may still be
running in the background. It can take several minutes for the run to complete, and the symbols won't be
generated until such time. You can see whether the finsql.exe is still running by using Task Manager and looking
on the Details tab for finsql.exe .
When the process ends, a file named navcommandresult.txt is saved to the Dynamics NAV Client connected
to Business Central installation folder. If the command succeeded, the file will contain text like
[0] [06/12/17 14:36:17] The command completed successfully in '177' seconds. If the command failed, another
file named naverrorlog.txt will be generated. This file contains details about the error(s) that occurred.
NOTE
The symbol references are stored in the Symbol Reference column of the Object Metadata table of the database. For
on-premises installations, if you experience problems with generating symbols, check the information in the
naverrorlog.txt file. It is also important that the Filter parameter applied to generatesymbolreference command
must refer to Object Metadata fields such as, for example, Object Type or Object ID .
NOTE
Use generatesymbolreference set to yes as a command line argument each time you start finsql.exe to have all
compilations add a symbol reference to the Object Metadata table. The default setting of the argument is no.
NOTE
If you make changes in C/SIDE and start the C/SIDE development environment without the generatesymbolreference
flag set to yes , the symbols downloaded from Visual Studio Code will not reflect your changes.
Syntax example
finsql.exe generatesymbolreference=yes
This flag is also a part of the Compile-NavApplicationObject PowerShell command and you can use it to compile
and generate symbols on a filtered set of application objects through PowerShell. This alternative should be
considered if you don't work with the UI in C/SIDE. For more information about it, see Compile-
NavApplicationObject.
IMPORTANT
This setting must be enabled to allow any symbol generation. If the setting is not enabled, the
generatesymbolreference setting doesn't have any effect.
See Also
Developing Extensions
Create Runtime Packages for Business Central On-
Premises
2/6/2023 • 2 minutes to read • Edit Online
If you want to distribute extensions, you can generate runtime packages that don't contain AL code, but only the
final artifacts used by the server at runtime. Runtime packages thereby allow you to protect the intellectual
property represented by your AL source code.
When the runtime package is generated on the server, the developer license is checked for permissions to the
used extension IDs. The extension in a runtime package can then be installed on servers that don't have a
developer license. The server only needs permissions to run the objects, but not to modify or insert them.
For publishing and installing the package, use the Publish-NavApp and the Install-NAVApp PowerShell cmdlets.
Upgrade considerations
Like any extension, extensions distributed in runtime packages will occasionally have to be upgraded so that
they can run on with the latest Business Central version. There are two ways to upgrade a runtime package. Each
way provides a different level of upgrade.
Create a new extension version and runtime package
The recommended way to upgrade a runtime package is to build a new version of the extension against the
latest platform and application. Then, publish the extension to an on-premise instance, and create a new runtime
package version for distribution. Once you have the package, you can then publish it on tenants, and run a data
upgrade like with any other extension.
Recompile the existing package
Another way to upgrade the package is to use the Repair-NAVApp cmdlet to recompile the published package
against the new platform and Business Central server instance. Once complied, you can reinstall the package on
the tenant. Be aware that using the Repair-NAVApp cmdlet doesn't guarantee the extension will work properly.
It's not recommended when upgrading to a new version.
The Repair-NAVApp cmdlet requires that the runtime package includes the source code. You can include the
source code in two different ways:
In the extension's app.json file, set "allowDownloadingSource" or showMyCode to true .
When you run the Get-NavAppRuntimePackage cmdlet, use either the -IncludeSourceInPackageFile $true or
-ShowMyCode $true parameter.
Limitations
The limitation of runtime packages is that they only work for on-premise installations, so you can't submit them
to AppSource. For more information about the extension requirements for AppSource, see Technical Validation
Checklist. Moreover, debugging into an extension to view the source code isn't allowed by default; the
allowDebugging flag is by default set to false . For more information, see Resource Exposure Policy Setting.
NOTE
Runtime packages are guaranteed to work only if published to a platform with the same version as the one where they
were produced.
NOTE
If you set the showMyCode flag to true when running the Get-NavAppRuntimePackage cmdlet, you can enable
debugging and thereby also allow viewing the source code.
See Also
Publish-NAVApp cmdlet
Install-NAVApp cmdlet
JSON Files
2/6/2023 • 20 minutes to read • Edit Online
When you start a new AL project, two JSON files; the app.json file and the launch.json file are generated
automatically. The app.json file contains information about the extension that you're building, such as publisher
information and specifies the minimum version of base application objects that the extension is built on. Often,
the app.json file is referred as the manifest. The launch.json file contains information about the server that
the extension launches on.
NOTE
For information about data migration and creating a migration.json file, see The Migration.json File.
IMPORTANT
The rad.json and the snapshots.json files should not be modified.
App.json file
The following table describes the settings in the app.json file. To see an example app.json file, go to Business
Central Performance Toolkit.
SET T IN G M A N DATO RY VA L UE
brief No, but required for AppSource Short description of the extension.
submission
description No, but required for AppSource Longer description of the extension.
submission
privacyStatement No, but required for AppSource URL to the privacy statement for the
submission extension.
EULA No, but required for AppSource URL to the license terms for the
submission extension.
help No, but required for AppSource URL to an online description of the
submission extension focusing on the help and
troubleshooting content. The link is
used in AppSource and can be the
same as the value of the
contextSensitiveHelpUrl property.
To learn more about help links, see
Help and Support Links.
url No, but required for AppSource URL of the extension package. The link
submission is used in Business Central, on the
Extension Management page, as
Website . This URL can be a link to an
advertising page for your app, a page
describing the features and additional
resources other than troubleshooting
and help, or it can be a link for
contacting the app support, for
example, see Support Links.
logo No, but required for AppSource Relative path to the app package logo
submission from the root of the package.
platform Yes, if system tables are referenced in The minimum supported version of
the extension the platform symbol package file, for
example: "16.0.0.0". See the Symbols
for the list of object symbols contained
in the platform symbol package file.
application Yes, if base application is referenced in The supported version of the system
the extension. Required for AppSource and base application package file, for
submission example: "16.0.0.0". The file name of
this reference is
Microsoft_Application.app and the
name is Application . If the base
application has been customized, the
Microsoft_Application.app file can be
modified to reference the code-
customized base application instead.
It's important to keep
"name": "Application" in the
extension, but information about
publisher can be changed and the .app
file can be renamed. For more
information, see The
Microsoft_Application.app File.
SET T IN G M A N DATO RY VA L UE
contextSensitiveHelpUrl No, but required for AppSource The URL for the website that displays
submission context-sensitive Help for the objects
in the app, such as
https://mysite.com/documentation/
. If the app doesn't support all locales
currently supported by Business
Central, then include a parameter for
the locale in this URL, /{0}/ , and
also specify the relevant locales in the
supportedLocales setting.
The GenerateLockedTranslations
flag is used to generate
<trans-unit> elements in the XLIFF
file for locked labels. The syntax is
"features": [ "TranslationFile",
"GenerateCaptions",
"GenerateLockedTranslations" ]
. For more information, see Working
with Translation Files.
applicationInsightsConnectionString No, but recommended for AppSource The instrumentation key of the Azure
submission Application Insights resource for
monitoring operations, for example,
like app secrets retrieval by extensions.
Launch.json file
The following table describes the settings in the launch.json file. The launch.json file has two configurations
depending on whether the extension is published to a local server or to the cloud.
Publish to local server settings
SET T IN G M A N DATO RY VA L UE
applicationFamily No (Yes for Embed apps) The application family in the cloud
server, for example Fabrikam . This
property is reserved for Embed apps.
SET T IN G M A N DATO RY VA L UE
NOTE
If a local launch.json file doesn't contain a valid AL launch configuration, we'll try to find one in the code-workspace
first, and then in the settings.json files. However, if the launch property is specified in the code-workspace file even
without specifying a valid AL configuration, the global settings.json file won't be able to override it.
See Also
AL Development Environment
App Identity
Debugging in AL
Resource Exposure Policy Setting
AL Language Extension Configuration
Configure Context-Sensitive Help
App Key Vaults
The Migration.json File
2/6/2023 • 2 minutes to read • Edit Online
INTRODUCED IN: Business Central 2019 Release Wave 2, update 15.3, for on-premises only
Data migration allows you to move table and field data between extensions. The migration.json file provides a
pointer to the ID of an app that one or more tables will be moved to. This file allows you to move table and field
data from, for example, a code-customization on the base application to an extension of the base application.
The migration.json file can be added into the app project of an extension that a table is moved from to specify
the ID of the app that the table will be moved to. It can, for example, be placed at the root of the AL project. The
migration.json file must be created manually by following the steps and syntax as described below.
In the extension app.json file, ensure that "target": "OnPrem" . For more information, see JSON Files.
{
"apprules": [
{
"id": "12345678-abcd-abcd-abcd-1234567890ab"
}
]
}
See Also
JSON Files
Migrating Tables and Fields Between Extensions
AL Language Extension Configuration
2/6/2023 • 4 minutes to read • Edit Online
The AL Language extension has many settings that can be defined for a specific user or for a workspace. To
activate the settings, press Ctrl+Shift+P , and then choose Preferences: Open Settings (UI) for workspace
settings, or choose Preferences: Open User Settings for user settings. Under Extensions , and AL
Language extension configuration , you'll find the settings that are available for the AL Language extension.
For tips on how to optimize Visual Studio Code, see Optimizing Visual Studio Code for AL Development.
Settings
The following table describes the user and workspace settings for the AL Language extension:
SET T IN G VA L UE
Assembly Probing Paths Sets the list of directory paths where the compiler searches
for referenced .NET assemblies. For example:
"al.assemblyProbingPaths": ["./.netpackages",
"C:/Program Files/Assemblies"]
Are Profile Lenses Supported Enables the Profiler CodeLens for AL, default value is true .
Syntax is "al.areProfileLensesSupported": true . For
more information, see AL Profiler Overview.
Background Code Analysis Specifies whether the code analysis should be performed in
the background.
Code Analyzers Sets the list of paths to code analyzers to use for performing
code analysis. For example:
"al.codeAnalyzers": ["${AppSourceCop}",
"${CodeCop}"]
.
SET T IN G VA L UE
Editor Services Log Level Sets the logging verbosity level for the AL Language Editor
Services host executable. Possible values are Verbose ,
Normal , Warning , and Error .
Editor Services Path Specifies the path to the Editor Services host executable.
Enable Code Actions Specifies whether code actions should be enabled for all
source files in the current project. Default is false .
Enable Code Analysis Specifies whether code analysis should be performed for all
source files in the current project. Default is false . If this is
set to true , you must specify the Code Analyzers setting
with the list of code analyzers to use.
Enable Script IntelliSense Specifies whether IntelliSense should be enabled for control
add-in script files. Turn this off, if it interferes with advanced
JavaScript or TypeScript configurations. Default is true .
Package Cache Path Sets the directory path where reference symbol packages are
located.
Profiler Colors Specifies the colors used to define the application types in
the profiler output. Accepts valid color names, hex codes,
and rgba() values. The properties are systemApplication -
default color green , baseApplication - default color
magenta , and extension - default color yellow .
Rule Set Path Sets the path to the file containing the customized rules to
use when running code analysis.
Snapshot Debugger Lines Hit Decoration Specifies the decoration values for a line that is hit by the
snapshot debugger. Syntax is
al.snapshotDebuggerLinesHitDecoration .
Snapshot Debugging Path Sets the directory path where the snapshot debugger
sources are located. Default is ./.snapshot .
Snapshot Output Path Sets the directory path where snapshot files are saved.
Default is ./.snapshots .
Statement Lens Minimum Sets the lower limit for the time spent on statement
execution expressed in milliseconds. Default value is 500 .
Syntax is "al.statementLensMin": 100 . For more
information, see AL Profiler Overview.
Use Legacy Runtime Use the .NET Framework runtime for hosting the language
service instead of the .NET Core runtime. Enabling this might
result in a reduced level of performance.
Generate PermissionSet for Extension Objects Generate a permission set as an AL object. Syntax is
al.generatePermissionSetForExtensionObjects . When
invoking the command, the developer can choose to create
a new permission file or select an existing file to update.
See Also
AL Development Environment
Debugging in AL
JSON Files
Working with multiple projects and project references
Resource Exposure Policy Setting
2/6/2023 • 7 minutes to read • Edit Online
When you develop an extension, your code is protected against downloading or debugging by default. Read
below about adding Intellectual Property (IP) protection against downloading or debugging into an extension to
see the source code in the extensions.
The extension development package provides a pre-configured setting for protection against viewing or
downloading the code of the extensions. However, this setting can also be controlled in the manifest; the
app.json file.
When you start a new project, an app.json file is generated automatically, which contains the information
about the extension that you're building. In the app.json file, you can specify a setting called
resourceExposurePolicy that defines the accessibility of the resources and source code during different
operations. resourceExposurePolicy specifies the following list of options: applyToDevExtension , allowDebugging ,
allowDownloadingSource , and includeSourceInSymbolFile . Each of these properties defines the specific areas in
which the source code of an extension can be accessed. All of the options are by default set to false , which
means that by default, no dependent extension can debug or download the source code of your extension. The
syntax of the resourceExposurePolicy setting is as follows:
NOTE
The resourceExposurePolicy setting isn't visible in the app.json file when it's generated. If you want to change the
default value from false , you must add the setting as shown in the syntax example above. You can always override this
for your AppSource aåå or per-tenant extension by changing the setting.
IMPORTANT
The AL: Go! template sets the allowDebugging , allowDownloadingSource , and includeSourceInSymbolFile
options in the resourceExposurePolicy setting to true .
applyToDevExtension
APPLIES TO: Business Central 2022 release wave 2 and later
With the applyToDevExtension flag, you can specify if all resource exposure policies specified for the extension
also apply to developer extensions, by setting the value to true .
allowDebugging
To allow debugging into your extension, you must set the allowDebugging flag when the extension is taken as a
dependency, otherwise debugging isn't allowed. The default value of allowDebugging is false .
If you want to allow debugging into your extension to view the source code, the allowDebugging property in the
app.json file must be set to true . For example, if someone develops an extension A and another person
develops an extension B, where B depends on A, then debugging B will only step into the code for A, if a method
from A is called and if the allowDebugging flag is set to true in the app.json file for extension A as shown in
the example below. By adding this setting, you enable debugging into an extension to view the source code and
variables when that extension is set as a dependency.
NOTE
allowDebugging doesn't apply to Profiles, Page Customizations and Views, because these objects can't define any
custom logic in procedures or triggers. The code for Profiles, Page Customizations, and Views defined in an extension with
allowDebugging set to false can still be accessed and copied using Designer.
includeSourceInSymbolFile
When this flag is set to true in the app.json file of extension A, the downloaded symbol file in Visual Studio
Code, which is accessed by using the Downloading Symbols functionality, contains symbols, source code, and
all other resources of extension A. When includeSourceInSymbolFile is set to false , the source isn't available in
the symbol files, and you can't use Go to Definition to view source. You can, however, still extend, get
IntelliSense for, and call functionality in extension A by relying on its exposed symbols and signatures. The
default value of includesourceInSymbolFile is false .
Example JSON file
Example JSON file with default values when generated by using the AL: Go! command.
...
"resourceExposurePolicy": {
"allowDebugging": true,
"allowDownloadingSource": false,
"includeSourceInSymbolFile": false
},
"runtime": "8.0",
"keyVaultUrls": [
"https://mykeyvault.vault.azure.net"
],
"applicationInsightsConnectionString": "MyConnectionString1234"
...
NOTE
Remember to register all apps that should access your key vaults, it's not enough to just add the key vault setting to your
app.json manifest files.
IMPORTANT
Resource exposure policy overrides can be used to dynamically grant users of a given AAD tenant ID access. The users
performing the action, such as debugging, can be delegated admins or a guest user on the target environment. In
addition, you must specify the tenant property in the launch.json file. The tenant property must be set to the
target tenant ID. For more information, see JSON Files.
For more information, see Using Key Vault Secrets in Business Central Extensions and Setting up App Key Vaults
for Business Central Online. For Business Central online, the app key vault feature is only supported for
AppSource extensions.
The BC-ResourceExposurePolicy-Overrides secret
Once the key vault is set up, the policy of an extension can be overridden by using settings in your extension's
key vault. A secret named BC-ResourceExposurePolicy-Overrides must be added to the key vault. The value of the
secret is a .json file with the structure as shown in the example below. Because the json secret value in this case
spans multiple lines, you must use Azure PowerShell instead of the Azure portal to define the json secret value.
To enable one or more of the properties for use by an Azure AD tenant, you must add the tenant ID to enable
that property for the users of the tenant. Doing so enables a temporary access to the source code, for example,
for debugging purposes.
$json = '{
"allowDebugging": [
"9e2b6561-1ba6-4790-abcc-c84abf9a8961"
],
"allowDownloadingSource": [
"9e2b6561-1ba6-4790-abcc-c84abf9a8961"
],
"includeSourceInSymbolFile": [
"9e2b6561-1ba6-4790-abcc-c84abf9a8961"
]
}'
$Secret = ConvertTo-SecureString -String $json -AsPlainText -Force
Set-AzKeyVaultSecret -VaultName "YourKeyVaultName" -Name "BC-ResourceExposurePolicy-Overrides" -SecretValue
$Secret
NOTE
If debugging is enabled dynamically, a breakpoint can be set in the protected source code when the debugging session is
started.
Partner telemetry
If you specify the applicationInsightsConnectionString setting for your extension in the app.json file, it enables
a signal to be sent every time the policy is read from the key vault whenever, there's an issue with reading the
policy, or an issue with parsing the JSON. For more information, see Sending Extension Telemetry to Azure
Application Insights.
"applicationInsightsConnectionString": "MyConnectionString1234"
See Also
JSON Files
AL Development Environment
NonDebuggable Attribute
Develop for Multiple Platform Versions
2/6/2023 • 2 minutes to read • Edit Online
The AL language extension is compatible with multiple platform versions. You can install the AL Language
extension from the Visual Studio Code marketplace and use it to develop solutions for Dynamics 365 Business
Central.
NOTE
The AL Language extension isn't compatible with Dynamics NAV 2018 version backwards. For Dynamics NAV 2018
development, the traditional method should be used. You must install the Visual Studio Code extension from the
ALLanguage.vsix file shipped on the DVD.
Version compatibility
The following two elements are compared when you publish an extension.
1. The runtime version of the extension defined in the app.json file.
2. The runtime version of the platform that the extension is targeting.
In the app.json file, set the extension runtime version lower than the platform version. When you set the
extension to a higher runtime version, the extension package may contain certain features that the platform
may not support which would result in an error. Therefore, you must lower the extension runtime version than
the one that platform supports in order to publish your extension.
Things to be aware of
1. An error will be thrown when you publish an extension with a higher runtime version than the one that
platform supports. For example, if you set the runtime value to 2.0 , you get the following error
message.
The runtime version of the extension package is currently set to '2.0'. The runtime version must be
set to '1.0' or earlier in the app.json file in order to install the extension package on this
platform.
2. When you lower the extension runtime version, you may get warnings about the newest features not
supported by the earlier versions of the platform.
3. A best-effort compilation is made when you publish an extension compiled with a lower runtime version.
This is allowed in order to avoid recompilation of the extension package every time you upgrade the
platform.
See Also
Debugging in AL
Developing Extensions
Microsoft .NET Interoperability from AL
Optimize Visual Studio Code for AL Development
2/6/2023 • 2 minutes to read • Edit Online
Visual Studio Code is built to handle many smaller dependent projects instead of one large project. However, as
the base application isn't yet split into modules or components that allow managing the code in smaller projects,
we recommend the following performance optimizations.
Open your settings.json file in the project (or global settings if you prefer that) pressing Ctrl+Shift+P . Set:
"al.enableCodeAnalysis": false to turn off code analysis completely, read more here Using the Code
Analysis Tool.
"al.backgroundCodeAnalysis": false to turn off running code analysis in the background, but code
analysis will be enabled when building with Ctrl+Shift+B . This is an alternative if analyzers are required
with "al.enableCodeAnalysis": true .
"al.enableCodeActions": false to turn off AL Code Actions, read more here AL Code Actions.
"al.incrementalBuild": true to allow the compiler to reuse the existing background compilation for
creating the package.
"editor.codeLens": false to turn off code lens in Visual Studio Code, see Code Navigation.
"[al]": {"editor.formatOnSave": false } to turn off formatting when saving a file for AL. If you still want
formatting, then you can adjust what to run formatting on, and you can choose modifications by using
the Format On Save Mode option.
Add the build folder to the exclusion list for Windows Defender.
See also
Development in AL
Best Practices for AL
Work with multiple AL project folders within one
workspace
2/6/2023 • 2 minutes to read • Edit Online
Visual Studio Code offers the multi-root workspace feature, which enables grouping different project folders
into one workspace. The AL Language extension also supports the multi-root functionality and allows you to
work with multiple AL folders including roots and projects within one workspace.
The al.packageCachePath setting allows you to specify the path to a folder that will act as the cache for the
symbol files used by your project. It can be specified in the User Settings , Workspace Settings , or Project
Settings . The al.enableCodeAnalysis setting allows you to enable the execution of code analyzers on your
project. It can likewise be specified in the User Settings , Workspace Settings , or Project Settings . For more
information, see AL Language Extension Configuration.
See also
Development in AL
Best Practices for AL
Working with Multiple Projects and Project References
Work with multiple projects and project references
2/6/2023 • 6 minutes to read • Edit Online
A project reference in an AL-based workspace is defined as a dependency in the app.json file and exists as a
project in the workspace. There's no special visual representation of a project reference.
IMPORTANT
A project reference is the full id , name , publisher , and version of an existing project in the workspace. This is
contrary to an application reference where it is enough to specify a minimal version. If you're using workspaces with
multiple projects and change the name or publisher of an extension in the workspace, the dependencies in the
app.json file must be updated with the new name and publisher or you may encounter issues with reference resolution.
For more information, see App Identity.
In the example below, the project called Leaf defines two dependencies to the projects Middle and Root . Since,
both Root and Middle are projects in the workspace they're considered project references.
The advantage of working with project references is that there's no need to download the symbols for a project
reference. They're there as the symbols for the reference project and will be resolved as they're modified. For
example, if you add a new method to a codeunit in the Root project and reference the codeunit in the Leaf
project, the method will automatically resolve as you touch the Leaf project.
When a project is built with Ctrl+Shift+B , the following will happen:
1. The .app file is copied to the .alpackages folder of all projects that depend on it.
2. All project references that might be "dirty" are also built.
NOTE
If reference resolution stops working then building the project reference and re-initializing the workspace using Reload
Window resolves references.
Publish changes
With the introduction of project references, the publishing logic in a workspace has changed. Publishing, either
with Ctrl+F5 or RAD publishing using Alt+Ctrl+F5 , will do a set publishing of all the projects that have
changed with defining a startup project. The startup project is always the active project.
A project is considered changed if any of its application objects have changed in the sense that the application
object is already in the rad.json or will be in the rad.json once the project has been built. This means that if
you change an application object, you save it, and then close Visual Studio Code without building the project, the
rad.json won't update and then the project won't be considered "dirty".
For example, in a workspace with three projects; Leaf , Middle , and Base . Leaf depends on Middle and Base ,
and Middle depends on Base as illustrated below:
Assuming that:
All the three projects; Leaf , Base , and Middle have changed.
The Leaf project is the current project that is published.
Then all the three projects; Base , Middle , and Leaf will be part of the set that will be published.
In a scenario where Middle hasn't changed, but Leaf is still the startup project, then only Base and Leaf will be
published.
A new file is created to package the set dependencies called *.dep.app . This file gets transferred to the server
and it's deleted if publishing of the dependency set is successful.
Server publishing changes
Although server publishing is an internal step, it does have an impact on the dependency publishing and is
useful to know.
For example, in a workspace with two projects; Leaf depends on Base , and External and Indirect are projects
outside of the workspace as illustrated below:
Assuming that:
A workspace exists with Leaf and Base as workspace projects.
Base is published.
On the server Base , Leaf , External , and Indirect are already installed apps.
The following happens on the server:
All apps that depend on Base will be uninstalled, including External and Indirect dependency.
Any other apps that directly depend on Base and aren't published in the global scope - in this case Leaf and
External - are unpublished.
Base will be uninstalled, unpublished, and then published.
Leaf and External will be published, installed and then compiled against the newly published Base .
Important to notice here's that the External app also will be published.
Strict Dependency publishing will fail if there are any installed apps
that depend on the startup project.
NOTE
With the Ignore setting only Leaf will be published against what has already been published on the server for Middle
and Base . If a change has been done on Base that would break Leaf , even though local compilation would pass, the
server compilation will fail in this scenario. The benefit of using this option is to gain publishing time when Base is a large
project. Assuming that Base is published, then Leaf and Middle will be left untouched on the server. Only runtime errors
will reveal if Base has broken Middle and Leaf .
To remove unnecessary manual work, use the AL: Publish full dependency tree for active project
command, which will traverse a project dependency graph in the workspace and install any required projects if
these aren't already deployed to the NST server. Find the command by using Ctrl+Shift+P or by using the
keyboard shortcut Shift+Alt+W . This will calculate the correct order in which to compile and publish the
dependencies of the current project and publish them using the launch.json option selected from the current
active project.
NOTE
Only project and app references covered by the workspace will be traversed. If the deployed AL project has dependencies
to apps that aren't included in the workspace, these will still have to be present or manually deployed in advance.
See also
Development in AL
Best Practices for AL
Working with multiple AL project folders within one workspace
JSON Files
The Code Analysis Tool
2/6/2023 • 3 minutes to read • Edit Online
This article shows you how to use static code analysis tool on an AL project from within Visual Studio Code.
NOTE
By default, code analysis is run in the background.
Code analyzers
A code analyzer is a library that builds on the compiler's functionality to offer enhanced analysis of the syntax
and semantics of your code at build time. The AL Language extension for Visual Studio Code contains four
analyzers:
CodeCop is an analyzer that enforces the official AL Coding Guidelines. For more information about the
CodeCop rules, see CodeCop Analyzer Rules.
PerTenantExtensionCop is an analyzer that enforces rules that must be respected by extensions meant to
be installed for individual tenants. For more information about the PerTenantExtensionCop rules, see
PerTenantExtensionCop Analyzer Rules.
AppSourceCop is an analyzer that enforces rules that must be respected by extensions meant to be
published to Microsoft AppSource. For more information about the AppSourceCop rules, see AppSourceCop
Analyzer Rules.
UICop is an analyzer that enforces rules that must be respected by extensions that are meant to customize
the Web Client. For more information about the UserInterfaceCop rules, see UICop Analyzer Rules.
See Also
Using the Code Analysis Tools with the Ruleset
Ruleset for the Code Analysis Tool
Development in AL
Directives in AL
Debugging in AL
AL Language Extension Configuration
AL Compiler Diagnostics
2/6/2023 • 53 minutes to read • Edit Online
AL0273 The name '{0}' is an Area type. Using Warning (Future Error)
an Area type name will limit
extensibility as dependent extension
won't be able to reference it.
AL0468 Length of the table field name '{0}' Warning (Future Error)
must not exceed {1} characters. Longer
field names are prone to cause SQL
errors.
AL0481 The property Image can only be used Warning (Future Error)
on fields that are contained in a
CueGroup control.
ID M ESSA GE DEFA ULT SEVERIT Y
AL0486 A member of type {0} with name '{1}' is Warning (Future Error)
already defined in {2} '{3}' by the
extension '{4}'.
AL0534 Length of the table key name '{0}' Warning (Future Error)
must not exceed {1} characters. Longer
key names are prone to cause SQL
errors.
AL0547 The event '{0}' should not expose Warning (Future Error)
global variables.
AL0548 Cannot move symbol '{0}' from '{1}' Warning (Future Error)
area to '{2}' area.
AL0550 Groups defined in the action area '{0}' Warning (Future Error)
should only contain actions.
AL0551 The action area '{0}' can only contain Warning (Future Error)
actions.
AL0552 The action area '{0}' can only directly Warning (Future Error)
contain groups.
AL0559 A Part type page cannot contain other Warning (Future Error)
parts.
AL0560 Only parts and groups are valid in an Warning (Future Error)
area of type 'RoleCenter'.
AL0561 Only parts are valid in an area of type Warning (Future Error)
'FactBoxes'.
AL0568 Groups defined in the action area '{0}' Warning (Future Error)
should only contain actions or groups.
AL0573 {0} is not valid for client expressions. Warning (Future Error)
AL0579 The value for the property '{0}' for the Error
language code '{1}' is not valid because
its length exceeds {2} characters ({3}
characters).
AL0589 The name '{0}' is used across multiple Warning (Future Error)
columns and data items. This will
prevent extensibility of this column or
data item.
ID M ESSA GE DEFA ULT SEVERIT Y
AL0593 The type of the parameter '{0}' on the Warning (Future Error)
event subscriber '{1}' has a smaller
capacity than the parameter type '{2}'
on the publisher.
AL0598 Cannot move or modify the {0} '{1}' in Warning (Future Error)
the same '{2}' that you added.
AL0600 The property '{0}' can only be set on Warning (Future Error)
elements of type Option.
AL0614 The value '{0}' is not allowed for Warning (Future Error)
property '{1}'.
AL0639 'Variant' is not a valid column type for Warning (Future Error)
column '{0}' in report '{1}'.
ID M ESSA GE DEFA ULT SEVERIT Y
AL0650 The text with a length of {0} is longer Warning (Future Error)
than the MaxLength of {1} which
means that the text will be trimmed.
AL0677 The member '{0}' in object '{1}' cannot Warning (Future Error)
be declared as protected in object type
'{2}'.
AL0692 The primary key '{0}' on table '{1}' Warning (Future Error)
cannot be obsolete. All related
properties will have no effect.
AL0694 The field '{0}' which is part of the Warning (Future Error)
primary key of table '{1}' cannot be
obsolete. All related properties will
have no effect.
AL0695 The method {0} will only be available Warning (Future Error)
for {1} development for runtime
version {2}.
AL0711 A member of type {0} with name '{1}' is Warning (Future Error)
already defined in {2} '{3}' by the
extension '{4}'. Duplicate member
names are not allowed when defining
CueActions.
AL0715 The {0} name '{1}' is reserved for future Warning (Future Error)
AL language features.
AL0727 The property '{0}' can only be set if the Warning (Future Error)
property '{1}' is set.
AL0728 The property '{0}' can only be set if the Warning (Future Error)
property '{1}' is set to '{2}'.
AL0729 The property '{0}' can only be set if the Warning (Future Error)
property '{1}' is set with any of the
values of: '{2}'.
AL0731 The name '{0}' does not exist in the Warning (Future Error)
current context.
AL0733 Access modifier '{0}' is not allowed for Warning (Future Error)
member '{1}' in the context of object
type '{2}'.
AL0743 The property '{0}' is not valid for the Warning (Future Error)
cue action '{1}'.
AL0745 The property '{0}' is not valid for action Warning (Future Error)
'{1}' defined in a report request page.
ID M ESSA GE DEFA ULT SEVERIT Y
AL0751 Enum values can't be nested. Use '{0}' Warning (Future Error)
instead.
AL0758 The name of {0} '{1}' conflicts with {0} Warning (Future Error)
'{2}' defined in {3} '{4}' by the extension
'{5}'. Please choose another name for
one of them. Otherwise, this might
cause runtime issues.
AL1078 Key vault URL is not a valid Azure key Warning (Future Error)
vault URL. A valid key vault URL must
use HTTPS and point to the Azure key
vault domain.
ID M ESSA GE DEFA ULT SEVERIT Y
AL1404 The action '{0}' is not found in the Designer Customization Warning
target '{1}'.
AL1405 The control '{0}' is not found in the Designer Customization Warning
target '{1}'.
AL1406 The view '{0}' is not found in the target Designer Customization Warning
'{1}'.
ID M ESSA GE DEFA ULT SEVERIT Y
AL1410 The target {0} {1} for the extension Designer Customization Warning
object is not found.
AL1412 {0} '{1}' is marked for removal. {2}. Designer Customization Warning
AL1413 A member of type {0} with name '{1}' is Designer Customization Warning
already defined in {2} '{3}' by the
extension '{4}'.
AL1414 The page customization for page '{0}' Designer Customization Information
does not make any modifications, so it
can be removed without affecting any
profiles or user personalization.
AL1416 The {0} '{1}' cannot be moved relatively Designer Customization Information
to '{2}' because '{2}' is missing. This
move is ignored.
AL1417 The {0} '{1}' cannot be added relatively Designer Customization Information
to '{2}' because '{2}' is missing. '{1}' is
added at a default location instead.
AL1418 A DataItem with name '{0}' could not Designer Customization Warning
be found in the target {1}.
AL1420 The {0} '{1}' cannot be used as target Designer Customization Warning
of the ActionRef '{2}'. ActionRefs can
only target Actions. Ignoring the
ActionRef.
AL1421 The {0} '{1}' is using the '{2}' property. Designer Customization Warning
This will be automatically converted to
the new syntax when customizing the
related page in the webclient.
ID M ESSA GE DEFA ULT SEVERIT Y
See Also
Get Started with AL
Developing Extensions
Ruleset for the Code Analysis Tool
2/6/2023 • 2 minutes to read • Edit Online
In an AL project, you can use a custom ruleset file to specify how code analysis will report the issues it
encounters. Different settings can affect how rules are applied and each ruleset file name must follow the
pattern <name>.ruleset.json to benefit from IntelliSense in Visual Studio Code.
NOTE
Use the truleset and trule snippets provided by the AL Language extension to create your ruleset.
An IncludedRuleSet is a complex JSON object that defines the inclusion of an external ruleset file in the
current ruleset, and has the following properties:
action Yes Error | Warning | Info | Hidd The action to apply for all
en | None | Default the diagnostics that have
an action specified in the
included ruleset that is
different from None and
Hidden .
A Rule is a complex JSON object that defines how you can process a specific diagnostic. A Rule object has the
following properties:
action Yes Error | Warning | Info | Hidd The action to apply if the
en | None diagnostic is emitted. There
can't be two rules with the
same id and different
actions in the same rule file.
Examples
The following example shows a ruleset that sets the severity of rule AA0001 : There must be exactly one
space character on each side of a binar y operator such as := + - AND OR =. provided by the
CodeCop analyzer to Error .
{
"name": "Company ruleset",
"description": "These rules must be respected by all the AL code written within the company.",
"rules": [
{
"id": "AA0001",
"action": "Error",
"justification": "This diagnostic helps to improve readability. It must be respected in all
cases."
}
]
}
The following example shows a project-specific ruleset that extends a company-wide ruleset contained in the file
company.ruleset.json and sets the severity of the rule AA0005 : Only use BEGIN..END to enclose
compound statements. provided by the CodeCop analyzer to Info .
{
"name": "Personal Project ruleset",
"description": "A list of project specific rules",
"includedRuleSets": [
{
"action": "Default",
"path": "./company.ruleset.json"
}
],
"rules": [
{
"id": "AA0005",
"action": "Info",
"justification": "For this specific project, this diagnostic should be informational."
}
]
}
See Also
Using the Code Analysis Tools
Using the Code Analysis Tools with the ruleset
AL Development Environment
Directives in AL
AL Language Extension Configuration
Using the Code Analysis Tools with the Ruleset
2/6/2023 • 3 minutes to read • Edit Online
This article helps you to customize a ruleset for the severity of diagnostics produced by the code analysis tools
that are part of the AL Language extension for Visual Studio Code.
On the View tab of Visual Studio Code, select the Problems option and you'll see a warning with the message
"There must be exactly one space character on each side of '+'." . In this case, the problem can be fixed
by running the AL Formatter command. For more information, see AL Formatter.
{
"name": "My Custom ruleset",
"rules": [
{
"id": "AA0001",
"action": "None"
}
]
}
4. In your project settings, set Rule Set Path to the path of the <name>.ruleset.json file, relative to the
project root. For more information about custom rules, see Ruleset for the Code Analysis Tool.
NOTE
Use the truleset and trule snippets provided by the AL Language extension to create your ruleset. The ruleset will
be applied to all the analyzers enabled for the current project. For more information about selectively enabling analyzers,
see The Code Analysis Tools.
Limitations
Changing the contents of the ruleset file won't be detected by the AL Language extension. To see the effects of
changing the ruleset file, you can try any of the following steps:
Reload the window.
In the project settings, change the Rule Set Path setting to an invalid path and save it. Then change it back
and save again.
See also
Ruleset for the Code Analysis Tool
Using the Code Analysis Tools
Directives in AL
Development in AL
Debugging in AL
AL Language Extension Configuration
AppSourceCop Analyzer Rules
2/6/2023 • 10 minutes to read • Edit Online
AppSourceCop is an analyzer that enforces rules that must be respected by extensions meant to be published to
Microsoft AppSource.
Rules
ID T IT L E C AT EGO RY DEFA ULT SEVERIT Y
NOTE
Several rules enforced by the AppSourceCop analyzer are incompatible with rules enforced by the PerTenantExtensionCop.
Make sure to enable only one of these at a time.
NOTE
Failing to comply with the rules whose default severity is set to Error will fail the submission of your extension to the
AppSource marketplace. It is recommended, but not mandatory to comply with the rules whose severity is marked as
Warning or Info .
Configuration
The AppSourceCop analyzer can be further configured by adding a file named AppSourceCop.json in the
project's root folder. The AL Language extension will offer IntelliSense for this file.
The following table describes the settings in the AppSourceCop.json file:
SET T IN G M A N DATO RY VA L UE
The name , publisher , version properties are used for specifying a previous version of the current package.
This package must be located in the baseline package cache folder of your extension. This cache can be specified
using the baselinePackageCachePath property. If this property is not specified, the dependency package cache
path of the extension will be used instead. The al.packageCachePath setting allows you to specify the path to the
folder that will act as the cache for the dependencies symbol files used by your project. AppSourceCop will
compare the previous version of your extension with its current version and will report any breaking changes
introduced by the current package.
The mandatoryAffixes property specifies strings that must be prepended or appended to the names of all new
objects, extension objects and fields. By using these affixes, you can prevent clashes between objects added by
your extension and objects added by other extensions.
The supportedCountries property specifies the codes that correspond to the countries for which the product
allows AppSource submissions. For more information, see Availability and supported Countries/Regions and
Translations
The properties obsoleteTagVersion , obsoleteTagPattern , and obsoleteTagPatternDescription can be used to
enable additional validation on object obsoletion. These are not required for AppSource submissions.
Example
In the following example, we will configure AppSourceCop to validate that all new elements have a name that
contains one of the specified affixes.
NOTE
Make sure that code analysis is enabled and ${AppSourceCop} is specified in the list of enabled code analyzers. For more
information see AL Language Extension Configuration.
We continue by adding the configuration file AppSourceCop.json in the project's root folder and setting its
content to the following.
{
"mandatoryAffixes": [ "Foo", "Bar" ]
}
IMPORTANT
If you are running a multi-root workspace environment, you must have one AppSourceCop.json file in the root folder of
each of the projects. For more information, see Working with multiple AL project folders within one workspace.
AS0011: The identifier 'CustomerListExt' must have at least one of the mandatory affixes 'Foo, Bar'.
Prepending Foo to the name of the page extension object will fix this error and prevent clashes between this
page extension and page extensions added by other developers.
NOTE
It is still possible to use the mandatoryPrefix and mandatorySuffix properties in the AppSourceCop.json . For more
information see AS0011.
See Also
Using the Code Analysis Tool
Ruleset for the Code Analysis Tool
Using the Code Analysis Tools with the Ruleset
CodeCop Analyzer Rules
2/6/2023 • 5 minutes to read • Edit Online
Rules
ID T IT L E C AT EGO RY DEFA ULT SEVERIT Y
See Also
Using the Code Analysis Tool
Ruleset for the Code Analysis Tool
Using the Code Analysis Tools with the Ruleset
PerTenantExtensionCop Analyzer Rules
2/6/2023 • 2 minutes to read • Edit Online
PerTenantExtensionCop is an analyzer that enforces rules that must be respected by extensions meant to be
installed for individual tenants.
Rules
ID T IT L E C AT EGO RY DEFA ULT SEVERIT Y
See Also
Using the Code Analysis Tool
Ruleset for the Code Analysis Tool
Using the Code Analysis Tools with the Ruleset
UICop Analyzer Rules
2/6/2023 • 2 minutes to read • Edit Online
UICop is an analyzer that enforces rules that must be respected by extensions meant to customize the Web
Client.
Rules
ID T IT L E C AT EGO RY DEFA ULT SEVERIT Y
See Also
Using the Code Analysis Tool
Ruleset for the Code Analysis Tool
Using the Code Analysis Tools with the Ruleset
Compilation Scope Overview
2/6/2023 • 2 minutes to read • Edit Online
In Dynamics 365 Business Central, there are different layers to manage what can be published to the server and
accessed from within a project.
IMPORTANT
The Internal and Extension values have been deprecated, starting with runtime 4.0 and replaced by the OnPrem
and Cloud respectively.
The target property informs the compiler which APIs can be used within the current project.
If you specify "target":"OnPrem" , you can use any platform APIs and .NET types. This is the most permissive
target. It's only if you specify this target, that you can use methods marked with Scope('OnPrem') or tables
with the property Scope (Tables) set to OnPrem .
If you specify "target":"Cloud" , you can only use APIs that are safe for use in a cloud environment. If the
target is set to Cloud , the extension can't use any method marked with Scope('OnPrem') or table with the
property Scope set to the OnPrem . For example, if you have two extensions; A and B. Extension A has an
app.json target setting "target": "OnPrem" and defines a method with the Scope Attribute set to
[Scope('OnPrem')] . Extension B has a dependency on extension A and extension B has an app.json target
setting "target": "Cloud" and tries to call the method in extension A marked with scope OnPrem , you'll get a
compile error when you're trying to compile extension B. For more information, see JSON Files.
NOTE
A table with the property Scope set to OnPrem carries this scope forward to every other object that might refer it as
SourceTable , even if those elements are declared within the same extension.
See Also
AL Development Environment
Developing Extensions in AL
JSON Files
Scope Attribute
Scope (Table) Property
Configuring Business Central Server
Debugging in AL
2/6/2023 • 7 minutes to read • Edit Online
Debugging is the process of finding and correcting errors. With Visual Studio Code and the AL Language
extension, you get an integrated debugger to help you inspect your code and verify that your application can
run as expected. You can start a debugging session by pressing F5 . For more information about Debugging in
Visual Studio Code, see Debugging.
An alternative to classic debugging is snapshot debugging, which allows you to record running code, and later
debug it. For more information, see Snapshot Debugging.
IMPORTANT
To enable debugging in versions before Business Central April 2019, the NetFx40_LegacySecurityPolicy setting in the
Microsoft.Dynamics.Nav.Server.exe.config file must be set to false . This step requires a server restart.
IMPORTANT
To use the development environment and debugger, you must make sure that port 7049 is available.
TIP
To be able to debug an online environment with an Embed app published in it, make sure to specify the
applicationFamily parameter in your launch.json file. You must define the application family for your Embed app
during onboarding.
Breakpoints
The basic concept in debugging is the breakpoint, which is a mark that you set on a statement. When the
program flow reaches the breakpoint, the debugger stops execution until you instruct it to continue. Without
any breakpoints, the code runs without interruption when the debugger is active. You can set a breakpoint by
using the Debug Menu in Visual Studio Code. For more information, see Debugging Shortcuts.
Set breakpoints on the external code that isn't part of your original project. You can step into the base
application code by using the Go to Definition feature and set breakpoints on the referenced code, which is
generally a .dal file. To set a breakpoint on the external code or base application code, you do as follows:
Use Go to Definition , which opens the "external file", and then a breakpoint can be set.
By using the debugger, you can step into the code, and then set a breakpoint.
The following video illustrates that Customer.dal is an external file. A breakpoint is set in the Customer.dal file,
which is referenced from your AL project to stop execution at the marked point.
Break on errors
Specify if the debugger breaks on the next error by using the breakOnError property. If the debugger is set to
breakOnError , it stops execution on both errors that are handled in code and unhandled errors.
The default value of the breakOnError property is true , which means the debugger stops the execution that
throws an error by default. To skip the error handling process, set the breakOnError property to false in the
launch.json file.
TIP
If the debugging session takes longer, you can refresh the session by pressing the Ctrl+Shift+P keys and selecting
Reload Window .
REC O RD C H A N GE A L M ET H O DS
Debugging shortcuts
K EY ST RO K E A C T IO N
F5 Start debugging
F12 Go To Definition
For more shortcuts, see Debugging in Visual Studio Code. For working with Snapshot Debugging, see Snapshot
Debugging.
Current SQL latency (ms) When the debugger hits a breakpoint, the Business Central
Server will send a short SQL statement to the database, and
measures the time it takes. The value is in milliseconds.
Number of SQL Executes This number shows the total number of SQL statements
executed in the debugging session since the debugger was
started.
Number of SQL Rows Read This number shows the total number of rows read from the
Business Central database in the debugging session since
the debugger was started.
TIP
You can also get database insights from the AL runtime by using the SqlStatementsExecuted() and SqlRowsRead()
methods.
Statement The SQL statement that the AL server sent to the Business
Central database. For further analysis, you can copy the SQL
statement into other database tools, such as SQL Server
Management Studio.
Execution time (UTC) The timestamp (in UTC) of when the SQL statement was
executed. You can use this to infer whether the SQL
statement was part of the AL code between the current and
last breakpoint (if set).
IN SIGH T DESC RIP T IO N
Approx. Rows Read This number shows the approximate number of rows read
from the Business Central database by the SQL statement.
You can use this insight to analyze whether you're missing
filters.
The number of SQL statements tracked by the debugger can be configured in the Business Central Server. The
default value is 10.
NOTE
For Business Central on-premises, the Business Central Server instance has several configuration settings that control the
SQL statistics. These statistics are gathered and then displayed in the debugger, like whether long running SQL
statements or SQL statements are shown. Check the server configuration if you don't see the insights that you expect in
the debugger. For more information, see Configuring Business Central Server.
NonDebuggable attribute
The ability to debug certain methods and/or variables can be restricted. For more information, see
NonDebuggable Attribute.
See Also
Attach and Debug Next
Developing Extensions
JSON Files
AL Code Navigation
Attach and Debug Next
2/6/2023 • 2 minutes to read • Edit Online
If you don't want to publish and invoke functionality to debug it, you can instead attach a session to a specified
server, and await a process to trigger the breakpoint you've set. Then debugging starts when the code that the
breakpoint is set on is hit.
NOTE
To use the attach functionality, you must make sure that your app is published with Ctrl+F5 first, or with Alt+Ctrl+F5
for RAD publishing, before you start the debugging session with F5 . To debug using attach, you must make sure to
debug on a new session. Creating a new server session from the client can be achieved for example by launching a new
client session. Pressing F5 (Refresh) in a browser may not create a new server session, because it is cached, but if a session
is expired and refreshed that will create a new session.
IMPORTANT
Only the user who starts a Visual Studio Code attach session can issue the Web request on the server.
Attach configuration
You can activate the attach functionality by creating a new configuration in the launch.json file. The
configuration has two flavors; Attach to the next client on the cloud sandbox and Attach to the next
client on your ser ver . Use the first option to attach to a cloud session, and the second option to attach to a
local server.
In the attach configuration, the breakOnNext setting specifies the next client to break on when the debugging
session starts and allows only one option. The available options are: WebServiceClient , WebClient , and
Background . The example below illustrates a configuration for a local server.
...
{
"name": "My attach to local server",
"type": "al",
"request": "attach",
"server": "https://localhost",
"serverInstance": "BC200",
"authentication": "Windows",
"breakOnError": true,
"breakOnRecordWrite": false,
"enableSqlInformationDebugger": true,
"enableLongRunningSqlStatements": true,
"longRunningSqlStatementsThreshold": 500,
"numberOfSqlStatements": 10,
"breakOnNext": "WebClient"
}
...
Attach support
The following configurations for attach are supported:
IMPORTANT
If you modify the app code during the debugging session, make sure to re-publish the app using Ctrl+F5 .
NOTE
If you have more attach configuration settings, you must first select which configuration to start.
7. Debug and inspect the code. You can add more breakpoints while debugging.
8. Stop the attach debugging session by selecting Detach in the Visual Studio Code toolbar.
See Also
AL Development Environment
Developing Extensions in AL
Debugging
Snapshot Debugging
JSON Files
EnableLongRunningSQLStatements Property
EnableSQLInformationDebugger Property
LongrunningSQLStatementsThreshold Property
NumberOfSQLStatements Property
Snapshot Debugging
2/6/2023 • 10 minutes to read • Edit Online
NOTE
With Business Central 17.2 - Snapshot Debugging is available in production cloud environments.
With snapshot debugging, you can record AL code that runs on the server, and when it has completed, debug
the recorded snapshot in Visual Studio Code. Snapshot debugging lets you inspect code execution and variables
in the production environment on a cloud service for a specified user session. To create and download a
snapshot file that exists on the server on behalf of an end-user, the user must be part of the D365 Snapshot
Debug permission set. For more information, see Assign Permissions to Users and Groups.
Snapshot debugging introduces the concept of snappoints. A snappoint is a breakpoint in Visual Studio Code
that is set while creating a snapshot but they don't stop execution of code like regular debugging. Snappoints
log the state at the breakpoint for later offline inspection. Snapshot debugging will record AL code as it runs on
the server, but will only collect variable information on:
Snappoints
AL exceptions
NOTE
With Business Central version 18.1, it's possible to snapshot the debug event subscribers triggered by built-in codeunit
triggers if a snappoint is placed in an AL file on the stack trace that leads to the built-in method. For more information,
see Snapshot debugging built-in methods.
IMPORTANT
To enable snapshot debugging, it's very important that the symbols on the tenant match the symbols on the server. This
isn't automatically detected, and must be manually checked. In this release, you can ensure this by copying the specific
sandbox and download symbols from that copy. Furthermore, any code that snappoints are set in, must have been
deployed, otherwise debugging will not work. For more information, see the section Downloading symbols on the
snapshot debugger endpoint.
K EY B O A RD SH O RTC UT A C T IO N
userId The GUID of the user who initiated the process to start
snapshot debugging. For on-premises, this can also be the
user name in user password authentication scenarios. The
user must be able to start, or have a session type opened
that is specified in the breakOnNext parameter.
Note: Specifying userId doesn't work with Windows
authentication: "authentication" : "Windows" , in which
case you can only choose sessionId or attach to the next
session. For more information, see JSON Files.
tenant The AAD tenant ID for the tenant to connect to. Specify this
if your target is a different tenant from the user's own AAD
tenant, for example when running as a delegated admin.
When a configuration is defined, a snapshot debugging session can be initialized by pressing Ctrl+Shift+P ,
and then selecting AL:Initialize Snapshot Debugging or by pressing F7 .
NOTE
If you're going to use the snapshot for profiling the code, you must enable the configuration parameter called
executionContext . For more information, see AL Profiler Overview.
To record the AL execution, the server will now wait for a connection to happen where the following rules apply:
If a sessionId is specified for a userId in the given tenant, then it will be the session that's going to be
snapshot debugged.
If only a userId is specified for a given tenant then the next session that is specified in the breakOnNext
configuration parameter is snapshot debugged.
If no userId is specified then the next session on a given tenant that validates the breakOnNext parameter
will be snapshot debugged.
TIP
If you're having difficulty getting the snapshot debugger to attach to a new session using WebClient for the
breakOnNext configuration parameter, then close the browser window and try again.
TIP
To do snapshot debugging of Service to Service (S2S) web service calls set the breakOnNext configuration parameter to
WebServiceClient in the launch.json file and use table explorer to find the userId of the user record mapped to
the S2S Azure AD Authentication Application. When the snapshot session is initialized, trigger the session either from the
integration (service or device) or manually by invoking a web service call using tools like Postman or Fiddler. For
information about creating S2S refer to Using Service to Service Authentication, Client Credentials Grant Flow, App-only
Authentication, and Postman HowTo.
Once a snapshot debugging session is initialized, the snapshot debugging session counter on the status bar will
be updated and look like this:
IMPORTANT
The snapshot file can contain customer privacy data and must therefore be handled according to the privacy and
compliance policies. The file should be deleted when it's not needed anymore.
Snapshot debugging sessions that have produced a snapshot file can be debugged. The location of a snapshot
file is controlled by the al.snapshotOutputPath configuration parameter. By default it's local to the current
workspace and it's called ./.snapshots . For more information, see AL Language Extension Configuration.
IMPORTANT
Debugging requires that symbols on the server are matched with the symbols that the user has locally. If this isn't the
case, and you set a breakpoint on a given line in Visual Studio Code, the line of the code may differ from what is on the
server. For example, if you don't download the symbols from the production servers for snapshot debugging, you can face
a scenario where you set a breakpoint in a DAL file on line 12, but line 12 on the server is an empty line or a completely
different line because the symbols aren't the same.
During snapshot debugging playback, the left-side code editor gutter contains a vertical visual bar to indicate
which code was executed in the snapshot capture. The color of the gutter bar can be controlled using the
al.snapshotDebuggerLinesHitDecoration in the settings.json file. For more information, see AL Language
Extension Configuration.
Breakpoints can be added or removed and they'll be hit if the breakpoint is in the execution context of a recorded state. This
means that if you walk the execution stack for a breakpoint and the next stepped line is reached, then the code will break on
the breakpoint.
A snappoint is a breakpoint in Visual Studio Code that is set when creating a snapshot. They don't, however, stop execution of
code like when using regular debugging. Snappoints instruct execution to log the state at the breakpoint for later offline
inspection.
You can always navigate through all the breakpoints with Continue (F5). The order may not be the same as the execution
order on the Business Central server. This is because some calls on the server are AL calls with non-walkable stacks. Some are
direct server calls on the server like triggers. A snapshot debugging session on the Business Central server can only record AL
calls and walk AL stack traces.
This is also true when stepping. The rule of thumb is that breakpoints within the reach are hit first, and if there are none; the
next line is hit. Breakpoints on triggers may not always qualify as code within reach.
Stepping out of triggers with no recorded stack information will move execution to the first recorded method's first line. This
may be far from the user's execution of interest. For example, stepping out from an OnOpenPage trigger with a snappoint
may land on deep inside base code execution where recording has started. Navigating with F5 will start over breakpoint
resolution, thus this is an exit strategy from a scenario like this.
A snappoint may resolve as a non-reachable breakpoint if there was no execution state on the server hitting the snappoint.
A snapshot debugger session with a Business Central server will be closed if not attached to after 30 minutes.
See Also
Debugging
Attach and Debug Next
Developing Extensions
JSON Files
AL Code Navigation
EnableLongRunningSQLStatements Property
EnableSQLInformationDebugger Property
LongrunningSQLStatementsThreshold Property
NumberOfSQLStatements Property
Debug Upgrade and Install Code
2/6/2023 • 2 minutes to read • Edit Online
To test and troubleshoot issues in install and upgrade code, it's important to ensure that these processes run
smoothly when the app is installed for the first time or when it's upgraded. You can add breakpoints in the install
or upgrade code, and then attach and trigger publishing of an extension to debug these scenarios.
NOTE
If you don't increment the version of the app, the install codeunits will not be invoked. If you do increment the
version of the app, or if you set the forceUpgrade flag to true in the launch.json file, the upgrade
codeunits will be invoked.
3. If your app isn't yet published, then use Ctrl+F5 to publish the app file first; the attach option won't publish
the app. After, start the attach session as you would normally start the debugging session with F5 .
See Also
Debugging
Snapshot Debugging
Attach and Debug Next
AL Profiler Overview
2/6/2023 • 8 minutes to read • Edit Online
> INTRODUCED IN: Business Central 2021 release wave 2 and updated with sampling profiling for Business
Central 2022 release wave 1.
Profiling allows you to collect data about performance and analyze this data with the goal of optimizing a
certain area in the code or a certain process. The AL Profiler for the AL Language extension offers options for
instrumentation profiling and sampling profiling.
O P T IO N DESC RIP T IO N
"configurations": [
{
"name": "Your own server",
"type": "al",
"userId": "555",
"request": "snapshotInitialize",
"environmentType": "OnPrem",
"server": "http://localserver",
"serverInstance": "BC200",
"authentication": "Windows",
"breakOnNext": "WebClient",
"executionContext": "Profile",
"profilingType": "Sampling"
}
L AY ER C O LO R
System Blue
The color legend can be changed by specifying the al.profilerColors property in the AL configuration. For
more information, see AL Language Extension Configuration.
IMPORTANT
If you run Visual Studio Code with the setting Run as administrator , the graph will not display in the performance
profiling editor view. As a workaround, you can launch Visual Studio Code from the command line with the flag
--no-sandbox .
View modes
To switch between views, you can either right-click the profile file and choose a view, or you can use the small
button in the upper right corner. There are two different view modes in the graph; top-down and bottom-up.
When sorting the stack in top-down direction, the graph sorts the methods according to the call sequence,
which means that the child nodes are the methods called from the parent node. And when sorting bottom-up,
the graph is sorted as a reverse call stack, which means that the child nodes are methods who called the parent
node.
Details
To investigate further, the Self-time and Total time columns are important indicators of where time is spent in
the code. The Self-time is the amount of time spent in the method only, excluding any calls out of the method.
The Total time is the amount of Self-time plus any calls out of the method. On bottom-up graphs the Total
time and Self-time columns are sortable. Clicking them will first sort them in ascending order, clicking again
will sort them in descending.
Hit count is only available on top-down graphs and shows the number of times a specific method was called.
Time spent is aggregated.
Filter
The nodes in the graph can be filtered. The syntax is as follows:
@column name | <alias> <op> <value> where
<column name> := [function, url, path, selfTime, totalTime, id, objectType, objectName, declaringApplication]
C o l u m n n a m e a l i a se s
The aliases that are available for the column names are:
<alias> := [f, u, p, s, t, id, ot, on, da]
<op> := [numeric operators, boolean operators, string operators]
numeric operators : [:, =, >, <, <=, >=, <>, !=]
: := equal
boolean operators : [:, =, <>, !=]
string operators : [:, =, !=, <>, ~, =]
~ = := <regex>
F i l t e r e x a mp l e s
@t > 1000 Shows all nodes in the graph where the total time is greater
than 1 second.
@h > 20 Shows all nodes in the graph where the hit count was larger
than 20.
@da ~= Ba* Shows all nodes in the graph that start with Ba.
K EY B O A RD SH O RTC UT A C T IO N
*(star) Expand one level for all nodes. Consecutive keystrokes will
expand to the next level.
NOTE
Because of the aggregation of frames, there can be minor discrepancies between the information appearing in the
CodeLens and in the profiler.
Sampling profiling
Sampling profiling is useful as an initial analysis of code performance. You can perform sampling profiling in
Visual Studio Code on AL code. Sampling profiling is based on a snapshot of running code. It gets the AL stack
frame of the currently executing AL method in the context of an attached session in a given time interval.
Sampling isn't as accurate as instrumentation profiling is. But it can give an indication about the self-time of an
AL method. The benefit of doing sampling profiling is that it's less noisy and is much faster to get profile
information.
There are a few server restrictions for sampling profiling to be aware of:
The maximum duration of a sampling session is 10 minutes. This is a configurable server setting.
The number of stack frame entries is limited to 2000. This is a configurable server setting.
Performance profiling in Business Central
In Business Central, you can use the Performance Profiler page to record a snapshot to do sampling profiling.
This allows for recording of a process that seems slow directly in Business Central. When the Performance
Profiler has run and recorded a process in Business Central, it generates a .alcpuprofile file, which can be
downloaded and shared using OneDrive. When receiving such a .alcpuprofile file, it can be opened in the
Visual Studio Code and further investigated. For more information, see Performance Profiler Overview.
See Also
Snapshot Debugging
AL Language Extension Configuration
Performance Profiler Overview
Work with Rapid Application Development
2/6/2023 • 2 minutes to read • Edit Online
When working with Visual Studio Code and Dynamics 365 Business Central, you can benefit from Rapid
Application Development (RAD) on large code projects. RAD allows faster development on projects with a large
number of files by doing a delta compilation and publishing only on those application objects that have changed
during development in Visual Studio Code. RAD publishing is an interim state and doesn't replace a full publish.
IMPORTANT
The rad.json file should not be modified.
IMPORTANT
If you change many files and close Visual Studio Code without a build (Ctrl+Shift+B ), publish (Ctrl+F5 , Ctrl+Shift+F5 )
or debug (F5 , Shift+F5 ), all the RAD changes will be lost. This means that if you, in the next Visual Studio Code session
perform a RAD publishing, it'll be done on the latest changes and not on the prior changes. This can lead to an
incomplete published package if it succeeds. It's therefore a best practice to do a regular publish. You can always check the
RAD file in the code project to see what application objects are going to be changed during publishing.
In scenarios when application IDs are renamed, or refactored it's also a best practice to first do a full publishing,
and then a RAD publishing for the consecutive changes. RAD doesn't check for application ID changes and ID
changes can occur in a wrongly published application.
A RAD published file won't contain the following files that are normally packaged during regular publishing:
Translation files
Permission files
Custom word and report rdl layout files
Table data
Web service definitions
These files will need to be regenerated with full publishing (Ctrl+F5 ). A RAD file will be deleted as a result of a
successful publishing.
NOTE
If RAD publishing fails, then you must do a full publishing before performing another RAD publishing. The final state of an
application must be built using full publishing, and never with RAD publishing.
NOTE
When building using RAD, all translations will be ignored, even though the "features": [ "TranslationFile" ]
setting is specified in the app.json file. For more information, see Working with Translation Files.
RAD shortcuts
There are two commands for starting a RAD-based action.
See also
Developing Extensions in AL
Debugging
Sign an APP Package File
2/6/2023 • 3 minutes to read • Edit Online
Code signing is a common practice for many applications. It's the process of digitally signing a file to verify the
author and that the file hasn't been tampered with since it was signed. The signature of the APP package file is
verified during the publishing of the extension using the Publish-NAVApp cmdlet. For more technical information
on signing, see Authenticode.
NOTE
If you want to publish an unsigned extension package in your on-premise environment, you need to explicitly state it by
using the - SkipVerification parameter on the Publish-NAVApp cmdlet. An extension without a valid signature won't be
published on AppSource.
The signing of an APP package file must be performed on a computer that has Dynamics 365 Business Central
installed. If you're running Dynamics 365 Business Central on Docker for your development environment, that
environment will meet this requirement. You must also have the certificate that will be used for signing on the
computer. The certificate must include code signing as the intended purpose. It's recommended that you use a
certificate purchased from a third-party certificate authority.
IMPORTANT
If you publish the extension as an app on AppSource, the APP package file must be signed using a certificate purchased
from a Certification Authority that has its root certificates in Microsoft Windows. You can obtain a certificate from a range
of certificate providers, including but not limited to DigiCert and Symantec, see the image below. You don't have to use an
EV Code Signing certificate, standard code signing certificates can be used for signing your extensions.
IMPORTANT
It's recommended to use a time stamp when signing the APP package file. A time stamp allows the signature to be
verifiable even after the certificate used for the signature has expired. For more information, see Time Stamping
Authenticode Signatures. Depending on the certification authority, you may need to acquire a specific certificate in order
to time stamp, an Extended Validation certificate from DigiCert for example.
NOTE
If you are using the BCContainerHelper PowerShell module to run Dynamics 365 Business Central on Docker, you can use
the function Sign-BCContainerApp to perform all the steps above.
Self-signed certificate
For testing purposes and on-premises deployments, it's acceptable to create your own self-signed certificate
using the New-SelfSignedCertificate cmdlet in PowerShell on Windows 10 or MakeCert.
The following example illustrates how to create a new self-signed certificate for code signing:
The following (deprecated) MakeCert command is used to create a new self-signed certificate for code signing:
See Also
Get Started with AL
Keyboard Shortcuts
AL Development Environment
Use Azure AD Authentication for Business Central
On-Premises Installations
2/6/2023 • 2 minutes to read • Edit Online
In addition to using Windows and NavUserPassword authentication, you can use Azure AD to authenticate and
publish in on-premises installations and containers from Visual Studio Code. Using Azure AD makes it possible
to mimic application lifecycle operations in an on-premises environment, while keeping the cloud-based Azure
AD authentication.
To enable Azure AD authentication, make sure to do as follows:
Use the primaryTenantDomain setting in the launch.json file to specify the URL of the Azure AD organization
or company associated with the Azure AD tenant. For more information, see Find tenant ID, domain name,
user object ID and JSON Files.
On the NST, you must ensure that the server is set up to use Azure AD as authentication mechanism. For
more information, see User Authentication with Azure AD for Single Sign-on.
Furthermore, if the Allowed Extension Target Level setting is set to Cloud , the server setting
ForceExtensionAllowedTargetLevel must be set to true . If the Allowed Extension Target Level setting is set
to OnPrem , it isn't necessary to set ForceExtensionAllowedTargetLevel . For more information, see Microsoft
Dynamics 365 Business Central Server Configuration.
See also
JSON Files
User Authentication with Azure AD for Single Sign-on
Find tenant ID, domain name, user object ID
Testing the Application Overview
2/6/2023 • 7 minutes to read • Edit Online
Before you release your Business Central application, you should test its functionality to ensure it works as
expected. Testing is an iterative process. It's important and helpful to create repeatable tests that can be
automated. This article describes the features in Business Central to help you test the business logic in your
application and provides best practices for testing.
For a walkthrough concerning advanced extension testing, see Testing the Advanced Extension Sample.
Business Central includes the features that are listed below to help you test your application.
B USIN ESS C EN T RA L
SO L UT IO N EN VIRO N M EN T T EST IN G A L LO W ED M O RE DETA IL S
TIP
You can reuse test runners from Test Runner module in the Microsoft/ALAppExtensions GitHub repo. You can also use the
repo to request for the new functionality.
Test pages
Test pages mimic actual application pages but don't present any UI on a client computer. Test pages let you test
the code on a page by using AL to simulate user interaction with the page.
There are two types of test pages:
TestPage, which is a regular page and can be of any kind. It includes page parts and subpages as well.
TestRequestPage, which represents the request page on a report.
You access the page's fields and properties or a field by using the dot notation. You can open and close test
pages, do actions on the test page, and navigate around the test page by using AL methods. For more
information, see Testing Pages.
UI handlers
To create tests that can be automated, you must handle cases when user interaction is requested by the code
that is being tested. UI handlers run instead of the requested UI. UI handlers provide the same exit state as the
UI. For example, a method that has the ConfirmHandler Attribute set, handles Confirm Method calls. If code that
is being tested calls the Confirm Method, then the ConfirmHandler method is called instead of the Confirm
Method. You can write code in the ConfirmHandler method to verify that the expected question is displayed by
the Confirm Method. You can also write AL code to return the relevant reply.
For each page and report that you want to handle, you need to create a specific handler for the page and a
specific report handler for the report.
If you run a test codeunit from a test runner codeunit, then any unhandled UI in the test methods of the test
codeunit causes a failure of the test. If you don't run the test codeunit from a test runner codeunit, then any
unhandled UI is displayed as it typically would.
For more information, see Create Handler Methods.
ASSERTERROR Keyword
You use AssertError statements in test methods to test how your application behaves under failing conditions.
These statements are called positive and negative tests. The AssertError keyword specifies that an error is
expected at run time in the statement that follows the AssertError keyword.
If a simple or compound statement that follows the AssertError keyword causes an error, then execution
successfully continues to the next statement in the test method. You can get the error text of the statement by
using the GETLASTERRORTEXT Method.
If a statement that follows the AssertError keyword doesn't cause an error, then the AssertError statement
causes the following error and the test method that is running produces a FAILURE result.
IMPORTANT
Use ASSERTERROR in a test code only. It isn't allowed or supported in the production code.
Example
To create a test method to test the result of a failure of a CheckDate method that you've defined, you can use the
following code. This example requires that you create a method called CheckDate. This method checks whether
the date is valid for the customized application. You also create the following text constant, Date variable
InvalidDate, and Text variable InvalidDateErrorMessage.
InvalidDate := 010184D;
InvalidDateErrorMessage := 'The date is outside the valid date range.';
ASSERTERROR CheckDate(InvalidDate);
if GETLASTERRORTEXT <> InvalidDateErrorMessage then
ERROR('Unexpected error: %1', GETLASTERRORTEXT);
TIP
Use the Any module in the Microsoft/ALAppExtensions GitHub repo to generate pseudo-random values during
test set-up. This module generates the same set of numbers, allowing you to reproduce test failures.
Tests should be readable and fast to execute. We recommend that test codeunits run under 2 minutes,
and that you don't add more than 100 test methods to the codeunit.
See Also
Testing Pages
Create Handler Methods
Test Codeunits and Test Methods
Application Testing Example: Testing Purchase Invoice Discounts
Random Test Data
Testing the Advanced Extension Sample
Create Test Codeunits and Test Methods
2/6/2023 • 2 minutes to read • Edit Online
In Dynamics 365 Business Central, you can create test codeunits and then test methods in the test codeunits.
Test codeunits are codeunits that have the SubType Property set to Test . You write tests as Al code in the
methods inside of the test codeunits. There are three types of methods that you can add in a test codeunit: test,
handler, and normal. Each method type is used for a specific purpose and behaves differently. When a test
codeunit runs, it runs the OnRun trigger, and then runs each test method in the codeunit.
By default, each test method runs in a separate database transaction, but you can use the TransactionModel
Attribute on test methods and the TestIsolation Property on test runner codeunits to control the transactional
behavior.
The results of a test codeunit and of the individual test methods are displayed in a message window, but you can
use the OnAfterTestRun Trigger on a test runner codeunit to capture the results. The outcome of a test method is
either SUCCESS or FAILURE. If any error is raised by either the code that is being tested or the test code, then the
global outcome of the test codeunit is FAILURE and the error is included in the results log file.
The difference between a normal codeunit and a test codeunit is their execution at runtime. When a normal
codeunit is run, if one of its methods fails, then the codeunit is terminated. When a test codeunit is run, even if
the outcome of one test method is FAILURE, the next test methods are still running.
The methods in a test codeunit can be one of the following types:
Test method You use test methods that include AL code that tests the
business logic in the application, where each method covers
a transaction. You declare the Test Attribute on the method.
Normal method You use normal methods to structure the test code by using
the same design practices and principles as methods in other
codeunits of the application. You declare the Normal
Attribute on the method.
See Also
Testing the Application
Create Handler Methods
2/6/2023 • 2 minutes to read • Edit Online
You can create test codeunits, test methods, and test pages to test your application. We recommend that you
create tests that can be automated. To create automated tests, you must write code to handle all UI interactions
so that the tests don't require user interaction when they're running. To do this, you create special handler
methods.
You can use the following handler methods:
PageHandler Handles specific pages that aren't run <Function name>(var <Page>: Page
modally. <page id>)
ModalPageHandler Handles specific pages that are run <Function name>(var <Page>: Page
modally. <page id>; var <Response>: Action)
[MessageHandler]
procedure MessageHandler(Message: Text[1024])
begin
Assert.IsTrue(StrPos(Message, MSG_HAS_BEEN_CREATED) > 0, Message);
end;
The parameters of the methods that are being handled are passed as parameters to the handler methods. For
example, when Message is called in a test method, the parameter of the Message method is passed as the
parameter of the MessageHandler method. For page and report handlers, the page, report, or request page is
passed as the parameter of the PageHandler , ModalPageHandler , Repor tHandler , or
RequestPageHandler .
You can call handler methods from methods that have the Test Attribute and then specify the handler methods
that it will use in the HandlerFunctions Attribute. The code inside the test method should simulate that the UI
was actually raised and some values entered or some actions were taken. You can specify more than one
handler method by separating the handler method names with a comma.
NOTE
Every handler method that you enter in the HandlerFunctions Attribute of a test method must be called at least one time
in the test method. If you run a test method that has a handler method listed that isn't called, then the test fails.
The following example shows a test method that uses the HandlerFunctions Attribute to call the
MessageHandler method.
[Test]
[HandlerFunctions('MessageHandler')]
procedure ApproveRequestForPurchCreditMemo()
var
PurchHeader: Record "Purchase Header";
begin
ApproveRequestForPurchDocument(PurchHeader."Document Type"::"Credit Memo");
end;
See Also
Testing the Application
AL Methods
Create Test Runner Codeunits
2/6/2023 • 2 minutes to read • Edit Online
You can create test runner codeunits to manage the execution of test codeunits and to integrate with test
management or test reporting frameworks. By integrating with a test management framework, you can
automate your tests and enable them to run unattended.
To create a test runner codeunit, create a codeunit and set the SubType Property to TestRunner .
To specify what changes in the database you want to roll back after the tests in the test runner codeunit execute,
set the TestIsolation Property.
Test runner codeunits include the following triggers:
OnRun Trigger
OnBeforeTestRun Trigger
OnAfterTestRun Trigger
In the OnRun trigger, you'll enter the code to run the codeunits. It runs when you execute the codeunit and
before the test methods run. You can use the OnBeforeTestRun and the OnAfterTestRun triggers to perform
preprocessing and postprocessing, such as initialization or logging test results. If you implement the
OnBeforeTestRun trigger, then it executes before each test method executes. If you implement the
OnAfterTestRun trigger, then it executes after each test method executes and also suppresses the automatic
display of the results message.
WARNING
The OnBeforeTestRun and OnAfterTestRun triggers always run in their own transactions, regardless of the value of
the TestIsolation Property, the value of the TransactionModel Property, or the outcome of a test method.
Example
This sample codeunit runs three test codeunits in the automated application test libraries.
trigger OnRun()
begin
Codeunit.RUN(Codeunit::"ERM Vendor Statistics");
Codeunit.RUN(Codeunit::"ERM Sales Quotes");
Codeunit.RUN(Codeunit::"ERM Dimension");
end;
}
You may want to define your test suite in a table and then write code in the test runner codeunit to iterate
through the items in the table. And then run each test codeunit. In that case, you can make use of the following
example.
codeunit 50102 TestRunnerCodeunit
{
Subtype = TestRunner;
trigger OnRun()
var
EnabledTestCodeunit: Record "CAL Test Enabled Codeunit";
Object: Record "Object";
begin
if EnabledTestCodeunit.FINDSET then
repeat
if Object.GET(ObjectType::Codeunit, '', EnabledTestCodeunit."Test Codeunit ID") then
CODEUNIT.RUN(EnabledTestCodeunit."Test Codeunit ID");
until EnabledTestCodeunit.NEXT = 0
end;
}
See Also
Testing the Application
Testing Pages
2/6/2023 • 3 minutes to read • Edit Online
You use test page objects to simulate user interactions with the application. You can:
View or change the value of a field on a test page.
View the data on page parts.
View or change the value of a field on a subpage.
Filter the data on a test page.
Perform any actions that are available on the page.
Navigate to different records.
You can create and open a test page in the following ways:
Declare a test page variable and then write AL code to open the test page by using one of the following
methods:
OpenNew Method (TestPage)
OpenEdit Method (TestPage)
OpenView Method (TestPage)
Create a PageHandler or ModalPageHandler method that has a test page parameter.
Write AL code to trap a call to open a test page by using the Trap Method (TestPage).
NOTE
You must consider how you set the TransactionModel Property to simulate the scenario that you want to test and to
return the database to its initial state after the test.
NOTE
Test methods and code on test pages run on the Dynamics 365 Business Central Server instance, even though they
simulate client interactions.
For more information about the AL methods that you use on a test page, see TestPage Data Type.
CustomerList.Filter.SetFilter("No.", '20000..30000');
See Also
Testing the Application
Testing the Advanced Sample Extension
Create Handler Methods
2/6/2023 • 2 minutes to read • Edit Online
You can create test codeunits, test methods, and test pages to test your application. We recommend that you
create tests that can be automated. To create automated tests, you must write code to handle all UI interactions
so that the tests don't require user interaction when they're running. To do this, you create special handler
methods.
You can use the following handler methods:
PageHandler Handles specific pages that aren't run <Function name>(var <Page>: Page
modally. <page id>)
ModalPageHandler Handles specific pages that are run <Function name>(var <Page>: Page
modally. <page id>; var <Response>: Action)
[MessageHandler]
procedure MessageHandler(Message: Text[1024])
begin
Assert.IsTrue(StrPos(Message, MSG_HAS_BEEN_CREATED) > 0, Message);
end;
The parameters of the methods that are being handled are passed as parameters to the handler methods. For
example, when Message is called in a test method, the parameter of the Message method is passed as the
parameter of the MessageHandler method. For page and report handlers, the page, report, or request page is
passed as the parameter of the PageHandler , ModalPageHandler , Repor tHandler , or
RequestPageHandler .
You can call handler methods from methods that have the Test Attribute and then specify the handler methods
that it will use in the HandlerFunctions Attribute. The code inside the test method should simulate that the UI
was actually raised and some values entered or some actions were taken. You can specify more than one
handler method by separating the handler method names with a comma.
NOTE
Every handler method that you enter in the HandlerFunctions Attribute of a test method must be called at least one time
in the test method. If you run a test method that has a handler method listed that isn't called, then the test fails.
The following example shows a test method that uses the HandlerFunctions Attribute to call the
MessageHandler method.
[Test]
[HandlerFunctions('MessageHandler')]
procedure ApproveRequestForPurchCreditMemo()
var
PurchHeader: Record "Purchase Header";
begin
ApproveRequestForPurchDocument(PurchHeader."Document Type"::"Credit Memo");
end;
See Also
Testing the Application
AL Methods
Application Testing Example: Testing Purchase
Invoice Discounts
2/6/2023 • 4 minutes to read • Edit Online
Before you release a customized Dynamics 365 Business Central application to a production environment, you
must test the application. This walkthrough demonstrates how to use the test codeunits and test libraries to test
an application.
Prerequisites
To complete this example, you will need:
Dynamics 365 Business Central with a developer license.
The CRONUS International Ltd. demo data company.
To import the Test Toolkit.
TIP
By default, methods in test codeunits are test methods unless you specify otherwise.
Guidelines
In this example, the name of the test method consists of the tested functionality, Purchase Invoice
Discount Calculation, and relevant parameters that affect the test result. We recommend that you follow
this naming pattern for your test methods also. In our example, the following parameters are introduced:
PInv for the document that is tested, purchase invoices. You can apply the same test to purchase orders
or purchase credit memos. Also, we recommend that you have mirrored sets of tests for the sales area.
Above . It is a good practice to have tests for positive and negative scenarios. In this test, Isaac wants to
check that discount come into effect when the document amount is above a minimum amount. But the
amount in the document can be also less than or equal to the minimum amount.
Isaac first defines the test scenario [SCENARIO], then details it with the GIVEN-THEN-WHEN notation.
Finally, he adds the AL code.The code in this test method prepares the test data by setting a random
discount percent, a minimum amount, and a document amount. Then, it creates a purchase document
with a line and runs the Purch-Calc.Discount codeunit, which contains the code that is being tested.
Finally, it verifies the results of running the Purch-Calc.Discount codeunit and raises an error if the results
are not as expected.
You can create additional test methods in this test codeunit to test other aspects of vendor discounts.
These test methods should include negative tests, which validate that the code being tested works as
intended under failing conditions.
NOTE
This test code does not guarantee that the state of the database after you run the test is the same as the state of the
database before you run the test.
Code
codeunit 50111 "ERM Vendor Discount"
{
// Specifies the codeunit to be a test codeunit
Subtype = Test;
trigger OnRun()
begin
end;
var
PurchLine: Record "Purchase Line";
MinAmount: Decimal;
DocAmount: Decimal;
DiscountPct: Decimal;
PurchCalcDisc: Codeunit "Purch.-Calc.Discount";
begin
// [SCENARIO] "Inv. Discount Amount" should be calculated on Purchase Invoice (in LCY), where
Invoice amount is
// above the minimal amount required for invoice discount calculation.
// [GIVEN] Vendor with invoice discount percentage "D" for minimal amount "A" in LCY
// [GIVEN] Create purchase invoice with one line and amount >"A"
DiscountPct := RandomNumberGenerator.RandDec(100, 5);
MinAmount := RandomNumberGenerator.RandDec(1000, 2);
DocAmount := MinAmount + RandomNumberGenerator.RandDec(100, 2);
CreatePurchDocument(PurchLine, PurchLine."Document Type"::Invoice, DocAmount, MinAmount,
DiscountPct);
DiscountPct);
// [WHEN] Calculate invoice discount for purchase document (line)
PurchCalcDisc.RUN(PurchLine);
// [THEN] "Inv. Discount Amount" = Amount "A" * discount "D" / 100
PurchLine.Find;
Assert.AreEqual(Round(PurchLine."Line Amount" * DiscountPct / 100), PurchLine."Inv. Discount
Amount", PurchInvDiscErr);
end;
var
VendorInvoiceDisc: Record "Vendor Invoice Disc.";
PurchaseHeader: Record "Purchase Header";
VendorNo: Code[30];
begin
// Create vendor
VendorNo := LibraryPurchase.CreateVendorNo;
// Create vendor invoice discount
VendorInvoiceDisc.Init;
VendorInvoiceDisc.Code := VendorNo;
VendorInvoiceDisc.Validate("Currency Code", '');
VendorInvoiceDisc.Validate("Minimum Amount", MinAmount);
VendorInvoiceDisc.Validate("Discount %", DiscountPct);
VendorInvoiceDisc.Insert(TRUE);
// Create purchase line
LibraryPurchase.CreatePurchaseDocumentWithItem(PurchaseHeader, Purchline, DocumentType, VendorNo,
'', 1, '', 0D);
PurchLine.Validate("Direct Unit Cost", DocAmount);
PurchLine.Modify(TRUE);
end;
var
RandomNumberGenerator: Codeunit "Library - Random";
LibraryPurchase: Codeunit "Library - Purchase";
Assert: Codeunit Assert;
myInt: Integer;
PurchInvDiscErr: Label 'The Purchase Invoice Discount Amount was not calculated correctly.';
See Also
Testing the Application
The Performance Toolkit Extension
2/6/2023 • 19 minutes to read • Edit Online
The Performance Toolkit extension is built for Independent Solution Vendors (ISVs) and Value Added Resellers
(VARs) who develop vertical solutions and customize Business Central for their customers. Because things
change between released versions, it's important that ISVs and VARs can test the performance of their solutions
to ensure that new versions don't introduce performance regressions when the volume of users grows. To help,
the Performance Toolkit lets developers simulate workloads in realistic scenarios to compare performance
between builds of their solutions.
The Performance Toolkit extension helps answer questions such as, "Does my solution for Business Central
support X number of users doing this, that, and the other thing at the same time?"
The extension doesn't answer questions such as, "How many orders can Business Central process per hour?"
C O M P O N EN T DESC RIP T IO N
PowerShell Scripts A command line tool for simulating multiple users signing in
and interacting with Business Central.
Get started
There are two ways to get started with the Performance Toolkit:
The recommended way is to install the Performance Toolkit extension from the Extension Marketplace in
Visual Studio Code. This extension is purpose-built to make it easy to set up the toolkit and start testing
performance.
If you want to set up the toolkit yourself, install the toolkit from AppSource via the Extensions Marketplace
page in Business Central, get the test samples from GitHub and download the DVD to get the PowerShell
scripts. This method is useful, for example, if you can't install the extension in Visual Studio Code or your
environment is not supported. Learn more about getting the scripts at Run using the PowerShell scripts.
The following steps provide an overview of how to get started. This article describes each step in more detail.
1. Install the Performance Toolkit extension in Visual Studio Code.
2. In Visual Studio Code, prepare your BCPT project and set up the Performance Toolkit extension on your
environment.
3. Write tests for the scenarios to simulate.
4. In Business Central, configure a BCPT suite.
Install the Performance Toolkit extension in Visual Studio Code
NOTE
Remember that you can't install the extension in a production environment.
1. In Visual Studio Code, open the Extension Marketplace , search for Performance Toolkit , and then
install the extension.
2. Create a project by running the BCPT Setup new Business Central Performance Toolkit project
command.
NOTE
If third-party extensions are installed, the toolkit will renumber the tests to avoid conflicts.
3. Choose whether to test in a Docker or online (SaaS) environment. Use Docker for Business Central on-
premeses.
4. Sign in to your Business Central, and choose your environment.
5. Specify the directory to create the BCPT project in.
When you choose OK , the extension verifies that the following Performance Toolkit components are
installed in your Business Central. If the components aren't installed, the extension will install them.
The Performance Toolkit.
The sample test cases.
The PowerShell scripts.
6. When installation is complete, choose Open a new window to open your project.
Create codeunits for your test scenarios
The test scenarios that the extension provides are meant to serve as inspiration for creating your own tests. To
test your environment, you'll need to write your own scenarios. A test scenario is a codeunit of either a Normal
or Test subtype.
If the subtype is Normal, the test scenario should be defined in the OnRun trigger because the Performance
Toolkit uses the codeunit to run the test scenario. These codeunits are useful when you want to write a scenario
without the involvement of pages. An example is shown below.
trigger OnRun();
var
Customer: Record Customer;
*SalesHeader: Record "Sales Header";*
begin
Customer.FindFirst();
*SalesHeader.Init();*
*SalesHeader."Document Type" := SalesHeader."Document Type"::Order;*
*SalesHeader.Insert(true);*
BCPTTestContext.EndScenario('Add Order');
BCPTTestContext.UserWait();
BCPTTestContext.StartScenario('Enter Account No.');
*SalesHeader.Validate("Sell-to Customer No.", Customer."No.");*
*SalesHeader.Modify(true);*
BCPTTestContext.EndScenario('Enter Account No.');
BCPTTestContext.UserWait();
To interact with pages and make the tests more realistic, define a codeunit of the subtype Test and use Test
Pages. The following code example shows the main difference between normal and test codeunits.
var
BCPTTestContext: Codeunit "BCPT Test Context";
trigger OnRun();
var
Customer: Record Customer;
*SalesOrder: TestPage "Sales Order";*
begin
Customer.FindFirst();
*SalesOrder.OpenNew();*
*SalesOrder."No.".SetValue('');*
BCPTTestContext.EndScenario('Add Order');
BCPTTestContext.UserWait();
BCPTTestContext.StartScenario('Enter Account No.');
*SalesOrder."Sell-to Customer No.".SetValue(Customer."No.");*
BCPTTestContext.EndScenario('Enter Account No.');
BCPTTestContext.UserWait();
TIP
We recommend that you only write scenarios using test pages for scenarios in which the client behavior is predictable. For
example, if an unexpected dialog shows up during the test, the test will fail with an exception.
Tests can use the StartScenario and EndScenario functions on the BCPT Test Context codeunit to log when
the scenario you're measuring started and stopped. These scenarios can also be nested, as shown in the earlier
example. Here we have a top level scenario for Add order, which contains sub-scenarios, such as Enter Account
No.. This allows you to perform overall measurements and more detailed measurements.
To simulate delays between user actions and make your tests more realistic, call the UserWait() function while
moving between fields. When using Business Central, an implicit Commit() is called for every interaction. Tests
should simulate the implicit Commit() by calling an explicit Commit() .
NOTE
The UserWait function will call the commit, so you don't need to do it yourself.
You can also specify parameters that you can provide for your tests. This is useful when you want to be able to
change certain behavior of your test. For example, you might want to change the number of sales lines you add
to a sales order. To enable parameters, implement the BCPT Test Param. Provider interface. The following
example shows how to implement the interface.
codeunit 50000 "Create PO with N Lines" implements "BCPT Test Param. Provider"
{
var
BCPTTestContext: Codeunit "BCPT Test Context";
NoOfLinesParamLbl: Label 'Lines';
ParamValidationErr: Label 'Parameter is not defined in the correct format. The expected format is
"%1"', Comment = '%1 = Format';
NoOfLinesToCreate: Integer;
trigger OnRun();
begin
...
end;
Next, extend the BCPT Test Param. Enum to make it available in the Performance Toolkit.
enumextension 50000 "Test Codeunits with Params" extends "BCPT Test Param. Enum"
{
value(50000; "50000")
{
Implementation = "BCPT Test Param. Provider" = "Create PO with N Lines";
}
...
}
Learn more about writing test scenarios at Testing the Application Overview.
Configure a BCPT suite
Configure a suite for the scenario that you want to simulate. When you configure a suite, you'll need to specify:
What tests to run and, if applicable, with what parameters.
How many concurrent sessions you want to simulate for each test.
The duration of the scenario.
Single and multiple sessions
Typically, you'll want to run the suite for multiple sessions at the same time. After you configure the suite, you
can do that by using the Star t action. You can also use the Visual Studio Code extension or PowerShell scripts.
Learn more at Run a test suite using the Visual Studio Code extension.
To do a quick test, for example, during the development phase, choose the Star t in Single Run mode action to
run all your tests (suite lines) one time. It will also skip the user delays. Single Run mode lets you monitor the
number of SQL statements between runs and define baselines, and gives you quick feedback that can help
identify regressions early on.
You can run up to 500 sessions at the same time for a test suite. The Total No. of Sessions field shows how
many sessions will be created when you run the suite.
Run tests in the background and foreground
On the suite lines, the Run in Foreground checkbox lets you run tests in the foreground rather than as a
background task. You can specify this for each individual suite line. However, if your test involves UI interactions,
then it must run in the foreground. From the client, it's only possible to have one foreground test running at a
time. If multiple lines have the run in foreground option enabled, they will run sequentially. Background tests
will still run in parallel.
NOTE
If you must run multiple foreground tests in parallel, you must use the Visual Studio Code extension or the PowerShell
scripts.
Test performance
There are two ways to run BCPT suites.
Directly from Business Central.
By using the Visual Studio Code extension or Powershell scripts.
Known limitations
There are a couple of limitations for running BCPT suites.
If you run it from the client, you can only run one session at a time in the foreground.
Depending on whether you're environment is on-premises, Docker, or online, there might be a limit to the
number of sessions you can run at the same time in the background. Typically, the default number of
sessions is 10 . Learn more at Operational Limits for Business Central Online.
If your BCPT suite runs more than one session in the foreground, or more than 10 sessions at the same time in
the background, you must run the suite from the Visual Studio Code extension or PowerShell. Learn more at
Run using the PowerShell scripts.
To run a test in Single Run mode
The following steps provide an example of how to run a test in Single Run mode.
1. On the BCPT Suites page, choose New .
2. In the Code field, enter a name for the test suite. In this example, we'll use PreTest .
3. In the Tag field, enter something that will make it easy to identify the suite later when you analyze the
results.
4. The fields for duration and delays aren't used for Single Run mode, so we'll leave their default values.
5. On the BCPT Suit Lines FastTab, choose the test suite for your component.
6. In this example, we're calculating the total weight of the items on a sales order, so we'll use the Sales
Order page test with a parameter that creates four lines. The parameter looks as follows: Lines=4.
7. Clear the Run in Foreground checkbox. This will run the test suite in a background thread.
8. Choose Star t in Single Run mode .
9. To set your baseline after the run completes, in the Base Version field, enter 1 .
TIP
If you run the test again you'll have delta values on the test line. Learn more at Analyze the results. You can reset
the baseline to any version, and run as many tests as needed.
NOTE
The the Performance Toolkit extension in Visual Studio Code automatically installs these PowerShell scripts. However, if you
aren't using the Performance Toolkit in Visual Studio Code, you'll need to download the scripts. The scripts are available in
the DVD in the Applications\testframework\TestRunner folder. To get there, follow these steps:
1. Go to Download the files.
2. Choose the link to the latest version of Business Central.
3. In the Resolution section, choose the link to the latest update.
Depending on what you want to do, there are several ways to start the test suite by using the PowerShell scripts.
Create the credential object.
$Credential = New-Object PSCredential -ArgumentList <user email>,(ConvertTo-SecureString -String <password>
-AsPlainText -Force)
NOTE
When you use RunBCPTTests.ps1, there are a few important parameters to use.
-Environment - Specifies the environment the tests will be run in. The supported values are PROD , TIE , and
OnPrem . Default is PROD .
AuthorizationType - Specifies the authorization type needed to authorize to the service. The supported values are
Windows , NavUserPassword , and AAD .
SandboxName - Specifies the sandbox name. This is necessary only when the environment is either PROD or TIE .
Default is sandbox .
ServiceUrl - Specifies the base URL of the service. This parameter is used only in OnPrem environment. For
example, http://localhost:8080/PerformanceToolkit .
ClientId - Specifies the guid that the Business Central is registered with in Azure AD. To set up Azure AD, go to
https://github.com/microsoft/BCTech/tree/master/samples/PSOAuthBCAccess.
1. In Visual Studio Code, on the Explorer Pane, choose the script that you want to run.
2. Choose the type of environment you want to target.
3. Choose the environment to run the test in.
4. Enter the name of the BCPT suite that you want to run, and then choose OK .
In Business Central, you can check the status of the BCPT suite by choosing the Refresh action.
NOTE
When you run tests there's a two second delay between new sessions. The delay prevents locking issues when the users
are signing into Business Central.
No. of Iterations How many times it ran. This will be 1 because we used the
Star t in Single Run Mode action.
Average duration Equal to the Total Duration in (ms) field for the first run,
but after you run a test multiple times it's a result of the sum
of runs since your baseline.
No. of SQL statements The number of SQL statements generated for one run.
Avg. No. of SQL Statements Similar to the duration fields, for the first run this will be the
same as the No. of SQL statements field, but will become
averaged after subsequent runs.
Total Duration Base (ms) The total duration of the baseline run.
Avg. Duration Base (ms) Not relevant for Single Run mode.
Avg. No. of SQL Statements Base The number of SQL statements in your base run.
The following table describes the fields that show the delta between the run and the baseline.
Change in No. of SQL statements (%) The percent of difference between the baseline and the latest
run.
Changes in Duration (%) The change in measured time between a baseline and the
latest run.
NOTE
The first iteration of any run will show a higher number of SQL Statements because nothing has been cached.
TIP
If you attach an Application Insights key or connection string in the admin center for online or Business Central Server for
on-premises then the log entries are also shown in the Application Insights ID.
See Also
Testing the Application Overview
Development in AL
Best Practices for AL
FAQ about Testing your Business Central App
2/6/2023 • 4 minutes to read • Edit Online
This section contains answers to frequently asked questions about testing your app when you submit an app for
Business Central.
I only made minor code changes in my updated app. Can I test just
these changes?
No. You should always test 100% coverage no matter what. Testing only what you changed isn't the correct
approach. Even minor changes can lead to breaking changes where you least expect it.
See also
FAQ about Updating your Business Central App
FAQ about Library & Dependency Apps in Business Central
Update Lifecycle for AppSource Apps FAQ
The Lifecycle of Apps and Extensions for Business Central
Sandbox Environments for Dynamics 365 Business
Central Development
2/6/2023 • 2 minutes to read • Edit Online
To get started developing for Dynamics 365 Business Central it is important to understand the different options
you have at hand. You can either choose to run a sandbox environment deployed as a Dynamics 365 Business
Central service, or you can run a container-based image either hosted as an Azure VM or locally. Both options
provide the AL development tools; the container-based sandbox additionally provides access to the C/SIDE
development tools. You can also choose to run a sandbox environment with production data using the Business
Central Admin Center . For more information, see Business Central Admin Center.
NOTE
Extensions that have been published to a sandbox environment from Visual Studio Code or created using Designer are
removed when the environment is updated or relocated within our service. For more information, see Production and
Sandbox Environments and FAQ for Developing in AL.
IMPORTANT
It is not supported to publish, from Visual Studio Code, an extension with the same identifiers as an extension published
to AppSource. Identifiers include the combination of appID and version or name, publisher, and version. If you do publish
such an extension, it can be removed at any time.
C A PA B IL IT Y O N L IN E SA N DB O X C O N TA IN ER SA N DB O X
Production data Manually uploaded using Rapid Start Manually uploaded using Rapid Start
packages. Or, available through the packages
Business Central Admin Center.
Tools Visual Studio Code, Designer Visual Studio Code, Designer, on-
premise tools such as SQL Server
Management Studio, and C/SIDE.
Getting started
Based on the overview above and the requirements for your development environment, you can get started
with a sandbox by following the links below:
Online Sandbox with Demo Data
Online Sandbox with Production Data
Container Sandbox
See Also
Get Started with AL
Keyboard Shortcuts
AL Development Environment
Production and Sandbox Environments
Get started with the Container Sandbox
Development Environment
2/6/2023 • 3 minutes to read • Edit Online
Dynamics 365 Business Central offers a container-based image environment that enables access to the AL
development environment.
You set up a container sandbox by running the Container Sandbox Environment page from Dynamics 365
Business Central. You will have to decide whether you want an Azure-hosted or locally hosted container
sandbox. See the next section for details.
TIP
Dynamics 365 Business Central also offers an online sandbox. For more information, see Sandbox Environments for
Dynamics 365 Business Central Development.
NOTE
You must set the Accept Eula setting to Yes in order to continue.
...
Container IP Address: 172.22.147.63
Container Hostname : mybc
Container Dns Name : mybc
Web Client : http://mybc/BC/
Dev. Server : http://mybc
Dev. ServerInstance : BC
Files:
http://test:8080/ALLanguage.vsix
10. Write down or copy the following parameter/values from the console: Dev. Server , Dev. ServerInstance
, and Files . You will need this information later to set up Visual Studio Code for extension development.
You now have a container sandbox set up on your computer. The following shortcuts have been added to your
desktop:
<Container name> Web Client - opens the Web client for the your application in the container.
<Container name> PowerShell Prompt - opens a Windows PowerShell prompt in the container. This
gives you access to the Dynamics NAV (/powershell/business-central/overview), which you can run against
the container sandbox environment.
<Container name>Command Prompt - opens a Windows command prompt in the container.
For more information about working with a container sandbox, see Running a Container-Based Development
Environment.
Set up Visual Studio Code
After the container sandbox is set up, you must set up Visual Studio Code for extension development. To do this,
you need the values for Dev. Server , Dev. ServerInstance , and Files parameters that you retrieved from the
Windows PowerShell ISE console when you ran the CreateBCSandbox.ps1 script.
1. In Visual Studio Code, go to Extensions , and install the AL Language extension from the Marketplace.
You now have the AL Language extension enabled.
2. In Visual Studio Code, press Ctrl+Shift+P and then choose AL Go! .
3. Choose where to create the project, and then choose the Your own ser ver option.
4. Open the generated launch.json file, update the "server" setting with the value of the Dev. Server
parameter and the "serverInstance" setting with the value of the Dev. ServerInstance to reflect the
container you just created. For example:
"server": "http://mybc",
"serverInstance": "BC",
"authentication": "Windows",
See Also
Running a Container-Based Development Environment
Working with Sandboxes and Entitlements
Sandbox Environments for Dynamics 365 Business Central Development
AL Development Environment
Working with Development Sandboxes and
Entitlements
2/6/2023 • 4 minutes to read • Edit Online
The experience that a user has in Dynamics 365 Business Central depends on the purchased subscription plan.
In Dynamics 365 Business Central, there are two main plans; the Essential and the Premium plan, plus a few
more. For more information, see Licensing in Dynamics 365 Business Central. For detailed information about
the Essential and Premium plans, see Business Central on the Microsoft Dynamics 365 site.
When you develop in a Docker sandbox, the Essential experience is automatically assigned to you (you set the
experience on the Company Information page), which makes it difficult to test how a user with the Premium
plan assigned will experience what you have developed.
NOTE
There is no license check in a Docker Sandbox except for on Purchase and Sales documents. There is a different behavior
in these documents as the TEAMMEMBER license has partial access. In particular Invoices, Orders, Quotes and Credit
Memos share the same table and the TEAMMEMBER license has access only to Quotes.
NOTE
In the table below non-default means not assigned by default, but the plan allows this to be assigned to the user.
USER N A M E
T H E T Y P E O F SUB SC RIP T IO N P L A N
A SSIGN ED TO T H E GIVEN USER USER GRO UP S
TIP
For more information about how to choose a user experience, see Changing Which Features are Displayed.
This assigns the Premium plan to your default admin user. Internally this just adds a record to the User Plan
table.
To create the test users, you must call the Setup-BCContainerTestUsers method:
specifying the container and the password that you want to use for the new users.
Internally, the Setup-BCContainerTestUsers downloads an app which exposes an API, publishes and installs the
app, and then invokes the CreateTestUsers API with the password needed. After this, the app is uninstalled and
unpublished.
If you want to see code behind the app, it is available here.
Docker run
If you are using Docker run to run your containers, you have a little more work to do.
First of all, you must override the SetupNavUsers.ps1 by sharing a local folder to c:\run\my in the container and
place a file called SetupNavUsers.ps1 in that folder with the following content:
This will assign the Premium plan to the admin user in the database.
TIP
To set up test users, you can clone the createtestusers repository and modify the code to create the users on the
oninstall trigger with the password that you want.
See Also
Programming in AL
Sandbox Environments for Dynamics 365 Business Central Development
Container Sandbox
Changing Which Features are Displayed
Production and Sandbox Environments
App Identity
2/6/2023 • 4 minutes to read • Edit Online
Apps built using AL extend the functionality of Business Central. The app.json file is, together with the
launch.json file, automatically generated when you create a new AL project. The app.json file contains
information about the app that you are building, such as publisher information and specifies the minimum
version of base application objects that the extension is built on. Often the app.json file is referred to as the
manifest. The app.json file contains numerous project settings, but a few of them constitutes the actual identity
of the app that you are creating.
NOTE
With Business Central 2021 release wave 2, name and publisher are no longer considered part of the app identity and
can therefore be changed to reflect branding or acquisition, for example. If the name and/or publisher information is
changed, the version must also be incremented. If you are using workspaces with multiple projects and change the
name or publisher of an extension in the workspace, the dependencies in the app.json file must be updated with the
new name and publisher or you may encounter issues with reference resolution. For more information, see Working with
Multiple Projects and Project References.
IMPORTANT
In cases where the Application app is substituted with another application app, the name is still used as identification. For
more information, see The Microsoft_Application.app File.
NOTE
In a Visual Studio Code workspace an app's name , publisher , and version are part of identifying a project and a
project dependency. Therefore, if any of these properties change, it is recommended that you reload the workspace.
See Also
JSON Files
Publish NAVApp
Working with Multiple Projects and Project References
Choosing Runtime Version in AL
2/6/2023 • 2 minutes to read • Edit Online
The capabilities and features of AL for Business Central are determined by the runtime version. The runtime
version can be specified in the app.json file for a project. It is expressed with the following syntax, for example:
"runtime": "7.0" . Specifying the runtime version is mostly interesting for scenarios where you develop for on-
prem or a mix of on-prem and SaaS. For SaaS only development, you will most likely be interested in using the
current runtime. If the runtime setting is not specified, the compiler will detect the runtime that matches the
server.
The runtime version specified in the app.json file determines which runtime the project is targeting. A project
can be published to the server with an earlier or with the same runtime version as the server.
See Also
JSON Files
FAQ about Library and Dependency Apps in
Business Central
2/6/2023 • 2 minutes to read • Edit Online
This section contains answers to frequently asked questions about library apps and dependency apps in
Business Central.
When I get the latest updated version of my app, why don't I get the
updated library/dependency apps that my AppSource app depends
on?
Libraries are updated only when the new version of your app requires a higher version than the version
currently installed in your environment. If you want your library app to be automatically updated when your
AppSource app is updated, you must increase the minimum version required in the manifest (app.json) of your
AppSource app.
You can also uninstall and reinstall the library/dependency app to have it updated.
For your extension to run properly, configuration and starting data such as permission sets and table data may
be needed. An extension can include the following types of data that can be imported for the tenant during the
installation of the extension.
Permission sets
Web services
Starting table data
Custom report layouts
The data must be exported into files to be included in the extension. To use the export functions you must use a
container sandbox environment for Dynamics 365 Business Central. For more information, see Get started with
the Container Sandbox Development Environment.
NOTE
Export each permission set to a separate XML file.
3. Add the exported permission set files to the Visual Studio Code project that contains your extension.
WARNING
If you do not include a permission set with your extension, only users with the SUPER permission set will be able
to use the extension.
IMPORTANT
With the latest version of Dynamics 365 Business Central permissions are no longer defined as data in the
application database. Permissions that can be created by using AL objects are called system permissions. For more
information, see Entitlements and Permission Sets Overview.
NOTE
Export each web service to a separate XML file.
3. Add the exported web services files to the Visual Studio Code project that contains your extension. An
exported web service XML file looks like the following:
NOTE
Export the data for each table to a separate XML file.
3. Add the exported table data files to the Visual Studio Code project that contains your extension.
4. Call the procedure in a Codeunit with the Subtype property Install or Upgrade and specify the table ID
in the NavApp.LoadPackageData procedure as shown in the following example.
WARNING
An extension can only include table data for new tables that are added as part of the extension.
NOTE
Export each custom report layout to a separate XML file.
3. Add the exported custom report files to the Visual Studio Code project that contains your extension.
See Also
Developing Extensions in AL
Converting Extensions V1 to Extensions V2
Writing Extension Install Code
The Txt2Al Conversion Tool
2/6/2023 • 5 minutes to read • Edit Online
DEPRECATED WITH Starting with Business Central 2022 Release Wave 2 (v21) this tool is no longer
available.
The Txt2Al conversion tool allows you to take C/AL objects, which were created in Dynamics NAV or Business
Central Spring 2019 (version 14), and convert them into the new .al format. The .al format is used when
developing extensions for Dynamics 365 Business Central. Converting the objects consists of following two
steps:
1. Exporting the objects from C/SIDE in a cleaned .txt format.
2. Converting the objects to the new syntax.
Parameters
PA RA M ET ER DESC RIP T IO N
--source=Path Required. The path of the directory containing the .delta files.
--target=Path Required. The path of the directory into which the converted
AL files will be placed.
--rename Rename the output files to prevent clashes with the source
.txt files.
--dotNetTypePrefix Specify a prefix to be used for all .NET type aliases created
during the conversion.
--runtime Specify the target runtime for the converted AL. The default
is the latest supported runtime. The string should be in a
format similar to major.minor .
--dataClassificationDefaulting Specify the DataClassification property for all table fields that
don't have it specified. For more information, see
DataClassification Property.
--tableDataOnly For table objects, specifies to convert only the table and field
definitions, including properties. Methods and trigger code
isn't included. Note: This parameter was first introduced in
Business Central version 14.2 (cumulative update 11) and
Business Central version 15.5.
NOTE
It's recommended to only use the conversion tool for export. Importing objects that have been exported can damage
your application.
TIP
You can use the Dynamics NAV Development Shell cmdlet Export-NAVApplicationObject with the
-ExportToNewSyntax flag set instead of using finsql. From the command prompt in the Dynamics NAV Development
Shell, run Get-Help Export-NAVApplicationObject -full to see the full syntax.
See Also
Developing Extensions
AL Development Environment
Page Extension Object
Report Object
Page Properties
Viewing Table Data
2/6/2023 • 2 minutes to read • Edit Online
For developers, administrators, and support personnel, it can be useful to inspect table data in the tenant
database, particularly when debugging or troubleshooting. To support this need, you can view table objects in
the Web client. This lets you see the data in all rows and columns of a specific table, including any columns that
are added by table extensions.
In a production environment, administrators and support can view a table directly from the Web client.
From the Business Central administration center, you can launch a list of all tables, sorted by storage size.
For more information, see Storage usage by environment.
In a development environment, in addition to viewing a table directly from the Web client, developers can
view a table automatically when they publish/debug an AL project from Visual Studio Code.
NOTE
The table appears as read-only in the client, so modifications, insertions, and deletions cannot be made.
IMPORTANT
Data in the tables can be sensitive. Make sure that you follow your organization's guidelines for handling such data.
Required permissions
Whether viewing the table directly from the client or from Visual Studio Code, your Dynamics 365 user account
must have the following permissions:
Read permission on the table that you want to view.
Execution permission (direct) on the System object 1350 Run table .
Any end-user that is assigned these permissions will be able to view that table in the browser.
For information about assigning permissions, see Manage Users and Permissions.
https://businesscentral.dynamics.com/?table=18
Note the use of & when table=<TableID> isn't located directly after the domain name.
{
"version": "1.0.0",
"configurations": [
{
"type": "al",
"request": "launch",
"name": "Publish to Microsoft cloud sandbox",
"serverInstance": "dynamics",
"startupObjectType": "Table"
"startupObjectId": 18
}
]
}
For more information about the launch.json file, see Launch.json file.
Constraints
You cannot view virtual tables or the following system tables:
ID NAME
2000000130 Device
2000000191 Entitlement
2000000180 MediaSet
2000000181 Media
ID NAME
2000000001 Object
See Also
Developing Extensions
Deprecated Tables
Managing Capacity
Inspecting and Troubleshooting Pages
2/6/2023 • 6 minutes to read • Edit Online
The Business Central Web client includes a page inspection feature that lets you get details about a page. Page
inspection provides insight into the page design, the different elements that form the page, and the source
behind the data it displays. Page inspection helps you:
Learn the data model behind a page.
Discover pages and parts that can be reused in your application design.
Troubleshoot data issues without having to do tasks like copying the production database, viewing the entire
source table, or digging into SQL.
Debug the application, complementing Designer.
When the Page Inspection pane first opens, it shows information that pertains to the main page object.
Use the keyboard or pointing device to move focus to different elements on the page. When you select a FactBox
or a part on the main page, a border will highlight the area. The Page Inspection pane then shows information
about the selected element. For example, the previous figure shows information about the list part in the Sales
Order page.
As you navigate to other pages in the application, the Page Inspection pane will automatically update with
page information as you move along.
What Page Inspection Shows
The page inspection pane shows the information for the main page or page part, including:
The page's source table (if any) and fields.
Extensions that affect the page.
Current filters applied to the page.
The following sections describe details about what is shown.
NOTE
If you do not see all details described below, you might not have the required permissions. For more information, see
Controlling Access to Page Inspection Details.
TIP
To copy the values of a field or entity under one of the tabs to the clip board, select the field or entity and press Ctrl+C.
Page
Table
Table Fields
Extensions
Page Filters
The Page field shows information about the main page or a selected (highlighted) subpage in a part. The field
shows the following information:
The name, as specified by its Name property
The ID as specified by the ID property.
The type, as specified by the PageType property.
Elements shown with limited information
Role Center pages
If a page has the type Role Center, the Table field doesn't appear. Because the Role Center consists of
several parts, there's no more information shown. To see more details, select the different parts that make
up the Role Center.
Report request pages and previews
If you open a report request page or preview for inspection, the only information shown in the Page
Inspection pane is the report's name and ID.
TIP
From the Business Central client, you can export report results as raw data to a Microsoft Excel file. The file
contains all columns of the dataset, but without the layout applied. Use the file to help validate that the report
returns the expected data, and to ensure that the report layout controls match the dataset value types. To export
a report, run the report and select the Send to > Microsoft Excel Document (data only) on the request
page. For more information, see Working with Reports - Send to Excel.
AL is the programming language that is used for manipulating data such as retrieving, inserting, and modifying
records in a Dynamics 365 Business Central database. It controls the execution of the various application objects,
such as pages, reports, or codeunits.
With AL, you can create business rules to ensure that the data, which is stored in the database is meaningful and
consistent with the way customers do business. Through AL programming, you can:
Add new data or transfer data from one table to another, for example, from a journal table to a ledger table.
Combine data from multiple tables into one report or display it on one page.
NOTE
If the AL code is in a local method, then you cannot run it from another object.
Variable declarations
Variables in AL are declared using the var keyword, and the syntax looks like this:
var
myInt: Integer;
If you have multiple variables of the same type, these can be declared in one line, such as:
var
myInt, nextInt, thirdInt : Integer;
isValid, doCheck : Boolean;
The protected keyword can be used to make variables accessible between tables and table extensions and
between pages and page extensions. For more information, see Protected Variables.
Reusing code
Reusing code makes developing applications both faster and easier. More importantly, if you organize your AL
code as suggested, your applications will be less prone to errors. By centralizing the code, you won't
unintentionally create inconsistencies by performing the same calculation in many places, for example, in
several triggers that have the same table field as their source expression. If you have to change the code, you
could either forget about some of these triggers or make a mistake when you modify one of them.
See Also
Simple Statements
Control Statements
Methods
System-Defined Variables
Developing Extensions
Get Started with AL
FAQ for Developing in AL
2/6/2023 • 2 minutes to read • Edit Online
This topic contains a number of frequently asked questions and answers to these questions.
See Also
Get Started with AL
Keyboard Shortcuts
AL Development Environment
System-Defined Variables
2/6/2023 • 2 minutes to read • Edit Online
Dynamics 365 Business Central automatically declares and initializes several variables that you can use when
you develop applications. The following table describes the system-defined variables.
RequestOptionsPage This variable specifies the request options page for the
current report.
CurrFieldNo This variable specifies the field number of the current field in
the current table. Retained for compatibility reasons.
Using CurrPage
You can access the controls of the page through the CurrPage variable and set the dynamic properties of the
page and its controls. The CurrPage.Editable variable reflects the runtime value of the Editable property, which
can be changed at design-time, programmatically, or by the user when switching view modes on a page. The
CurrPage.Update([SaveRecord]) variable can be used to save the current record and then update the controls on
the page. When the View mode on a page is false , then the Edit, New, and Delete modes are true .
Using CurrReport
You can access properties of a report through the CurrReport variable and set them dynamically. For example,
by using CurrReport.Preview, you can determine if the report is being run in preview mode.
Using RequestOptionsPage
You can access properties of the request page through the RequestOptionsPage variable and set them
dynamically.
See Also
AL Method Reference
Properties
AL Simple Statements
2/6/2023 • 5 minutes to read • Edit Online
AL simple statements are single-line statements that are executed sequentially and don't alter the flow of code
execution. This article explains some of the simple statements in AL.
Assignment statements
Assignment statements assign a value to a variable. The value that you assign to the variable is an AL
expression. It can be a constant or a variable, or it can consist of multiple elements of AL expressions. If you use
a method call as the value to assign to a variable in an assignment statement, then the value that is assigned is
the return value of the method.
You use the ":=" operator for assignment statements.
Example
The following example assigns a constant integer value to a variable that you've defined.
Count := 1;
Example
The following example assigns a value that consists of a constant, an operator, and a variable.
Amount := 2 * Price;
Example
The following example assigns the return value of the Open Method (File) to a Boolean variable that you've
defined.
NOTE
This method is supported only in Business Central on-premises.
OK := TestFile.Open('C:\temp\simple.xml');
The return value of the Open method is optional. If you don't handle the return value in your code, then a run-
time error occurs when a method returns false . The following example causes a run-time error if the file
C:\temp\simple.xml can't be opened.
TestFile.Open('C:\temp\simple.xml');
Example
If you want to perform arithmetic operations on a variable and then assign the result to the same variable, you
can use the following syntax.
Counter := 0;
// for addition
Counter += 1;
// for subtraction
Counter -= 1;
// for multiplication
Counter *= 1:
// for division
Counter /= 1;
// instead of
Counter := Counter + 1;
The following example shows how to use this syntax on variables of the Text Data Type.
Method statements
You use method statements to run either built-in system methods or user-defined (custom) methods. Method
calls may include parameters, which are passed to the method. For more information, see Calling Methods.
AssertError statements
You use AssertError statements in test methods to test how your application behaves under failing conditions.
The AssertError keyword specifies that an error is expected at run time in the statement that follows the
AssertError keyword.
If a simple or compound statement that follows the AssertError keyword causes an error, then execution
successfully continues to the next statement in the test method. You can get the error text of the statement by
using the GetLastErrorText method.
If a statement that follows the AssertError keyword doesn't cause an error, then the AssertError statement
causes the following error and the test method that is running produces a FAILURE result:
TestAsserterrorFail: FAILURE
Example
To create a test method to test the result of a failure of a CheckDate method that you've defined, you can use the
following code. This example requires that you create a method called CheckDate to check whether the date is
valid for the customized application.
InvalidDate := 19000101D;
InvalidDateErrorMessage := Text001;
AssertError CheckDate(InvalidDate);
var
InvalidDate : Date;
InvalidDateErrorMessage : Text;
Text001 : Label 'The date is outside the valid date range.';
with <Record> do
<Statement>
When you work with records, addressing is created as record name, dot (period), and field name:
<Record>.<Field>
If you work continuously with the same record, then you can use with statements. When you use a with
statement, you can only specify the record name one time.
Within the scope of <Statement>, fields in <Record> can be addressed without having to specify the record
name.
You can nest several with statements. If you have identical names, then the inner with statement overrules the
outer with statement.
Example
This example shows two ways to write the same code that creates a record variable that you can commit later.
CustomerRec."No." := '1234';
CustomerRec.Name := 'Windy City Solutions';
CustomerRec."Phone No." := '555-444-333';
CustomerRec.Address := '1241 Druid Avenue';
CustomerRec.City := 'Windy City';
Message('A variable has been created for this customer.');
var
CustomerRec : Record Customer;
The following example shows another way to create a record variable that you can commit later:
Programming conventions
Within with-do blocks, don't repeat the name of the object by using the member variable or method.
If you nest a with-do block within another explicit or implicit with-do block, then the with-do block that you
create within another with-do block must always be attached to a variable of the same type as the variable that
is attached to the surrounding with-do block. Otherwise, it can be difficult to see what variable that a member
variable or method refers to. For example, implicit with-do blocks occur in table objects and in pages that have
been attached to a record.
Example
The following example demonstrates nested with-do blocks. Both with-do blocks are attached to a Customer
Ledger Entry record variable.
Incorrect example
The following example demonstrates incorrect code in which you can't directly tell which record variable that the
MyField field refers to.
AL code consists of one or more statements, which are executed sequentially in a top-down order. However,
you'll often need to control the direct top-down flow of the execution. One or more statements may have to be
repeated more than once, or you may have to make the execution of a certain statement conditional. To do so,
you use control structures.
The control structures in AL are divided into the following main groups, as described in this article:
AL Compound Statements
AL Conditional Statements
AL Repetitive Statements
NOTE
In the following sections, conventions for how to structure and align AL code are presented to introduce best practices. In
many cases, the structure isn't necessary to get the code to compile, but rather to improve readability.
AL compound statements
In some cases, the AL syntax only lets you use a single statement. However, if you have to run more than one
simple statements, the statements can be written as a compound statement by enclosing the them between the
begin and end keywords.
begin
<Statement 1>;
<Statement 2>;
..
<Statement n>;
end;
The individual statements are separated by a semicolon. In AL, a semicolon is used to separate statements and
not to terminate them, as in other programming languages. Nevertheless, an extra semicolon before an end
doesn't cause an error because it's interpreted by the compiler as an empty statement.
Blocks
The begin-end structure is also called a block. Blocks can be useful to refer to the other control structures in AL.
When begin follows, then, else, or do should be on the same line and preceded by one space character.
Example
Example
if (xxx = yyyyyyyyyy) and
(aaaaaaaaaa = bbb)
then begin
x := a;
x := y;
a := y;
end else begin
y := x;
y := a;
end;
AL conditional statements
You use conditional statements to specify a condition and one or more commands to execute if the condition is
evaluated as true or false. There are two types of conditional statements in AL:
if-then-else, where there are two choices
case, where there are more than two choices
If-then-else statements
if-then-else statements have the following syntax.
if <Condition> then
<Statement1>
[else
<Statement2>]
If <Condition> is true, then <Statement1> is executed. If <Condition> is false, then <Statement2> is executed.
The square brackets around else <Statement2> mean that this part of the statement is optional. The else
statement is used when different actions are executed depending on how <Condition> is evaluated.
You can build more complex control structures by nesting if-then-else statements. The following example is a
typical if-then-else statement.
if <Condition1> then
if <Condition2> then
<Statement1>
else
<Statement2>
If <Condition1> is false, then nothing is executed. If <Condition1> and <Condition2> are both true, then
<Statement1> is executed. If <Condition1> is true and <Condition2> is false, then <Statement2> is executed.
NOTE
A semicolon in front of an else statement is not allowed.
Reading several nested if-then-else statements can be confusing but generally, an else statement belongs to the
last if statement that lacks an else statement.
Programming conventions
if and then should be on the same line, else should be on a separate line.
If there are many or long expressions, then should be on a new line and be aligned with if .
When you write if expressions with then and else parts, write them so that the then result is more
probable than the else one.
If the last statement in the then part of an if-then-else statement is an exit or an error , don't
continue with an else statement.
Example
if x = y then
x := x + 1
else
x := -x - 1;
Example
Example
if x <> y then
exit(true);
x := x * 2;
y := y - 1;
Incorrect example
if x < y then
exit(true)
else begin
x := x * 2;
y := y - 1;
end;
Example
The following example shows an if-then statement without the optional else statement.
Example
The following example shows a nested if-then-else statement.
...
if Amount < 1000 then begin
if I > J then
Max := I
else
Max := J;
Amount := Amount * Max;
end;
else
...
Case statements
Case statements have the following syntax.
case <Expression> of
<Value set 1>:
<Statement 1>;
<Value set 2>:
<Statement 2>;
In this definition, the result of <Expression> is matched against each value set and <Value set> must be an
expression or a range.
NOTE
<Expression> cannot be an application object variable, since application objects don't have a comparator.
Case statements are also called multiple option statements and are typically used when you must choose
between more than two different actions. The method of the case statement is as follows:
The <Expression> is evaluated, and the first matching value set executes the associated statement, if
there's one.
If no value set matches the value of the expression and the optional else part has been omitted, then no
action is taken. If the optional else part is used, then the associated statement is executed.
The data type of the value sets must be the same as the data type of <Expression> or at least be convertible to
the same data type.
In most cases, the data type of the value sets is converted to the data type of the evaluated expression. The only
exception is if the evaluated expression is a Code variable. If the evaluated expression is a Code variable, then
the value sets aren't converted to the Code data type.
NOTE
This type conversion can cause an overflow at run time if the resulting data type cannot hold the values of the datasets.
For more information about Code variables, see Code Data Type.
Programming conventions
When you use a case statement, indent the value sets by four character spaces. If you've two or more value sets
on the same line, then separate them by commas without spaces. The last value set on a line is immediately
followed by a colon without a preceding space. The action starts on the line after the value set and is further
indented by four character spaces. If there's a begin, then it should be put on a separate line unless it follows
else. If a begin follows an else, then it should be on the same line as else.
If there are more than two alternatives, use a case statement. Otherwise, use an if-then-else statement.
Example
case Field of
Field::A:
begin
x := x + 1;
y := -y - 1;
end;
Field::B:
x := y;
Field::C,Field::D:
y := x;
else begin
y := x;
a := b;
end;
end;
Example
The following AL code prints various messages depending on the value of Number. If the value of Number
doesn't match any of the entries in the case structure, then the else entry is used as the default.
case Number of
1,2,9:
message('1, 2, or 9.');
10..100:
message('In the range from 10 to 100.');
else
message('Neither 1, 2, 9, nor in the range from 10 to 100.');
end;
Example
The following AL code shows how value sets in a case statement are evaluated if the expression is a Code data
type.
MyCode := 'ABC';
case MyCode of
'abc':
message('This message is not displayed.');
'def':
message('This message is not displayed.');
else
message('The value set does not match the expression.');
end;
This example requires that you create the following code data type variable.
var
MyCode : Code[10];
The value set 'abc' isn't converted because the evaluated expression MyCode is a code variable.
AL repetitive statements
A repetitive statement is also known as a loop. The following table shows the looping mechanisms in AL.
The data type of <Control Variable> , <Start Number> , and <End Number> must be Boolean, number, time, or
date.
Use for-to and for-downto statements when you want to execute code for a specific number of times. The
<Control Variable> controls the number of times that the code of the inner statement is executed according to
the following:
In a for-to loop statement, the <Control Variable> value is increased by one after each iteration. The
inner <Statement> is executed repeatedly until the *<Start Number> * value is greater than the
*<End Number>* value.
In a for-downto loop statement, the <Control Variable> value is decreased by one after each iteration.
The inner <Statement> is executed repeatedly until the <Start Number> value is less than the
<End Number> value.
NOTE
When the for statement is executed, <Start Number> and <End Number> are converted to the same data type as
<Control Variable> if it's required. This type conversion can cause a run-time error.
NOTE
If the value of the <Control Variable> is changed inside the for loop, then the behavior is not predictable.
Furthermore, the value of the <Control Variable> is undefined outside the scope of the for loop.
Example 1
The following code initiates a for loop that uses the integer control variable named Count.
for Count := 1000 to 100000000000000 do
var
Count : Integer;
When this statement is executed, then a run-time error occurs because the start, and end values are converted
to the same data type as the Count control variable. Count has been declared as an integer variable. The end
number 100000000000000 is outside the valid range for integers, and an error occurs.
Example 2
The following example shows how to nest for statements.
Set the Dimensions property of variable A to 5;7.
The following for statements could be used to initialize every element in a 5x7 array with the value 23.
for I := 1 to 5 do
for J := 1 to 7 do
A[I,J] := 23;
var
I : Integer;
J : Integer;
The <List> variable must be of the List, XmlNodeList, XmlAttributeCollection, or JsonArray type. The <Element>
variable must be a data type that is compatible with elements specified by the <List> .
The following code example iterates through a list of customer names and returns each customer name in a
message.
If <Condition> is true, then <Statement> is executed repeatedly until <Condition> becomes false. If
<Condition> is false from the start, then <*Statement> is never executed.
The while do statement can be used when some code should be repeated as long as an expression is true.
Programming conventions
When there's only one condition, put while and do on the same line. Put the statements on separate lines and
indented by two spaces.
When there are multiple conditions, put the conditions on separate lines, and indented by two spaces and put
do on a separate line that is aligned with while .
Example
while <expr> do
<Statement>;
Example
Example
Example
The following AL code increases the variable I until it equals 1000 and displays a message when it's finished.
var
I : integer
repeat
<Statements> until <Condition>
<Statements> is executed repeatedly until <Condition> is true.
The repeat until control structure resembles the while control structure. The difference is that because the
repeat until statement is executed from left to right, the <Statements> is always executed at least one time,
regardless of what the <Condition> is evaluated to. This contrasts with the while control structure, which
performs the evaluation before the <Statement> is executed. In the while control structure, if the first
evaluation of <Condition> returns false, then no statements are executed.
Programming conventions
Always put repeat on a separate line.
Example
Example
This code uses a repeat-until loop to count the number of entries in the Customer table.
Count := 0;
if Customer.find('-') then
repeat
Count := Count + 1;
until Customer.next <= 0;
message('The Customer table contains %1 records.',Count);
var
Count : Integer;
Customer : Record Customer;
The find method finds the first entry in the table. Each time NEXT is called, it steps one record forward. When
NEXT equals 0, there are no more entries in the table. The loop is exited, and a message displays how many
entries were found.
Exit statement
The exit statement is used to control the flow of the execution. The following syntax shows an exit statement.
exit([<Value>])
An exit statement is used to interrupt the execution of an AL trigger. The interruption occurs even when the code
is executed inside a loop or a similar structure. The exit statement is also used when a local method should
return a value.
Using exit without a parameter in a local method corresponds to using the parameter value 0. The AL method
will return the value 0 or '' (empty string).
A compile-time error occurs if exit is called by using a return parameter from either:
System-defined triggers, or
Local methods that don't return a value.
Example
The following example shows the use of the exit statement in a local method. Assume that the if statement is
used to detect an error. If the error condition is met, then execution is stopped and the local method returns the
error code 1.
Break statement
You use the break statement to terminate the iterative statement in which it appears.
break;
You typically use the break statement in the repeating statements such as for , while , or repeat to stop an
iteration or loop when certain conditions are met.
NOTE
The break statement is different than the Break Method (Report, XMLport). Although both stop an iteration or loop, the
break method will also terminate the trigger in which it's run.
Example
The following AL code increases the variable I by one for each iteration, and terminates the iteration when I
equals 10.
var
I : integer
See Also
Programming in AL
AL Simple Statements
Directives in AL
AL Essential Methods
Using Access Modifiers in AL
2/6/2023 • 2 minutes to read • Edit Online
Access modifiers are used to set accessibility of tables, table fields, codeunits, and queries, which controls
whether the object can be used from other code in your module or other modules. Access modifiers in AL are
designed to create solid APIs, by limiting the symbols that dependant modules can take a reference on. Limiting
the API surface can hide implementation details and allow for later refactoring of code without breaking external
code.
You set the object accessibility by using the Access Property. If the Access property isn't specified; default is
Public .
NOTE
In AL, access modifiers are primarily intended for designing APIs and cannot be used as a security boundary.
Access modifiers
The access modifiers that are available in AL are:
internal The object or field can be accessed only by code in the same
module, but not from another module.
Note: This accessibility level is controlled by the
internalsVisibleTo setting. For more information, see
JSON Files
local The field can be accessed only by code in the same table or
table extension where the field is defined.
Note: Applies to table fields only.
protected The field can be accessed only by code in the same table or
table extensions of that table.
Note: Applies to table fields only.
public The object or field can be accessed by any other code in the
same module and in other modules that references it.
Note: This is the default value.
IMPORTANT
Access modifiers are only taken into consideration at compile time. For example, at compile time, a table with
Access = Internal can't be used from other modules that don't have access to the internals of the module where the
table is defined, but at runtime, any module can access the table by using reflection-based mechanisms such as
RecordRef , or TransferFields . And the OnRun trigger can be run on internal codeunits by using Codeunit.Run .
Setting the object accessibility level as Access = Internal; cannot be used as a security boundary. Also see JSON Files.
See Also
AL Development Environment
Access Property
XML Comments in Code
2/6/2023 • 4 minutes to read • Edit Online
In Dynamics 365 Business Central, you can add documentation directly in your source code by including XML
elements in special comment fields before the block of code that the comment refers to. The documentation
comment must immediately precede a user-defined type that it annotates, for example a codeunit, table,
interface, or a member such as a field or method. The syntax for adding XML comments in your code is triple
slashes /// followed by one of the supported XML tags. There's IntelliSense support for writing documentation
comments that also provides a template comment on entering the third slash in the triple slash.
Documentation comments are visible when you hover over source symbols, in completion lists, and in signature
help. By adding XML comments in code, you can improve readability, add useful information about the
implementation, and help others take over code that you wrote. With XML comments, you also enable
IntelliSense in Visual Studio Code on the AL objects that you add in the code as a help to other developers,
working with or extending your code. When your code is documented using XML comments, it means that when
you've built an extension and someone extends this code, they'll get inline documentation when they call the
given object.
NOTE
Integration with documentation generator tools like DocFx and SandCastle is currently not supported.
NOTE
If you have the allowDownloadingSource setting in the app.json file set to false and you then download an app
package; the app package won't contain any XML comments.
F O RM AT T IN G XM L TA G DESC RIP T IO N SY N TA X
List syntax
<list type="bullet|number|table">
<listheader>
<term>term</term>
<description>description</description>
</listheader>
<item>
<term>term</term>
<description>description</description>
</item>
</list>
Example
The following example is taken from the Email.Codeunit.al file in the System Application. In this example, the
parameter EmailMessageId is documented using the <param> syntax.
/// <summary>
/// Provides functionality to create and send e-mails.
/// </summary>
/// <summary>
/// Enqueues an email in the outbox to be sent in the background.
/// </summary>
/// <param name="EmailMessageId">The ID of the email to enqueue</param>
procedure Enqueue(EmailMessageId: Guid)
begin
EmailImpl.Enqueue(EmailMessageId);
end;
...
Special symbols
For special symbols, such as angle brackets, to appear in text of a documentation comment, use the HTML
encoding of < and > , which is < and > respectively. The following example illustrates how.
/// <summary>
/// This property always returns a value < 1.
/// </summary>
Writing tips
Code comments improve the readability of the code that you've developed and they're useful for anyone
modifying or maintaining that code. Furthermore, code comments form the basis of auto-generated
documentation. Great code comments must do the following:
1. Never state the obvious.
2. Write a meaningful comment, use precise wording to describe why.
3. Imagine yourself in the shoes of the developer using this piece of code, what would you want to know?
4. For properties and methods, use active wording such as Sets..., Gets..., and Specifies..., and then explain what
it does.
5. List all pre-conditions for your parameters (can't be null, must be within a certain range, and so on).
6. List any post-conditions that could influence how callers deal with return values.
7. List any exceptions the method may throw (and under what circumstances).
8. If similar methods exist, explain the differences between them.
9. Call attention to anything unexpected (such as modifying global state).
10. Enumerate any side-effects, if there are any.
11. Be consistent.
12. Be concise.
13. Make sure that your comments are reviewed.
For more examples, see https://stackoverflow.com/questions/3143324/what-are-best-practices-for-
documenting-c-sharp-code-with-xml-comments.
See also
AL Development Environment
Developing Extensions in AL
Pages Overview
Microsoft Writing Style Guide
Data Types and Methods in AL
2/6/2023 • 9 minutes to read • Edit Online
The following data types are available as part of the AL Language. Each data type has various methods that
support it. For more information about a data type and its methods, select a link in the table.
Any This data type can be substituted by any other data type.
Blob Is a complex data type. Variables of this data type differ from
normal numeric and string variables in that BLOBs have a
variable length. The maximum size of a BLOB(binary large
object) is 2 GB.
Codeunit Is a container for AL code that you can use from other
application objects.
FieldRef Identifies a field in a table and gives you access to this field.
Guid Represents a 16 byte binary data type. This data type is used
for the global identification of objects, programs, records,
and so on. The important property of a GUID is that each
value is globally unique. The value is generated by an
algorithm, developed by Microsoft, which assures this
uniqueness.
InStream Is a generic stream object that you can use to read from or
write to files and BLOBs. You can define the internal structure
of a stream as a flat stream of bytes. You can assign one
stream to another. Reading from and writing to a stream
occurs sequentially.
Media Encapsulates media files, such as image .jpg and .png files, in
application database tables. The Media data type can be
used as a table field data type, but cannot be used as a
variable or parameter. The Media data type enables you to
import a media file to the application database and reference
the file from records, making it possible to display the media
file in the client user interface. You can also export media
from the database to files and streams.
Option Denotes an option value. In the code snippet below, you can
see how the Option data type is declared.
OutStream Is a generic stream object that you can use to write to files
and BLOBs.
RecordId Contains the table number and the primary key of a table.
Action Represents the action that the user took on the page.
Undefined dates
An undefined or blank date is specified by 0D. The undefined date is considered to be before all other dates.
Syntax
The syntax for defining DateTime format follows the ISO standard.
The syntax for defining Date format is yyyymmddD , where D is a mandatory letter. For example, 20180325D ,
read as the 25th of March, 2018.
To assign a normal date to a variable, use the following format: yyyymmddD .
Example
This example shows a valid assignment of date. This example is compiled and run on a computer with the
regional format set to English (United States).
var
Date1: Date;
begin
Date1 := 20180612D;
Message(Format(Date1));
end;
See Also
Get Started with AL
Developing Extensions
About Dates in Business Central
DateTime Data Type
2/6/2023 • 2 minutes to read • Edit Online
Denotes a date and time ranging from January 1, 1753, 00:00:00.000 to December 31, 9999, 23:59:59.999. An
undefined or blank DateTime is specified by 0DT.
The displayed text format of a DateTime is determined by your Regional and Language Options in Windows.
Remarks
A DateTime is stored in the database as Coordinated Universal Time (UTC). UTC is the international time
standard (formerly Greenwich Mean Time, or GMT). Zero hours UTC is midnight at 0 degrees longitude.
The DateTime is always displayed as local time in Dynamics 365 Business Central. Local time is determined by
the time zone regional settings used by your computer. You must always enter DateTimes as local time. When
you enter a DateTime as local time, it is converted to UTC using the current settings for the time zone and
daylight savings time.
The DateTime data type does not support closing dates.
By default, DateTimes are displayed using the standard display format. When you use the standard display
format, seconds and milliseconds are not displayed until you select the DateTime field. Furthermore, if you
export your data using an XMLport or by writing it to a file, the seconds and milliseconds are not exported
unless you specify that DateTime fields use another format and display this information. For more information
about how DateTime objects are displayed and the formats that are available, see Formatting Values, Dates, and
Time.
The only constant available when you use the DateTime data type is the undefined DateTime, 0DT. To assign a
constant value to a DateTime variable you must use the CreateDateTime method.
If you use a date that is outside the valid date range, a run-time error occurs.
Syntax
The syntax for defining DateTime format follows the ISO standard.
The syntax for defining Date format is yyyymmddD , where D is a mandatory letter. For example, 20180325D ,
read as the 25th of March, 2018.
The syntax for defining Time format is hhmmssT , where T is the time designator. For example, 093125H , read
as 9:13:25.
SQL Server
In SQL Server, the earliest permitted DateTime is January 1, 1753, 00:00:00.000. The latest permitted DateTime
is December 31, 9999, 23:59:59.999. If you store a date in the database that is outside the valid range for a SQL
DateTime, a runtime error occurs.
See Also
Get Started with AL
Developing Extensions
About Dates in Business Central
CurrentDateTime Method
Formatting Values, Dates, and Time
Duration Data Type
2/6/2023 • 2 minutes to read • Edit Online
Represents the difference between two DateTimes. This value can be negative. It is stored as a 64-bit integer. The
integer value is the number of milliseconds during the duration.
The following are examples of durations:
DateTime-DateTime=Duration
DateTime-Duration=DateTime
DateTime+Duration=DateTime
The value of the Duration data type can also be explicitly defined in milliseconds.
Example 1
This example shows how to calculate the difference between two DateTimes. This example is run on a computer
with the Current Format in the Regional and Language Options set to English (United States).
var
DateTime1: DateTime;
DateTime2: DateTime;
Duration: Duration;
begin
DateTime1 := CreateDateTime(20090101D, 080000T); // January 1, 2009 at 08:00:00 AM
DateTime2 := CreateDateTime(20090505D, 133001T); // May 5, 2009 at 1:30:01 PM
Duration := DateTime2 - DateTime1;
Message(Format(Duration));
end;
Example 2
The following example shows how to specify the duration of a timeout in milliseconds.
See Also
Get Started with AL
Developing Extensions
Time Data Type
2/6/2023 • 2 minutes to read • Edit Online
Denotes a time ranging from 00:00:00.000 to 23:59:59.999. An undefined or blank time is specified by 0T.
The displayed text format of the time is determined by your Regional and Language Options in Windows.
The following are examples of valid assignments of times to a Time variable MyTime. Time must be set by
specifying hours, minutes, and seconds.
MyTime := 0T;
MyTime := 115900T;
Message(Format(MyTime));
MyTime := 115934T;
Message(Format(MyTime));
MyTime := 115934.444T;
Message(Format(MyTime));
MyTime := 235900T;
Message(Format(MyTime));
MyTime := 030000T;
Message(Format(MyTime));
The following shows what the message windows display accordingly on a computer with the regional format set
to English (United States) for the syntax examples above.
11:59:00 AM
11:59:34 AM
11:59:34.444 AM
11:59:00 PM
3:00:00 AM
SQL Server
Microsoft SQL Server stores information about both date and time in columns of the DATETime type. Dynamics
365 uses only the time part and inserts a constant value for the date: 01-01-1754.
The Dynamics 365 undefined time is represented by the same value as an undefined date. The undefined date is
represented by the earliest valid DateTime in SQL Server, which is 01-01-1753 00:00:00:000.
See Also
Get Started with AL
Developing Extensions
Integer Data Type
2/6/2023 • 2 minutes to read • Edit Online
Stores whole numbers with values that range from -2,147,483,647 to 2,147,483,647.
Remarks
In addition to representing whole numbers in this range, you can use integers to represent Boolean values. For
Boolean values, 1 represents true and 0 represents false .
If you assign -2,147,483,648 directly to an Integer variable, then you get an error when you try to compile the
code. However, you can indirectly assign -2,147,483,648 to an Integer variable by using the following code.
IntegerVar := -2147483647;
IntegerVar -= 1;
If you try to indirectly assign a value that is smaller than -2,147,483,648 or larger than 2,147,483,647, then you
get a run-time error.
Example 1
The following are examples of integer values.
546
-3425
Example 2
The following example is a decimal and not an integer.
342.45
See Also
Get Started with AL
Developing Extensions
BigInteger Data Type
2/6/2023 • 2 minutes to read • Edit Online
Stores very large whole numbers that range from -9,223,372,036,854,775,807 to 9,223,372,036,854,775,807.
Remarks
This data type is a 64-bit integer.
You must add an L to the constant definition to inform AL that the integer must be interpreted and treated as a
BigInteger.
If you assign -9,223,372,036,854,775,808 directly to a BigInteger variable, then you get an error when you try to
compile the code. However, you can indirectly assign -9,223,372,036,854,775,808 to a BigInteger variable by
using the following code.
BigIntegerVar := -9223372036854775807L;
BigIntegerVar := BigIntegerVar - 1;
If you try to indirectly assign a value that is smaller than -9,223,372,036,854,775,808, or larger than
9,223,372,036,854,775,807, then you get a run-time error.
Example
BI := 1L;
BI := 455500000000L;
See Also
Get Started with AL
Developing Extensions
Decimal Data Type
2/6/2023 • 2 minutes to read • Edit Online
Example 1
The following are examples of decimal values.
546.88
3425.57
Example 2
The following is not a decimal, but rather an Integer Data Type.
342
L IM IT VA L UE
Maximum persisted value. Can read previous stored values but cannot store values
outside the formatting range since field variables cannot be
This is the maximum value that can be stored in the assigned values outside the formatting range.
database.
L IM IT VA L UE
The maximum safe value that will work on all Business Central versions of is +/- 999,999,999,999,999.99.
It is possible to assign to a variable the maximum value that can be formatted and then multiply that variable by
a large positive number, thereby generating a greater value. However, we do not recommend doing this. If you
do, you will get errors if you attempt to format this variable to a text variable or assign the variable to a field
variable in a record.
See Also
Get Started with AL
Developing Extensions
BigText Data Type
2/6/2023 • 2 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
TextPos(Text) Gets the position at which a specific string first occurs in this
BigText instance.
Remarks
This data type cannot be shown in a message window or be seen in the Debugger. The maximum length of a
BigText variable is 2,147,483,647 characters and this corresponds to 2 GB. You can use the BigText methods to
manipulate a BigText variable, for example to extract part of a BigText variable or to add a text string to a BigText
variable. The normal string methods cannot be used with a BigText variable.
See Also
Get Started with AL
Developing Extensions
Byte Data Type
2/6/2023 • 2 minutes to read • Edit Online
Stores a single, 8-bit character as a value in the range 0 to 255. You can easily convert this data type from a
number to a character and vice versa. This means you can use mathematical operators on Byte variables.
Example
The following example assumes that you have a Byte variable named B and a Text variable named S.
You can assign a constant string of the length 1 to a Byte variable, as shown in the first line of the following code
example. You can assign a single character in a Text or Code variable to a Byte variable, as shown in the second
line of the following code example. You can assign a numeric value to a Byte variable, as shown in the third line
of the following code example. This causes the Byte variable to contain the character from the ASCII character
set that corresponds to the numeric ASCII code.
B := 'A';
B := S[2];
B := 65;
You cannot assign a character to a position greater than the position of the null terminator. For example, if the
value of the text variable MyText is 'abc', then the null terminator is at position 4 and the following assignment
causes a run-time error to occur.
MyText[5] := 'e';
See Also
Get Started with AL
Developing Extensions
Char Data Type
2/6/2023 • 2 minutes to read • Edit Online
Stores a single, 16-bit character as a value in the range 0 to 65535. You can convert this data type from a
number to a character and vice versa. This means you can use mathematical operators on Char variables.
Example
The following example assumes that you have a Char variable named C and a Text or Code variable named S.
You can assign a constant string of the length 1 to a Char variable, as shown in the first line of the following
code example. You can assign a single Char in a Text or Code variable to a Char variable, as shown in the second
line of the following code example. You can assign a numeric value to a Char variable, as shown in the third line
of the following code example.
C := 'A';
C := S[2];
C := 65;
You cannot assign a Char to a position greater than the position of the null terminator. For example, if the value
of the Text variable MyText is 'abc', then the null terminator is at position 4 and the following assignment causes
a run-time error to occur.
MyText[5] := 'e';
See Also
Get Started with AL
Developing Extensions
Code Data Type
2/6/2023 • 2 minutes to read • Edit Online
Denotes a special type of string that is converted to uppercase and removes any trailing or leading spaces.
Remarks
The length of a Code variable equals the number of characters in the text without leading or trailing spaces.
You must specify the length of a Code variable or field. The maximum length of a Code variable is 1024
characters. The maximum length of a Code field in a table is 2048 characters. A Code variable cannot be null.
The Code data type supports Unicode.
You can index any character position in a string, such as A[65]. The resulting value will be a Char Data Type. You
cannot assign a char to a position in the code variable greater than the current length of the variable +1.
Fields that contain a date formula must not have data type Code. Instead, use the DateFormula Data Type. All
fields that contain a date formula with data type Code must be converted into data type DateFormula.
Example
This example shows some typical examples of code string assignments. In these examples, assume that the
variable c is a code variable with a maximum length of 4.
c := 'ABC';
// Results in variable c, which contains 'ABC'
// and is 3 characters in length.
c := '1';
// Results in variable c, which contains '1'
// and is 1 character in length.
c := '';
// Results in variable c, which contains '' (empty string)
// and is zero (0) characters in length.
c := ' 2 ';
// Results in variable c, which contains '2'
// and is 1 character in length.
See Also
Get Started with AL
Developing Extensions
Text Data Type
2/6/2023 • 5 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
ConvertStr(Text, Text, Text) Replaces all chars in source found in FromCharacters with
the corresponding char in ToCharacters and returns the
converted string. If the length of the FromCharacters
parameter and the ToChars parameter are different, an
exception is thrown. If the parameter FromCharacters or the
parameter ToChars is empty, the source is returned
unmodified. Each element in source is only converted ONCE
a double-replacement cannot happen.
CopyStr(Text, Integer [, Integer]) Copies a substring of any length from a specific position in a
string (text or code) to a new string.
DelChr(Text [, Text] [, Text]) Deletes chars contained in the which parameter in a string
based on the contents on the where parameter. If the where
parameter contains an equal-sign, then all occurrences of
characters in which is deleted from the current value. If the
where parameter contains a less-than, then the characters
are only deleted when they are first in the string. If the
where parameter contains a greater-than, then the
characters are only deleted when they are the last in the
string. If the where parameter contains any other char, an
exception is thrown. If the where parameter or the which
parameter is empty, the source is returned unmodified. The
which parameter is to be considered as an array of chars to
delete where the order does not matter.
PadStr(Text, Integer [, Text]) Changes the length of a string to a specified length. If the
string is shorter than the specified length, length spaces are
added at the end of the string to match the length. If the
string is longer than the specified length, the string is
truncated. If the specified length is less than 0, an exception
is thrown.
StrCheckSum(Text [, Text] [, Integer]) Calculates a checksum for a string that contains a number. If
the source is empty, 0 is returned. Each char in the source
and in the weight must be a numeric character 0-9,
otherwise an exception is thrown. If the WeightString
parameter is shorter then the source, it is padded with '1' up
until the length of source. If the WeightString parameter is
longer than the source, an exception is thrown.
StrPos(Text, Text) Searches for the first occurrence of substring inside a string.
StrSubstNo(Text [, Any,...]) Replaces %1, %2, %3... and #1, #2, #3... fields in a string with
the values you provide as optional parameters.
The following methods are available on instances of the Text data type.
M ET H O D N A M E DESC RIP T IO N
IndexOf(Text [, Integer]) Reports the one-based index of the first occurrence of the
specified string in this instance.
IndexOfAny(Text [, Integer]) Reports the one-based index of the first occurrence of the
specified string in this instance. The search starts at a
specified character position.
IndexOfAny(List of [Char] [, Integer]) Reports the one-based index of the first occurrence in this
instance of any character in a specified array of Unicode
characters. The search starts at a specified character position.
LastIndexOf(Text [, Integer]) Reports the one-based index position of the last occurrence
of a specified string in this instance.
PadLeft(Integer [, Char]) Returns a new Text that right-aligns the characters in this
instance by padding them on the left, for a specified total
length.
M ET H O D N A M E DESC RIP T IO N
PadRight(Integer [, Char]) Returns a new string that left-aligns the characters in this
string by padding them with spaces on the right, for a
specified total length.
Trim() Returns a new Text in which all leading and trailing white-
space characters from the current Text object are removed.
Remarks
The Text data type is a value type, such that every time you use a method on it, you create a new string object in
memory. This requires a new allocation of space. In situations where you need to perform repeated
modifications to a string, the overhead associated with creating a Text data type can be costly.
The TextBuilder Data Type is a reference type, which holds a pointer elsewhere in memory. For performance
reasons, we recommend you to use it when you want to modify a string without creating a new object. For
example, using TextBuilder Data Type can boost performance when concatenating many strings together in a
loop.
See Also
Get Started with AL
Developing Extensions
TextBuilder Data Type
TextConst Data Type
2/6/2023 • 2 minutes to read • Edit Online
Remarks
The TextConst data type is typically used for UI messages; process or error messages. Keeping the TextConst
data type in global scope, makes it easier to reuse the same message for several situations. For information
about naming, see CodeCop Rule AA0074.
IMPORTANT
The TextConst data type is not included in the .xlf files for translation. Make sure to use the Label Data Type instead.
Example
The data type can be declared with the syntax as shown in the example below.
var
globalTextConst: TextConst ENU = 'My text', DAN = 'Min tekst';
}
See Also
Get Started with AL
Developing Extensions
TextBuilder Data Type
2/6/2023 • 2 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
Insert(Integer, Text) Inserts a string into this TextBuilder instance at the specified
character position.
Replace(Text, Text, Integer, Integer) Replaces, within a substring of this instance, all occurrences
of a specified string in this TextBuilder instance with another
specified string.
Remarks
The TextBuilder data type is one-based indexed, that is, the indexing begins with 1.
The Text Data Type is a value type, such that every time you use a method on it, you create a new string object in
memory. This requires a new allocation of space. In situations where you need to perform repeated
modifications to a string, the overhead associated with creating a Text Data Type can be costly.
The TextBuilder data type is a reference type, which holds a pointer elsewhere in memory. For performance
reasons, we recommend you to use it when you want to modify a string without creating a new object. For
example, using TextBuilder data type can boost performance when concatenating many strings together in a
loop.
See Also
Get Started with AL
Developing Extensions
Text Data Type
Boolean Data Type
2/6/2023 • 2 minutes to read • Edit Online
See Also
Get Started with AL
Developing Extensions
Guid Data Type
2/6/2023 • 3 minutes to read • Edit Online
Represents a 16 byte binary data type. This data type is used for the global identification of objects, programs,
records, and so on. The important property of a GUID is that each value is globally unique. The value is
generated by an algorithm, developed by Microsoft, which assures this uniqueness.
The GUID is a 16-byte binary data type that can be logically grouped into the following subgroups:
4byte-2byte-2byte-2byte-6byte.
The standard textual representation is {12345678-1234-1234-1234-1234567890AB}.
The virtual table OLE Control (2000000042) does not use the GUID data type. It uses a textual representation of
the GUID in a text field instead. It is easier to make operations and references to this text field using the GUID
data type than it is using the textual representation. The GUID data type is compatible with the existing textual
representation.
The GUID data type is useful when you want to uniquely identify some data, so that it can be exchanged with
external applications. For example, if you want to transfer an item catalog to an external application, you add a
GUID field to the record in the table and use this as the primary reference when you communicate with the
external application.
Compatibility
You can assign and compare the Text data type and the GUID data type. Assigning a Text to a GUID can be done
as follows:
MyTableRec.MyGuid := MyTableRec.MyText;
Guid := CreateGUID();
This method creates a new unique GUID value. The value can then be assigned to a field of the GUID data type
or of the Text data type.
Ok := IsNullGUID(Guid);
This method is a convenient way to check if a value has already been assigned to a GUID. A NULL GUID
(consisting only of zeroes) is valid, but should never be used for reference purposes.
A NULL GUID is valid but is not useful in a table. Therefore, the AutoSplitKey property is implemented for the
GUID data type when it is used in a page. When GUID is selected as a primary key, AutoSplitKey is enabled for
the page, and the GUID value remains NULL. When you create a new record, a valid GUID is created and
assigned automatically.
The CreateGUID method and IsNullGUID method methods are available in the AL Symbol Menu under SYSTEM,
Variables.
CreateGUID takes no arguments and returns a valid 16-byte GUID value. If the result is assigned to a TEXT
variable or field, the value is converted to a string and follows the syntax explained earlier. The algorithm that
generates the new GUID value uses Microsoft's CoCreateGuid method.
IsNullGUID takes a GUID value as a required argument and returns True/False depending on whether the GUID
value is NULL. This method does not accept a Text value as an argument.
AutoSplitKey is a property, not a method and can be applied to pages. If you have defined a GUID field as part
of the primary key, the AutoSplitKey property automatically generates a new valid GUID value. When a new
record is created and the GUID field is left as NULL, the AutoSplitKey property ensures that a valid GUID value
is automatically inserted into the field. If you then enter a NULL GUID into this record, for example, by using the
Clear method, this new NULL GUID value is not automatically replaced by the AutoSplitKey property. The
AutoSplitKey property only applies to new records.
Format
The GUID value can also be represented as text. You can use the standard AL methods Format and Evaluate to
convert from GUID values to Text values. If you do not use the correct format when you edit a GUID value in its
textual format, the following error message is displayed:
Invalid Format of GUID string. The correct format of the GUID string is {CDEF7890-ABCD-1234-
ABCD-1234567890AB} where 0-9, A-F symbolizes hexadecimal digits.
See Also
Get Started with AL
Developing Extensions
Blob Data Type
2/6/2023 • 2 minutes to read • Edit Online
Is a complex data type. Variables of this data type differ from normal numeric and string variables in that BLOBs
have a variable length. The maximum size of a BLOB(binary large object) is 2 GB.
The following methods are available on instances of the Blob data type.
M ET H O D N A M E DESC RIP T IO N
CreateInStream(InStream [, TextEncoding]) Creates an InStream object for a binary large object (BLOB).
This enables you to read data from the BLOB.
Remarks
Use BLOBs to store memos (text), pictures (bitmaps), or user-defined types.
NOTE
You cannot view text that is stored in BLOBs from the development environment.
You can read from and write to BLOBs by creating input and output streams, respectively. To do so, use
CreateInStream method (BLOB) and CreateOutStream method (BLOB).
See Also
Get Started with AL
Developing Extensions
Media Data Type
2/6/2023 • 2 minutes to read • Edit Online
Encapsulates media files, such as image .jpg and .png files, in application database tables. The Media data type
can be used as a table field data type, but cannot be used as a variable or parameter. The Media data type
enables you to import a media file to the application database and reference the file from records, making it
possible to display the media file in the client user interface. You can also export media from the database to
files and streams.
The following methods are available on the Media data type.
M ET H O D N A M E DESC RIP T IO N
The following methods are available on instances of the Media data type.
M ET H O D N A M E DESC RIP T IO N
ExportStream(OutStream) Exports the current media object (such as a JPEG image) that
is used on record to an OUTSTREAM object. The
OUTSTREAM object can be created from a BLOB field, a FILE
or from a .NET Framework interoperability object. In the
record, the media is referenced in a Media data type field.
HasValue() Checks whether a Media data type field in a record has been
initialized with a media object and that the specified media
object exists in the database.
ImportFile(Text, Text [, Text]) Adds a media type, such as a JPEG image, from a file to a
Media data type field of a record for displaying the media
with the record in the client. The media file is imported to
the application database, and a reference to the media is
included in the Media data type field.
ImportStream(InStream, Text [, Text]) Adds a media type (MIME), such as jpeg image, from an
InStream object to a Media data type field of a record for
displaying the media in the client. The media file is imported
to the application database and a reference to the media is
included in the Media data type field.
M ET H O D N A M E DESC RIP T IO N
ImportStream(InStream, Text, Text, Text) Adds a media type (MIME), such as jpeg image, from an
InStream object to a Media data type field of a record for
displaying the media in the client. The media file is imported
to the application database and a reference to the media is
included in the Media data type field.
NOTE
Starting with Business Central 2021 release wave 1, when importing Microsoft Word files (.docx), macro packages (VBA
code) will automatically be removed from the file when stored in the database. If macros are needed for end-user
scenarios, the macro must be in the Word template (.dotx) associated with the document being imported.
See Also
Get Started with AL
Developing Extensions
Working With Media on Records
MediaSet Data Type
2/6/2023 • 2 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
FindOrphans() Discovers all orphaned media sets. Orphaned media sets are
media sets that are not referenced by any other table.
The following methods are available on instances of the MediaSet data type.
M ET H O D N A M E DESC RIP T IO N
Count() Gets the number of media objects that are included in the
MediaSet of a record.
ImportFile(Text, Text [, Text]) Adds a media, such as a JPEG image, to the MediaSet data
type field of a record for displaying the media in the client.
The media is imported to the database and included in a
MediaSet for the record.
ImportStream(InStream, Text [, Text]) Adds a media file, such as a JPEG image, from an InStream
object to the MediaSet of record for displaying in the client.
The media is imported to the database and included in a
MediaSet for the record.
See Also
Get Started with AL
Developing Extensions
Working With Media on Records
Record Data Type
2/6/2023 • 8 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
AreFieldsLoaded(Any,...) Checks whether the specified fields are all initially loaded.
Ascending([Boolean]) Gets or sets the order in which the system searches through
a table.
CalcFields(Any [, Any,...]) Calculates the FlowFields in a record. You specify which fields
to calculate by using parameters.
CalcSums(Any [, Any,...]) Calculates the total of a column in a table. You specify which
fields to calculate by using parameters.
CopyFilter(Any, Any) Copies the filter that has been set for one field and applies it
to another field.
CopyFilters(var Record) Copies all the filters set by the SETFILTER method (Record) or
the SETRANGE method (Record) from one record to another.
DeleteAll([Boolean]) Deletes all records in a table that fall within a specified range.
DeleteLinks() Deletes all of the links that have been added to a record.
FieldError(Any [, Text]) Stops the execution of the code causing a run-time error,
and creates an error message for a field.
FieldError(Any, ErrorInfo) Stops the execution of the code causing a run-time error,
and creates an error message for a field.
FindFirst() Finds the first record in a table based on the current key and
filter.
FindLast() Finds the last record in a table based on the current key and
filter.
FindSet([Boolean] [, Boolean]) Finds a set of records in a table based on the current key
and filter.
GetAscending(Any) Gets the sort order for the records returned. You can use
GETASCENDING to identify the sort order of the specified
field because fields can be sorted in ascending or descending
order. For example, you can read data from an ODATA web
service where the data is sorted in ascending order on the
Name field but in descending order on the City field.
GetFilter(Any) Gets a list of the filters within the current filter group that
are applied to a field.
GetFilters() Gets a string that contains a list of the filters within the
current filter group for all fields in a record. In addition, this
method also returns the state of the MARKEDONLY method
(Record).
GetPosition([Boolean]) Gets a string that contains the primary key of the current
record.
GetView([Boolean]) Gets a string that describes the current sort order, key, and
filters on a table.
LoadFields(Any,...) Accesses the table's corresponding data source and loads the
values of the specified fields on the record.
Mark([Boolean]) Marks a record. You can also use this method to determine
whether a record is marked.
MarkedOnly([Boolean]) Activates a special filter. After you use this function, your
view of the table includes only records marked by the Mark
(Record) method.
ModifyAll(Any, Any [, Boolean]) Modifies a field in all records within a range that you specify.
SecurityFiltering([SecurityFilter]) Gets or sets how security filters are applied to the record.
SetAscending(Any, Boolean) Sets the sort order for the records returned. Use this
method after you have set the keys to sort after, using
SETCURRENTKEY. The default sort order is ascending. You
can use SETASCENDING to change the sort order to
descending for a specific field, while the other fields in the
specified key are sorted in ascending order.
SetRange(Any [, Any] [, Any]) Sets a simple filter, such as a single range or a single value,
on a field.
SetRecFilter() Sets the values in the current key of the current record as a
record filter.
SetView(Text) Sets the current sort order, key, and filters on a table.
TestField(Any) Tests that the content of the field is not zero or blank (empty
string).
TestField(Any, ErrorInfo) Tests that the content of the field is not zero or blank (empty
string).
TestField(Any, Boolean) Tests whether the contents of a field match a given value.
TestField(Any, Boolean, ErrorInfo) Tests whether the contents of a field match a given value.
TestField(Any, Integer) Tests whether the contents of a field match a given value.
TestField(Any, Integer, ErrorInfo) Tests whether the contents of a field match a given value.
TestField(Any, BigInteger) Tests whether the contents of a field match a given value.
TestField(Any, BigInteger, ErrorInfo) Tests whether the contents of a field match a given value.
TestField(Any, Decimal) Tests whether the contents of a field match a given value.
TestField(Any, Decimal, ErrorInfo) Tests whether the contents of a field match a given value.
TestField(Any, Guid) Tests whether the contents of a field match a given value.
TestField(Any, Guid, ErrorInfo) Tests whether the contents of a field match a given value.
TestField(Any, Text) Tests whether the contents of a field match a given value.
TestField(Any, Text, ErrorInfo) Tests whether the contents of a field match a given value.
M ET H O D N A M E DESC RIP T IO N
TestField(Any, Label) Tests whether the contents of a field match a given value.
TestField(Any, Label, ErrorInfo) Tests whether the contents of a field match a given value.
TestField(Any, TextConst) Tests whether the contents of a field match a given value.
TestField(Any, TextConst, ErrorInfo) Tests whether the contents of a field match a given value.
TestField(Any, Code) Tests whether the contents of a field match a given value.
TestField(Any, Code, ErrorInfo) Tests whether the contents of a field match a given value.
TestField(Any, Text) Tests whether the contents of a field match a given value.
TestField(Any, Text, ErrorInfo) Tests whether the contents of a field match a given value.
TestField(Any, Enum) Tests whether the contents of a field match a given value.
TestField(Any, Enum, ErrorInfo) Tests whether the contents of a field match a given value.
TestField(Any, Any) Tests whether the contents of a field match a given value.
TestField(Any, Any, ErrorInfo) Tests whether the contents of a field match a given value.
TransferFields(var Record [, Boolean]) Copies all matching fields in one record to another record.
TransferFields(var Record, Boolean, Boolean) Copies all matching fields in one record to another record.
Validate(Any [, Any]) Calls the OnValidate trigger for the field that you specify.
See Also
Get Started with AL
Developing Extensions
System Data Type
2/6/2023 • 6 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
ApplicationPath() Returns the path of the directory where the executable file
for the product is installed.
ArrayLen(Array of [Any] [, Integer]) Returns the total number of elements in an array or the
number of elements in a specific dimension.
CalcDate(Text [, Date]) Calculates a new date that is based on a date expression and
a reference date.
CalcDate(DateFormula [, Date]) Calculates a new date that is based on a date expression and
a reference date.
Clear(var Array of [Any]) Clears the value of a single variable. Also, it clears all the
filters that were set if the variable is a record and resets the
key to the primary key and the company on a record
variable.
Clear(var Any) Clears the value of a single variable. Also, it clears all the
filters that were set if the variable is a record and resets the
key to the primary key and the company on a record
variable.
ClearAll() Clears all internal variables (except REC variables), keys, and
filters in the object and in any associated objects, such as
reports, pages, codeunits, and so on that contain AL code.
ClearCollectedErrors() Clears all collected errors from the current collection scope.
CodeCoverageLog([Boolean] [, Boolean]) Starts and stops the logging of code. You can also use this
method to retrieve the current logging status.
CopyArray(Array of [Any], Array of [Any], Integer [, Integer]) Copies one or more elements in an array to a new array.
CreateGuid() Creates a new unique GUID. The value can then be assigned
to a GUID data type or a text data type. Use the text data
type if you want to compare the GUID to another text
string.
Date2DMY(Date, Integer) Gets the day, month, or year of a Date Data Type.
Date2DWY(Date, Integer) Gets the day of the week, week number, or year of a Date
Data Type.
DMY2Date(Integer [, Integer] [, Integer]) Gets a Date object based on a day, month, and year.
DWY2Date(Integer [, Integer] [, Integer]) Gets a Date that is based on a week day, a week, and a year.
M ET H O D N A M E DESC RIP T IO N
Evaluate(var Any, Text [, Integer]) Evaluates a string representation of a value into its typical
representation. The result is assigned to a variable.
GetDocumentUrl(Guid) Gets the URL for the specified temporary media object ID.
GetLastErrorCallStack() Gets the call stack from where the last error occurred.
GetUrl(ClientType [, Text] [, ObjectType] [, Integer] [, Record] [, Generates a URL for the specified client target that is based
Boolean]) on the configuration of the server instance. If the code runs
in a multitenant deployment architecture, the generated URL
will automatically apply to the tenant ID of the current user.
GetUrl(ClientType, Text, ObjectType, Integer, RecordRef [, Generates a URL for the specified client target that is based
Boolean]) on the configuration of the server instance. If the code runs
in a multitenant deployment architecture, the generated URL
will automatically apply to the tenant ID of the current user.
M ET H O D N A M E DESC RIP T IO N
ImportEncryptionKey(Text, Text) Points to a password protected file that contains the key on
the current server. When encrypting or decrypting data in
Dynamics 365 Business Central, an encryption key is used. A
single key is used per tenant, and every tenant will have a
different key. Keys can be created or imported if one exists
already, as may be the case if upgrading or migrating a
system from one set of hardware to another. The
IMPORTENCRYPTIONKEY method allows an administrator to
specify a file (password protected) which contains a key and
imports it to the current Dynamics 365 Business Central
service.
NormalDate(Date) Gets the regular date (instead of the closing date) for the
argument Date.
Power(Decimal, Decimal) Raises a number to a power. For example, you can use this
method to square the number 2 to get the result of 4.
TemporaryPath() Gets the path of the directory where the temporary file is
stored.
WorkDate([Date]) Gets and sets the work date for the current session.
See Also
Get Started with AL
Developing Extensions
JsonArray Data Type
2/6/2023 • 5 minutes to read • Edit Online
Is a container for any well-formed JSON array. A default JsonArray contains an empty JSON array.
The following methods are available on instances of the JsonArray data type.
M ET H O D N A M E DESC RIP T IO N
Get(Integer, var JsonToken) Retrieves the value at the given index in the JsonArray.
Insert(Integer, JsonToken) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
Insert(Integer, JsonArray) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
Insert(Integer, JsonObject) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
Insert(Integer, JsonValue) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
Insert(Integer, Boolean) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
Insert(Integer, Char) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
M ET H O D N A M E DESC RIP T IO N
Insert(Integer, Byte) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
Insert(Integer, Option) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
Insert(Integer, Integer) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
Insert(Integer, BigInteger) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
Insert(Integer, Decimal) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
Insert(Integer, Duration) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
Insert(Integer, Date) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
Insert(Integer, Time) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
Insert(Integer, DateTime) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
Insert(Integer, Text) Inserts the value at the given index in the array while
shifting all the values to the right by one position.
Path() Retrieves the JSON path of the array relative to the root of
its containing tree.
ReadFrom(Text) Reads the JSON data from the string into a JsonArray
variable.
ReadFrom(InStream) Reads the JSON data from the stream into a JsonArray
variable.
Set(Integer, JsonToken) Replaces the value at the given index with a new value.
Set(Integer, JsonObject) Replaces the value at the given index with a new value.
Set(Integer, JsonArray) Replaces the value at the given index with a new value.
Set(Integer, JsonValue) Replaces the value at the given index with a new value.
Set(Integer, Boolean) Replaces the value at the given index with a new value.
M ET H O D N A M E DESC RIP T IO N
Set(Integer, Char) Replaces the value at the given index with a new value.
Set(Integer, Byte) Replaces the value at the given index with a new value.
Set(Integer, Option) Replaces the value at the given index with a new value.
Set(Integer, Integer) Replaces the value at the given index with a new value.
Set(Integer, BigInteger) Replaces the value at the given index with a new value.
Set(Integer, Decimal) Replaces the value at the given index with a new value.
Set(Integer, Duration) Replaces the value at the given index with a new value.
Set(Integer, Date) Replaces the value at the given index with a new value.
Set(Integer, Time) Replaces the value at the given index with a new value.
Set(Integer, DateTime) Replaces the value at the given index with a new value.
Set(Integer, Text) Replaces the value at the given index with a new value.
WriteTo(var Text) Serializes and writes the JSON data of the JsonArray to a
given Text object.
NOTE
For performance reasons all HTTP, JSON, TextBuilder, and XML types are reference types, not value types. Reference types
holds a pointer to the data elsewhere in memory, whereas value types store its own data.
NOTE
The JsonArray is 0-based by design.
See Also
Get Started with AL
Developing Extensions
JsonObject Data Type
2/6/2023 • 3 minutes to read • Edit Online
Is a container for any well-formed JSON object. A default JsonObject contains an empty JSON object.
The following methods are available on instances of the JsonObject data type.
M ET H O D N A M E DESC RIP T IO N
Get(Text, var JsonToken) Retrieves the value of a property with a given key from a
JsonObject.
Path() Retrieves the JSON path of the object relative to the root of
its containing tree.
ReadFrom(Text) Reads the JSON data from the string into a JsonObject
variable.
ReadFrom(InStream) Reads the JSON data from the stream into a JsonObject
variable.
Remove(Text) Removes the property with the given key from the object.
Replace(Text, JsonToken) Replaces the value of the property with the given key with
the new value.
Replace(Text, JsonArray) Replaces the value of the property with the given key with
the new value.
Replace(Text, JsonObject) Replaces the value of the property with the given key with
the new value.
Replace(Text, JsonValue) Replaces the value of the property with the given key with
the new value.
Replace(Text, Boolean) Replaces the value of the property with the given key with
the new value.
Replace(Text, Char) Replaces the value of the property with the given key with
the new value.
Replace(Text, Byte) Replaces the value of the property with the given key with
the new value.
Replace(Text, Integer) Replaces the value of the property with the given key with
the new value.
Replace(Text, Option) Replaces the value of the property with the given key with
the new value.
Replace(Text, BigInteger) Replaces the value of the property with the given key with
the new value.
Replace(Text, Decimal) Replaces the value of the property with the given key with
the new value.
Replace(Text, Duration) Replaces the value of the property with the given key with
the new value.
M ET H O D N A M E DESC RIP T IO N
Replace(Text, Date) Replaces the value of the property with the given key with
the new value.
Replace(Text, Time) Replaces the value of the property with the given key with
the new value.
Replace(Text, DateTime) Replaces the value of the property with the given key with
the new value.
Replace(Text, Text) Replaces the value of the property with the given key with
the new value.
WriteTo(var Text) Serializes and writes the JSON data of the JsonObject to a
given Text object.
NOTE
For performance reasons all HTTP, JSON, TextBuilder, and XML types are reference types, not value types. Reference types
holds a pointer to the data elsewhere in memory, whereas value types store its own data.
Remarks
An unitialized variable of JsonObject type represents an empty JSON object. Given a value of JsonObject type,
you can check if it is empty by checking that the number of keys in the object is 0.
jsonObject.Keys.Count = 0
See Also
Get Started with AL
Developing Extensions
JsonToken Data Type
2/6/2023 • 2 minutes to read • Edit Online
Is a container for any well-formed JSON data. A default JsonToken object contains the JSON value of NULL.
The following methods are available on instances of the JsonToken data type.
M ET H O D N A M E DESC RIP T IO N
Path() Retrieves the JSON path of the token relative to the root of
its containing tree.
ReadFrom(Text) Reads the JSON data from the string into a JsonToken
variable.
ReadFrom(InStream) Reads the JSON data from the stream into a JsonToken
variable.
WriteTo(var Text) Serializes and writes the JSON data of the JsonToken to a
given Text object.
NOTE
For performance reasons all HTTP, JSON, TextBuilder, and XML types are reference types, not value types. Reference types
holds a pointer to the data elsewhere in memory, whereas value types store its own data.
See Also
Get Started with AL
Developing Extensions
JsonValue Data Type
2/6/2023 • 2 minutes to read • Edit Online
Is a container for any well-formed fundamental JSON value. A default JsonValue is set to the JSON value of
NULL.
The following methods are available on instances of the JsonValue data type.
M ET H O D N A M E DESC RIP T IO N
ReadFrom(InStream) Reads the JSON data from the stream into a JsonValue
variable.
WriteTo(var Text) Serializes and writes the JSON data of the JsonValue to a
given object.
NOTE
For performance reasons all HTTP, JSON, TextBuilder, and XML types are reference types, not value types. Reference types
holds a pointer to the data elsewhere in memory, whereas value types store its own data.
See Also
Get Started with AL
Developing Extensions
XmlAttribute Data Type
2/6/2023 • 2 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
The following methods are available on instances of the XmlAttribute data type.
M ET H O D N A M E DESC RIP T IO N
SelectNodes(Text, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectNodes(Text, XmlNamespaceManager, var XmlNodeList) Selects a list of nodes matching the XPath expression.
M ET H O D N A M E DESC RIP T IO N
SelectSingleNode(Text, var XmlNode) Selects the first XmlNode that matches the XPath expression.
SelectSingleNode(Text, XmlNamespaceManager, var Selects the first XmlNode that matches the XPath expression.
XmlNode)
WriteTo(OutStream) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, OutStream) Serializes and saves the current node to the given variable.
WriteTo(var Text) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, var Text) Serializes and saves the current node to the given variable.
See Also
Get Started with AL
Developing Extensions
XmlAttributeCollection Data Type
2/6/2023 • 2 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
Set(Text, Text) Sets the value of the specified attribute or creates it if is not
part of the collection.
Set(Text, Text, Text) Sets the value of the specified attribute or creates it if is not
part of the collection.
See Also
Get Started with AL
Developing Extensions
XmlCData Data Type
2/6/2023 • 2 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
The following methods are available on instances of the XmlCData data type.
M ET H O D N A M E DESC RIP T IO N
SelectNodes(Text, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectNodes(Text, XmlNamespaceManager, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectSingleNode(Text, var XmlNode) Selects the first XmlNode that matches the XPath expression.
SelectSingleNode(Text, XmlNamespaceManager, var Selects the first XmlNode that matches the XPath expression.
XmlNode)
WriteTo(OutStream) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, OutStream) Serializes and saves the current node to the given variable.
WriteTo(var Text) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, var Text) Serializes and saves the current node to the given variable.
See Also
Get Started with AL
Developing Extensions
XmlComment Data Type
2/6/2023 • 2 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
The following methods are available on instances of the XmlComment data type.
M ET H O D N A M E DESC RIP T IO N
SelectNodes(Text, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectNodes(Text, XmlNamespaceManager, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectSingleNode(Text, var XmlNode) Selects the first XmlNode that matches the XPath expression.
SelectSingleNode(Text, XmlNamespaceManager, var Selects the first XmlNode that matches the XPath expression.
XmlNode)
WriteTo(OutStream) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, OutStream) Serializes and saves the current node to the given variable.
WriteTo(var Text) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, var Text) Serializes and saves the current node to the given variable.
See Also
Get Started with AL
Developing Extensions
XmlDeclaration Data Type
2/6/2023 • 2 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
The following methods are available on instances of the XmlDeclaration data type.
M ET H O D N A M E DESC RIP T IO N
SelectNodes(Text, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectNodes(Text, XmlNamespaceManager, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectSingleNode(Text, var XmlNode) Selects the first XmlNode that matches the XPath expression.
SelectSingleNode(Text, XmlNamespaceManager, var Selects the first XmlNode that matches the XPath expression.
XmlNode)
WriteTo(OutStream) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, OutStream) Serializes and saves the current node to the given variable.
M ET H O D N A M E DESC RIP T IO N
WriteTo(var Text) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, var Text) Serializes and saves the current node to the given variable.
See Also
Get Started with AL
Developing Extensions
XmlDocument Data Type
2/6/2023 • 2 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
ReadFrom(Text, var XmlDocument) Reads and parses the XML document from the given data
source.
ReadFrom(Text, XmlReadOptions, var XmlDocument) Reads and parses the XML document from the given data
source.
ReadFrom(InStream, var XmlDocument) Reads and parses the XML document from the given data
source.
ReadFrom(InStream, XmlReadOptions, var XmlDocument) Reads and parses the XML document from the given data
source.
The following methods are available on instances of the XmlDocument data type.
M ET H O D N A M E DESC RIP T IO N
AddFirst(Any,...) Adds the specified content at the start of the child list of this
document.
GetChildElements() Gets a list containing the child elements for this document,
in document order.
GetChildElements(Text) Gets a list containing the child elements for this document,
in document order.
GetChildElements(Text, Text) Gets a list containing the child elements for this document,
in document order.
M ET H O D N A M E DESC RIP T IO N
GetChildNodes() Gets a list containing the child elements for this document,
in document order.
GetDescendantElements(Text, Text) Gets a list containing the descendant elements for this
document, in document order.
GetDocumentType(var XmlDocumentType) Gets the Document Type Definition (DTD) for this document.
GetRoot(var XmlElement) Gets the root element of the XML tree for this document.
SelectNodes(Text, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectNodes(Text, XmlNamespaceManager, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectSingleNode(Text, var XmlNode) Selects the first XmlNode that matches the XPath expression.
SelectSingleNode(Text, XmlNamespaceManager, var Selects the first XmlNode that matches the XPath expression.
XmlNode)
WriteTo(OutStream) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, OutStream) Serializes and saves the current node to the given variable.
M ET H O D N A M E DESC RIP T IO N
WriteTo(var Text) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, var Text) Serializes and saves the current node to the given variable.
See Also
Get Started with AL
Developing Extensions
XmlDocumentType Data Type
2/6/2023 • 2 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
The following methods are available on instances of the XmlDocumentType data type.
M ET H O D N A M E DESC RIP T IO N
GetInternalSubset(var Text) Gets the internal subset for this Document Type Definition
(DTD).
GetName(var Text) Gets the name for this Document Type Definition (DTD).
GetPublicId(var Text) Gets the public identifier for this Document Type Definition
(DTD).
GetSystemId(var Text) Gets the system identifier for this Document Type Definition
(DTD).
SelectNodes(Text, var XmlNodeList) Selects a list of nodes matching the XPath expression.
M ET H O D N A M E DESC RIP T IO N
SelectNodes(Text, XmlNamespaceManager, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectSingleNode(Text, var XmlNode) Selects the first XmlNode that matches the XPath expression.
SelectSingleNode(Text, XmlNamespaceManager, var Selects the first XmlNode that matches the XPath expression.
XmlNode)
SetInternalSubset(Text) Sets the internal subset for this Document Type Definition
(DTD).
SetName(Text) Sets the name for this Document Type Definition (DTD).
SetPublicId(Text) Sets the public identifier for this Document Type Definition
(DTD).
SetSystemId(Text) Sets the system identifier for this Document Type Definition
(DTD).
WriteTo(OutStream) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, OutStream) Serializes and saves the current node to the given variable.
WriteTo(var Text) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, var Text) Serializes and saves the current node to the given variable.
See Also
Get Started with AL
Developing Extensions
XmlElement Data Type
2/6/2023 • 2 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
The following methods are available on instances of the XmlElement data type.
M ET H O D N A M E DESC RIP T IO N
AddFirst(Any,...) Adds the specified content at the start of the child list of this
element.
GetChildElements() Gets a list containing the child elements for this element, in
document order.
GetChildElements(Text) Gets a list containing the child elements for this element, in
document order.
GetChildElements(Text, Text) Gets a list containing the child elements for this element, in
document order.
GetChildNodes() Gets a list containing the child elements for this element, in
document order.
GetDescendantElements(Text, Text) Gets a list containing the descendant elements for this
element, in document order.
GetDescendantNodes() Gets a list containing the descendant nodes for this element,
in document order.
GetNamespaceOfPrefix(Text, var Text) Gets the namespace associated with a particular prefix for
this element.
GetPrefixOfNamespace(Text, var Text) Gets the prefix associated with a namespace URI for this
element.
HasElements() Gets a value indicating whether this element has at least one
child element.
InnerText() Gets the concatenated values of the node and all its child
nodes.
InnerXml() Gets the markup representing only the child nodes of this
node.
SelectNodes(Text, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectNodes(Text, XmlNamespaceManager, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectSingleNode(Text, var XmlNode) Selects the first XmlNode that matches the XPath expression.
SelectSingleNode(Text, XmlNamespaceManager, var Selects the first XmlNode that matches the XPath expression.
XmlNode)
SetAttribute(Text, Text) Sets the value of the specified attribute or create it if is not
part of the element's attribute collection.
SetAttribute(Text, Text, Text) Sets the value of the specified attribute or create it if is not
part of the element's attribute collection.
WriteTo(OutStream) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, OutStream) Serializes and saves the current node to the given variable.
WriteTo(var Text) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, var Text) Serializes and saves the current node to the given variable.
See Also
Get Started with AL
Developing Extensions
XmlNamespaceManager Data Type
2/6/2023 • 2 minutes to read • Edit Online
Represents a namespace manager that can be used to resolve, add and remove namespaces to a collection. It
also provides scope management for these namespaces.
The following methods are available on instances of the XmlNamespaceManager data type.
M ET H O D N A M E DESC RIP T IO N
LookupNamespace(Text, var Text) Gets the namespace URI for the specified prefix.
LookupPrefix(Text, var Text) Finds the prefix declared for the given namespace URI.
RemoveNamespace(Text, Text) Removes the given namespace for the given prefix.
See Also
Get Started with AL
Developing Extensions
XmlNameTable Data Type
2/6/2023 • 2 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
Get(Text, var Text) Gets the atomized string with the specified value.
See Also
Get Started with AL
Developing Extensions
XmlNode Data Type
2/6/2023 • 2 minutes to read • Edit Online
Represents a XML node which can either be for instance an XML attribute, an XML element or a XML document.
The following methods are available on instances of the XmlNode data type.
M ET H O D N A M E DESC RIP T IO N
AsXmlText() Converts the node to an XmlText node. The operation will fail
if the node is not an XmlText.
SelectNodes(Text, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectNodes(Text, XmlNamespaceManager, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectSingleNode(Text, var XmlNode) Selects the first XmlNode that matches the XPath expression.
SelectSingleNode(Text, XmlNamespaceManager, var Selects the first XmlNode that matches the XPath expression.
XmlNode)
WriteTo(OutStream) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, OutStream) Serializes and saves the current node to the given variable.
WriteTo(var Text) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, var Text) Serializes and saves the current node to the given variable.
See Also
Get Started with AL
Developing Extensions
XmlNodeList Data Type
2/6/2023 • 2 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
See Also
Get Started with AL
Developing Extensions
XmlText Data Type
2/6/2023 • 2 minutes to read • Edit Online
M ET H O D N A M E DESC RIP T IO N
The following methods are available on instances of the XmlText data type.
M ET H O D N A M E DESC RIP T IO N
SelectNodes(Text, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectNodes(Text, XmlNamespaceManager, var XmlNodeList) Selects a list of nodes matching the XPath expression.
SelectSingleNode(Text, var XmlNode) Selects the first XmlNode that matches the XPath expression.
SelectSingleNode(Text, XmlNamespaceManager, var Selects the first XmlNode that matches the XPath expression.
XmlNode)
WriteTo(OutStream) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, OutStream) Serializes and saves the current node to the given variable.
WriteTo(var Text) Serializes and saves the current node to the given variable.
WriteTo(XmlWriteOptions, var Text) Serializes and saves the current node to the given variable.
See Also
Get Started with AL
Developing Extensions
AL Development Environment
2/6/2023 • 2 minutes to read • Edit Online
This section describes all of the objects that are available with the AL Language development environment for
Dynamics 365 Business Central.
TIP
If you are looking for the C/SIDE documentation, visit our Dynamics NAV library.
Learn about how to define new table objects for your Table Object
extension.
Learn about how to modify and extend existing table Table Extension Object
objects.
Learn about how to create new page objects for your Page Object
extension.
Learn about how to modify and extend existing page Page Extension Object
objects.
Learn about how to create page customization objects. Page Customization Object
Learn about how to create report extension objects. Report Extension Object
Learn about how to create control add-in objects. Control Add-In Object
Learn about how to create permissionset extension objects. Permissionset Extension Object
Writing AL code
TO SEE
Get an overview of methods in AL grouped by the data type Data Types and Methods in AL
that they support.
See Also
Developing Extensions
Get Started with AL
FAQ for Developing in AL
AL Language Extension Configuration
Joker Data Type
2/6/2023 • 2 minutes to read • Edit Online
Joker is an internal data type that is not exposed to AL developers. Joker can replace any other type and
represents a wildcard. In certain cases, Joker plays the role of a generic T which is inferred from the type of the
left-hand side of the invocation expression, in other cases, it is inferred from another parameter.
The following illustrates examples of how Joker is used in AL.
See Also
AL Method Reference
AL Development Environment
Array Methods
2/6/2023 • 2 minutes to read • Edit Online
An array is a data structure that contains many variables, which are accessed through computed indices. An
index is the location of the variable stored in an array. The variables contained in an array are also called the
elements of the array. The array always stores elements of the same data type.
An array has a rank that determines the number of indices that is how long it takes to reach an element. And if
there are repeating elements, their rank will be same as their first occurrence in the array. The rank of an array is
also referred to as the dimension of the array. An array with a rank of one is called a single-dimensional array.
An array with a rank greater than one is called a multi-dimensional array. Specific sized multi-dimensional
arrays are often referred to as two-dimensional arrays, three-dimensional arrays, and so on. Each dimension of
an array has an associated length, which is an integral number greater than or equal to zero. The maximum
number of dimensions is 10 and the total number of elements in all dimensions is 1,000,000.
The length of a dimension determines the valid range of indices for that dimension. For a dimension of length N,
indices can range from 1 to N inclusive. The total number of elements in an array is the product of the lengths
of each dimension in the array. If one or more of the dimensions of an array have a length of zero, the array is
considered to be empty.
Syntax
The syntax for declaring an array of a specific type is the following:
The Dimension is a comma-delimited list of integer literals greater than 0, where each integer defines the
number of elements in that dimension.
The Type is the element type of the array.
Code example
The following code sample shows the declaration of an array with a simple element type.
The following code sample shows the declaration of an array with an element type of a fixed length.
The following code sample shows the declaration of an array with a complex element type.
In this case, each element of the array will contain a temporary Item record referencing the same temporary
table, meaning that an insert into ItemRecArrayTemp[0] is also reflected in ItemRecArrayTemp[1] .
This is the same behavior as using Copy(RecordRef [, Boolean]) with the ShareTable parameter set to true .
See Also
AL Method Reference
Dictionary Data Type
2/6/2023 • 2 minutes to read • Edit Online
Represents an unordered collection of keys and values. The Dictionary data type is optimized for fast lookup of
values.
The following methods are available on instances of the Dictionary data type.
M ET H O D N A M E DESC RIP T IO N
Add(TKey, TValue) Adds the specified key and value to the dictionary.
Get(TKey, var TValue) Gets the value associated with the specified key.
Remove(TKey) Removes the value with the specified key from the
Dictionary.
Set(TKey, TValue) Sets the value associated with the specified key.
Set(TKey, TValue, var TValue) Sets the value associated with the specified key.
Remarks
Each addition to the dictionary consists of a value, and its associated key. Every key in a Dictionary must be
unique. A key cannot be null, but a value can be, only when the value type is a reference type.
The Dictionary data type does not support holding instantiated records. For this purpose, use temporary tables.
WARNING
Previously in C/AL, one would have typically used an in-memory temporary table to create a key-value data structure, as
shown in the code below. In AL you use the Dictionary Data Type instead.
for i := 1 to StrLen(customerName) do
begin
if counter.Get(customerName[i], c) then
counter.Set(customerName[i], c + 1)
else
counter.Add(customerName[i], 1);
end;
end;
See Also
Get Started with AL
Developing Extensions
List Data Type
List Data Type
2/6/2023 • 3 minutes to read • Edit Online
Represents a strongly typed list of ordered objects that can be accessed by index. Contrary to the Array data
type, a List is unbounded, such that its dimension does not need to be specified upon declaration.
The following methods are available on instances of the List data type.
M ET H O D N A M E DESC RIP T IO N
AddRange(T [, T,...]) Adds the elements of the specified collection to the end of
the list.
AddRange(List of [T]) Adds the elements of the specified collection to the end of
the list.
Get(Integer) Gets the element at the specified index. This method will
raise an error if the index is outside the valid range.
GetRange(Integer, Integer, var List of [T]) Get a shallow copy of a range of elements in the source.
IndexOf(T) Searches for the specified value and returns the one-based
index of the first occurrence within the entire List.
LastIndexOf(T) Searches for the specified value and returns the one-based
index of the last occurrence within the entire List.
Remarks
The List can only be used with simple types i.e. you can have a List of [Integer] but cannot have a List of [Blob].
Similarly, the List data type does not support holding instantiated records. For this purpose, use temporary
tables.
Lists are 1-based indexed, that is, the indexing of a List begins with 1.
A List is a reference type, so assigning an instance of a list to another variable or passing as a method parameter
by value (for example without var), creates a second variable that reads/writes the same list. It does not create a
new list.
To create a new list that contains the same values as the original list, you can do the following to perform a
shallow copy:
trigger OnRun()
var
l1: List of [Integer];
l2: List of [Integer];
begin
l2 := l1.GetRange(1, l1.Count);
end;
A shallow copy does not copy the elements within the list, only the list itself, so if the elements within the list are
reference types as well, for example a list of lists, they will still be the same lists as in the original list.
To perform a deep copy, meaning to copy reference types within reference types, you will need to apply the
same approach to the elements of the list:
trigger OnRun()
var
innerlist: List of [Integer];
l1: List of [List of [Integer]];
l2: List of [List of [Integer]];
begin
foreach innerlist in l1 do begin
l2.Add(innerlist.GetRange(1, innerlist.Count));
end;
end;
WARNING
Previously in C/AL, one would have typically used an in-memory temporary table to create an unbounded "array" data
structure, as shown in the code below. In AL you use the List Data Type instead.
procedure WorkWithListOfCustomers();
var
customerNames : List of [Text];
begin
// Adding an element to the list
customerNames.Add('John');
See Also
Get Started with AL
Developing Extensions
Dictionary Data Type
Extensible Enums
2/6/2023 • 4 minutes to read • Edit Online
An enumeration type, also known as an enum in programming, is a keyword used to declare a type that consists
of a set of named constants. The list of named constants is called the enumeration list. Enums can be used as
table fields, local and global variables, and parameters.
To declare an enum in AL you must specify an ID and a name. The enumeration list consists of values and each
of the values are declared with an ID and a value. The value ID is the ordinal value on the enumeration list and
must be unique. When the enum values are displayed in the UI they're sorted by the order of declaration. In
addition, if extension B extends extension A , the enum values declared in extension A are displayed before the
enum values declared in extension B .
The following example shows the declaration of an enum, which can be extended, and has the four values;
None , Bronze , Silver , and Gold .
value(0; None) { }
value(1; Bronze) { }
value(2; Silver) { }
value(3; Gold)
{
Caption = 'Gold Customer';
}
}
NOTE
While enums and enumextension objects have object IDs, these are not enforced by the license. In previous versions they
reused the range for tables, and were checked against the license at deployment time, but this is no longer the case.
Uniqueness validation is now enforced during installation, which will fail if an enum object ID clashes with an already
installed enum. Thus, as always, it is important that you use object IDs in your assigned range. This is enforced for
AppSource apps, but not for per-tenant extensions, or on-premise. The enum does not have to use the same ID as the
table it is put on.
IMPORTANT
Only enums with the Extensible Property set to true can be extended.
IMPORTANT
When creating captions for enums, it's important that the caption doesn't contain a comma. Having a comma in the
caption, such as Caption = 'Diamond Level, with bonus' , can display over multiple lines in the UI. This behavior also
causes that the actual value selected by the user in the UI, doesn't correspond to the value, which is saved in the
database.
An AppSourceCop warning will be triggered if .xlf files contain commas in enum captions. For more information, see
AppSourceCop Warning AS0087.
Enumextension object
Enums can be extended in order to add more values to the enumeration list in which case the Extensible
property must be set to true . The syntax for an enum extension, which extends the Loyalty enum with the
value Diamond , is shown below.
Usage
When referencing a defined enum from code, you use the syntax as illustrated below.
enum Loyalty
If you want to define an enum as a table field type, use the syntax illustrated below:
Or, as a variable:
var
LoyaltyLevel: enum Loyalty;
In code, you address a specific enum value like in the following example:
Example
The following example illustrates how to define an enum extension of TypeEnum , using it in a table extension
TableWithRelationExt and displaying it as a control on a new page.
enumextension 50133 TypeEnumExt extends TypeEnum
{
value(10; Resource) { }
}
layout
{
area(Content)
{
repeater(MyRep)
{
field(Id; Id)
{
ApplicationArea = All;
}
field(Type; Type)
{
ApplicationArea = All;
}
field(Relation; Relation)
{
ApplicationArea = All;
}
}
}
}
}
TIP
For another example of how to extend the usage of the TableRelation property in connection with enums, see
TableRelation Property.
P RO P ERT Y N A M E DATA T Y P E
EnumTypeId Integer
EnumTypeName Text
Some table fields share options that are semantically identical. In those cases, the EnumTypeId and
EnumTypeName must be the same across all the fields. There's no design or runtime check for collision of IDs,
but loading generated symbols, see Running C/SIDE and AL Side-by-Side, into the compiler will show collision
errors.
Conversions
Conversion to and from enum is more strict than for Options in C/SIDE.
An enum can be assigned/compared to an enum of the same type.
To be backwards compatible, we support conversion to/from any Option for now.
See Also
AL Data Types
TableRelation Property
Extensible Property
Enum Data Type
AssignmentCompatibility Property
Option Data Type
2/6/2023 • 2 minutes to read • Edit Online
Denotes an option value. In the code snippet below, you can see how the Option data type is declared.
Syntax example
procedure HelloWithOptions(OptionParameter : Option Alpha, "Bra-vo")
var
OptionVariable : Option C, "or D";
begin
Message('%1',OptionParameter::Alpha);
Message('%1',OptionVariable::C);
end;
NOTE
It is not possible to reference the members of the OptionParameter from outside the body of the procedure.
Remarks
In the OptionString Property of the field or variable, you can enter the option values as a comma-separated list.
The Option type is a zero-based enumerator type, which means that the option values are assigned to sequential
numbers, starting with 0. You can convert option data types to integers.
Example 1
The following code sample shows how to define an option field in a table.
Example 2
This example shows how you can use the value of an option field as a constant in your AL code.
See Also
Get Started with AL
Developing Extensions
Interfaces in AL
2/6/2023 • 2 minutes to read • Edit Online
An interface in AL is similar to an interface in any other programming language; it is a syntactical contract that
can be implemented by a non-abstract method. The interface is used to define which capabilities must be
available for an object, while allowing actual implementations to differ, as long as they comply with the defined
interface.
This allows for writing code that reduces the dependency on implementation details, makes it easier to reuse
code, and supports a polymorphic way of calling object methods, which again can be used for substituting
business logic.
The interface declares an interface name along with its methods, and codeunits that implement the interface
methods, must use the implements keyword along with the interface name(s). The interface itself does not
contain any code, only signatures, and cannot itself be called from code, but must be implemented by other
objects.
The AL compiler checks to ensure that implementations adhere to assigned interfaces.
You can declare variables as a given interface to allow passing objects that implement the interface, and then call
interface implementations on the passed object in a polymorphic manner.
Snippet support
Typing the shortcut tinterface will create the basic layout for an interface object when using the AL Language
extension in Visual Studio Code.
Interface example
The following example defines an interface IAddressProvider , which has one method getAddress with a certain
signature. The codeunits CompanyAddressProvider and PrivateAddressProvider both implement the
IAddressProvider interface, and each define a different implementation of the getAddress method; in this case
a simple variation of address value.
The MyAddressPage is a simple page with an action that captures the choice of address and calls, based on that
choice, an implementation of the IAddressProvider interface.
interface "IAddressProvider"
{
procedure GetAddress(): Text
}
begin
exit(ExampleAddressLbl);
end;
}
begin
exit(ExampleAddressLbl);
end;
}
value(0; Company)
{
Implementation = IAddressProvider = CompanyAddressProvider;
}
value(1; Private)
{
Implementation = IAddressProvider = PrivateAddressProvider;
}
}
layout
{
area(Content)
{
group(MyGroup)
{
}
}
}
actions
{
area(Processing)
{
action(GetAddress)
{
ApplicationArea = All;
trigger OnAction()
var
AddressProvider: Interface IAddressProvider;
begin
AddressproviderFactory(AddressProvider);
Message(AddressProvider.GetAddress());
end;
}
action(SendToHome)
{
ApplicationArea = All;
trigger OnAction()
begin
sendTo := sendTo::Private;
end;
}
action(SendToWork)
{
ApplicationArea = All;
trigger OnAction()
begin
sendTo := sendTo::Company;
end;
}
}
}
var
sendTo: enum SendTo;
}
See Also
Codeunit Object
Extensible Enums
AL methods
2/6/2023 • 5 minutes to read • Edit Online
Like other languages, AL methods are a fundamental programming element. A method, also known as a
procedure, is a named group of statements that perform an operation or task. Depending on the scope,
methods can be run, or called, from the same object in which they are declared or from other parts of the
application.
There are two types of methods: system methods (built-in) and user-defined (custom) methods.
Built-in methods are part of the platform. Built-in methods can be used for different purposes, such as
string handling, text formatting, database handling, and so on. For information about the available built-in
methods, see AL method Reference and Essential AL methods. For information about method scope, see
Scope Attribute.
Custom methods are specialized methods for your application to bind the objects, such as tables, pages,
and code units, together to form a unified whole. You can create special methods for use anywhere in the
database.
TIP
If you already know the name of, for example, a data type, method, property, or trigger, use the Filter by title field in the
upper left corner, above the table of contents to find the topic faster. Otherwise, you can scan the table of contents to find
it.
Declaring methods
The method declaration defines the method and has the following syntax:
[Attributes(arguments list)]
local procedure <method_name>(parameter list) <return_value_name> : <data_type>[<length>]
Snippet support
Typing the shortcut tprocedure will create the basic structure for a method when using the AL Language
extension in Visual Studio Code.
Attributes (optional)
An attribute is a modifier on a method declaration that specifies information that controls the method's use and
behavior. Adding an attribute on a method declaration is also known as decorating a method. For example,
decorating a method with the Integration attribute sets the method to be an event publisher. An attribute can
have one or more arguments that set properties for the method instance.
Attributes are placed before the method. For information about the available attributes, see Method Attributes.
Local and global scope
A method can be a local method or global method. A local method can only be accessed or called from inside
the object in which it is declared. A global method can be called from inside the object in which it is declared and
from other objects.
To declare a local method, start the declaration with local :
local procedure Mymethod();
procedure Mymethod();
Parameters (optional)
A parameter is one or more variables or expressions that are sent to the method through the method call. The
parameter provides information to the method, and the method can modify that information. In the method
declaration, you place the parameters in parentheses () . If there is more than one parameter, the parameters
are separated by semicolons. A parameter is defined by a data type. Some data types, such as Record , require
an additional subtype.
For example, the following method declaration includes two parameters: MyCustomer and MyDimension :
This example also illustrates how parameters can be passed by value or passed by reference. The MyCustomer
parameter is passed by value, and the MyDimension parameter is passed by reference in the example above. For
more information, see the section Parameters below.
Return values (optional)
A method can return data that can be then coded against. A return value is defined by a name (optional), data
type, and optional length depending on the data type.
For example, if the return value is a Text DataType, the text might have a length of 50.
Calling methods
You can run, or call, a built-in or a custom method by using its name in a method call statement. When a method
is called the current application sequence is suspended and the code on the method is run. When the method
code is completed, the application code sequence returns to where the method was called from. How the
method is called determines what happens when it returns.
A method can be used as part of an expression. For example, the following code uses a method named
CalculatePrice as an expression:
In this case, the CalculatePrice method must return a value that is used in evaluating the expression. This
return value is then multiplied by the Quantity variable and that result is assigned to the TotalCost variable.
A method can also be run by using a method call statement. This statement only calls the method and does not
return any value. The following is an example of calling a method named MyRunMethod :
if Quantity > 5 then
MyRunMethod;
Example 1
The following shows the syntax for a method. The first example shows a method with two mandatory
parameters.
method(Parameter1, Parameter2)
Some built-in methods have optional parameters, the syntax is shown below. The optional parameters may be
omitted starting from the right.
The method that uses the syntax above can be called by using the following code.
method(Optional1, Optional2)
Example 2
ABS is an example of an AL method that has a fixed number of parameters (1).
Example 3
The method DMY2DATE is an example of a method that can be called by using a variable number of parameters.
Depending on the use of the DMY2DATE method, one, two, or three parameters can be passed to the method
because the second and third parameters are optional. When the second and third parameters are not used,
values from the system date are used as default values.
Example 4
You can assign the return value of a method to a variable.
ReturnVal := MyMethod(Param1);
Example 5
In this example, MyMethod returns a Boolean value. You can use the return value in a conditional statement.
if (MyMethod(Param1)) then
<Statement1>
else
<Statement2>
See Also
Development Overview
AL Methods
AL Simple Statements
AL Control Statements
Progress Windows, Message, Error, and Confirm
Methods
2/6/2023 • 4 minutes to read • Edit Online
You can use several specialized methods to display messages and gather input. We recommend that you use
pages to ensure that your application has a consistent user interface. However, there are situations where you
may want to use the dialog methods instead of pages. The most important uses of the dialog methods are as
follows:
To display a window that indicates the progress of some processing that may take a long time.
To stop the running program to display an error message.
To let the user confirm a choice before the program continues running.
You can also use the StrMenu method to create pages that present options to the user. It's much faster to use this
method than to design a page, which only presents a limited set of options to the user. For more information
about the StrMenu method, see StrMenu Method.
Message method
The Message Method) displays a message in a window that remains open until the user chooses the OK button.
The Message method has the following syntax.
The Message method runs asynchronously, which means that the message isn't run until the method from
which it was called ends or another method requests user input. The method is useful for notifying the user that
some processing has been successfully completed.
For an example of the Message method, see codeunit 83 in the CRONUS International Ltd. demonstration
database. The code in the OnRun trigger converts a quote into a sales order and then displays a message. The
message is generated by the following code.
var
Text001 : Label 'Quote %1 has been changed to order %2';
message(Text001,"No.",SalesHeader2."No.");
NOTE
Unlike the progress window, the Message method doesn't require that you first declare a variable of the type Dialog. The
Message method creates a window of its own.
Error method
The Error Method) is similar to the Message method except that when the user has acknowledged the message
from an Error method, execution ends. The Error method is also similar to the FieldError method. For more
information, see CalcFields, CalcSums, FieldError, FieldName, Init, TestField, and Validate Methods.
The Error method has the following syntax.
Confirm method
The Confirm Method) is used just like the Message method to display a message. However, unlike the Message
method, the Confirm method has a required return value.
The Confirm method has the following syntax.
The false parameter in the confirm statement means that No is the default.
See Also
Dialog Data Type
Method Attributes
2/6/2023 • 2 minutes to read • Edit Online
An attribute is a modifier on a method declaration that specifies information that controls the method's use and
behavior. Adding an attribute on a method declaration is also known as decorating a method. For example,
decorating a method with the Integration attribute sets the method to be an event publisher. An attribute can
have one or more arguments that set properties for the method instance.
In AL, attributes are placed before the method, and they have the following syntax:
For example, the Integration attribute has two arguments, and the syntax is:
TIP
If you already know the name of, for example, a data type, method, property, or trigger, use the Filter by title field in the
upper left corner, above the table of contents to find the topic faster. Otherwise, you can scan the table of contents to find
it.
See Also
AL Method Reference
AL Complex Types
2/6/2023 • 2 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
With the latest version of Business Central, it's possible to return most types from procedures - both user-
defined types and most built-in types.
The method in the example below, will take a name, and return the first customer record that matches the name.
The signature specifies the return type at the end of the procedure declaration, and the procedure exits by
returning the found customer record.
///<summary>
/// Getthefirstcustomerwithnamestartingwith<paramref name="Name"/>
///</summary>
///<param name="Name">Namefilter</param>
///<returns>Firstcustomer</returns>
It's also possible to use a named return value. Internally, the exit-statement as seen in the example above causes
an assignment to an allocated return value. The assignment will have a small performance cost based on the
type. Since the record type is treated as a value-type, it's better.
procedureGetCustomerByName(Name:Text) Customer:recordCustomer;
begin
Customer.SetFilter(Name,'@'+Name+'*');
Customer.FindFirst();
end;
The method GetCustomerByName() returns a Customer record. It can be used as you would expect in the
following example.
//Getthe firstcustomerwithnamestartingwith'spo'
Customer:=GetCustomerByName('spo');
The returned value doesn't have to be used in an assignment statement. It can be used as part of an expression
like in the following example.
DoSomethingWithSales(GetCustomerByName('spo').GetSalesLCY());
It doesn't only work for user-defined types like records, codeunits, etc., but also for built-in types. For example,
when using the HttpClient Data Type, it's possible to write code as illustrated below.
///<summary>
///Returnsabing-readyHttpClient
///</summary>
///<returns>BingHttpClient</returns>
procedure GetBingClient() Result: HttpClient;
begin
Result.SetBaseAddress('https://www.bing.com');
end;
///<summary>
///Gettheresponsefromarequesttobing.
///</summary>
///<returns>Theresponsemessage</returns>
///<summary>
///Gettheresponsefromwww.bing.comasanhtml-string.
///</summary>
///<returns>stringwithhtml</returns>
procedure GetBingHtml() Result: Text;
begin
GetBingResponse().Content().ReadAs(Result);
end;
See Also
Programming in AL
AL Simple Statements
Directives in AL
AL Essential Methods
HttpClient Data Type
Procedure overload
2/6/2023 • 2 minutes to read • Edit Online
Procedure overload enables developers to create multiple procedures with the same name, but with different
signatures, on the same application object. Conceptually, overloaded procedures are used to execute the same
task on a different set of arguments. When an overloaded procedure is called, a specific implementation of that
procedure, appropriate to the context of the call, will be run.
Example
The following example shows how a ToString method can be implemented with and without using procedure
overloads.
In the first code snippet, a ToString procedure is implemented. This takes a Variant value and inspects the type
of the value to delegate to different implementations. If the caller passes a value of a different type than Integer,
Date, and Text, an empty string will be returned. This can lead to bugs that will only show up at runtime.
codeunit 10 Stringifier
{
local procedure TextToString(value : Text) : Text;
begin
Exit(value);
end;
In the second code snippet, we overload the ToString procedure for Text, Date and Integer. At this point, it is not
possible for a caller to call a ToString method with a different type other than Integer, Date, or Text. This will catch
the bug above at compile time.
codeunit 10 StringifierWithOverloads
{
procedure ToString(value : Text) : Text;
begin
Exit(value);
end;
See Also
AL Method Reference
AL Development Environment
Create Handler Methods
2/6/2023 • 2 minutes to read • Edit Online
You can create test codeunits, test methods, and test pages to test your application. We recommend that you
create tests that can be automated. To create automated tests, you must write code to handle all UI interactions
so that the tests don't require user interaction when they're running. To do this, you create special handler
methods.
You can use the following handler methods:
PageHandler Handles specific pages that aren't run <Function name>(var <Page>: Page
modally. <page id>)
ModalPageHandler Handles specific pages that are run <Function name>(var <Page>: Page
modally. <page id>; var <Response>: Action)
[MessageHandler]
procedure MessageHandler(Message: Text[1024])
begin
Assert.IsTrue(StrPos(Message, MSG_HAS_BEEN_CREATED) > 0, Message);
end;
The parameters of the methods that are being handled are passed as parameters to the handler methods. For
example, when Message is called in a test method, the parameter of the Message method is passed as the
parameter of the MessageHandler method. For page and report handlers, the page, report, or request page is
passed as the parameter of the PageHandler , ModalPageHandler , Repor tHandler , or
RequestPageHandler .
You can call handler methods from methods that have the Test Attribute and then specify the handler methods
that it will use in the HandlerFunctions Attribute. The code inside the test method should simulate that the UI
was actually raised and some values entered or some actions were taken. You can specify more than one
handler method by separating the handler method names with a comma.
NOTE
Every handler method that you enter in the HandlerFunctions Attribute of a test method must be called at least one time
in the test method. If you run a test method that has a handler method listed that isn't called, then the test fails.
The following example shows a test method that uses the HandlerFunctions Attribute to call the
MessageHandler method.
[Test]
[HandlerFunctions('MessageHandler')]
procedure ApproveRequestForPurchCreditMemo()
var
PurchHeader: Record "Purchase Header";
begin
ApproveRequestForPurchDocument(PurchHeader."Document Type"::"Credit Memo");
end;
See Also
Testing the Application
AL Methods
Properties Overview
2/6/2023 • 2 minutes to read • Edit Online
This section describes the properties that are available to developers in Dynamics 365 Business Central for
controlling the behavior of objects, like tables, pages, and reports.
TIP
If you already know the name of, for example, a data type, method, property, or trigger, use the Filter by title field in the
upper left corner, above the table of contents to find the topic faster. Otherwise, you can scan the table of contents to find
it.
There are different properties for various the AL object types. Some properties can be set on the object-level,
and others pertain to specific controls of the object. Properties are added at the beginning of the code for the
object or control, after the its definition, by using the syntax: Property_name = value; . For example:
layout
{
area(Content)
{
group(GroupName)
{
field(Name; Name)
{
// Field properties
ApplicationArea = All;
}
}
}
}
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on selecting a property and help on its syntax.
See Also
Methods
Triggers
Table Object
2/6/2023 • 2 minutes to read • Edit Online
Tables are the core objects used to store data in Dynamics 365 Business Central. No matter how data is
registered in the product - from a web service to a finger swipe on the phone app, the results of that transaction
will be recorded in a table.
The structure of a table has four sections:
The first block contains metadata for the overall table, such as the table type.
The fields section describes the data elements that make up the table, such as their name and the type of data
they can store.
The keys section contains the definitions of the keys that the table needs to support.
The final section details the triggers and code that can run on the table.
IMPORTANT
Only tables with the Extensible Property set to true can be extended.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
IMPORTANT
System and virtual tables can't be extended. System tables are created in the ID range of 2.000.000.000 and above. For
more information about object ranges, see Object Ranges.
Snippet support
Typing the shortcut ttable will create the basic layout for a table object when using the AL Language extension
in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Table example
This table stores address information and it has four fields; Address , Locality , Town/City , and County .
table 50104 Address
{
Caption = 'Sample table';
DataPerCompany = true;
fields
{
field(1; Address; Text[50])
{
Description = 'Address retrieved by Service';
}
field(2; Locality; Text[30])
{
Description = 'Locality retrieved by Service';
}
field(3; "Town/City"; Text[30])
{
Description = 'Town/City retrieved by Service';
}
field(4; County; Text[30])
{
Description = 'County retrieved by Service';
trigger OnValidate();
begin
ValidateCounty(County);
end;
}
}
keys
{
key(PrimaryKey; Address)
{
Clustered = TRUE;
}
}
var
Msg: Label 'Hello from my method';
trigger OnInsert();
begin
end;
procedure MyMethod();
begin
Message(Msg);
end;
}
System fields
The Dynamics 365 Business Central platform will automatically add several system fields to tables. For more
information, see System Fields.
See Also
AL Development Environment
Table Overview
Table Extension Object
SqlTimestamp Property
Table Keys
Table, Table Fields, and Table Extension Properties
Table Extension Object
2/6/2023 • 2 minutes to read • Edit Online
The table extension object allows you to add additional fields or to change some properties on a table provided
by the Dynamics 365 Business Central service. In this way, you can add data to the same table and treat it as a
single table. For example, you may want to create a table extension for a retail winter sports store. In your
solution you want to have ShoeSize as an additional field on the customer table. Adding this as an extension
allows you to write code for the customer record and also include values for the ShoeSize .
Along with defining other fields, the table extension is where you write trigger code for your additional fields.
When developing a solution for Dynamics 365 Business Central , you will follow the code layout for a table
extension as shown in the example below.
IMPORTANT
Only tables with the Extensible Property set to true can be extended.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
IMPORTANT
System and virtual tables cannot be extended. System tables are created in the ID range of 2.000.000.000 and above. For
more information about object ranges, see Object Ranges.
IMPORTANT
Extending tables from Dynamics 365 for Sales is currently not supported.
Snippet support
Typing the shortcut ttableext will create the basic layout for a table extension object when using the AL
Language extension in Visual Studio Code.
Properties
Using a table extension allows you to overwrite some properties on fields in the base table. For a list of Table
properties, see Table and Table Extension Properties.
Table extension syntax
tableextension Id MyExtension extends MyTargetTable
{
fields
{
// Add changes to table fields here
}
var
myInt: Integer;
}
trigger OnBeforeInsert();
begin
if not HasShoeSize then
ShoeSize := Random(42);
end;
}
See Also
AL Development Environment
Table Overview
Table Object
Table, Table Fields, and Table Extension Properties
Table Keys
Table Keys
2/6/2023 • 12 minutes to read • Edit Online
The database management system, which is SQL Server, uses keys to identify rows in a table. Keys identify the
rows by combining one or more columns of a table. SQL also uses indexes to speed up data retrieval from rows
in a table. This article explains how to create keys and indexes for Business Central tables from AL code.
Keys in AL
In AL, a key definition is a sequence of one or more field IDs from a table. You can define keys in table objects
and table extension objects, depending on the type of key. There are two types of keys: primary and secondary.
Primary keys
A primary key uniquely identifies each record in a table. Every table has a primary key, and there can only
be one primary key per table. Primary keys are defined on table objects only. In SQL, table extension
objects inherit the primary key of the table object they extend (the base table object). So any key that you
define in a table extension object is considered a secondary key.
Secondary keys
Secondary keys create indexes in SQL. They're defined in both table objects and table extension objects.
You can define multiple secondary keys for a single table object and table extension object.
A key in table extension object can include fields from the base table object or the table extension object.
There are some limitations, however. For more information, see Limitations and Restrictions.
Primary keys
The primary key keeps track of data in a table. The primary key is composed of up to 16 fields in a record. The
combination of values in fields in the primary key makes it possible to uniquely identify each record. In AL, the
first key defined in a table object is the primary key. The primary key determines the logical order in which
records are stored, no matter the physical placement of the fields in the table object.
Logically, records are stored sequentially in ascending order and sorted by the primary key. Before adding a new
record to a table, SQL Server checks if the information in the record's primary key fields is unique. If so, it then
inserts the record into the correct logical position. Records are sorted dynamically so the database is always
structurally correct. This sorting allows for fast data manipulation and retrieval.
The primary key is always active. SQL Server keeps the table sorted in primary key order and rejects records
with duplicate values in primary key fields. That's why the values in the primary key must always be unique. It's
not the value in each field in the primary key that must be unique. Instead, it's the combination of values in all
fields that make up the primary key.
NOTE
In the development environment, it's technically possible to create a primary key based on up to 20 fields. However,
because of SQL Server limitations, only the first 16 are used.
Secondary keys
In a table object, any keys defined after the primary key are called secondary keys. All keys defined in a table
extension object are considered secondary keys.
A secondary key is implemented on SQL Server using a structure that is called an index. This structure is like an
index that is used in textbooks. A textbook index alphabetically lists important terms at the end of a book. Next
to each term are page numbers. You can quickly search the index to find a list of page numbers (addresses), and
you can locate the term by searching the specified pages. The index is an exact indicator that shows where each
term occurs in the textbook.
When you define a secondary key and mark it as enabled, an index is automatically maintained on SQL Server.
The index reflects the sorting order that is defined by the key. Several secondary keys can be active at the same
time.
A secondary key can be disabled so that it doesn't occupy database space or use time during updates to
maintain its index. Disabled keys can be re-enabled, although this operation can be time-consuming because
SQL Server must scan the whole table to rebuild the index.
The fields that make up the secondary keys don't always contain unique data. SQL Server doesn't reject records
with duplicate data in secondary key fields. So if two or more records contain identical information in the
secondary key, SQL Server uses the table's primary key to resolve this conflict.
TIP
You can see a list of potential columns that can be indexed and other useful information about them in Business Central
on Database Missing Indexes . For more information on missing indexes, see Missing Indexes in Dynamics 365
Business Central
NOTE
The Unique property isn't supported in table extension objects.
System keys
There's always a unique secondary key on the SystemId field.
Secondary keys with included fields
INTRODUCED IN: Business Central 2021 release wave 2
With non-clustered secondary keys, you can use the IncludedFields property to add fields that aren't part of the
key itself. In SQL server, these non-key fields correspond to what are called included columns. Using included
fields lets you create indexes that cover more queries, and lets you bypass the maximum number of fields in a
key.
A secondary key with included fields can improve SQL query performance, especially when SQL index contains
all columns in the query, either as key columns or included columns. The performance improves because the
query optimizer can locate all the column values within the index. And, it doesn't access table or clustered index
data, which results in fewer disk I/O operations. For more information about included columns in SQL, see
Create indexes with included columns.
Non-clustered Columnstore keys
INTRODUCED IN: Business Central 2021 release wave 2
NOTE
The Clustered property isn't supported in table extension objects.
K EY K EY T Y P E DEF IN IT IO N
When you sort by the primary key, the Customer table resembles the following table.
C USTO M ER N UM B ER C USTO M ER N A M E
001 Customer C
002 Customer A
003 Customer B
004 Customer C
If you select the secondary key for sorting, then the order is based on the contents of the Customer Name field.
Because the contents of these fields aren't unique, the records must be subsorted according to the primary key.
C USTO M ER N A M E C USTO M ER N UM B ER
Customer A 002
Customer B 003
Customer C 001
Customer C 004
NOTE
The two records that have the same Customer Name value are sorted by Customer Number.
Increase the number of secondary Retrieve data in several different Enter data because indexes for each
keys that are marked as active. sorting sequences because the data is secondary key must be maintained.
already sorted.
IF Y O U P ERF O RM A N C E IM P RO VES W H EN Y O U P ERF O RM A N C E SLO W S W H EN Y O U
Decide to use only a few keys. Enter data because a minimal number Retrieve data. You may have to define
of indexes are maintained. or reactivate the secondary keys to get
the appropriate sorting. Depending on
the size of the database, this operation
can take some time, because the index
must be rebuilt.
The decision whether to use a few or many keys isn't easy. The appropriate keys and the number of active keys
to use is a compromise between maximizing the speed of data retrieval and data updates (operations that insert,
delete, or modify data). In general, it may be worthwhile to deactivate complex keys if they're rarely used.
The overall speed depends on the following factors:
Size of the database.
Number of active keys.
Complexity of the keys.
Number of records in your tables.
Speed of your computer and its hard disk.
keys
{
key(Name1; Fields)
{
}
key(Name2; Fields)
{
}
}
Replace Name with descriptive text that you want to use to identify the key. Replace Field with the name of a
field that you want to use as the key. If you want to include multiple fields in a single key, separate each field
with a comma.
In a table object, the first key keyword defines the primary key. Subsequent key keywords define secondary
keys.
TIP
Starting in Business Central version 18, it is possible to create a table extension that only holds key definitions. You can
utilize this to add keys to tables in the base application or in AppSource extensions, where you don't have ownership of
the table definitions.
The following code illustrates simple examples of a table object and table extension object.
table 50120 MyBaseTable
{
fields
{
field(1; MyBaseField1; Integer)
{
}
field(2; MyBaseField2; Integer)
{
}
}
keys
{
key(PK; MyBaseField1) //primary key
{
Clustered = true;
}
key(Key1; MyBaseField2) //secondary key
{
}
}
}
keys
{
key(ExtKey1; MyExtField1) //secondary key
{
IncludeFields = MyExtField2,MyExtField3;
}
key(ExtKey2; MyBaseField1, MyBaseField2) //secondary key
{
}
// The following key isn't allowed because it contains fields from the base table and the table
extension
//key(ExtKey3; MyBaseField1, MyExtField2)
//{
//}
}
}
tableextension 50122 MyCustomerKeyExt extends Customer
{
// This example illustrates how to use a table extension to add a key on the Customer table from the
base application
keys
{
key(ExtKey1; "No.", "Name", City)
{
}
}
}
Key properties
There are several properties that configure the behavior of a key, such as the Enabled, Clustered, and Unique
properties:
keys
{
key(PrimaryKey; ID)
{
Clustered = true;
}
key(CustomerInfo; Name,Address,City)
{
Unique = true;
}
key(Currency; Currency Code)
{
Enabled = false;
}
}
For a more information about the different key properties, see Key Properties.
When you invoke IntelliSense for table fields, the primary key members are marked with a (PKx) in the
IntelliSense list, where x is a sequential number, which indicates the order of the field in the key. This allows
you to identify the table fields that make up the primary key and the sequency of these fields in the key.
See Also
Key Properties Tables Overview
Table Object
Table Extension Object
SystemId Field
Page Object
2/6/2023 • 2 minutes to read • Edit Online
Pages are the main way to display and organize visual data in Dynamics 365 Business Central. They are the
primary object that a user will interact with and have a different behavior based on the type that you choose.
Pages are designed independently of the device they are to be rendered on, and in this way the same page can
be reused across phone, tablet, and web clients.
The structure of a page is hierarchical and breaks down in to three sections. The first block contains metadata for
the overall page; the type of the page and the source table it is showing data from. The next section; the layout,
describes the visual parts on the page. The final section details the actions that are published on the page.
When developing a solution for Dynamics 365 Business Central, you will follow the code layout for a page as
shown in the page example below, but for more details on the individual controls and properties that are
available, see Page Property Overview.
If you want to, for example, add functionality to a page that already exists in Business Central, you can create a
page extension object that changes an existing page object. For more information, see Page Extension Object.
Depending on how much you want to change on an existing page, you can also create a page customization
object, which offers modifications on actions and layout. For more information, see Page Customization Object.
IMPORTANT
Only pages with the Extensible Property set to true can be extended.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
Snippet support
Typing the shortcut tpage will create the basic layout for a page object when using the AL Language extension
in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Views
Views in Dynamics 365 Business Central are used on list pages to define a different view of the data on a given
page. Views can be defined for Pages, Page Extensions, and Page Customization. For more information, see
Views.
Page example
page 50101 SimpleCustomerCard
{
PageType = Card;
SourceTable = Customer;
ContextSensitiveHelpPage = 'my-feature';
layout
{
area(content)
{
group(General)
{
field("No."; "No.")
{
ApplicationArea = All;
CaptionML = ENU = 'Hello';
trigger OnValidate()
begin
if "No." < '' then
Message('Number too small')
end;
}
field(Name; Name)
{
ApplicationArea = All;
}
field(Address; Address)
{
ApplicationArea = All;
}
}
}
}
actions
{
area(Navigation)
{
action(NewAction)
{
ApplicationArea = All;
RunObject = codeunit "Document Totals";
}
}
}
}
See Also
AL Development Environment
Views
Adding Help Links from Pages, Reports, and XMLports
Page Extension Object
Page, Page Fields, and Page Extension Properties
Page Properties
Developing Extensions
Configure Context-Sensitive Help
Page Extension Object
2/6/2023 • 4 minutes to read • Edit Online
The page extension object extends a Dynamics 365 Business Central page object and adds or overrides the
functionality.
The structure of a page is hierarchical and breaks down into three sections. The first block contains metadata for
the overall page; the type of the page and the source table it is showing data from. The next section; the layout,
describes the visual parts on the page. The final section details the actions that are published on the page.
For more information about the Page and Page Extension objects, see Pages Overview.
IMPORTANT
Only pages with the Extensible Property set to true can be extended.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
IMPORTANT
The API page type should not be extended by creating a page extension object. Instead, create a new API by adding a
page object.
NOTE
Modifying actions in Cue groups on page extensions is not supported.
Snippet support
Typing the shortcut tpageext will create the basic layout for a page extension object when using the AL
Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Views
Views in Dynamics 365 Business Central are used on list pages to define a different view of the data on a given
page. Views can be defined for Pages, Page Extensions, and Page Customization. For more information, see
Views.
K EY W O RDS SY N TA X A P P L IES TO
Example
To modify the existing fields and groups on a page, you use the modify keyword. See the code snippet below
for addlast , modify and action syntax. In the following example, the actions section creates a new group in
the ribbon and places it last in the Creation group.
pageextension 70000020 CustomerCardExtension extends "Customer Card"
{
layout
{
// Adding a new control field 'ShoeSize' in the group 'General'
addlast(General)
{
field("Shoe Size"; ShoeSize)
{
Caption = 'Shoe size';
trigger OnValidate();
begin
if (ShoeSize < 10) then
Error('Feet too small');
end;
}
}
trigger OnAction();
begin
Message('My message');
end;
}
}
}
}
}
trigger OnValidate();
begin
if (rec.ShoeSize < 0) then
begin
message('Shoe size not valid: %1', rec.ShoeSize);
end;
end;
}
}
trigger OnBeforeInsert();
begin
if not HasShoeSize then
ShoeSize := Random(42);
end;
}
trigger OnValidate();
begin
if (ShoeSize < 10) then
Error('Feet too small');
end;
}
// display-only control (without underlying datasource)
field(ShoesInStock; 10)
{
ApplicationArea = All;
Caption = 'Shoes in stock';
}
}
modify("Address 2")
{
Caption = 'New Address 2';
}
}
actions
{
{
addlast(Creation)
{
group(MyActionGroup)
{
Action(MyAction1)
{
ApplicationArea = All;
Caption = 'Hello!';
trigger OnAction();
begin
Message('My message');
end;
}
Action(MyAction2)
{
ApplicationArea = All;
You can reference Report and XMLPort objects and use these objects in the RunObject property, as well as,
declare variables of the types Repor t and XMLPor t and call AL methods on them. This page extension object
extends the Customer List page object by adding two actions; the first action calls the Customer - List report,
the second action calls the Expor t Contact XMLPort.
See Also
Page Object
Views
Page, Page Fields, and Page Extension Properties
Extending Pages Previously Based on the Date Virtual Table Developing Extensions
AL Development Environment
Page Customization Object
2/6/2023 • 2 minutes to read • Edit Online
The page customization object in Dynamics 365 Business Central allows you to add changes to the layout and
actions on page that are accessible for a profile. See Using keywords to place actions and controls for how to
place actions and controls on a page customization object.
The page customization object has more restrictions than the page extension object; when you define a new
page customization object, you cannot add variables, procedures, or triggers.
NOTE
A single page customization can be used with multiple profiles within the same extension. Page customizations only apply
to the RoleCenters they are specified for. In order to view or changes the RoleCenters in the client, go to My Settings >
Role Center .
NOTE
Extension objects can have a name with a maximum length of 30 characters.
NOTE
Modifying actions in Cue groups on page extensions is not supported.
NOTE
The property allowDebugging , which is a setting under resourceExposurePolicy does not apply to page
customizations. Page customizations defined in an extension with allowDebugging set to false can still be copied
using Designer. For more information, see Resource Exposure Policy Setting.
Snippet support
Typing the shortcut tpagecust will create the basic layout for a page customization object when using the AL
Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Views
Views in Dynamics 365 Business Central are used on list pages to define a different view of the data on a given
page. Views can be defined for Pages, Page Extensions, and Page Customization. For more information, see
Views.
Page customization example
The following page customization example MyCustomization makes changes to Customer List . By using the
moveafter method, Blanket Orders is moved after the Orders action item. And the modify method is used to
hide the NewSalesBlanketOrder action item.
profile TheBoss
{
Description = 'The Boss';
RoleCenter = "Business Manager Role Center";
Customizations = MyCustomization;
Caption = 'Boss';
}
modify(NewSalesBlanketOrder)
{
Visible = false;
}
}
}
You can use the same page customization on another profile within the same extension package by referencing
its name from the profile definition, for example:
profile TheSalesman
{
ProfileDescription = 'The Boss';
RoleCenter = "Sales Manager Role Center";
Customizations = MyCustomization;
Caption = 'Salesman';
}
See Also
Developing Extensions
AL Development Environment
Page Object
Page Extension Object
Views
Page, Page Fields, and Page Extension Properties
Report Object
2/6/2023 • 4 minutes to read • Edit Online
Reports are used to print or display information from a database. You can use a report to structure and
summarize information, and to print documents, such as sales quotes and invoices.
Creating a report consists of two primary tasks; the first task is to create the underlying data model and the next
is to define the visual layout that displays the data. The report object defines the underlying data model and
specifies which database tables and fields to pull data from. When the report is run, that data is displayed in a
specified layout; the visual layout, which determines the content and format of a report when it's viewed and
printed.
For more information about defining database tables and fields, see Defining a Report Dataset. For more
information about the Report data type, see Report Data Type.
You build the layout of a report by arranging data items and columns, and specifying the general format, such as
text font and size. There are three types of report layouts; client report definition, also called RDL layouts, Word
layouts, and Excel layouts. RDL layouts are defined in Visual Studio Report Designer or Microsoft SQL Server
Reporting Services Report Builder. Word layouts are created using Word. Word layouts are based on a Word
document that includes a custom XML part representing the report dataset. Excel layouts are created in Excel
based on the report dataset, utilizing the Excel capabilities such as sliders, diagrams, charts, pivot tables, and
PowerQuery. One report can contain multiple report layout definitions. For more information, see Defining
Multiple Report Layouts.
If you want to modify an existing report, for example, add new columns, add to the request page, or add a new
layout, you can create a report extension instead. For more information, see Report Extension Object.
TIP
It is possible to use a query object as the data source for a report. This can in many cases improve the performance of
data retrieval when running the report.
Snippet support
Typing the shortcut treport will create the basic layout for a report object when using the AL Language
extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Report example
The following example is a report that prints the list of customers. The report object defines a dataset of
columns from the Customer table. This example defines a report that uses an RDL report layout. For more
information about creating an RDL report layout, see Creating an RDL Layout Report. For more information on
creating a report that uses Word Layout, see Creating a Word Layout Report. For information about creating an
Excel layout, see Creating an Excel Layout Report.
report 50103 "Customer List"
{
CaptionML=ENU='Customer List';
DefaultLayout = RDLC; // if Word use WordLayout property
RDLCLayout = 'MyRDLReport.rdl';
dataset
{
dataitem(Customer;Customer)
{
RequestFilterFields="No.","Search Name","Customer Posting Group";
column(CompanyName;CompanyName)
{
}
column(CurrReport_PageNo;Customer."no.")
{
}
column(Customer_TableCaption_CustFilter;TableCaption + ': ' + CustFilter)
{
}
column(CustFilter;CustFilter)
{
}
column(Customer_No;"No.")
{
}
column(Customer_Customer_Posting_Group;"Customer Posting Group")
{
}
column(Customer_Customer_Disc_Group;"Customer Disc. Group")
{
}
column(Customer_Invoice_Disc_Code;"Invoice Disc. Code")
{
}
column(Customer_Customer_Price_Group;"Customer Price Group")
{
}
column(Customer_Fin_Charge_Terms_Code;"Fin. Charge Terms Code")
{
}
column(Customer_Payment_Terms_Code;"Payment Terms Code")
{
}
column(Customer_Salesperson_Code;"Salesperson Code")
{
}
column(Customer_Currency_Code;"Currency Code")
{
}
column(Customer_Credit_Limit_LCY;"Credit Limit (LCY)")
{
DecimalPlaces=0:0;
}
column(Customer_Balance_LCY;"Balance (LCY)")
{
}
column(CustAddr_1;CustAddr[1])
{
}
column(CustAddr_2;CustAddr[2])
{
}
column(CustAddr_3;CustAddr[3])
{
}
column(CustAddr_4;CustAddr[4])
{
}
}
column(CustAddr_5;CustAddr[5])
{
}
column(Customer_Contact;Contact)
{
}
column(Customer_Phone_No;"Phone No.")
{
}
column(CustAddr_6;CustAddr[6])
{
}
column(CustAddr_7;CustAddr[7])
{
}
column(Customer_ListCaption;Customer_ListCaptionLbl)
{
}
column(CurrReport_PageNoCaption;CurrReport_PageNoCaptionLbl)
{
}
column(Customer_NoCaption;FieldCaption("No."))
{
}
column(Customer_Customer_Posting_GroupCaption;Customer_Customer_Posting_GroupCaptionLbl)
{
}
column(Customer_Customer_Disc_GroupCaption;Customer_Customer_Disc_GroupCaptionLbl)
{
}
column(Customer_Invoice_Disc_CodeCaption;Customer_Invoice_Disc_CodeCaptionLbl)
{
}
column(Customer_Customer_Price_GroupCaption;Customer_Customer_Price_GroupCaptionLbl)
{
}
column(Customer_Fin_Charge_Terms_CodeCaption;FieldCaption("Fin. Charge Terms Code"))
{
}
column(Customer_Payment_Terms_CodeCaption;Customer_Payment_Terms_CodeCaptionLbl)
{
}
column(Customer_Salesperson_CodeCaption;FieldCaption("Salesperson Code"))
{
}
column(Customer_Currency_CodeCaption;Customer_Currency_CodeCaptionLbl)
{
}
column(Customer_Credit_Limit_LCYCaption;FieldCaption("Credit Limit (LCY)"))
{
}
column(Customer_Balance_LCYCaption;FieldCaption("Balance (LCY)"))
{
}
column(Customer_ContactCaption;FieldCaption(Contact))
{
}
column(Customer_Phone_NoCaption;FieldCaption("Phone No."))
{
}
column(Total_LCY_Caption;Total_LCY_CaptionLbl)
{
}
trigger OnAfterGetRecord();
begin
CalcFields("Balance (LCY)");
FormatAddr.FormatAddr(
CustAddr,Name,"Name 2",'',Address,"Address 2",
CustAddr,Name,"Name 2",'',Address,"Address 2",
City,"Post Code",County,"Country/Region Code");
end;
}
}
requestpage
{
SaveValues=true;
ContextSensitiveHelpPage = 'my-feature';
layout
{
}
actions
{
}
}
labels
{
LabelName = 'LabelText', Comment = 'Foo', MaxLength = 999, Locked = true;
}
trigger OnPreReport();
var
CaptionManagement : Codeunit 42;
begin
CustFilter := CaptionManagement.GetRecordFiltersWithCaptions(Customer);
end;
var
FormatAddr : Codeunit 365;
CustFilter : Text;
CustAddr : ARRAY [8] OF Text[50];
Customer_ListCaptionLbl : Label 'Customer - List';
CurrReport_PageNoCaptionLbl : Label 'Page';
Customer_Customer_Posting_GroupCaptionLbl : Label 'Customer Posting Group';
Customer_Customer_Disc_GroupCaptionLbl : Label 'Cust./Item Disc. Gr.';
Customer_Invoice_Disc_CodeCaptionLbl : Label 'Invoice Disc. Code';
Customer_Customer_Price_GroupCaptionLbl : Label 'Price Group Code';
Customer_Payment_Terms_CodeCaptionLbl : Label 'Payment Terms Code';
Customer_Currency_CodeCaptionLbl : Label 'Currency Code';
Total_LCY_CaptionLbl : Label 'Total (LCY)';
}
TIP
From the Business Central client, you can export report results as raw data to a Microsoft Excel file. The file contains all
columns of the dataset, but without the layout applied. Use the file to help validate that the report returns the expected
data, and to ensure that the report layout controls match the dataset value types. To export a report, run the report and
select the Send to > Microsoft Excel Document (data only) on the request page. For more information, see
Working with Reports - Send to Excel.
Schedule reports
It's possible to schedule a report to run at your desired date and time by using AllowScheduling property. By
setting the property to true, you'll get the Schedule action button to set the date and time for your report. To
learn more about scheduling a report, see AllowScheduling Property and Schedule a report.
See also
Report Extension Object
Request Pages
Report Properties
Creating an RDL Layout Report
Creating a Word Layout Report
Adding Help Links from Pages, Reports, and XMLports
Page Extension Object
Page Properties
Developing Extensions
AL Development Environment
Profile Object
2/6/2023 • 2 minutes to read • Edit Online
The profile object in Dynamics 365 Business Central allows you to build an individual experience for each user
profile. The Profile object performs a validation to check whether the specified role center page exists, and page
customization objects exists, when you define a new profile object. On a page customization you can add
changes to the page layout, and actions; but you cannot add variables, procedures, or triggers.
NOTE
Page customizations only apply to the RoleCenter they are specified for. In order to see them, in Dynamics 365 Business
Central under My Settings , Role Center change to the specific RoleCenter that a page customization is defined for.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
NOTE
The property allowDebugging , which is a setting under resourceExposurePolicy does not apply to page
customizations. Page customizations defined in an extension with allowDebugging set to false can still be copied
using Designer. For more information, see Resource Exposure Policy Setting.
Snippet support
Typing the shortcut tprofile will create the basic layout for a profile object when using the AL Language
extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Profile example
The following profile object example creates a profile for the MyRoleCenter Role Center, which is available in the
Role Explorer in the UI and available to end-users. The profile also depends on the customization
MyCustomization and modifies the layout of the Customer List to make the Name field invisible using the
modify method. For more information, see Profile Properties.
profile MyProfile
{
Description = 'Some internal comment that only the Dev can see';
Caption = 'My User-friendly Name';
ProfileDescription = 'A detailed description of who is this profile for, why/how to use it (etc)';
RoleCenter = MyRoleCenter;
Enabled = true;
Promoted = true;
Customizations = MyCustomization;
}
See Also
AL Development Environment
Developing Extensions
Pages Overview
Page Customization Object
Codeunit Object
2/6/2023 • 2 minutes to read • Edit Online
A codeunit is a container for AL code that you can use in many application objects. You typically implement
business logic in codeunits and call the codeunit from the object that needs to perform that specific logic.
Snippet support
Typing the shortcut tcodeunit will create the basic layout for a codeunit object when using the AL Language
extension in Visual Studio Code.
Codeunit example
This codeunit example checks whether a given customer has registered a shoe size. If not, the customer is
assigned a shoe size of 42.
The codeunit can be used both as a direct call to codeunit.run(customer) or as a call to the procedure inside the
codeunit createcustomer.CheckSize(customer) .
See Also
Developing Extensions
Table Extension Object
Page Extension Object
AL Development Environment
XML Comments in Code
Query Object
2/6/2023 • 4 minutes to read • Edit Online
Business Central query objects enable you to retrieve records from one or more tables and then combine the
data into rows and columns in a single dataset. Query objects can also perform calculations on data, such
finding the sum or average of all values in a column of the dataset.
There are two types of query objects: normal and API. This article describes normal query objects, which can be
used to display data in the user interface. API query objects are used to generate web service endpoints and
cannot be displayed in the user interface. For information about creating a query of the type API, see API Query
Type.
Dataitem links and joins determine which records to include in the dataset based on the values of a
common field between dataitems. You set a link between one or more fields of the dataitem tables with
the DataItemLink Property and you define the type of the link using the SQLJoinType Property. Both
properties must be set on the lower dataitem of the query object. For more information, see Linking and
Joining Data Items.
The following shows the basic structure of a query object.
query ID Name
{
elements
{
dataitem(DataItem1; Table1)
{
column(Column1; Field1)
{
}
column(Column2; Field2)
{
}
dataitem(DataItem2; Table2)
{
// Sets a link between FieldY of Table2 and FieldX of Table1.
DataItemLink = FieldY = DataItem1.FieldX;
//The dataset contains records from Table1 and Table2 where a match is found between FieldY
and FieldX.
SqlJoinType = InnerJoin;
column(Column1; Field1)
{
}
dataitem(DataItem3; Table3)
{
DataItemLink = FieldZ = DataItem2.FieldY;
SqlJoinType = InnerJoin;
column(Column1; Field1)
{
}
}
}
}
}
}
NOTE
Extension objects can have a name with a maximum length of 30 characters.
Snippet support
Typing the shortcut tquery will create the basic layout for a Query object when using the AL Language
extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Query example
The following example shows a query that displays a list of customers with sales and profit figures. The query
primarily retrieves fields from the Customer table, but also displays fields from the Salesperson Purchaser
and Countr y Region tables.
The query also uses the DataItemLink property to create a link between the Customer table, Salesperson
Code field and the Salesperson Purchaser table, Code fields and a link between the Customer table,
Countr y/Region Code field and the Countr y/Region table, Code field.
DataAccessIntent = ReadOnly; // use this to read data from the secondary database replica to speed up
performance
elements
{
dataitem(Customer; Customer)
{
column(Name; Name)
{
}
column(No; "No.")
{
}
column(Sales_LCY; "Sales (LCY)")
{
}
column(Profit_LCY; "Profit (LCY)")
{
}
column(Country_Region_Code; "Country/Region Code")
{
}
column(City; City)
{
}
column(Global_Dimension_1_Code; "Global Dimension 1 Code")
{
}
column(Global_Dimension_2_Code; "Global Dimension 2 Code")
{
}
column(Salesperson_Code; "Salesperson Code")
{
}
dataitem(Salesperson_Purchaser; "Salesperson/Purchaser")
{
DataItemLink = Code = Customer."Salesperson Code";
column(SalesPersonName; Name)
{
}
dataitem(Country_Region; "Country/Region")
{
DataItemLink = Code = Customer."Country/Region Code";
column(CountryRegionName; Name)
{
}
}
}
}
}
}
IMPORTANT
You cannot run a query that gets data from both the application database and the business data database. This also
applies to single-tenant deployments so that you do not have to rewrite queries if you decide to export the application.
For a description of which tables are considered part of the application database, see Separating Application Data from
Business Data.
See Also
Linking and Joining Data Items
Aggregating Data in Query Objects
Query Objects and Performance
Query Properties
Query DataAccessIntent
Developing Extensions
AL Development Environment
API Query Type
XMLport Object
2/6/2023 • 2 minutes to read • Edit Online
XMLports are used to export and import data between an external source and Dynamics 365 Business Central.
Sharing data between different computer systems is seamless when it is shared in an XML format. Working with
XML files can be tedious so the details of how the XML file is handled are encapsulated in XMLports.
To use an XMLport to import or export data, you first create an XMLport object. Once created, you can run the
XMLport from a page or codeunit object.
You can design XMLports to include a request page, which is a dialog box that enables the user to set a filter on
the data, sort the data, or choose whether to export or import the data. For more information about request
pages, see Request Pages.
XMLport example
The following example shows a page extension of the Permission Sets page that adds an action to the
specified page calling the XMLport Expor tPermissionSet . The XMLport exports the permission set data to an
XML file.
schema
{
textelement(PermissionSets)
{
tableElement(PSet; "Aggregate Permission Set")
{
SourceTableView = WHERE ("App Name" = FILTER (<> ''));
XmlName = 'PermissionSet';
fieldattribute(RoleID; pset."Role ID") { }
fieldattribute(RoleName; pset.Name) { }
tableelement(P; "Tenant Permission")
{
XmlName = 'Permission';
LinkTable = pset;
LinkFields = "Role ID" = FIELD ("Role ID");
textelement(ObjectType)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Object Type";
ObjectType := format(int);
end;
}
textelement(ObjectID)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Object ID";
ObjectID := format(int);
end;
}
textelement(ReadPermission)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Read Permission";
ReadPermission := format(int);
end;
}
textelement(InsertPermission)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Insert Permission";
InsertPermission := format(int);
end;
}
textelement(ModifyPermission)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Modify Permission";
ModifyPermission := format(int);
end;
}
textelement(DeletePermission)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Delete Permission";
DeletePermission := format(int);
end;
}
textelement(ExecutePermission)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Execute Permission";
ExecutePermission := format(int);
end;
end;
}
textelement(SecurityFilter)
{
trigger onbeforePassvariable();
begin
SecurityFilter := format(p."Security Filter");
end;
}
}
}
}
}
}
See Also
Developing Extensions
AL Development Environment
XMLport Overview
Using Namespaces with XMLports
Page Extension Object
Report Object
Control Add-In Object
2/6/2023 • 4 minutes to read • Edit Online
The control add-in object allows you to add custom functionality to Dynamics 365 Business Central. A control
add-in is a custom control, or visual element, for displaying and modifying data within an iframe or a page. For
example, a control add-in can display the content of a webpage, visualize data as a chart or on a map, or host a
custom web application. Control add-ins can exchange data with the Dynamics 365 server on various data types
and respond to user interaction to raise events that execute additional AL code.
// The procedure declarations specify what JavaScript methods could be called from AL.
// In main.js code, there should be a global function CallJavaScript(i,s,d,c)
{Microsoft.Dynamics.NAV.InvokeExtensibilityMethod('CallBack', [i, s, d, c]);}
procedure CallJavaScript(i: integer; s: text; d: decimal; c: char);
// The event declarations specify what callbacks could be raised from JavaScript by using the webclient
API:
// Microsoft.Dynamics.NAV.InvokeExtensibilityMethod('CallBack', [42, 'some text', 5.8, 'c'])
event Callback(i: integer; s: text; d: decimal; c: char);
}
ApplicationArea = All;
// The control add-in events can be handled by defining a trigger with a corresponding
name.
trigger Callback(i: integer; s: text; d: decimal; c: char)
begin
Message('Got from js: %1, %2, %3, %4', i, s, d, c);
end;
}
}
}
actions
{
area(Creation)
{
action(CallJavaScript)
{
ApplicationArea = All;
trigger OnAction();
begin
// The control add-in methods can be invoked via a reference to the usercontrol.
CurrPage.ControlName.CallJavaScript(5, 'text', 6.3, 'c');
end;
}
}
}
}
$.get(url).done(function(response) { } );
Correct:
$.ajax({
url: url,
xhrFields: {
withCredentials: true
}
)).done(function(data) {
$("#controlAddIn").text(data);
});
See Also
AL Development Environment
Developing Extensions
Asynchronous Considerations for Control Add-ins
Control Add-In Best Practices
InvokeExtensibility Method
GetImageResource Method
GetEnvironment Method
Pages Overview
Page Extension Object
Page Customization Object
Entitlement Object
2/6/2023 • 2 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
The entitlement object in Business Central describes which objects in Business Central a customer is entitled to
use according to the license that they purchased or the role that they have in AAD.
An entitlement consists of a number of PermissionSet Objects put together to constitute a set of meaningful
permissions for a user. An entitlement can only include permission set objects which reference the objects that
are included within the same app. This is to ensure that the entitlements included with one app cannot alter or
redefine the entitlements included with another app.
Entitlements can only be used with the online version of Business Central.
NOTE
In the current version of Business Central entitlements can only be included with Microsoft apps (enforced by the
AppSource cop rules and the technical validation checks that we run for the apps submitted to AppSource). These objects
will become available for the ISV apps when we introduce ability to monetize AppSource apps in one of our future
releases.
Snippet support
Typing the shortcut tentitlement will create the basic layout for an entitlement object when using the AL
Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Entitlement examples
This example illustrates a simple entitlement object with the Type property set to Role , which means that the is
entitlement is associated with an AAD role. When Type is set to Role , the RoleType property is used to
distinguish between local and delegated assignments of the role, in this case it is Delegated . The
ObjectEntitlements property defines the list of permissions that the entitlement includes.
entitlement BC_Role_Delegated
{
Type = Role;
RoleType = Delegated;
Id = '1a2aaaaa-3aa4-5aa6-789a-a1234567aaaa';
ObjectEntitlements =
”D365 BUS PREMIUM - BaseApp”;
}
See Also
Developing Extensions
AL Development Environment
Entitlements and Permission Set Overview
Permission Set Extension Object
Permission Set Object
2/6/2023 • 2 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
The permission set object in Business Central describes permissions on objects. Permission sets are building
blocks used to compose assignable permission sets and entitlements. Assignable permission sets are
permissions that an admin can assign to users in Business Central, using the Permission Sets page. An
entitlement is a collection of permission sets that constitute a set of meaningful permissions for a user.
Some permission sets can be non-assignable, meaning that they aren't discoverable and assignable in the UI in
Business Central, instead they can be used as building blocks to compose functional assignable permission sets.
For information about which permissions can be assigned to objects, see Permissions on Database Objects.
Snippet support
Typing the shortcut tpermissionset will create the basic layout for a permission set object when using the AL
Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
When adding new AL objects, it's easy to forget to update the permissions. With the
al.generatePermissionSetForExtensionObjects command, you can generate or update a permission file for the
active project in Visual Studio Code. Choose to create a new permission file or select an existing file to make
updates to. For more information, see AL Language Extension Configuration.
Permissions =
tabledata Customer = RIMD,
tabledata "Payment Terms" = RMD,
tabledata Currency = RM,
tabledata "Sales Header" = RIM,
tabledata "Sales Line" = RIMD;
}
The following example of a permission set illustrates assigned permissions to run codeunits. With the
IncludedPermissionSets property, we specify that the permission set Sales Person is also included in
MyPermissionSet .
permissionset50135MyPermissionSet
{
Assignable = true;
Caption = 'My PermissionSet';
IncludedPermissionSets= "Sales Person";
Permissions=
tabledataVendor=RIm,
codeunit SomeCode =x,
codeunit AccSchedManagement=X;
}
You can also use the ExludedPermissionSets property to exclude permissions defined in other permission sets.
To learn more, see Composing Permission Sets From Other Permission Sets.
See Also
Developing Extensions
AL Development Environment
Entitlements and Permission Set Overview
Permission Set Extension Object
Permissions on Database Objects
Assignable Property
IncludedPermissionSets
Permissions Property
Permission Set Extension Object
2/6/2023 • 2 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
The permission set extension object in Business Central adds permissions to an existing permission set defined
in AL. A permission set extension object cannot remove permissions from an existing permission set, it can only
add permissions. If you, for example, add an extension to Business Central, you can use permission set extension
objects to grant permissions to the objects in your extension. This means that the admin of Business Central
does not have to assign additional permission sets to the users, because that automatically happens when the
extension is installed, and the permissions go away if the extension is uninstalled.
For information about which permissions can be assigned to objects, see Permissions on Database Objects.
Snippet support
Typing the shortcut tpermissionsetextension will create the basic layout for a permission set extension object
when using the AL Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
See Also
Developing Extensions
AL Development Environment
Entitlements and Permission Set Overview
Permission Set Object
Permissions on Database Objects
Assignable Property
Permissions Property
Create Test Codeunits and Test Methods
2/6/2023 • 2 minutes to read • Edit Online
In Dynamics 365 Business Central, you can create test codeunits and then test methods in the test codeunits.
Test codeunits are codeunits that have the SubType Property set to Test . You write tests as Al code in the
methods inside of the test codeunits. There are three types of methods that you can add in a test codeunit: test,
handler, and normal. Each method type is used for a specific purpose and behaves differently. When a test
codeunit runs, it runs the OnRun trigger, and then runs each test method in the codeunit.
By default, each test method runs in a separate database transaction, but you can use the TransactionModel
Attribute on test methods and the TestIsolation Property on test runner codeunits to control the transactional
behavior.
The results of a test codeunit and of the individual test methods are displayed in a message window, but you can
use the OnAfterTestRun Trigger on a test runner codeunit to capture the results. The outcome of a test method is
either SUCCESS or FAILURE. If any error is raised by either the code that is being tested or the test code, then the
global outcome of the test codeunit is FAILURE and the error is included in the results log file.
The difference between a normal codeunit and a test codeunit is their execution at runtime. When a normal
codeunit is run, if one of its methods fails, then the codeunit is terminated. When a test codeunit is run, even if
the outcome of one test method is FAILURE, the next test methods are still running.
The methods in a test codeunit can be one of the following types:
Test method You use test methods that include AL code that tests the
business logic in the application, where each method covers
a transaction. You declare the Test Attribute on the method.
Normal method You use normal methods to structure the test code by using
the same design practices and principles as methods in other
codeunits of the application. You declare the Normal
Attribute on the method.
See Also
Testing the Application
Create Test Runner Codeunits
2/6/2023 • 2 minutes to read • Edit Online
You can create test runner codeunits to manage the execution of test codeunits and to integrate with test
management or test reporting frameworks. By integrating with a test management framework, you can
automate your tests and enable them to run unattended.
To create a test runner codeunit, create a codeunit and set the SubType Property to TestRunner .
To specify what changes in the database you want to roll back after the tests in the test runner codeunit execute,
set the TestIsolation Property.
Test runner codeunits include the following triggers:
OnRun Trigger
OnBeforeTestRun Trigger
OnAfterTestRun Trigger
In the OnRun trigger, you'll enter the code to run the codeunits. It runs when you execute the codeunit and
before the test methods run. You can use the OnBeforeTestRun and the OnAfterTestRun triggers to perform
preprocessing and postprocessing, such as initialization or logging test results. If you implement the
OnBeforeTestRun trigger, then it executes before each test method executes. If you implement the
OnAfterTestRun trigger, then it executes after each test method executes and also suppresses the automatic
display of the results message.
WARNING
The OnBeforeTestRun and OnAfterTestRun triggers always run in their own transactions, regardless of the value of
the TestIsolation Property, the value of the TransactionModel Property, or the outcome of a test method.
Example
This sample codeunit runs three test codeunits in the automated application test libraries.
trigger OnRun()
begin
Codeunit.RUN(Codeunit::"ERM Vendor Statistics");
Codeunit.RUN(Codeunit::"ERM Sales Quotes");
Codeunit.RUN(Codeunit::"ERM Dimension");
end;
}
You may want to define your test suite in a table and then write code in the test runner codeunit to iterate
through the items in the table. And then run each test codeunit. In that case, you can make use of the following
example.
codeunit 50102 TestRunnerCodeunit
{
Subtype = TestRunner;
trigger OnRun()
var
EnabledTestCodeunit: Record "CAL Test Enabled Codeunit";
Object: Record "Object";
begin
if EnabledTestCodeunit.FINDSET then
repeat
if Object.GET(ObjectType::Codeunit, '', EnabledTestCodeunit."Test Codeunit ID") then
CODEUNIT.RUN(EnabledTestCodeunit."Test Codeunit ID");
until EnabledTestCodeunit.NEXT = 0
end;
}
See Also
Testing the Application
Triggers Overview
2/6/2023 • 2 minutes to read • Edit Online
This section describes the triggers that are available to developers in Business Central.
TIP
If you already know the name of, for example, a data type, method, property, or trigger, use the Filter by title field in the
upper left corner, above the table of contents to find the topic faster. Otherwise, you can scan the table of contents to find
it.
Triggers activate a method when a certain event occurs. When AL methods are run because of a predefined
event on either an object or a control, the event triggers the method. Together the event and method make a
trigger.
Triggers are useful for doing calculations and validations. Compared to properties, they provide a more diverse,
effective way of doing such operations. For example, you can use triggers in reports to control how data is
selected and retrieved.
Coding triggers
There are different triggers for the various AL object types. Some triggers are set on the object-level, while
others are set on the controls. For example, a table has some triggers on the table object and other triggers on
field controls. Or consider reports, which have some triggers on the report object and some on the data items.
Trigger are typically added at the end the code block for the object or control. Triggers have the following syntax:
trigger OnWhat()
var
myVariable: type;
begin
// Custom code
end;
Snippet support
Typing the shortcut ttrigger will create the basic layout for a trigger when using the AL Language extension in
Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Example
The following example shows the basic trigger layout for a table object.
table 50100 MyTable
{
fields
{
field(1;MyField; Integer)
{
// Field triggers
trigger OnLookup()
var
myInt: Integer;
begin
end;
}
}
keys
{
key(Key1; MyField)
{
Clustered = true;
}
}
var
myInt: Integer;
end;
trigger OnModify()
begin
end;
trigger OnDelete()
begin
end;
trigger OnRename()
begin
end;
}
See Also
Methods
Properties
AL Error Handling
2/6/2023 • 2 minutes to read • Edit Online
The AL language has many error handling features, which can help you deal with unexpected situations that
occur when code is run. This section contains articles about using these methods in AL to handle errors that
occur during code execution, while making sure that your application has a consistent user interface.
The following articles introduce error handling in AL:
Handling Errors using Try Methods
Collecting Errors
Progress Windows, Message, Error, and Confirm Methods
M ET H O D DESC RIP T IO N
ErrorInfo Data Type Contains a set of methods that helps identify errors, classify
these errors, send errors to telemetry and display UI
messages. Go to the data type article for an overview.
System Data Type Is a complex data type and contains multiple methods for
getting and classifying errors.
GetLastErrorCallStack Method Gets the call stack from where the last error occurred.
GetLastErrorCode Method Gets the classification of the last error that occurred.
GetLastErrorText Method Gets the last error that occurred in the debugger.
TIP
If you already know the name of a data type, use the Filter by title field in the upper left corner, above the table of
contents to find the topic faster.
Run a code unit and decide to do something if an error if not Codeunit.run() . For more information, see
occurs. Codeunit.Run return value
Check for an error and show an error dialog to the user. Dialog.Error(Message: ErrorInfo) . For more
information, see Error Method.
Check for an error and show an error dialog to the user with Using the ErrorInfo Data Type with the Error Method
added support information.
Do bulk validations in AL and not show an error dialog for Collecting Errors
each of them to the user.
Catch errors raised by other AL methods Handling Errors using Try Methods
Catch errors/exceptions that are thrown during .NET Handling .NET Exceptions using Try Methods
framework interoperability operations (on-premises only).
Log an error that happens within a database transaction Either log the error in a new session using a background
(that rollback) session, or use Session.LogMessage to log the error to
telemetry.
See also
AL Control Statements
AL Development Environment
Handling Errors using Try Methods
2/6/2023 • 2 minutes to read • Edit Online
Try methods in AL enable you to handle errors that occur in the application during code execution. For example,
with try methods, you can provide more user-friendly error messages to the end user than those that are
thrown by the system.
NOTE
Try Methods are available from runtime version 2.0.
NOTE
The return value isn't accessible within the try method itself.
Example 1
The following simple example illustrates how the try method works. First, create a codeunit that has a local
method MyTrymethod . Add the following code on the OnRun trigger and MyTrymethod method.
trigger OnRun()
begin
MyTrymethod;
message('Everything went well');
end;
When you run this codeunit, the execution of the OnRun trigger stops. The error message
An error occurred during the operation is thrown in the UI.
Now, set the TryFunction Attribute of the MyTrymethod method. Then, add code to the OnRun trigger to handle
the return value of the try method:
[TryFunction]
local procedure MyTryMethod()
begin
error('An error occurred during the operation');
end;
trigger OnRun()
begin
if MyTryMethod then
message('Everything went well')
else
message('Something went wrong')
end;
When you run the codeunit, instead of stopping the execution of the OnRun trigger when the error occurs, the
error is caught and the message Something went wrong is returned.
See Also
AL Simple Statements
Collecting Errors
2/6/2023 • 4 minutes to read • Edit Online
This article explains how to write AL code that captures multiple errors and displays them in the user interface.
Referred to as collectible errors, this feature can simplify validation scenarios. Specifically, scenarios where users
are presented with a list of things to fix.
Normally, when an error occurs in a procedure, the procedure stops on the first error it meets. Using collectable
errors essentially postpones error handling to the end of the procedure call. AL code execution won't stop on
errors. But instead, it continues until the end and gathers errors as they occur.
M ET H O D DESC RIP T IO N
ErrorInfo.PageNo([Integer]) Specifies the page number that the error relates to.
ErrorInfo.RecordId([RecordId]) Specifies the record ID of the record that the error relates to.
ErrorInfo.SystemId([Guid]) Specifies the system ID of the record that the error relates
to.
Collected errors
The following methods are available on the System data type for handling collected errors. These methods can
be invoked using property access syntax.
M ET H O D DESC RIP T IO N
System.ClearCollectedErrors() Clears all collected errors from the current collection scope.
IMPORTANT
If you clear the list of collected errors, any changes performed in the database won't be rolled back. So, in most cases, it
makes sense to combine the clear operation with an if Codeunit.Run then … statement, as shown in the
PostWithErrorCollectCustomUI procedure of the example.
Error behavior
The ErrorBehavior specifies the behavior of collectable errors inside the method scope. Adding
[ErrorBehavior(ErrorBehavior.Collect)] to a procedure makes it possible to collect and handle errors that are
raised in the scope of the procedure.
Example
The following code example illustrates how to use collectable errors. It's built around the DoPost codeunit,
which sets simple criteria on what can or can't be included in table fields. By itself, this procedure will stop when
errors occur. By applying the ErrorBehavior(ErrorBehavior::Collect) attribute, the PostWithErrorCollect () and
PostWithErrorCollectCustomUI () procedures show you a couple ways to collect and present these errors.
[ErrorBehavior(ErrorBehavior::Collect)]
procedure PostWithErrorCollect()
var
i: Record Integer;
begin
i.Number := -9;
Codeunit.Run(Codeunit::DoPost, i);
// After executing the codeunit, there will be collected errors,
// and therefore an error dialog will be shown when exiting this procedure.
end;
[ErrorBehavior(ErrorBehavior::Collect)]
procedure PostWithErrorCollectCustomUI()
var
errors: Record "Error Message" temporary;
error: ErrorInfo;
i: Record Integer;
begin
i.Number := -9;
// By using Codeunit.Run, you ensure any changes to the database within
// Codeunit::DoPost are rolled back in case of errors.
if not Codeunit.Run(Codeunit::DoPost, i) then begin
// If Codeunit.Run fails, a non-collectible error was encountered,
// add this to the list of errors.
errors.ID := errors.ID + 1;
errors.Description := GetLastErrorText();
errors.Insert();
end;
// Clearing the collected errors will ensure the built-in error dialog
// will not show, but instead show our own custom "Error Messages" page.
ClearCollectedErrors();
trigger OnRun()
begin
if Number mod 2 <> 0 then
Error(ErrorInfo.Create('Number should be equal', true, Rec, Rec.FieldNo(Number)));
See Also
AL Simple Statements
Dialog.Error(Text [, Any,...]) Method
2/6/2023 • 2 minutes to read • Edit Online
Syntax
Dialog.Error(Message: Text [, Value: Any,...])
NOTE
This method can be invoked without specifying the data type name.
Parameters
Message
Type: Text
This string contains the text of the error message you want to display to the user. Use percent signs (%) or
number signs (#) to insert variable values into the string. Place the percent or number signs where you want to
substitute the variable value. The string can be a text constant that is enabled for multilanguage functionality.
[Optional] Value
Type: Any
Any variable or expression to be inserted in String. You can insert up to 10 values. For '#'-type fields, the value is
truncated according to the total number of number-sign characters in String. For '%'-type fields, the full length
of the value is printed.
Remarks
The window is automatically sized to hold the longest line of text and total number of lines. By calling the
method with an empty string the execution of AL code ends without displaying a message.
Programming Guidelines
We recommend the following guidelines for error messages:
Describe what is wrong and how to solve the problem.
Write a short descriptive message. Do not use more words than necessary.
Always end the error message with a period.
Use a text constant for the text of the message.
For more information, see Progress Windows, Message, Error, and Confirm Methods.
Example
This example shows how to use the Error method.
var
AccountNo: Integer;
Text000: Label 'Finance Account #1#### must not be blocked.';
Text001: Label 'Placeholder message.';
begin
AccountNo := 1230;
// The execution stops when the error statement is executed
// and all following statements will never be executed.
Error(Text000, AccountNo);
Message(Text001); // This line is not executed.
end;
See Also
Dialog Data Type
Get Started with AL
Developing Extensions
Analyzing Error Method Telemetry
Dialog.Error(ErrorInfo) Method
2/6/2023 • 2 minutes to read • Edit Online
NOTE
From runtime version 8.0 and onward, this method is supported in Business Central online.
Syntax
Dialog.Error(Message: ErrorInfo)
NOTE
This method can be invoked without specifying the data type name.
Parameters
Message
Type: ErrorInfo
The ErrorInfo structure that contains error message, error type, verbosity, and data classification.
Remarks
The window is automatically sized to hold the longest line of text and total number of lines.
Programming Guidelines
We recommend the following guidelines for error messages:
Describe what is wrong and how to solve the problem.
Write a short descriptive message. Do not use more words than necessary.
Always end the error message with a period.
Use a text constant for the text of the message.
For more information, see Progress Windows, Message, Error, and Confirm Methods.
Example
This example shows how to use the Error method.
procedure InitializeFromCurrentApp()
var
InitializeErrorInfo: ErrorInfo;
begin
// Initialize the .NET object
if InitializeFromCurrentAppInternal() then
IsInitialized := true
else begin
InitializeErrorInfo.DataClassification := DataClassification::SystemMetadata;
InitializeErrorInfo.ErrorType := ErrorType::Client;
InitializeErrorInfo.Verbosity := Verbosity::Error;
InitializeErrorInfo.Message := CannotInitializeErr;
Error(InitializeErrorInfo);
end;
end;
See Also
Dialog Data Type
Get Started with AL
Developing Extensions
Analyzing Error Method Telemetry
Dialog.LogInternalError(Text, DataClassification,
Verbosity) Method
2/6/2023 • 2 minutes to read • Edit Online
NOTE
This method is supported only in Business Central on-premises.
Syntax
Dialog.LogInternalError(Message: Text, DataClassificationInstance: DataClassification, VerbosityInstance:
Verbosity)
NOTE
This method can be invoked without specifying the data type name.
Parameters
Message
Type: Text
This string contains the text of the error message you want to log into telemetry. It is not what the user will get,
they will only get a generic error message.
DataClassificationInstance
Type: DataClassification
Sets the classification of the data in the error message.
VerbosityInstance
Type: Verbosity
Represents the security level of events.
See Also
Dialog Data Type
Get Started with AL
Developing Extensions
Dialog.LogInternalError(Text, Text,
DataClassification, Verbosity) Method
2/6/2023 • 2 minutes to read • Edit Online
NOTE
This method is supported only in Business Central on-premises.
Syntax
Dialog.LogInternalError(Message: Text, SubstitutionString: Text, DataClassificationInstance:
DataClassification, VerbosityInstance: Verbosity)
NOTE
This method can be invoked without specifying the data type name.
Parameters
Message
Type: Text
This string contains the text of the error message you want to log into telemetry. Use a percent sign (%) to insert
a variable value into the string. Place the percent where you want the system to substitute the variable value.
You may only insert one variable value. It is not what the user will get, they will only get a generic error
message.
SubstitutionString
Type: Text
This string replaces a percent sign in the "Message" Parameter.
DataClassificationInstance
Type: DataClassification
Sets the classification of the data in the error message.
VerbosityInstance
Type: Verbosity
Represents the security level of events.
See Also
Dialog Data Type
Get Started with AL
Developing Extensions
Formatting Decimal Values in Fields
2/6/2023 • 5 minutes to read • Edit Online
This article describes how you can format the decimal values that appear in fields on table, pages and reports.
For example, you can change how the data appears in a Cue on the Role Center page. To format data, you use a
combination of the AutoFormatType Property, AutoFormatExpression Property, and DecimalPlaces Property of
the field. These properties work together to enable you to specify the following:
Display amounts and unit amounts in another currency.
Specify the number of decimal places.
Specify whether to display a thousand separator.
Specify characters before and after the value, such as currency signs or %.
Implementation overview
When a field is used on a page or report, you can set the AutoFormatType and AutoFormatExpr properties
directly on the page field or report field (column), or you can set them on the underlying table field. If you
specify the properties on the table field, then the format applies wherever the field is used. Specifying the
properties on the page or report field will only apply the format to the specific page or report. If you specify the
properties on the table field and the page or report field, then the settings on the page or report field take
precedence.
When you use the AutoFormatType and AutoFormatExpression properties to format a field, two events are
raised by the system codeunit 45 Auto Format : OnResolveAutoFormat and OnAfterResolveAutoFormat.
0 Set to the number of decimal places Use this configuration when you want
that you want to display for the value. to format the decimal value according
the Standard Format 0 (which is the
default format) with a specific number
of decimal places.
AutoFormatType = 0;
DecimalPlaces = 0;
1 Set to return a currency code, such as Use this configuration when you want
USD or IDR. The blank currency code to format the data as an amount. For
'' denotes LCY and is the default example, a sales order will use two
value. decimals when the currency is defined
as US dollar and no decimals when the
currency is defined as IDR (Indonesian
rupiah). For example:
AutoFormatType = 1;
AutoFormatExpression = 'IDR';
10 Set to the property according to the Use SubType 1 to add the currency
following syntax: symbol and use the amount type
precision. You use SubType 2 for unit
'[SubType][,<currencycode or amount precision. For example, set the
expression>[,<PrefixedText>]]'
property to '1,USD' to add the $
symbol, like $543.21 .
SubType can be 1 , 2 , another
number, or omitted: AutoFormatType = 10;
AutoFormatExpression = '1,USD';
1 sets the value to an amount type
(see 1 above). 2 sets the value to a If you omit the SubType, you can use
unit amount type (see 2 above). The this configuration to customize the
syntax for these two settings is: format based on one of the standard
formats. This option enables you to
'SubType,<currencycode[,
<PrefixedText>]'
specify characters before and after the
decimal value, such as currency signs $
and percent %.
If you omit the subtype or use a
number other than 1 or 2, the syntax
For example, if you want to prefix the
is:
decimal value with a $ , include a
thousand separator, and have a
'<CustomNumber>, <expression>[,
<PrefixedText>]' maximum of two decimal places, such
as $76,453.21 , then you can set the
where <expression> sets the properties to:
precision and one of the standard
AutoFormatType = 10;
formats. For more information, see
Standard Formats. AutoFormatExpression =
'$<precision, 2:2><standard
format, 0>'
AutoFormatType = 10;
AutoFormatExpression =
'<precision, 1:1><standard
format,0>%'
11 Set the property to the standard Use this option when you want full
format as explained below. For control over the formatting. The
example: format string will be applied exactly as
specified in the AutoFormatExpr
'<Precision,3:3><Standard property.
Format,0>'
Precision
The precision determines the minimum and maximum number of decimal points for values. The precision takes
the format <precision,minimum:maximum> . For example, <precision,minimum:maximum> sets the data with a
minimum of 2 and a maximum of 3 decimal places.
Standard formats
The following table describes the standard formats that are available for the AutoFormatExpr property when
the AutoFormatType property is set to 10.
See Also
AutoFormatType Property
AutoFormatExpression Property
DecimalPlaces Property
Formatting Values, Dates, and Time
2/6/2023 • 6 minutes to read • Edit Online
With the Format function in Business Central, you can set the format of the source expression for various data
types in AL.
Remarks
You can choose to set Format to a predefined format, or you can build your own format. For more information,
see Format Method (Integer, Text).
Basic Settings
To choose a predefined format, use the syntax: <Standard Format,X>, where X is one of the entries in the Value
column of the following table.
VA L UE DESC RIP T IO N
NOTE
You must enter the < and > angle brackets, such as <Standard Format,2> .
Building Formats
You can use Format to create your own formats. To create a format, use the following rules:
A format property consists of zero or more Chars, Fields, or Attributes.
Fields and Attributes are expressed by using an identifier enclosed in brackets (<>).
Attributes must contain a comma (,) and a parameter after the identifier.
Fields can optionally take a comma (,) and a FieldLen.
The following table shows the syntax.
SY N TA X VA L UES
[, <Attribute>]
The 1000Character attribute specifies the character that separates the thousandths place digit from the
hundredths place digit, the millionth place digit from the hundred thousandths place digit, and so on. The
1000Character attribute must be after the Integer or Integer Thousand field name and before the Decimals field
name.
The Comma attribute specifies the character that separates the integer from the decimals. The Comma attribute
must be after the Decimals field name.
Filler Character indicates the character that is used to fill empty spaces.
The FieldName is a component that you can use to build a format expression. Depending on the data type in the
field, you can choose the appropriate FieldName from this list.
Date Day, Month, Month Text, Quarter, Year, Year4, Week, Week
Year, Week Year4, Weekday, Weekday Text, Closing
DateTime Day, Month, Month Text, Quarter, Year, Year4, Week, Week
Year, Week Year4, Weekday, Weekday Text, Hours24,
Hours12, Minutes, Seconds, Thousands, AM/PM, Second dec
Note: "Second dec" specifies a fraction of a second, in
decimal format.
Code Text
Text Text
Example
The following examples demonstrate how to use Format :
Choosing a standard format.
Use the Standard Format attribute to select one of the standard formats (these are listed at the end of this
topic).
For example, <Standard Format,5> selects Standard Format 5.
Using a standard format with an attribute.
<Precision,2:3><Standard Format,0> will use Standard Format 0 and will format the data with a
minimum of 2 and a maximum of 3 decimal places. For more information, see DecimalPlaces Property. If
you do not specify a precision, then the page uses the precision that is specified in the DecimalPlaces
Property of the corresponding field in the table.
Building a format.
You can create your own formats using Chars (which are displayed literally), Fields (to choose specific
components of a value, for example the year-part of a date) and Attributes (for example to select which
character to use as a filler).
For example, a field that is based on a source expression of the Date data type can use the following
format string:
<Weekday Text>, <Month Text> <Day>
This expression displays the date as Monday, April 15 .
NOTE
The settings that are specified under the Regional and Language Options in Windows determine how some
separators are displayed. In the Business Central client, you can specify a Region under Settings , this determines
how thousand and decimal separators are displayed.
<Sign><Integer><Decimals> 1 -76543,21
<Sign><Integer><Decimals> 2 -76543.21
<Comma,.>
<Integer><Decimals><Sign,1> 4 76543,21-
The following table shows the standard Decimal formats with the regional setting of English (US).
US DEC IM A L F O RM AT EXA M P L E
<Sign><Integer><Decimals> 1 -76543.21
<Sign><Integer><Decimals> 2 -76543.21
<Integer><Decimals><Sign,1> 4 76543.21-
<Closing><Day,2>-<Month,2>- 0 05-04-21
<Year>
<Closing><Day,2>-<Month,2>- 1 05-04-21
<Year>
<Day,2><Month,2><Year> 2 050421D
<Closing>D
<Closing><Year>-<Month,2>- 3 21-04-05
<Day,2>
<Closing><Day,2><Month,2><Year> 5 050421
<Closing><Year><Month,2><Day,2> 6 210405
US DAT E F O RM AT EXA M P L E
<Closing> 0 04/05/21
<Month,2>/<Day,2>/<Year>
<Closing> 1 04/05/21
<Month,2>/<Day,2>/<Year>
<Month,2><Day,2><Year> 2 040521D
<Closing>D
<Closing> 3 21/04/05
<Year>/<Month,2>/<Day,2>
<Closing><Month,2><Day,2><Year> 5 040521
<Closing><Year><Month,2><Day,2> 6 210405
EURO P E T IM E F O RM AT EXA M P L E
<Hours24>.<Minutes,2>. 0 4.35.55
<Seconds,2>
<Hours24>.<Minutes,2>. 1 4.35.55.553
<Seconds,2><Second dec.>
The following table shows the standard Time formats with the regional setting of English (US).
US T IM E F O RM AT EXA M P L E
<Hours12>:<Minutes,2>: 0 4:35:55 AM
<Seconds,2><Second dec.>
<AM/PM>
US T IM E F O RM AT EXA M P L E
<Hours12>:<Minutes,2>: 1 4:35:55.553 AM
<Seconds,2><Second dec.>
<AM/PM>
The following table shows the standard DateTime formats with the regional setting of English (US).
US DAT ET IM E F O RM AT EXA M P L E
<Sign><Integer> 0 -567
<Sign><Integer> 1 -567
<Sign><Integer> 2 -567
<Text> 0 True/False
<Text> 1 True/False
<Number> 2 1/0
{<4byte>-<2byte>-<2byte>- 0 {EA48A3E0-48E0-4AB7-B1A1-
<2byte>-<6byte>} E3EA85BF1B75}
{<4byte>-<2byte>-<2byte>- 1 {EA48A3E0-48E0-4AB7-B1A1-
<2byte>-<6byte>} E3EA85BF1B75}
GUID F O RM AT EXA M P L E
{<4byte>-<2byte>-<2byte>- 2 {EA48A3E0-48E0-4AB7-B1A1-
<2byte>-<6byte>} E3EA85BF1B75}
<16byte> 3 EA48A3E048E04AB7B1A1E3EA85BF1B
75
<4byte>-<2byte>-<2byte>- 4 EA48A3E0-48E0-4AB7-B1A1-
<2byte>-<6byte> E3EA85BF1B75
(<4byte>-<2byte>-<2byte>- 5 (EA48A3E0-48E0-4AB7-B1A1-
<2byte>-<6byte>) E3EA85BF1B75)
{0X<4byte>,0X<2byte>,0X<2byte>, 6 {0XEA48A3E0,0X48E0,0X4AB7,
{0X<1byte>,0X<1byte>,0X<1byte>,0 {0XB1,0XA1,0XE3,0XEA,0X85,0XBF,0X1
X<1byte>, B,0X75}}
0X<1byte>,0X<1byte>,0X<1byte>,0X
<1byte>}}
<Text> 0 Bronze
<Text> 1 Bronze
<Number> 2 1
<XML format> 9 1
<Text> 0 Blue
<Text> 1 Blue
<Number> 2 1
<XML format> 9 1
See Also
DecimalPlaces Property
About Dates in Business Central
Tables Overview
2/6/2023 • 2 minutes to read • Edit Online
Tables are the fundamental objects in any database. They are the objects in which you store and manipulate
data. This is true no matter what kind of data you need to manage. When you create a new database, you begin
by building the tables. Later, you create pages and reports in order to access and view the data in the tables.
A table can be visualized as a two-dimensional matrix, consisting of columns and rows. The following illustration
shows a table where each row is a record and each column is a field.
A table consists of two parts: the table data and a table description. The table data is the part users often think of
as comprising the database, because it contains the actual records with their data fields. The layout and
properties of those fields, however, are specified by the table description. The table description is not directly
visible to the user. The following illustration shows how the table data and the table description together form a
table.
When you design a table, you assign a number of characteristics to it, such as a name, an ID number, and the
fields it contains. You also assign a number of characteristics (such as name, ID number, data type, and initial
value) to each field. When you design a new table, you also specify which keys you want the system to maintain.
All these characteristics are stored in the table description when you save your table design.
The information in the table description is used by SQL Server and occasionally by database users who need
information about the table structure. The table description makes the database flexible, as it lets the system
access tables with different structures. The database can extract the definitions of the table structure from the
table description and thereby correctly access any table.
The following illustration shows that a table description contains properties, triggers, fields, and keys and shows
how these are related.
The table description contains some properties that are related to the table, others that are related to the fields
in the table, and other properties related to keys. You can also see that triggers are defined both for the table
and for the fields in the table.
Creating tables
In AL code, you can create new tables or modify existing tables. Read more about creating and modifying tables
in the following sections.
TO SEE
Decide which field data type you want to apply to your data Field Data Types
Apply table and field properties Table and Table Extension Properties
TO SEE
Learn about the set of triggers that Dynamics 365 Business Table Triggers
Central supports for tables and fields. Table Extension Triggers
Field Triggers
Field Extension Triggers
TO SEE
Get a brief introduction to relational database design in Setting Relationships Between Tables
Dynamics 365 Business Central.
See Also
Developing Extensions in AL
Tables Overview
2/6/2023 • 2 minutes to read • Edit Online
Tables are the fundamental objects in any database. They are the objects in which you store and manipulate
data. This is true no matter what kind of data you need to manage. When you create a new database, you begin
by building the tables. Later, you create pages and reports in order to access and view the data in the tables.
A table can be visualized as a two-dimensional matrix, consisting of columns and rows. The following illustration
shows a table where each row is a record and each column is a field.
A table consists of two parts: the table data and a table description. The table data is the part users often think of
as comprising the database, because it contains the actual records with their data fields. The layout and
properties of those fields, however, are specified by the table description. The table description is not directly
visible to the user. The following illustration shows how the table data and the table description together form a
table.
When you design a table, you assign a number of characteristics to it, such as a name, an ID number, and the
fields it contains. You also assign a number of characteristics (such as name, ID number, data type, and initial
value) to each field. When you design a new table, you also specify which keys you want the system to maintain.
All these characteristics are stored in the table description when you save your table design.
The information in the table description is used by SQL Server and occasionally by database users who need
information about the table structure. The table description makes the database flexible, as it lets the system
access tables with different structures. The database can extract the definitions of the table structure from the
table description and thereby correctly access any table.
The following illustration shows that a table description contains properties, triggers, fields, and keys and shows
how these are related.
The table description contains some properties that are related to the table, others that are related to the fields
in the table, and other properties related to keys. You can also see that triggers are defined both for the table
and for the fields in the table.
Creating tables
In AL code, you can create new tables or modify existing tables. Read more about creating and modifying tables
in the following sections.
TO SEE
Decide which field data type you want to apply to your data Field Data Types
Apply table and field properties Table and Table Extension Properties
TO SEE
Learn about the set of triggers that Dynamics 365 Business Table Triggers
Central supports for tables and fields. Table Extension Triggers
Field Triggers
Field Extension Triggers
TO SEE
Get a brief introduction to relational database design in Setting Relationships Between Tables
Dynamics 365 Business Central.
See Also
Developing Extensions in AL
Table Object
2/6/2023 • 2 minutes to read • Edit Online
Tables are the core objects used to store data in Dynamics 365 Business Central. No matter how data is
registered in the product - from a web service to a finger swipe on the phone app, the results of that transaction
will be recorded in a table.
The structure of a table has four sections:
The first block contains metadata for the overall table, such as the table type.
The fields section describes the data elements that make up the table, such as their name and the type of data
they can store.
The keys section contains the definitions of the keys that the table needs to support.
The final section details the triggers and code that can run on the table.
IMPORTANT
Only tables with the Extensible Property set to true can be extended.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
IMPORTANT
System and virtual tables can't be extended. System tables are created in the ID range of 2.000.000.000 and above. For
more information about object ranges, see Object Ranges.
Snippet support
Typing the shortcut ttable will create the basic layout for a table object when using the AL Language extension
in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Table example
This table stores address information and it has four fields; Address , Locality , Town/City , and County .
table 50104 Address
{
Caption = 'Sample table';
DataPerCompany = true;
fields
{
field(1; Address; Text[50])
{
Description = 'Address retrieved by Service';
}
field(2; Locality; Text[30])
{
Description = 'Locality retrieved by Service';
}
field(3; "Town/City"; Text[30])
{
Description = 'Town/City retrieved by Service';
}
field(4; County; Text[30])
{
Description = 'County retrieved by Service';
trigger OnValidate();
begin
ValidateCounty(County);
end;
}
}
keys
{
key(PrimaryKey; Address)
{
Clustered = TRUE;
}
}
var
Msg: Label 'Hello from my method';
trigger OnInsert();
begin
end;
procedure MyMethod();
begin
Message(Msg);
end;
}
System fields
The Dynamics 365 Business Central platform will automatically add several system fields to tables. For more
information, see System Fields.
See Also
AL Development Environment
Table Overview
Table Extension Object
SqlTimestamp Property
Table Keys
Table, Table Fields, and Table Extension Properties
System Fields
2/6/2023 • 6 minutes to read • Edit Online
System fields are fields that are automatically included in every table object by the platform. Dynamics 365
Business Central includes the following system fields:
SystemId
Data audit fields
Timestamp
System fields are assigned numbers in the range 2000000000-2147483647. This range is reserved for system
fields. You'll get a design-time error if you give a field a number in this range.
SystemId field
APPLIES TO: Business Central 2019 release wave 2 and later
The SystemId field is a GUID data type field that specifies a unique, immutable (read-only) identifier for records
in the table. The SystemId field has the following characteristics and behavior:
All records must have a value in the SystemId field.
You can assign your own value when a record is inserted in the database. Otherwise, the platform will
automatically generate and assign a value.
Once the SystemId has been set, it can't be changed.
There's always a unique secondary key on the SystemId field to ensure records don't have identical field
values.
The SystemId field is given the field number 2000000000.
The SystemId field is exposed in the platform code and for AL code, allowing you to code against it. For
example:
The Insert(Boolean, Boolean) lets you specify the SystemId value for a record, instead of using one
assigned by the platform:
myRec.SystemId := '{B6666666-F5A2-E911-8180-001DD8B7338E}';
myRec.Insert(true, true);
id := myRec.GetBySystemId('{B6666666-F5A2-E911-8180-001DD8B7338E}';
The SystemIdNo() gets the field number used by the SystemId field in the table:
myRec.Open(DATABASE::MyTable);
SystemIdFieldNo := myRec.SystemIdNo();
The TableRelation lets you use the SystemId field to set up table relationships:
field(1; MyField; Guid)
{
DataClassification = ToBeClassified;
TableRelation = Customer.SystemId;
}
If the SystemId field is specified in a Web Service POST request, the OData stack persists the value in the
database.
The SystemId field can be used as part of a (non-primary) key.
You can show the SystemId field as a field on a page.
You can link FactBoxes/page parts using the SystemId field.
Every table in Business Central includes the following four system fields, which can be used for auditing records:
C O L UM N N A M E ( IN
F IEL D N A M E ( IN A L ) DATA B A SE) DATA T Y P E F IEL D N UM B ER DESC RIP T IO N
Runtime characteristics
At runtime, the data audit fields have the following characteristics and behavior:
The platform will automatically generate and assign values according to the following triggers:
After all OnBeforeInsert and OnBeforeModify triggers are run
After the OnInsert and OnModify triggers are run
Before all OnAfterInsert and OnAfterModify triggers are run
NOTE
You can assign the values, but the values written to the database are always provided by the platform.
NOTE
Audit fields can't be imported with configuration packages.
In AL
The data audit fields are exposed in AL code. As a developer, the audit fields give you an easy and performant
way to program against historical data. For example, you can write AL queries that return data changes since a
specific date and time.
The following methods are available on the RecordRef data type:
M ET H O D DESC RIP T IO N
Timestamp field
The timestamp field contains rowversion numbers for records, as maintained in SQL Server. In SQL server,
timestamp is a synonym for the rowversion data type. The value of the timestamp field is an automatically
generated, unique binary number. The timestamp is a mechanism for version-stamping table rows.
A typical use of the timestamp field is for synchronizing data changes in tables. It lets you identify records that
have changed since the last synchronization. For example, you can read all the records in a table, then store the
highest timestamp value. Later, you can query and retrieve records that have a higher timestamp value than
the stored value.
In AL
In AL code, the timestamp is accessible through the SystemRowVersion field. However, you can't write to the
field.
The following methods are also available on the Database data type:
M ET H O D DESC RIP T IO N
LastUsedRowVersion Gets the last used rowversion from the database. This
method does the same as the @@DBTS (Transact-SQL)
function.
Alternatively, you can use a FieldRef Data Type variable to access the timestamp value of a record, as follows:
1. Create a RecordRef Data Type variable that references the record in a table for which you want to retrieve
its timestamp.
2. Use the Field Method on the RecordRef variable to get the FieldRef for the field that has the number 0.
This field contains the timestamp value.
The following example shows how to retrieve the timestamp value for the first record in the Customer table.
RecordRef and FieldRef are RecordRef Data Type and FieldRef Data Type variables, respectively.
RecordRef.Open(DATABASE::Customer);
RecordRef.FindFirst();
FieldRef := RecordRef.Field(0);
Message(Format(FieldRef.Value()));
See Also
Table Object
AL Development Environment
Table Overview
Table Extension Object
SqlTimestamp Property
Table Keys
Table Properties
Table Extension Object
2/6/2023 • 2 minutes to read • Edit Online
The table extension object allows you to add additional fields or to change some properties on a table provided
by the Dynamics 365 Business Central service. In this way, you can add data to the same table and treat it as a
single table. For example, you may want to create a table extension for a retail winter sports store. In your
solution you want to have ShoeSize as an additional field on the customer table. Adding this as an extension
allows you to write code for the customer record and also include values for the ShoeSize .
Along with defining other fields, the table extension is where you write trigger code for your additional fields.
When developing a solution for Dynamics 365 Business Central , you will follow the code layout for a table
extension as shown in the example below.
IMPORTANT
Only tables with the Extensible Property set to true can be extended.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
IMPORTANT
System and virtual tables cannot be extended. System tables are created in the ID range of 2.000.000.000 and above. For
more information about object ranges, see Object Ranges.
IMPORTANT
Extending tables from Dynamics 365 for Sales is currently not supported.
Snippet support
Typing the shortcut ttableext will create the basic layout for a table extension object when using the AL
Language extension in Visual Studio Code.
Properties
Using a table extension allows you to overwrite some properties on fields in the base table. For a list of Table
properties, see Table and Table Extension Properties.
Table extension syntax
tableextension Id MyExtension extends MyTargetTable
{
fields
{
// Add changes to table fields here
}
var
myInt: Integer;
}
trigger OnBeforeInsert();
begin
if not HasShoeSize then
ShoeSize := Random(42);
end;
}
See Also
AL Development Environment
Table Overview
Table Object
Table, Table Fields, and Table Extension Properties
Table Keys
Setting Relationships Between Tables
2/6/2023 • 2 minutes to read • Edit Online
It is common to distinguish among the following types of relationships between tables in relational database
design:
One-to-many relationships
Many-to-many relationships
One-to-one relationships
The one-to-many relationship is the most common. If your database design model indicates that you need to set
up a many-to-many relationship, then your design is probably inefficient. You can typically break down a many-
to-many relationship into two one-to-many relationships. A one-to-one relationship is usually not optimal and
can often be avoided by combining the two tables.
Using relationships
If your database contains tables with related data, then you can define a relationship between them. You relate
tables by specifying one or more fields that contain the same value in related records. These matching fields
often have the same name in each table. You can use relationships to:
Validate data entries
Perform lookup functions in other tables
Propagate changes automatically from one table to other tables
NOTE
You can define a relationship only to a field that is a member of the primary key group.
Advanced table relations are typically prefixed with a conditional statement and include filters. The following
syntax is for table relations.
<TableRelation> =
<TableName>[.<FieldName>] [WHERE(<TableFilters>)] |
if (<Conditions>) <TableName>[.<FieldName>]
[WHERE(<TableFilters>)] else <TableRelation>
<Conditions> ::=
<TableFilters>
<TableFilters> ::=
[<TableFilter> {,<TableFilter>}]
<TableFilter> ::=
<DstFieldName>=CONST(<FieldConst>) |
<DstFieldName>=FILTER(<Filter>)
For example:
table 50120 TableWithRelation
{
fields
{
field(1; Id; Integer) { }
field(2; Type; enum TypeEnum) { }
field(3; Relation; Code[20])
{
TableRelation =
if (Type = const (Customer)) Customer
else if (Type = const (Item)) Item;
}
}
}
SY M B O L DESC RIP T IO N
For example, you have a Vendors table with all your vendors and a Currency Code table. You can create a
relationship between a Currency Code field in the Vendors table and the Currency Code table. This will
allow users to look up information about valid currency codes.
Furthermore, if you change one of the currency codes in the Currency Code table, then the change is
automatically propagated to all tables that refer to this code.
See Also
Overview of Tables
Classifying Data in Dynamics 365
2/6/2023 • 5 minutes to read • Edit Online
Dynamics 365 includes development features for tagging business data with specific classifications. Specifically,
this includes data that is stored in table fields of the database and telemetry data that is emitted from the
application.
IMPORTANT
You should consider the data classification features offered in Dynamics 365 as the first layer of classification - done by
developers (Dynamics 365 and partners) on customizations, add-ons, and extensions. The second layer is to classify the
sensitivity of the data itself. For more information, see Classifying Data Sensitivity. It is also important to consider end-
users, and how they handle data they provide and that is made available to them.
EndUserIdentifiableInformation (EUII) Data that identifies or could be User name or display name
used to identify the user of a Microsoft (DOMAIN\UserName)
service. EUII does not contain User principle name
Customer content. (name@company.com)
User-specific IP address
IMPORTANT
Microsoft is providing this DataClassification property as a matter of convenience only. It is your responsibility to
classify the data appropriately and comply with any laws and regulations that are applicable to you. Microsoft disclaims all
responsibility towards any claims related to your classification of the data.
Bulk-classifying data
The Field Data Classification report, which is described in the Viewing current field classifications section in this
topic, provides an overview of the data classifications for fields. The report also lets you assign data
classifications for more than one field. For example, this is useful if you are assigning classifications for the first
time, or have changed several fields and want to update their classifications. You can bulk-edit classifications
only for fields in AL Language development environment. The script does not update fields in extensions.
To bulk-edit classifications, export the report to Excel, update the classifications, and then save your changes.
Then, in Windows PowerShell, run the following commands to run the Import-Module script and set the
classifications on the fields.
To run the script from the default folder on the DVD, run:
Import-Module WindowsPowerShellScripts\DataClassification\DataClassification.psm1
To update the DataClassification property, run the following command. Replace <FilePath> with the full path
to the client files. For example, C:\Program Files\Microsoft Dynamics 365 Business Central\160\RoleTailored
Client.
See Also
Data Classification
Classifying Data Sensitivity
Insert, Modify, ModifyAll, Delete, and DeleteAll
Methods
2/6/2023 • 4 minutes to read • Edit Online
The following methods maintain the database by adding, modifying, and removing records:
Insert
Modify
ModifyAll
Delete
DeleteAll
These methods are some of the most frequently used AL methods.
Some of these methods return an optional Boolean value that indicates whether the method succeeded. If you
do not handle the return value in your code, a run-time error occurs when a method returns false . If you handle
the return value by testing its value in an if statement, no error will occur, and you must take corrective action in
the code.
Insert method
The Insert method inserts a record in a table. Insert has the following syntax.
A record must be assigned a SystemId . You have the option to assign your own value or have the platform
assign an auto-generated value. The following example inserts a new record, with the SystemId , No., and
Name fields specified in the assigned values, while other fields will have their default values. If the No. field is
the primary key of the Customer table, then the record will be inserted in the Customer table unless the table
already contains a record with the same primary key. In this case you receive an error message because the
return value is not tested.
var
Customer: Record Customer;
begin
Customer.Init;
Customer.SystemId := '{B6666666-F5A2-E911-8180-001DD8B7338E}';
Customer."No." := '4711';
Customer.Name := 'Andrew Dixon';
Customer.Insert(false, true);
end;
IMPORTANT
After the SystemId has been set on a record, it cannot be changed.
Modify method
Modify modifies a record that already exists. For more information, see Modify Method. Modify has the
following syntax.
Modify returns an optional Boolean value. It returns true if the record to be modified exists; otherwise, it returns
false .
The following example changes the name of customer 4711 to Richard Roe. This example requires that you
create the following variable.
Customer.Get('4711');
Customer.Name := 'Richard Roe';
Customer.Modify;
ModifyAll method
ModifyAll performs a bulk update of records. For more information, see ModifyAll Method.
ModifyAll has the following syntax.
ModifyAll uses the current filters. This means that you can perform the update on a specified set of records in a
table. ModifyAll returns no value, nor does it cause an error if the set of records to be changed is empty.
In the following example, the SetRange statement selects the records where Salesperson Code is PS. The
ModifyAll statement changes the Salesperson Code of these records to JR. The example requires that you create
the following variable.
Customer.SetRange("Salesperson Code",'PS','PS');
Customer.ModifyAll("Salesperson Code",'JR');
Delete method
Delete deletes a record from the database. For more information, see Delete Method Delete has the following
syntax.
The record that you want to delete must be specified by using the values in the primary key fields before you
call this method. This means that Delete does take filters into consideration.
The following example shows how to use Delete to delete the record for customer number 4711. This example
requires that you create the following variable.
Customer."No." := '4711';
Customer.Delete;
Delete returns an optional Boolean value. It returns true if the record could be found; otherwise, it returns false .
Unless you test this value in your code, a run-time error occurs when Delete fails.
When you are developing your own applications, you should consider the following scenario:
1. Retrieve a record from the database.
2. Perform various checks to determine whether the record should be deleted.
3. If step 2 indicated that you should delete the record, then delete it.
This can cause problems in a multi-user environment. Another user can modify or delete the same record
between your performing steps 2 and 3. If the record is modified, then perhaps the new contents of the record
would have changed your decision to delete it. If it has been deleted by the other user, you can get a run-time
error if you have just verified that the record existed (in step 1). If the design of your application indicates that
you can encounter this problem, you should consider using the LockTable method. LockTable should be used
sparingly because this method degrades performance. For more information about the LockTable method, see
LockTable Method.
DeleteAll method
DeleteAll deletes all the records that are specified by the filter settings. If no filters are applied, it deletes all the
records in the table. For more information, see DeleteAll Method DeleteAll has the following syntax.
Record.DeleteAll([RunTrigger])
The following example deletes all the records from the Customer table where the Salesperson Code is PS. This
example requires that you create the following variable.
NOTE
When you use DeleteAll (true), a copy of the AL variable with its initial values is created. This means that when you use
DeleteAll(true) to run the OnDelete trigger, all the changes that were made to the variables in the method or codeunit
that is making the call cannot be seen in the OnDelete trigger. If you want to see the changes that you made to the
variables, you must use Delete(true) in a loop. There is no difference in performance between using DeleteAll(true) and
using Delete(true) in a loop.
See Also
AL Methods
SystemId Field
Temporary tables
2/6/2023 • 4 minutes to read • Edit Online
A temporary table is a temporary variable that holds a table. A temporary table is used as a buffer or
intermediate storage for table data.
You can use a temporary table just like you use a database table. The differences between a temporary table and
a database table are as follows:
A temporary table data isn't stored in the database. It's only held in memory until the table is closed.
The write transaction principle that applies to a database table doesn't apply to a temporary table.
TIP
Temporary tables retain system fields, like SystemID and data audit fields. For more information, see System Fields.
With this implementation, a physical table isn't created in the database. In the table object, set the TableType
property to Temporary :
table 50100 MyTable
{
DataClassification = ToBeClassified;
TableType = Temporary;
fields
...
}
This implementation has the same effect as using a temporary record variable or setting the
SourceTableTemporary property on a page. But the advantage is that the table schema isn't synchronized with
the database. So it doesn't have restrictions on breaking schema changes, like removing a field, changing its
data type or length.
It will also improve the performance of BACPAC generation using the sqlpackage command-line tool, compared
to temporary tables based on temporary record variables and pages. For more information, see Performance of
BACPAC generation.
Changing the table type
You can change from Normal to Temporar y , and the other way around. When changing Normal to
Temporar y the table, you'll have to synchronize the extension with the database. This step will remove the table
from the database. So if the table contains data, you'll have to synchronize the schema using the ForceSync
mode.
NOTE
Changing the table type is considered a destructive change. So this change can only be done with Business Central on-
premises.
var
TempInvoicePostBuffer: Record "Invoice Post. Buffer" temporary;
You manipulate the temporary table variable as you would with any other database table. For example, you can
apply filters and do searches. For more information about the operations you can do, see Record Data Type.
layout
...
}
See Also
Get Started with AL
Table Object
Temporary Property
UseTemporary Property (Report)
UseTemporary Property (XMLPort)
Retaining table data after publishing
2/6/2023 • 4 minutes to read • Edit Online
When developing an extension, you debug several times using the F5 shortcut key, and you also test your app
by adding some sample data every time. To simplify the extension development process in Business Central, you
can synchronize the sample data specified in the extension when you do subsequent publishing from Visual
Studio Code.
{
"type": "al",
"request": "launch",
"name": "your own server",
"server": "https://localhost",
"serverInstance": "Nav",
"authentcation": "UserPassword",
"startupobjectId": 22,
"schemaUpdateMode": "Recreate"
}
Recreate mode
When you set the schema update mode to Recreate , all the tables and table extensions are recreated at every
publish, which means that all the data in those tables are lost. This means that you will get empty records when
you publish your extension.
ForceSync mode
ForceSync is similar to the existing Synchronize schema update mode, but contains more freedom to make
schema changes while retaining data. To enable this mode, set schemaUpdateMode to "ForceSync" and then set
the "version" parameter in the app.json file to a fixed number. Data will be preserved in almost all cases with
the exception of changing the main table's primary key, in which case the data from the extension tables will be
lost. Field renames are allowed and supported in this mode, but the data can only be preserved if you maintain
the same ID for the field. If you change both the name and the ID of the field then the data will be lost.
IMPORTANT
This schema update mode is only meant for testing and development and should never be used in production.
In addition to the launch.json file setting, the ForceSync switch is available through the PowerShell cmdlet
Sync-NavApp –Mode ForceSync .
Things to be aware of
Synchronize is the default schema update mode for syncing the database and the extension. There are some
key factors to consider when you work with the Synchronize mode.
After publishing, the field data and the primary key information synchronizes with all the tables and the
table extensions. This means that you can do additions easily, but not deletions. Breaking changes are
never supported in synchronize mode. For example, you can add a field and sync that with the extension
just by pressing the F5 shortcut key, but if a field is removed then the table data cannot be synchronized.
If you, during development, for example, discover that you no longer want field X , and you then mark
field X as obsolete, you may still want to write an upgrade codeunit to move the data from the obsolete
field to a new field Y that you introduce. Later, the obsoleted field will not be available. But if you do not
want the data, you can choose to use the Recreate mode instead.
When you make changes to the data types, you can only enlarge the unit size, and not decrease the unit
size. For example, you can set a text type from Code[20] to Code[50] or Text[32] to Text[87] , and you
cannot set a text type from Code[50] to Code[30] or Text[87] to Text[40] .
For field data types, however, changing the length is not allowed. If you, for example, change version 1.0
of the field(50100; MyField; Text[50]) to field(50100; MyField; Text[150]) in version 2.0 it is
considered a breaking change. For more information, see AppSourceCop Rule AS0086.
Making major table structural changes could lead to compilation errors. For example, if you want to
update a primary key. In this case, the table data cannot be synchronized, and if you want to publish the
extension, you must change the schemaUpdateMode to Recreate . Likewise, changing the DataPerCompany
from true to false and from false to true is a schema-breaking change, and therefore not allowed
because it changes the number of tables per company.
For extensions built on Business Central Spring 2019 or earlier, if a table field has the SqlDataType set to
a value other than Varchar (which is the default), you must delete the SqlDataType property on the field,
otherwise, you will will not be able to successfully synchronize the extension.
If the SqlDataType property is still needed, you will have to create a new table in the extension that has
the same definition as the original table, and write upgrade code that migrates the data from the original
table to the new table. For more information, see Writing upgrade code.
Alternatively, if this is a development scenario, you can synchronize the extension using the ForceSync or
Recreate mode.
See Also
AL Development Environment
Upgrading Extensions
Debugging
Integrating Microsoft Dataverse for Extension
Development
2/6/2023 • 2 minutes to read • Edit Online
Develop extensions and streamline the workflow by synchronizing Microsoft Dataverse data with Dynamics 365
Business Central.
For developing extensions to integrate with sales data, you simply enable the tables used in Microsoft Dataverse.
The extension development process includes the following set of properties in Dynamics 365 Business Central
to enable field mapping. You can enable the field mapping by using the following properties. The tables are
extensible, so that you can update Microsoft Dataverse with data as well.
ExternalName Property Tables, Fields Specifies the name of the original table
in the external database when used as
a table property.
OptionMembers Property Fields Sets the option values for a field, text
box, or variable.
Snippet support
Typing the shortcut ttable will create the basic layout for a table object when using the AL Language extension
in Visual Studio Code.
Example
In the following example, the SalesIntegration table uses the TableType and ExternalName properties to link
the underlying Microsoft Dataverse table for mapping the columns from the Sales table with the specified
fields.
fields
{
field(1; ActualSales; Integer)
{
ExternalName = 'ActualSale';
ExternalAccess = Full;
ExternalType = 'String';
}
See Also
Table Properties
TableType Property
AL Proxy Table Generator
Creating Filter Pages for Filtering Tables
2/6/2023 • 2 minutes to read • Edit Online
In AL code, you can use the FilterPageBuilder data type to create a filter page that enables users to set filters on
multiple tables. Filter pages contain one or more filter controls, where each filter control can be used to set
filters on a specific table. In the Business Central client, filter pages are generated at runtime and run in a modal
dialog box. The following figure illustrates a filter page that filters on the Item table.
To create a filter page, you use AL code and the methods that are available for the FilterPageBuilder Data Type.
The following code example shows the code that creates the filter page in the figure.
var
Item: Record Item;
Customer: Record Customer;
FilterPage: FilterPageBuilder;
FilterPageCaption: TextConst ENU = 'Customer and Item Filter Page';
begin
FilterPage.AddTable(Customer.TableCaption(), Database::Customer);
FilterPage.AddRecord(Item.TableCaption(), Item);
FilterPage.Addfield(Item.TableCaption(), Item."No.", '>100');
FilterPage.PageCaption := FilterPageCaption;
FilterPage.RunModal();
end;
See Also
FilterPageBuilder Data Type
Working With Media on Records
2/6/2023 • 8 minutes to read • Edit Online
This article describes how you can upload media, such as an image, to the database for displaying with records
in the client. There are two ways that you can upload media:
Use a BLOB data type
You add media to a BLOB data type field on the record. For more information, see BLOB Data Type.
Use a Media or MediaSet data type
This way enables you to store media in system tables of the database, and then reference the media from
application records. For example, you can:
Display media with records in list type pages, when the page is viewed in the Tile layout. For more
information, see Displaying Data as Tiles.
Display media on a card type page for a record.
Display media in a report.
Using the Media or MediaSet data type provides better performance than using a BLOB data type and is more
flexible in its design. With a BLOB data type, each time the media is rendered in the client, it's retrieved from the
SQL database server, which requires extra bandwidth and affects performance. With the Media and MediaSet
data types, the client uses media ID to cache the media data, which in turn improves the response time for
rendering the media in the user interface.
NOTE
Starting with Business Central 2021 release wave 1, when importing Microsoft Word files (.docx), macro packages (VBA
code) will automatically be removed from the file when stored in the database. If macros are needed for end-user
scenarios, the macro must be in the Word template (.dotx) associated with the document being imported.
NOTE
If a MediaSet data type field is used in a report object, then only the first associated media file is displayed in the
generated report.
M IM E T Y P E F IL E EXT EN SIO N
image/bmp bmp
image/gif gif
application/msword doc
application/octet-stream json
application/vnd.openxmlformats- docx
officedocument.wordprocessingml.document
application/vnd.ms-excel xls
application/vnd.openxmlformats- xlsx
officedocument.spreadsheetml.sheet
application/vnd.ms-powerpoint ppt
application/vnd.openxmlformats- pptx
officedocument.presentationml.presentation
M IM E T Y P E F IL E EXT EN SIO N
application/pdf pdf
application/xml xml
audio/mpeg mp3
audio/x-wav wav
video/mp4 mp4
video/x-msvideo avi
text/plain txt
NOTE
GIF type is not supported on reports. If you want to display an image on a report, use another supported type.
Files with extensions that are not recognized are also supported and can be imported. These are stored as BLOBs (binary
larger objects).
AL methods
To get an overview of the methods that are related to the Media and MediaSet data types, see Media Data Type
and MediaSet Data Type.
This example will create a new media set that contains the shared media object references. When you delete the
media set (by deleting the MediaTargetTable record), the runtime will detect that the media object is used in
multiple media sets, so it won't delete the media objects. The media objects might eventually be deleted when
the runtime can't find other references.
IMPORTANT
The simple field copy statement mediaTargetTable.MediaSetField := mediaSourceTable.MediaSetField; can only be
used if mediaTargetTable is declared as the same record subtype as mediaSourceTable , and the target and source field
IDs are the same.
<Value>=Convert.ToBase64String(Fields!CompanyInfo2Picture.Value)</Value>
To use a direct reference without the base64 conversion, change <Value></Value> element expression to:
<Value>=Fields!CompanyInfo2Picture.Value</Value>
See Also
BLOB Data Type
Media Data Type
MediaSet Data Type
Get, Find, and Next Methods
2/6/2023 • 3 minutes to read • Edit Online
These methods are some of the most frequently used AL methods. When you search for records, you must
know the difference between Get and Find. You should also know how to use Find and Next in conjunction.
TIP
When using these methods, consider using the partial records methods to improve performance, especially when looping
through several records or when table extensions are defined on the table. For more information, see Using Partial
Records.
Get method
The Get Method (Record) retrieves one record based on values of the primary key fields.
Get has the following syntax.
For example, if the No. field is the primary key of the Customer table and if you've created a record variable
called CustomerRec that has a subtype of Customer, then you can use Get in the following way.
CustomerRec.Get('4711');
if CustomerRec.GET('4711') then
.... // Do some processing.
else
.... // Do some error processing.
Get searches for a record without changing any current filters. Get always searches through all the records in a
table.
GetBySystemId method
APPLIES TO: Business Central 2019 release wave 2 and later
The GetBySystemId(Guid) retrieves a record based on the value of its SystemId field.
GetBySystemId has the following syntax:
The following example gets the record that has the SystemId 5286305A-08A3-E911-8180-001DD8B7338E :
var
Customer: Record Customer;
Text000: Label 'Customer was found.';
begin
If Customer.GetBySystemId('{5286305A-08A3-E911-8180-001DD8B7338E}') then
Message(Text000);
end;
Similar to the Get method, GetBySystemId also searches for a record without changing any current filters.
Find methods
The Find Method (Record) locates a record in a table that is based on the values stored in the keys.
Find has the following syntax.
Ok := Record.Find([Which])
The Which parameter specifies how to perform the search. You can search for values that are greater than, less
than, or equal to the key value, or for the first or last record in a table.
The important differences between Get and Find are as follows:
Find uses the current filters.
Find can look for records where the key value is equal to, greater than, or smaller than the search string.
Find can find the first or the last record, depending on the sort order defined by the current key.
When you're developing applications in a relational database, there are often one-to-many relationships defined
between tables. An example could be the relationship between an Item table, which registers items, and a Sales
Line table, which registers the detailed lines from sales orders. One record in the Sales Line table can only be
related to one item, but each item can be related to any number of sales line records. You won't want an item
record to be deleted as long as there are still open sales orders that include the item. You can use Find to check
for open sales orders.
The OnDelete trigger of the Item table includes the following code that illustrates using Find.
SalesOrderLine.SetCurrentKey(Type,"No.");
SalesOrderLine.SetRange(Type,SalesOrderLine.Type::Item);
SalesOrderLine.SetRange("No.","No.");
if SalesOrderLine.Find('-') then
Error(Text001,TableCaption,"No.",SalesOrderLine."Document Type");
If you want to find the first record in a table or set, then use the FindFirst Method (Record). If you want to find
the last record in a table or set, then use the FindLast Method (Record).
Next method
The Next Method (Record) is often used with FIND to step through the records of a table.
Next has the following syntax.
Steps := Record.Next([Steps])
In the following example, Find is used to go to the first record of the table. Next is used to step through every
record, until there are no more. When there are no more records, Next returns a 0 (zero).
if (Rec.FindSet) then
repeat
// process record
until (Rec.Next = 0);
See Also
AL Methods
SystemId Field
Using Partial Records
2/6/2023 • 8 minutes to read • Edit Online
The partial records capability in Business Central allows for loading a subset of normal table fields when
accessing a SQL based data source. Using partial records improves performance of objects like reports and
OData pages - objects whose source code loops through records. It's particularly beneficial when table
extensions are used in the application.
Accessing a data source from AL code is typically done by using the record's methods Get, Find, Next, and so on.
Without using partial records, the runtime loads all normal fields when accessing the data source. Using the
partial records API, you can now select a set of fields and only load them.
API Overview
To accommodate partial record loading, the following methods are available on both the RecordRef and Record
data type in AL. These methods operate on the record instance that they're called on, changing the set of fields
to load until otherwise altered. The methods are divided into two groups: methods that pertain to subsequent
loads and methods that pertain to the currently loaded record.
Subsequent load methods
A record instance that has been previously loaded with fields can be reset to a non-partial load either by calling
Record.SetLoadFields without any parameters, or by calling Reset. After being reset, subsequent loads will
behave as if SetLoadFields hadn't previously been called on the record instance.
Example
The following code shows a way to load only a single field from the Item table for computing the arithmetic
mean.
Notice that the call to SetLoadFields occurs before the data fetching operations. This call determines which fields
are needed for the FindSet call. You use the same pattern for AddLoadFields calls.
Usage guidelines
This feature gives you the ability to limit the fields that load for a record to only those fields that are necessary.
In general, loading fewer fields will make operations faster. But the most significant performance gains can be
seen with table extensions - by not loading unnecessary fields in table extensions. Table extensions that don't
have any fields for loading won't be part of the data join, which saves time.
TIP
Testing on the previous example code showed that the execution time for loading only the "Standard Cost" field was nine
times faster than loading all normal fields. Your performance numbers will vary depending on the machine and the setup
with the SQL database.
For performance reasons, it's not recommended to use partial records on a record that will do inserts, deletes,
renames, field transfers, or copies to temporary records. All these operations require that all fields on the record
are loaded, so the platform will emit a JIT load if they're not already loaded. A JIT load requires to access the data
source again, this cost is larger than the gains of loading fewer fields. For this reason, the feature is especially
advantageous in reading-based scenarios.
trigger OnPreDataItem()
begin
CurrencyDataItem.AddLoadFields(CurrencyDataItem."ISO Numeric Code");
end;
trigger OnAfterGetRecord()
begin
if (CurrencyDataItem."ISO Numeric Code" <> 'DKK') then begin
CurrReport.Skip();
end;
end;
OData pages
For pages opened by OData service calls, the page's metadata is used to define which fields to show. In this case,
the fields referenced in the page’s layout are loaded as a minimum. More fields may be required, for example, to
enable subpage linking.
Like with reports, other fields aren't selected for load, even if they may be used in triggers. But you can add extra
fields the following ways:
Add the field to the page layout.
Add the field to the set of fields to be loaded via the AddLoadFields method on the OnFind trigger.
List and ListPart pages
Partial records are automatically applied based on the page’s metadata for List and ListPart page types that are
opened in the web client. As with OData pages, the page's definition is used to select which fields to load. More
fields may be required, for example, to enable subpage linking.
To extend which fields will be loaded, you can use the same approach as with OData pages.
NOTE
OnFindRecord and OnNextRecord triggers conflict with partial record feature, so if either of these triggers is defined in the
metadata, the partial record feature won't be applied and it fall back to standard loading behavior.
See Also
FAQ for Partial Records
Performance Articles For Developers
Get, Find, and Next Methods
Configuring Business Central Server
FAQ for Partial Records
2/6/2023 • 2 minutes to read • Edit Online
This article answers some of the most typical questions about the partial records capability in Business Central.
See Also
Performance Articles For Developers
Get, Find, and Next Methods
Configuring Business Central Server
Queries in Business Central
2/6/2023 • 3 minutes to read • Edit Online
Queries enable you to retrieve records from one or more tables or data sources and then combine the data into
rows and columns in a single dataset. Queries can also perform calculations on data, such as finding the sum or
average of all values in a column of the dataset.
Query Types
There are two types of query objects: normal and API.
A normal query retrieves records from business data tables in the Dynamics 365 Business Central database,
and can be used to display data in the user interface. This type of query is created by a query object. For
more information, see Query Object.
An API query is used to generate web service endpoints and this type of page cannot be displayed in the user
interface. A query of the API type can be used to join data from different data sources. The data can only be
viewed. For information about creating a query of the type API, see API Query Type.
Query usages
The following examples show how you can use queries in your Dynamics 365 Business Central application.
Creating charts that are based on a query instead of a table.
Saving a query as an .xml or .csv file. For example, you can use the SAVEASXML method to create an .xml
file that contains the resulting dataset of a query. You can use the .xml file to integrate with external
applications.
Exposing data as an OData web service. You can register and publish a query as a web service in the
same way that you can register and publish pages or codeunits as web services. You use the Web
Ser vices page to register and publish pages, codeunits, or queries. After you expose a query as a web
service, you can import it into other applications.
Using the query as a data source for a page. To do this, you have to copy the query resulting dataset into
a temporary table and set it as the source table for the page.
Using the query as a data source for a report. To do this, create a global variable that points to the query.
Then use the variable in the report dataset. For more information see, Defining a Report Dataset.
Performing calculations on data such as computing sums and averages. For more information, see Query
Totals and Grouping.
Replacing nested loops that use record variables to retrieve or to detect duplicate records. For more
information, see Using Queries Instead of Record Variables.
See Also
Query Object
Linking and Joining Data Items
Aggregating Data in Query Objects
Query Properties
Developing Extensions
AL Development Environment
Utilizing Read Scale-Out for Better Performance
Query Object
2/6/2023 • 4 minutes to read • Edit Online
Business Central query objects enable you to retrieve records from one or more tables and then combine the
data into rows and columns in a single dataset. Query objects can also perform calculations on data, such
finding the sum or average of all values in a column of the dataset.
There are two types of query objects: normal and API. This article describes normal query objects, which can be
used to display data in the user interface. API query objects are used to generate web service endpoints and
cannot be displayed in the user interface. For information about creating a query of the type API, see API Query
Type.
Dataitem links and joins determine which records to include in the dataset based on the values of a
common field between dataitems. You set a link between one or more fields of the dataitem tables with
the DataItemLink Property and you define the type of the link using the SQLJoinType Property. Both
properties must be set on the lower dataitem of the query object. For more information, see Linking and
Joining Data Items.
The following shows the basic structure of a query object.
query ID Name
{
elements
{
dataitem(DataItem1; Table1)
{
column(Column1; Field1)
{
}
column(Column2; Field2)
{
}
dataitem(DataItem2; Table2)
{
// Sets a link between FieldY of Table2 and FieldX of Table1.
DataItemLink = FieldY = DataItem1.FieldX;
//The dataset contains records from Table1 and Table2 where a match is found between FieldY
and FieldX.
SqlJoinType = InnerJoin;
column(Column1; Field1)
{
}
dataitem(DataItem3; Table3)
{
DataItemLink = FieldZ = DataItem2.FieldY;
SqlJoinType = InnerJoin;
column(Column1; Field1)
{
}
}
}
}
}
}
NOTE
Extension objects can have a name with a maximum length of 30 characters.
Snippet support
Typing the shortcut tquery will create the basic layout for a Query object when using the AL Language
extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Query example
The following example shows a query that displays a list of customers with sales and profit figures. The query
primarily retrieves fields from the Customer table, but also displays fields from the Salesperson Purchaser
and Countr y Region tables.
The query also uses the DataItemLink property to create a link between the Customer table, Salesperson
Code field and the Salesperson Purchaser table, Code fields and a link between the Customer table,
Countr y/Region Code field and the Countr y/Region table, Code field.
DataAccessIntent = ReadOnly; // use this to read data from the secondary database replica to speed up
performance
elements
{
dataitem(Customer; Customer)
{
column(Name; Name)
{
}
column(No; "No.")
{
}
column(Sales_LCY; "Sales (LCY)")
{
}
column(Profit_LCY; "Profit (LCY)")
{
}
column(Country_Region_Code; "Country/Region Code")
{
}
column(City; City)
{
}
column(Global_Dimension_1_Code; "Global Dimension 1 Code")
{
}
column(Global_Dimension_2_Code; "Global Dimension 2 Code")
{
}
column(Salesperson_Code; "Salesperson Code")
{
}
dataitem(Salesperson_Purchaser; "Salesperson/Purchaser")
{
DataItemLink = Code = Customer."Salesperson Code";
column(SalesPersonName; Name)
{
}
dataitem(Country_Region; "Country/Region")
{
DataItemLink = Code = Customer."Country/Region Code";
column(CountryRegionName; Name)
{
}
}
}
}
}
}
IMPORTANT
You cannot run a query that gets data from both the application database and the business data database. This also
applies to single-tenant deployments so that you do not have to rewrite queries if you decide to export the application.
For a description of which tables are considered part of the application database, see Separating Application Data from
Business Data.
See Also
Linking and Joining Data Items
Aggregating Data in Query Objects
Query Objects and Performance
Query Properties
Query DataAccessIntent
Developing Extensions
AL Development Environment
API Query Type
Linking and Joining Data Items to Define the Query
Dataset
2/6/2023 • 11 minutes to read • Edit Online
Business Central queries enable you to retrieve records from one or more tables and combine the specific
records into rows in a single dataset. In AL, each table is specified as a data item. The data included in the dataset
is a result of how the data items are linked and joined together.
TIP
The concept of linking and joining data items in AL is similar to Join clauses in SQL Select statements on tables in SQL
Server. For those familiar with SQL Joins, when describing links and joins in AL, this article provides the equivalent SQL
SELECT statement in most cases.
C O DE NAME
AA Annette
BB Bart
DD Debra
JJ John
1000 Autohaus AA
2000 Blanemark DD
3000 Candoxy JJ
Sample Query
The following query object links the Sale Header table with the Salesperson/Purchaser table on the
Salesperson_Code and Code fields, as specified by the DataItemLink Property. In the example, the
SQLJoinType Property is set to InnerJoin .
elements
{
dataitem(Salesperson_Purchaser; "Salesperson/Purchaser")
{
column(Salesperson; Name)
{
}
dataitem(Sales_Header; "Sales Header")
{
DataItemLink = "Salesperson Code" = Salesperson_Purchaser.Code;
// Change the SqlJoinType value to suit the desired results: LeftOuterJoin, InnerJoin,
RighOuterJoin, FullJoin, CrossJoin.
SqlJoinType = InnerJoin;
column(Order_Number; "No.")
{
}
column(Sell_to_Customer; "Sell-to Customer Name")
{
}
}
}
}
}
NOTE
In the sections that follow, some examples illustrate the use of either the WHERE clause and FROM clause to get the
same results. However, for better performance, we recommend using a FROM clause wherever possible.
The DataItemLink Property sets up an "equal to" (=) comparison condition between two columns of the data
items. When the query is run, the query compares each row of the two data items to find records that having
matching values for the columns. Records that have matching column values are combined into a row in the
resulting dataset. In some cases, there will be records that don't have matching values. You use the SqlJoinType
Property to include records that don't have matching column values.
Set the SqlJoinType Property
The SqlJoinType Property determines which records to combine into the results, based on the values of the
fields linked by the DataItemLink property. You use this property to limit the records that are included in the
resulting dataset based on the specified conditions. By default, the SqlJoinType property is LeftOuterJoin , so if
you omit this property, a LeftOuterJoin is performed.
TIP
In SQL join statements, tables are designated as either left or right. In AL query objects, because data items are arranged
vertically, when joining data items, the left corresponds to the upper data item (table) and right corresponds to the lower
data item (table).
elements
{
dataitem(Salesperson_Purchaser; "Salesperson/Purchaser")
{
column(Salesperson; Name)
{
}
dataitem(Sales_Header; "Sales Header")
{
DataItemLink = "Salesperson Code" = Salesperson_Purchaser.Code;
SqlJoinType = InnerJoin;
column(Order_Number; "No.")
{
}
column(Sell_to_Customer; "Sell-to Customer Name")
{
}
dataitem(Sales_Line; "Sales Line")
{
DataItemLink = "Sell-to Customer No." = Sales_Header."Sell-to Customer No.";
}
}
}
}
}
InnerJoin
InnerJoin creates a dataset by combining records from data item tables where a match is found between the
columns that are linked by the DataItemLink Property of the lower data item. Inner Join uses an "equal to"
comparison operator to match rows from the lower data item table with rows from the upper data item table
that is based on the values of the linked columns.
Each pair of matching records is combined into a row in the dataset.
Records from the upper and lower data item tables that don't have a matching column in the lower data
item table are excluded from the resulting dataset.
The following illustration shows an InnerJoin type between tables A and B. The shaded area indicates the
records that are included in the resulting dataset.
Dataset Example
The following table shows the resulting dataset for an InnerJoin between the Sales Header table and
Salesperson/Purchaser table in sample query.
SA L ESP ERSO N O RDER_N UM B ER SEL L _TO _C USTO M ER
The records for Bar t in the Salesperson table and New Concepts in the Sales Header table don't have
matching records in the opposing table, so they are excluded from the resulting dataset.
SQL SELECT Statement for Inner Join
To specify an inner join with an SQL statement, you can do either of the following:
Use a WHERE clause.
Use the INNER JOIN condition with an ON clause.
The following two examples show how to create an inner join on the Salesperson/Purchaser and Sales
Header tables with SQL statements. These two statements result in the same dataset.
LeftOuterJoin
A LeftOuterJoin resembles the InnerJoin except that the resulting dataset set contains every record from the
upper data item table, even if a record does not have a matching value in the lower data item for columns that
are linked by the DataItemLink Property.
For each record in the upper data item, a row is added in the dataset that combines columns from the
upper and lower data item.
When a record in the upper data item table has no matching record in the lower data item table, columns
coming from the lower data item table have null values.
The following illustration shows a LeftOuterJoin type between tables A and B. The shaded area indicates the
records that are included in the resulting dataset. In the sample query, the Salesperson/Purchaser table is
considered the left table.
Dataset Example
The following table shows the resulting dataset for a LeftOuterJoin between the Sales Header table and
Salesperson/Purchaser table in sample query.
SA L ESP ERSO N O RDER_N UM B ER SEL L _TO _C USTO M ER
The record for Bar t in the Salesperson/Purchaser table does not have a matching record in the Sales Header
table, so a row is included but the columns from the Sale Header table are given null values. The record for
New Concepts in the Sale Header table is not included in the resulting dataset because it does not have a
matching column in the Salesperson/Purchaser table.
SQL SELECT Statement for Left Outer Join
To specify a left outer join with an SQL statement, you use the LEFT OUTER JOIN condition.
The following example shows how to create a left outer join on the Salesperson/Purchaser and Sales
Header tables by using a SQL statement.
RightOuterJoin
A RightOuterJoin resembles the inner join except that the resulting dataset set contains every record from the
lower data item table, even if a record does not have a matching value in the upper data item for columns that
are linked by the DataItemLink Property.
For each record in the lower data item, a row is added in the dataset that combines columns from the
lower and upper data item tables.
When a record in the lower data item table has no matching record in the upper data item table, columns
coming from the upper data item table have null values.
The following illustration shows a RightOuterJoin type between tables A and B. The shaded area indicates the
records that are included in the resulting dataset.
Dataset Example
The following table shows the resulting dataset for a RightOuterJoin between the Salesperson/Purchaser
table and Sales Header table in the sample query. The Sales Header table is considered the right table.
The record for New Concepts in the Sales Header table does not have a matching record in the
Salesperson/Purchaser table, so a row is included but the columns from the Salesperson/Purchaser table
are given null values. The record for Bar t in the Salesperson/Purchaser table is not included in the resulting
dataset because it does not have a matching column in the Sales Header table.
SQL SELECT Statement for Right Outer Join
To specify a right outer join with an SQL statement, you use the RIGHT OUTER JOIN condition.
The following example shows how to create a right outer join on the Salesperson/Purchaser and Sales
Header tables by using a SQL statement.
FullOuterJoin
A FullOuterJoin contains all the records from the upper data item table, and all records from the lower data
item, including records that don't have a matching value for columns that are linked by the DataItemLink
Property.
Each pair of records from the data items that have matching column values are combined into a row in
the dataset.
Records from the upper data item table that do have a matching column are included in a row, where the
columns from lower data item table have null values.
Records from the lower data item table that do have a matching column are included in a row, where the
columns from upper data item table have null values.
The following illustration shows a FullOuterJoin type between tables A and B. The shaded area indicates the
records that are included in the resulting dataset.
Dataset Example
The following table shows the resulting dataset for a full outer join between the Sales Header table and
Salesperson/Purchaser table in sample query.
The records for Bar t in the Salesperson/Purchaser table and New Concepts in the Sales Header table are
included in a row, even though they not have matching values for columns.
SQL SELECT Statement for Full Outer Join
To specify a full outer join with an SQL statement, you use the FULL OUTER JOIN condition.
The following example shows how to create a full outer join on the Salesperson/Purchaser and Sales
Header tables by using a SQL statement.
CrossJoin
A CrossJoin contains rows that combine each row from the upper data item table with each row from a lower
data item table. Cross joins are also called Cartesian products. A cross join does not apply any comparisons
between columns of data items, so the DataItemLink Property is left blank.
Dataset Example
The following table shows the resulting dataset for a CrossJoin between the Sales Header table and
Salesperson/Purchaser table in sample query.
See Also
Query Object
Filtering Queries
Aggregating Data
Filtering in Query Objects
2/6/2023 • 8 minutes to read • Edit Online
You specify filters in a query to restrict the data in the resulting dataset. A filter applies conditions on fields in a
table that is associated with the query. For a record to be included in the resulting dataset, its values in these
fields must meet the conditions of the filter.
Overview
There are different ways to filter on fields of a query. You can set up filters on a field directly in the query object
or use the AL filter methods that are outlined in the following table.
Filter directly on a data item in query object You can set the DataItemTableFilter property of a data item
to filter on a field in the table of the data item. You can apply
the filter to any field in the table, not just fields that are
defined as columns in the resulting dataset. A data item filter
can't be overwritten from AL code.
Filter directly on a column in a query object You can set the ColumnFilter property of a column control
to filter on the source field of the column. A filter on a
column can be overwritten by the SETFILTER and SETRANGE
methods from AL code.
Add a filter row to a query object A filter row lets you add a filter on a field that will not be
included in the resulting dataset, but can be changed from
AL code. To set up a row filter add a filter control
referencing the field that you want to filter and then set its
ColumnFilter Property. A filter row is like a data item filter
except a filter on a filter row can be overwritten by the
SETFILTER and SETRANGE methods from AL code.
Use SETFILTER or SETRANGE method calls You can call the SETFILTER method method from AL code to
set a filter on a field that is exposed through a column or
filter row. The filter that is set by the SETFILTER method will
overwrite any filter that is applied to a column or filter row
on the same field by the ColumnFilter Property.
DataItemTableFilter = String;
elements
{
dataitem(C; Customer)
{
column(Customer_Number; "No.")
{
}
column(Customer_Name; Name)
{
}
column(Qty; Quantity)
{
}
}
}
}
}
ColumnFilter = String;
elements
{
dataitem(C; Customer)
{
column(Customer_Number; "No.")
{
}
column(Customer_Name; Name)
{
}
column(Qty; Quantity)
{
Method = Sum;
ColumnFilter = Qty = filter(< 50);
}
In an SQL SELECT statement, filters on a column or filter row that don't apply an aggregate method, as with the
Location_Code filter row in the example, would correspond to a WHERE clause. Filters on a columns or filter
rows that do apply a totals method, as with the Quantity column in the example, would correspond to a
HAVING clause. For more information, see Equivalent SQL SELECT Statements for Query Filters.
where:
Query is a variable of the Query type that specifies the query object.
Column is the name of the column or filter row as defined by its Name property.
String is the filter expression.
FromValue is the lower value of the range.
ToValue is the higher value of the range.
For more information about these methods and important behavior, see SETFILTER method and SETRANGE
method (Query).
Example
Referring to the query example in the previous sections, you can add the following code to the OnBeforeOpen
trigger of the query object to change the filters on the Quantity column and the Location\_Code filter row to
include quantities of in the range of 10 to 50 and a location code of RED.
trigger OnBeforeOpen()
begin
currQuery.SETRANGE(Qty, 10, 50);
currQuery.SETFILTER(Location_Code, '=RED');
end;
The following example shows the corresponding SQL SELECT statement for the previous column and filter row
example that links the Customer and Sales Line tables and filters on the Location Code field and the total sum
of the Quantity field.
SELECT Customer."No.", Customer.Name, SUM("Sales Line".Quantity) as Qty
FROM Customer LEFT OUTER JOIN "Sales Line"
ON Customer."No." = "Sales Line".Sell-to Customer No.
WHERE "Sales Line"."Location Code" = WHITE
GROUP BY Customer."No."
HAVING Qty 50
See Also
Query Object
Aggregating Data
SETFILTER method
SETRANGE method
Aggregating Data in Query Objects
2/6/2023 • 6 minutes to read • Edit Online
In a query object, you can use the Method property to do a calculation on the fields of a column and return the
calculated value in the dataset. For example, you can sum all the fields in a column or find the average value. The
Method property is set on column controls and can be set to any of the following aggregate methods.
column(Name; Field)
{
Method = Sum|Average|Min|Max|Count;
}
Setting an aggregate method on a column will automatically group the resultant data set by the other columns
in the query. Records that have matching values for the other columns are grouped together into a single row in
the results. The aggregate method is then applied against the group and a summary value returned in the row.
It's similar to the GROUP BY clause in SQL SELECT statements (see Creating Queries with Aggregates in SQL).
The aggregate methods and grouping are further explained in the following sections.
Sample Query
The following sample query object retrieves the number of line items in every sales order for each customer.
The query links the Customer table and the Sales Line table. In its current state, the Method property is
commented out so it doesn't implement any aggregate method.
elements
{
dataitem(C; Customer)
{
column(Customer_Number; "No.")
{
}
column(Customer_Name; Name)
{
}
column(Qty; Quantity)
{
// Change the value of the property to perform a different aggregate method on grouped
columns:
// Sum, Average, Max, Min, or Count
// Method = Sum|Average|Min|Max|Count;
}
}
}
}
}
The following table represents a simplified version of the resulting dataset for the sample query.
The following sections explain how you can modify the query to implement the different aggregate methods by
changing the value of the Method property.
Sum
The Sum method adds the values of all fields for the specified column within a group. To set up a Sum method
on the Quantity column of the sample query, set the Method property to Sum . The query is automatically
grouped by the No. and Name columns.
...
column(Qty; Quantity)
{
Method = Sum;
}
...
Looking at the sample query, you can use Sum method to get the total number of items in sales orders for each
customer. The following table illustrates the resulting dataset for the query.
Average
The Average method calculates the average value of the fields in the column within a group. To set up an
Average method on the Quantity column of the sample query, set the Method property to Average . The query
is automatically grouped by the No. and Name columns:
...
column(Qty; Quantity)
{
Method = Average;
}
...
Looking at the sample query, you can use Average method to get the average number of items in sales orders
for each customer. The following table illustrates the resulting dataset for the query.
Min
The Min method retrieves the lowest value of fields in the column within a group. To set up a Min method on
the Quantity column of the sample query, set the Method property to Min . The name of the Quantity column
automatically changes to Min_Quantity and the query is automatically grouped by the No. and Name
columns:
...
column(Qty; Quantity)
{
Method = Min;
}
...
Looking at the sample query, you can use Min method to get the least number of items in sales orders for each
customer. The following table illustrates the resulting dataset for the query.
Max
The Max method retrieves the highest value of fields in the column within a group. To set up a Max method on
the Quantity column of the sample query, set the Method property to Max . The name of the Quantity column
automatically changes to Max_Quantity and the query is automatically grouped by the No. and Name
columns:
...
column(Qty; Quantity)
{
Method = Max;
}
...
Looking at the sample query, you can use Max method to get the greatest number of items in sales orders for
each customer. The following table illustrates the resulting dataset for the query.
Count
The Count method returns the number of records from the data item table that comprise a group in the dataset.
Unlike the other aggregate methods, the Count method is not associated with a specific column. Records are
identified and counted based on the primary key of the data item table. Referring to the sample query, you can
use a Count method to get the number of open sales orders per customer.
To set up a Count method in the sample query, the column element definition cannot include a source table;
only a name. Therefore, you can delete the reference to the Quantity field in the column(Qty; Quantity)
element and set the Method property to Count :
...
column(Qty)
{
Method = Count;
}
Looking at the sample query, you can use Count method the number of sales orders for each customer. The
following table illustrates the resulting dataset for the query.
In SQL SELECT statements, the Count method corresponds to a COUNT(*) or COUNT(field) clause.
See Also
Method Property
Query Object
Filtering Queries
Aggregating Data
Aggregate Functions (Transact-SQL)
Retrieving Date Data in Queries
2/6/2023 • 4 minutes to read • Edit Online
When you have fields in a table that contain dates, you can use a date method to retrieve only the year, month,
or day instead of including the date in the resulting dataset of a query.
IMPORTANT
You can only use a date method on fields that have a Date or DateTime data type. For additional information about how
to use a date method on a field that has the DateTime data type, see Working with DateTime Data Types.
For more information about how to set up query columns and properties, see Query Object.
N O. B IL L - TO N A M E O RDER DAT E
NOTE
This is a simplified subset of the data that is found in table 36 Sales Header of the CRONUS International Ltd.
demonstration database.
Sample query
The following query object retrieves data from the sample Sales Header table. The query includes a totals
method that counts the total the number of records from the table included in the dataset.
query 50100 "Sample Data Query"
{
QueryType = Normal;
elements
{
dataitem(Sales_Header; "Sales Header")
{
column(Bill_to_Name; "Bill-to Name")
{
}
column(Count_)
{
Method = Count;
}
}
}
}
NOTE
A column that applies a date method is still part of the group unlike columns that apply an aggregate method.
Day method
The Day method retrieves the day from the date expression of a field value in the query column. The day is
returned as an integer, in the range of 1 to 31, which represents the day of the month. If the day in the date
expression is 0, then 1 is returned.
Example
The following table displays the resulting dataset for the sample query with the Method property of the
Order Date column set to Day .
Autohaus Meilberg KG 18 1
Autohaus Meilberg KG 21 1
Beef House 30 1
Month method
The Month method retrieves the month from the date expression of a field value in the query column. The
month is returned as an integer, in the range of 1 to 12, where 1 represents January and 12 represents
December. If the month in the date expression is 0, then 1 is returned.
Example
The following table displays the resulting dataset for the sample query with the Method property of the
Order Date column set to Month .
B IL L _TO _N A M E M O N T H _O RDER_DAT E C O UN T _
Autohaus Meilberg KG 1 1
Autohaus Meilberg KG 5 1
Beef House 9 1
Year method
The Year method gets the year from the date expression of a field value in the query column. The year is
returned as an integer. If the year in the date expression is 0, then 1900 is returned.
Example
The following table displays the resulting dataset for the sample query with the Method property of the
Order Date column set to Year
The differences in day, month, or year occur because when a date and time value is retrieved from the Business
Central database table, it is converted from the regional settings of the Business Central solution to the UTC date
and time. The day, month, or year is calculated on the SQL server, and then returned to the query dataset as an
integer, which does not consider the regional settings of the Business Central solution.
To avoid this condition, you should use the date method on fields that have a Date data type instead of a
DateTime data type whenever possible. You can also return the DateTime value and implement post processing
for the day, month, and year as needed.
See Also
Query Objects
Aggregating Data in Query Objects
Method Property
Using Queries Instead of Record Variables
2/6/2023 • 2 minutes to read • Edit Online
In scenarios where you want to read records from multiple tables, it can be a good idea to use a query instead of
implementing code with record variables. Using a query can improve performance and also simplify the AL
code that is required to perform the operation.
begin
count := 0;
if Item.FINDSET then
repeat
PrevDate := 0D;
TotalQty := 0;
ItemLedgerEntry.SETCURRENTKEY("Item No.", "Posting Date");
ItemLedgerEntry.SETRANGE("Item No.", Item."No.");
ItemLedgerEntry.SETRANGE("Entry Type",
ItemLedgerEntry."Entry Type"::Sale);
if ItemLedgerEntry.FINDSET then
repeat
if (ItemLedgerEntry."Posting Date" <> PrevDate) and (PrevDate <> 0D) then begin
OutputData(1, Item."No.", Item.Description, PrevDate, -TotalQty);
TotalQty := 0;
count := count + 1;
end;
PrevDate := ItemLedgerEntry."Posting Date";
TotalQty := TotalQty + ItemLedgerEntry.Quantity;
until (ItemLedgerEntry.NEXT = 0) or (count >= 4);
if PrevDate <> 0D then begin
OutputData(1, Item."No.", Item.Description, PrevDate, -TotalQty);
count := count + 1;
end;
until (Item.NEXT = 0) or (count >= 4);
end;
elements
{
// This dataitem corresponds to the `Item` record variable in the record variable example.
dataitem(Item; Item)
{
column(No_; "No.")
{
}
column(Description; Description)
{
}
// This dataitem corresponds to the `ItemLedgerEntry` record variable in the record variable
example.
dataitem(Item_Ledger_Entry; "Item Ledger Entry")
{
// The DataItemLink and SqlJoinType settings correspond to the
`ItemLedgerEntry.SETRANGE("Item No.",Item."No.");` statement in the record variable example.
DataItemLink = "Item No." = Item."No.";
SqlJoinType = InnerJoin;
Add the following code to a codeunit that will run the query.
var
ItemMovements: Query "Item Movements"
begin
ItemMovements.TopNumberOfRows(5);
ItemMovements.SetRange(Entry_Type,ItemMovements.Entry_Type::Sale);
ItemMovements.Open;
while ItemMovements.Read do
OutputData(2,
ItemMovements.Item_No,ItemMovements.Description,ItemMovements.Posting_Date,ItemMovements.Sum_Quantity);
end;
The ItemMovements.TOPNUMBEROFROWS(5); statement will include only the first 5 records in the resulting dataset
and corresponds to implementing the count variable in the record-based code example.
The OutputData method performs the same operations as the OutputData method in the record variable
example.
See Also
Query Object
Linking and Joining Data Items
Aggregating Data in Query Objects
Filtering Data in Query Objects
SETRANGE Method
OPEN Method
TOPNUMBEROFROWS Method
API Query Type
Developing Extensions
AL Development Environment
Accessing Columns of a Query Dataset
2/6/2023 • 2 minutes to read • Edit Online
If the query is in the reading state, you can retrieve the value of columns in the current active row of the dataset
by using the following syntax in AL.
Syntax
ColumnValue := QueryVariable.ColumnName
QueryVariable is a variable of the Query data type that specifies the query object.
ColumnName is the name of the column in the query object.
Return Value
The data type of the field that is used by the column, unless the column applies a totaling method as specified by
the Method Property. If the column applies a totaling method, then data type is an integer for the Count
method and a decimal for all other totaling methods.
Returns the value of the column in the current active row.
Remarks
A column of a row can only be accessed after the query has been opened by using a call to the Open Method
followed by a call to the Read Method. The current active row is the row that has been included in the query
variable after the last call to Read Method.
Example
This example demonstrates how to access a column of a query dataset. When the query is run, each row in the
dataset is read and message box is displayed that contains the value of a column in the row.
The following query object links table 18 Customer and table 37 Sales Line .
query 50123 "Customer_Sales_Quantity"
{
QueryType = Normal;
// Sets the results to only include the top forts the results in descending order
TopNumberOfRows = 5;
OrderBy = descending(Qty);
elements
{
dataitem(C; Customer)
{
column(Customer_Number; "No.")
{
}
column(Customer_Name; Name)
{
}
column(Qty; Quantity)
{
}
}
}
}
}
The following codeunit opens the query, reads each row of dataset, and then displays a message that has the
content of each row.
end;
var
MyQuery: Query "Customer_Sales_Quantity";
See Also
Query Object
Filtering Queries
Aggregating Data
Transferring Data Between Tables using
DataTransfer
2/6/2023 • 5 minutes to read • Edit Online
APPLIES TO: Business Central 2022 release wave 2 (version 21.0) and later.
DataTransfer is an AL data type that supports the bulk transferring of data between SQL based tables. Instead of
operating on a row-by-row model, like the record API does, DataTransfer produces SQL code that operates on
sets. This behavior improves the performance when moving data during upgrade.
For comparison, the following code illustrates how to copy rows using the record API:
Design guideline
DataTransfer uses a builder design pattern that, in general, requires that you complete the following steps:
1. Specify the source and destination tables by calling the SetTables.
2. Specify which fields to transfer or constant values by calling the AddFieldValue. Or you can set a constant
value for fields in the destination using AddConstantValue, respectively.
3. Define the relationship between the source and destination tables by calling AddJoin. In most cases, this
method is required for copying fields.
4. Add constraints on the data to transfer by calling AddSourceFilter.
5. Invoke the query for transferring data by calling CopyFields or CopyRows.
Because DataTransfer operates in bulk and not on a row-by-row basis, row based events or triggers won't be
executed. For example, when calling CopyFields, none of the following events will be called: OnBeforeModify,
OnModify, or OnAfterModify. Or, when calling CopyRows, none of the following events will be called:
OnBeforeInsert, OnInsert, or OnAfterInsert.
Copy fields
Calling CopyFields on the DataTransfer object will copy selected fields from one table (the source) to another
table (the destination). Unless you're copying with the same source and destination table, specifying a join
condition is necessary. The join condition specifies how to match rows from the source with rows from the
destination table.
Example 1
A typical scenario is obsoleting a field and moving its data into another table. For example, suppose you have
two tables, Source and Destination , as illustrated with sample data below. You're planning on obsoleting field
S3 in the Source table. But before you do, you want to copy some values of S3 into the field D3 of the
Destination table. Specifically, you only want to copy field S3 in rows where field S2 is equal to A.
1 A A 42 1 A A 99 1 A A 42
2 B A 43 2 B A 2 B A 43
3 C B 44 4 C B 4 C B
4 D B 45
Performance
The same scenario could also be coded using the record API, by first looping over all rows in the Source table
with a filter on field S2 , then for each match, calling Get on the destination record, setting the fields, and calling
Modify.
The record-based solution executes three SQL operations per-row, while the DataTransfer does a maximum of
two SQL queries altogether. Measurements for DataTransfer and record API solutions have shown an ~200x
performance improvement for DataTransfer. Gains are even greater if the destination table has modify triggers
or if the environment has significant latency to SQL.
Uniqueness in the source table
The join condition can be specified on arbitrary fields, which leaves the possibility that the set of fields doesn't
produce a unique set of rows on that set of fields. This situation would lead to a many-to-many relation between
the tables. A many-to-many relation would require the runtime to know which row to select—which at best
would be selected at random. Instead, the upgrade runtime will detect this situation and throw an error. The
following table illustrates an example where joining the fields S1 and S2 doesn't produce a unique set of rows,
and would therefore lead to a runtime error.
PK S1 S2 S3
1 A A 42
2 A A 43
3 C B 44
4 D B 45
Copy rows
Calling CopyRows on the DataTransfer object inserts a row in the destination table for each matching row in the
source table. Fields in the inserted row are populated with values specified by calling AddFieldValue or
AddConstantField. Fields not specified by AddFieldValue or AddConstantField are populated with the field's
InitValue or the field's default value.
If the code tries to copy a row from the source table that has the same primary key as an existing row in the
destination table, a runtime error will be thrown.
Example 2
To help explain CopyRows, consider an example using sample tables Source and Destination again.
PK S1 S2 S3 PK D1 D2 D3 PK D1 D2 D3
2 B A 43 1 A A 99 1 A A 99
3 C A 44 2 X 43
4 D B 45 3 X 44
In this code example, you copy the PK and S3 fields for all rows where S2 equals A and add them as new rows
in the Destination table. You use AddConstantValue method to give the field D2 the value X in the inserted
rows.
Performance
As with CopyFields, CopyRows is a bulk operation. It provides performant execution by doing only a single SQL
statement for the entire operation, instead of doing multiple per-row operations. Measurements have shown an
~50x performance improvement with a DataTransfer solution compared with a record API solution.
See Also
Upgrading Extensions
XMLport Overview
2/6/2023 • 2 minutes to read • Edit Online
XMLport object
You create an XMLport object in the AL Language development environment to define the schema of an XML
document. You can export and import data between an external source and Dynamics 365 Business Central with
XMLports. For more information, see XMLport Object.
XMLport schema
In order to define the underlying structure of the imported or exported document, you use the XMLport schema.
An XMLport schema determines which data is exported from or imported to Dynamics 365 Business Central
database tables and the format and structure of the files used. You build the XMLport schema by adding nodes.
For more information, see Defining a XMLport Schema.
Request page
Request pages are dialog boxes that enable the user to set a filter on the data, sort the data, or choose whether
to export or import the data. For more information, see Request Pages.
Unlike report request pages, XMLport request pages cannot be bookmarked by users from the user interface.
See Also
XMLport Object
Defining a XMLport Schema
Using Namespaces with XMLports
Request Pages
XMLport Data Type
XMLport Triggers
XMLport Object
2/6/2023 • 2 minutes to read • Edit Online
XMLports are used to export and import data between an external source and Dynamics 365 Business Central.
Sharing data between different computer systems is seamless when it is shared in an XML format. Working with
XML files can be tedious so the details of how the XML file is handled are encapsulated in XMLports.
To use an XMLport to import or export data, you first create an XMLport object. Once created, you can run the
XMLport from a page or codeunit object.
You can design XMLports to include a request page, which is a dialog box that enables the user to set a filter on
the data, sort the data, or choose whether to export or import the data. For more information about request
pages, see Request Pages.
XMLport example
The following example shows a page extension of the Permission Sets page that adds an action to the
specified page calling the XMLport Expor tPermissionSet . The XMLport exports the permission set data to an
XML file.
schema
{
textelement(PermissionSets)
{
tableElement(PSet; "Aggregate Permission Set")
{
SourceTableView = WHERE ("App Name" = FILTER (<> ''));
XmlName = 'PermissionSet';
fieldattribute(RoleID; pset."Role ID") { }
fieldattribute(RoleName; pset.Name) { }
tableelement(P; "Tenant Permission")
{
XmlName = 'Permission';
LinkTable = pset;
LinkFields = "Role ID" = FIELD ("Role ID");
textelement(ObjectType)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Object Type";
ObjectType := format(int);
end;
}
textelement(ObjectID)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Object ID";
ObjectID := format(int);
end;
}
textelement(ReadPermission)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Read Permission";
ReadPermission := format(int);
end;
}
textelement(InsertPermission)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Insert Permission";
InsertPermission := format(int);
end;
}
textelement(ModifyPermission)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Modify Permission";
ModifyPermission := format(int);
end;
}
textelement(DeletePermission)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Delete Permission";
DeletePermission := format(int);
end;
}
textelement(ExecutePermission)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Execute Permission";
ExecutePermission := format(int);
end;
end;
}
textelement(SecurityFilter)
{
trigger onbeforePassvariable();
begin
SecurityFilter := format(p."Security Filter");
end;
}
}
}
}
}
}
See Also
Developing Extensions
AL Development Environment
XMLport Overview
Using Namespaces with XMLports
Page Extension Object
Report Object
Defining an XMLport schema
2/6/2023 • 2 minutes to read • Edit Online
You use an XMLport object to export and import data between an external source and Dynamics 365 Business
Central. The schema determines which and how data is extracted from or inserted into the Dynamics 365
Business Central database tables through an XMLport. For more information, see XMLport Object.
You build the XMLport schema from nodes. A node can be:
A text element
A text attribute
A table element
A field element
A field attribute
You nest nodes inside other nodes in order to define the structure of the XMLport schema. Use the following
keywords to define the structure.
K EY W O RD DESC RIP T IO N
NOTE
There can only be one <root> node, which must be an element. If the Format Property is set to Xml, it must be a
textelement node.
There can be several attributes for a single element and their order does not matter. Attribute nodes must be
specified inside the element nodes they refer to and before other element nodes. They cannot have nested
element nodes.
Snippet support
Typing the shortcut txmlport will create the basic layout for an XMLport object when using the AL Language
extension in Visual Studio Code.
Example
The following example adds the Customer table as a table element, the Address field as a field element and the
County and City fields as field attributes.
schema
{
textelement(Customers)
{
tableelement(Customer; Customer)
{
fieldelement(Address; Customer.Address)
{
fieldattribute(County; Customer.County){}
fieldattribute(City; Customer.City){}
}
}
}
}
See Also
XMLport Object
XMLport Data Type
Using Namespaces with XMLports
XMLport Triggers Request Pages
XMLport Overview
Using Namespaces with XMLports
2/6/2023 • 2 minutes to read • Edit Online
The external system that provides or consumes AL Language development environment data as XML might
require that the XML documents include namespaces. Namespaces are used to avoid element name conflicts. In
these cases, you must add namespaces on the XMLport to make it compatible with the XML schema that is used
by the external system.
NOTE
Namespace-related properties are only available when the Format Property is set to Xml.
For example, the following code is a portion of a simple XML document for transferring sales order information.
The XML includes namespaces for mapping fields from the Sales Header table.
A namespace that does not include a prefix declares the default namespace. In the example, the default
namespace is urn:bc:schema:all. The default prefix is applied to all the elements that do not include a
prefix.
You declare the namespaces used in the XMLport using the Namespaces Property. For each namespace, you
specify a prefix and a namespace name. You can declare a default namespace by defining an empty prefix "" . In
the XML documents exported or imported by the XMLport, the namespaces declarations are only supported in
the <root> element.
You then apply the namespaces to XMLport elements by setting the NamespacePrefix Property of the element
to one of the namespace prefixes declared in the Namespaces Property. This property only applies to
textelement , tableelement and fieldelement nodes, otherwise it will be ignored.
You can also specify a default namespace using the DefaultNamespace Property and setting the
UseDefaultNamespace Property to true . Note that there can only be one default namespace, so if you specify
the default namespace in the Namespaces Property, you must set the DefaultNamespace Property to false .
See Also
XMLport Object
Namespaces Property
NamespacePrefix Property
DefaultNamespace Property
UseDefaultNamespace Property
Request Pages
2/6/2023 • 4 minutes to read • Edit Online
A request page is a page that is run before the report or XMLport starts to execute. Request pages enable end
users to specify options and filters for a report and an XMLport. Request pages are defined as part of designing
a Report object, a Report Extension Object, or an XMLport object. The syntax is shown further down in this
article. You design the filters on request pages by using the following report and XMLport properties:
RequestFilterHeading Property Sets a caption for the request page tab that is related to a
report's data item or an XMLport's table element.
NOTE
Request pages for XMLports are not supported by the Business Central Web client in versions prior to Dynamics 365
Business Central 2019 release wave 2. If you try to run an XMLport with a Request page from the web client in these
versions, you receive an error that the XMLport page type is not supported. Alternatively, XMLport request pages do
work in the Dynamics NAV Client connected to Business Central.
By default, a request page is displayed, unless the UseRequestPage is set to false ; then the report or XMLport
will start to print as soon as it's run. In this case, end users can't cancel the report or XMLport run. It's still
possible to cancel the report or XMLport, but some pages may print.
By default, without having set anything else, a request page will always display the following buttons:
Send to
Print
Preview
Cancel
Additionally, you can add more options on the request page to allow the end user to filter the data displayed.
NOTE
Only on the Windows client, filtering is possible even if RequestFilterFields is not set.
Defining the RequestFilterFields property in the dataitem() part of the report code is done as illustrated in
the following code example:
NOTE
It is recommended to add columns that the end-users of the report will frequently set filters on.
For more information about the report object, see Report Object.
Defining the RequestFilterFields property in the tableelement() part of an XMLport is done in a similar way:
For more information about the XMLport object, see XMLport Object.
By default, for every data item in the report and table element in a XMLport, a FastTab for defining filters and
sorting is created on the request page. To remove a FastTab from a request page, don't define any
RequestFilterFields for the data item or table element and set the DataItemTableView property in a report or
the SourceTableView property in an XMLport to define sorting. The request page is displayed, but there's no tab
for this data item or table element.
If a DataItemTableView or SourceTableView isn't defined, then end-users can select a sort column and sort order
at runtime.
In a complex report or XMLport that uses data from several tables, the functionality may depend on a specific
key and sort order. Design your reports and XMLports so that end-users can't change the sort order in a way
that affects their functionality.
For data items and table elements whose source table contains calculated fields, such as amounts and quantities,
the Filter totals by: section is automatically included on the request page, which allows you to adjust various
dimensions that influence calculations.
TIP
For information about how to enter filter criteria on the request page, see Filtering in the Business Central application
help.
NOTE
You can use the SaveValues property together with the AllowScheduling property to set up the request page to
support multiple previews. When both properties are true , users can preview the report from the request page as
many times as the like, without having the request page close. This capability lets users change filters, see what the
generated report will look like, and then try again. If either property is set to false , the report won't support multiple
previews and the request page closes once the user previews the report. In this case, the request page includes a
Preview and Close button instead of Preview .
...
requestpage
{
SaveValues = true;
layout
{
area(content)
{
group(Options)
{
Caption = 'Options';
field(PostingDate; PostingDateReq)
{
ApplicationArea = Basic, Suite;
Caption = 'Posting Date';
ToolTip = 'Specifies the posting date for the invoice(s) that the batch job creates.
This field must be filled in.';
}
}
}
}
trigger OnOpenPage()
begin
if PostingDateReq = 0D then
PostingDateReq := WorkDate;
end;
var
PostingDateReq: Date;
}
...
See Also
Report Object
Report Extension Object
XMLport Object
Reports Overview
Report Design Overview
RunRequestPage Method
RequestFilterHeading Property
RequestFilterHeadingML Property
RequestFilterFields Property
DataItemTableView
Customizing the User Interface for User Roles
2/6/2023 • 2 minutes to read • Edit Online
The strength of Business Central is its role-tailored experience that helps users focus on the work that is
important to them. Business Central offers several features for developers, application administrators, and end-
users, that can be used to customize the the pages that users work with in the client. These features customize
the pages on different layers, as illustrated in the following figure. Some customization is done in AL extensions,
while others can be done from the client.
Role Centers
The Role Center is first layer of customization. The Role Center is the user's entry point and home page for
Business Central, displaying information that is pertinent to the user's role in the company and enabling them to
easily navigate to relevant pages for viewing data and performing tasks. You can develop several different Role
Centers, where each Role Center is customized to the profile of the intended users.
A Role Center is created in AL by the rolecenter page type.
For more information, see Designing Role Centers.
Personalization
The last layer of customization is personalization. This is done strictly in the client by end-users for customizing
their own workspaces. The changes that users make take precedent over page customizations made on the
profile. The changes will only be seen by the user; not other users. For more information, see Personalizing Your
Workspace in the Business Central Application Help.
See Also
Developing Extensions
AL Development Environment
Page Object
Page Extension Object
Page Extension Properties
Inspecting and Troubleshooting Pages
2/6/2023 • 6 minutes to read • Edit Online
The Business Central Web client includes a page inspection feature that lets you get details about a page. Page
inspection provides insight into the page design, the different elements that form the page, and the source
behind the data it displays. Page inspection helps you:
Learn the data model behind a page.
Discover pages and parts that can be reused in your application design.
Troubleshoot data issues without having to do tasks like copying the production database, viewing the entire
source table, or digging into SQL.
Debug the application, complementing Designer.
When the Page Inspection pane first opens, it shows information that pertains to the main page object.
Use the keyboard or pointing device to move focus to different elements on the page. When you select a FactBox
or a part on the main page, a border will highlight the area. The Page Inspection pane then shows information
about the selected element. For example, the previous figure shows information about the list part in the Sales
Order page.
As you navigate to other pages in the application, the Page Inspection pane will automatically update with
page information as you move along.
What Page Inspection Shows
The page inspection pane shows the information for the main page or page part, including:
The page's source table (if any) and fields.
Extensions that affect the page.
Current filters applied to the page.
The following sections describe details about what is shown.
NOTE
If you do not see all details described below, you might not have the required permissions. For more information, see
Controlling Access to Page Inspection Details.
TIP
To copy the values of a field or entity under one of the tabs to the clip board, select the field or entity and press Ctrl+C.
Page
Table
Table Fields
Extensions
Page Filters
The Page field shows information about the main page or a selected (highlighted) subpage in a part. The field
shows the following information:
The name, as specified by its Name property
The ID as specified by the ID property.
The type, as specified by the PageType property.
Elements shown with limited information
Role Center pages
If a page has the type Role Center, the Table field doesn't appear. Because the Role Center consists of
several parts, there's no more information shown. To see more details, select the different parts that make
up the Role Center.
Report request pages and previews
If you open a report request page or preview for inspection, the only information shown in the Page
Inspection pane is the report's name and ID.
TIP
From the Business Central client, you can export report results as raw data to a Microsoft Excel file. The file
contains all columns of the dataset, but without the layout applied. Use the file to help validate that the report
returns the expected data, and to ensure that the report layout controls match the dataset value types. To export
a report, run the report and select the Send to > Microsoft Excel Document (data only) on the request
page. For more information, see Working with Reports - Send to Excel.
The strength of Dynamics 365 is its role-tailored experience that helps users focus on the work that is important
to them. The Role Center is an integral part of the role-tailored experience. And as a developer, role-tailoring
should be the foundation for your Role Center design.
2 Navigation bar The second-level navigation You should use these items
displays a flat list of links to to link to users' most useful
other pages. The pages entity lists in their business
targeted by the links will process. For example, with a
open in the content area of business manager, these
the Role Center. could be links to customers,
sales orders, and bank
You define this area with an accounts. You should place
area(embedding) control items in the order that
in the page code. reflects the business
process sequence. Try to
limit the number of second-
level items, and consider
placing items in the top-
level navigation instead, if
the number gets too large.
3 Action bar The actions bar provides The action area is designed
links to pages, reports, and for running the most
codeunits. The links can be important or most often
displayed on the root-level used tasks and operations
or grouped in a submenu. required by users. Actions
The objects targeted by will typically target card
these links will open in a type pages that enable
separate window in front of users to create new entities.
the Role Center page. Such as customers, invoices,
and sales orders, or run
You can define the actions reports. Place the most
by using the three different important action at the
area() controls that are root-level, and group
described in the next closely related actions in a
section. submenu.
Content area
The content area consists of one or more parts that display content from other pages. Unlike the navigation and
actions area that is defined in the Role Center page code, the content area consists of self-contained,
independent page part objects that can be used across Role Centers and in other pages. You define the content
area by adding a layout control in the page code, and then a part control for each individual part to display.
The following table describes some of the most common parts for Role Centers, as illustrated in the previous
figure.
N O. EL EM EN T DESC RIP T IO N M O RE IN F O RM AT IO N
Performance considerations
Role Centers that have many parts that process data from different sources can degrade performance. To
improve responsiveness and the time it takes to sign in to the Role Center, Business Central 2021 release wave 1
(and later) optimizes the sequence in which content is loaded. The sequence is as follows:
1. Content directly on the Role Center page object is loaded first, and users can immediately interact with it.
Examples of such content are the navigation menu and actions.
2. Parts are loaded one by one from top to bottom.
Parts on which the Visible property evaluates to false won't be loaded.
3. Parts that aren't in view are loaded when the user scrolls to display them.
Here are some practical tips to help you make the most of this optimization:
Consider hiding any parts that represent secondary content that only some users in that role will need. For
more information, see Choosing the visibility of parts.
For parts that require heavy processing, consider applying page background tasks. For more information, see
Using page background tasks.
IMPORTANT
Even if you've assigned a role to the user, you can experience a permission issue with an error "You don't have permission
to use the Role Center role center name". To resolve it, make sure the user has all the required permissions and permission
sets. For example, a user has the specific PAGE or TABLE added in the permission set to view it. For more information, see
Assign Permissions to Users and Groups
See Also
AL Development Environment
Page Types and Layouts
Page Extension Object
Actions Overview
Adding Pages and Reports to Tell Me
Personalizing Your Workspace
Using Designer
Simple Role Center Code Example
2/6/2023 • 2 minutes to read • Edit Online
The AL code in this article creates a simple Role Center customized for users assigned to a new profile.
For a more detailed explanation of Role Centers, see Designing Role Centers.
This example uses the RoleCenterHeadline page code example to display the headline and the
SalesInvoiceCuePage page and the following code example for the Cue and Action tile.
layout
{
area(RoleCenter)
{
group(Group1)
{
part(Part1; RoleCenterHeadline)
{
ApplicationArea = All;
}
part(Part2; SalesInvoiceCuePage)
{
Caption = 'Invoices';
}
}
}
}
actions
{
area(Sections)
{
group(PostedInvoices)
{
Caption = 'Posted Invoices';
Caption = 'Posted Invoices';
Image = RegisteredDocs;
action(PostedServiceInvoices)
{
Caption = 'Posted Service Invoices';
RunObject = Page "Posted Service Invoices";
ApplicationArea = All;
}
action(PostedSalesInvoices)
{
Caption = 'Posted Sales Invoices';
RunObject = Page "Posted Sales Invoices";
ApplicationArea = All;
}
group(SalesDocuments)
{
Caption = 'Sales Documents';
action("Sales Document Entity")
{
ApplicationArea = All;
RunObject = page "Sales Document Entity";
}
action("Sales Document Line Entity")
{
ApplicationArea = All;
RunObject = page "Sales Document Line Entity";
}
}
}
}
area(Embedding)
{
action(Sales)
{
Caption = 'Sales lists';
RunObject = Page "Sales list";
ApplicationArea = All;
}
action(Services)
{
Caption = 'Service lists';
RunObject = Page "Service list";
ApplicationArea = All;
area(Processing)
{
action(SeeSalesInvoices)
{
Caption = 'See Sales Invoices';
RunObject = Page "Posted Sales Invoices";
}
area(Creation)
{
action(AddSalesInvoice)
{
Caption = 'Add Sales Invoice';
Image = NewInvoice;
Image = NewInvoice;
RunObject = Page "Sales Invoice";
RunPageMode = Create;
}
}
area(Reporting)
{
action(SalesInvoicesReport)
{
Caption = 'Sales Invoices Report';
Image = "Report";
RunObject = Report "Sales - Invoice";
}
}
}
}
See Also
AL Development Environment
Page Extension Object
Actions Overview
Adding Pages and Reports to Tell Me
Personalizing Your Workspace
Using Designer
Adding Menus to the Navigation and Actions Area
2/6/2023 • 4 minutes to read • Edit Online
The navigation area appears at the top of the Dynamics 365 Business Central window, and contains multiple
sections that enable users to quickly navigate and perform actions in Dynamics 365 Business Central. In the
client, the navigation area is separated into three separate areas: navigation menu, navigation area, and actions
area. For an illustration that identifies the different areas in a Role Center, see Designing Role Centers. In AL,
these areas are defined by the area() control, as described in the sections that follow.
NOTE
The submenu items can include page extensions and other objects like reports, XMLPorts, and codeunits. The Dynamics
NAV Client connected to Business Central doesn't support submenus in the navigation menu.
You define the navigation menu by using an area(Sections) control in the page code.
Example
The example below adds the root menu item called My Customers to the navigation menu of the Sales Order
Processor Role Center. The My Customers menu item contains two actions, the Customer Bank Account List and
Customer Ledger Entries actions, which open corresponding page objects. The My Customers menu item also
includes a group that contains two other actions, which open sales-related documents.
pageextension 50120 ExtendNavigationArea extends "Order Processor Role Center"
{
actions
{
addlast(Sections)
{
group("My Customers")
{
action("Customer Bank Account List")
{
RunObject = page "Customer Bank Account List";
ApplicationArea = All;
}
action("Customer Ledger Entries")
{
RunObject = page "Customer Ledger Entries";
ApplicationArea = All;
}
// Creates a sub-menu
group("Sales Documents")
{
action("Sales Document Entity")
{
ApplicationArea = All;
RunObject = page "Sales Document Entity";
}
action("Sales Document Line Entity")
{
ApplicationArea = All;
RunObject = page "Sales Document Line Entity";
}
}
}
}
}
}
You can also enable pages and reports to appear in the Dynamics 365 Business Central search for a quick
navigational support. For more information, see Adding Pages and Reports to Tell Me.
Adding to actions
The actions area displays the most important or most often used tasks and operations required by users. It
contains links to pages, reports, and codeunits. The links are placed on the root-level, and they can be grouped
in a submenu.
You can define the actions by using three different area() controls.
The first action area that appears at the top of the Role Center page is area(Creation) . The following example
adds the item last, and it allows opening the Sales Journal page.
Example
...
addlast(Creation)
{
action("Sales Journal")
{
ApplicationArea = All;
RunObject = page "Sales Journal";
}
}
The actions in the area(Processing) control appears after the area(Creation) items. The example below shows
how you can use the group control to organize similar actions under a common parent. The created group is
placed at the end of this action area, and it targets pages needed for processing sales documents.
Example
...
addlast(Processing)
{
group(Documents)
{
action("Sales Document Entity")
{
ApplicationArea = All;
RunObject = page "Sales Document Entity";
}
action("Sales Document Line Entity")
{
ApplicationArea = All;
RunObject = page "Sales Document Line Entity";
}
}
}
The actions in the area(Reporting) control will appear last in the action area and they display with a default
report icon. This control's purpose is to target report objects and the following example opens the
Customer Sales Statistics report.
Example
...
addlast(Reporting)
{
action("Customer Statistics")
{
ApplicationArea = All;
RunObject = report "Customer Sales Statistics";
}
}
See Also
AL Development Environment
Page Extension Object
Actions Overview
Adding Pages and Reports to Tell Me
Get Users Started with the Checklist
2/6/2023 • 6 minutes to read • Edit Online
When the user hits Get star ted on their Home page, a checklist is revealed inside the banner. The checklist
provides users with an overview of their onboarding activities, while allowing them to learn and explore at their
own pace. The checklist serves as a platform for surfacing page tours, guiding users in the product interface, and
teaching users how to use the app in context. The checklist provides a sense of progression, nudging users to
complete onboarding activities. Users can navigate between the tasks of the checklist at their own pace.
Checklist tasks can point to pages or objects in Business Central or point to external URLs. Read more about the
checklist content in the Prerequisites for creating checklist items section.
As the user progresses through the checklist by either completing or skipping the steps, the banner title and
status indication will change accordingly to nudge and encourage users to finish. At any point, the user can
minimize the banner by hitting X and resume when ready. The following illustration shows the checklist with the
suggested setup and learning material.
The checklist provides an overview of the tasks to complete as well as a detailed description of the ongoing task.
The following illustration shows a Business Central Home page with a collapsed banner, which indicates the
completion progress as well as providing a clear call-to-action to resume with the checklist activities.
NOTE
The checklist has different purposes in evaluation and non-evaluation companies. Consider this when you add content to
the checklist. For more information, see Onboard New Users with the Welcome Banner].
ID NAME P URP O SE
The spotlight tour suppresses teaching tips on the page and immediately calls out Teams and Excel
integration features as shown in the following illustration.
Video
Records of type Video enables the user to watch a video provided by a custom URL. The video will play
in a window inside Business Central. Consider how you can utilize video to explain a feature or capability.
Video is normally used in a sales/evaluation scenario but could also be used for training purposes in an
onboarding case. The following illustration shows a video player that is started from the checklist.
Application Feature
Records of type Application Feature enables a checklist task to open any page inside Business Central.
Similar to Manual Setup this opens a page and will display a page tour if any is defined.
Checklist items can be based on records in the Guided Experience Item table, which means that before you
surface a task on the checklist, you must first add it to Guided Experience Item .
To insert a record in the Guided Experience Item table use the façade functions in the Guided Experience
codeunit:
InsertManualSetup
InsertAssistedSetup
InsertLearnLink
InsertTour
InsertSpotlightTour
InsertVideo
InsertApplicationFeature
For example, let's say that you have the page My ISV Solution Setup where the user can configure your app.
You want to invite the business manager to access this page from the checklist. In this example, you must insert
a new record in the Guided Experience Item table with the type Manual Setup and provide the metadata as
data (title, descriptions, and so on) as described below.
After having created this record, it can now be referenced from and inserted into a checklist.
Best practices for checklist content creation
Do:
Keep the list short (preferably 6 items or less) to avoid a scrollbar and to ensure a successful start for
users.
Keep checklist titles and descriptions short and to the point.
When writing the description, it's good practice to include the benefit of doing the task. But be brief.
TIP
If the task points to a page that comes from the manual setup list, the Shor tTitleChecklist is picked from there. Those
titles consist of nouns such as User permissions .
If the task points to wizards that comes from the assisted setup list, the LongerTitleCard is picked from there. Those
titles usually contain a verb such as Update users .
Don't:
Don't overwhelm the user with a long list of checklist tasks
Don't use too long titles as they're harder to understand and space becomes an issue.
Maximum character UX guideline
Checklist: Shor tTitleChecklist : Max 34 characters before truncation.
Checklist: LongerTitleCard : Max 53 characters before truncation.
Checklist: CardDescription: Max 180 characters before truncation
Client truncation limits
Checklist: Shor tTitleChecklist : Max 34 characters before truncation.
Checklist: LongerTitleCard : Max 53 characters before truncation.
Checklist: CardDescription: A scrollbar appears if the description renders as more than 4 lines.
Auto completion settings and time estimates
Add support for auto-completion when possible, such as for wizards, as this automatically makes the
checklist move to the next task and provides the user with a good sense of progress.
Provide a realistic time stamp of the estimated completion time and strive for tasks that take less than 5
minutes to complete.
See also
Teaching tips and in-app tours for onboarding users
Onboarding experiences in Business Central
Creating a Role Center Headline
2/6/2023 • 5 minutes to read • Edit Online
You can set up a Role Center to display a series of headline texts that appear one by one for a predefined period
of time.
The headlines can provide users with up-to-date information and insight into the business and daily work.
Typical categories of headlines might include:
My performance
My workday
Organizational health
Productivity tips
Cross-tenant insights (performance relative to peers)
Getting started information
IMPORTANT
Headlines will only appear in the Web client; they will not be shown on other client types.
NOTE
Headlines can display numbers and letters only. For example, headlines cannot display images.
Design concept
In development
In short, the Headline is basically a page that contains one or more fields. The page must be the HeadlinePar t
type page. Each field defines an individual headline to be displayed. The source for a field can be an expression
or a field in an underlying table.
The HeadlinePar t page is designed for Role Centers, that is, pages that have the type RoleCenter . If you
use a HeadlinePar t page on another page type, the part will not render in the client.
Using the OnDrillDown trigger, headlines can be made interactive, meaning that users can select the
headline to dig deeper into numbers or values that are shown in the headline or link to another page or
URL.
You can dynamically toggle visibility of a specific headline, for example based on its relevancy, by setting
the Visible property on the field.
There are only a few field properties that apply to fields that are used on a HeadlinePar t type page,
including Expression, Visible, ApplicationArea, Drilldown, and DrillDownPageID. All other properties are
ignored.
In the client
The Role Center will start by displaying the first visible headline that is defined on the HeadlinePart page. The
headline will appear for 5 seconds, then the next headline will appear for 5 seconds, and so on. When all the
headlines have been displayed, it will cycle back to the first headline, and continue from there.
If a headline is interactive, users can select the headline to open the target defined in the headline.
Users can pause on a headline by pointing to it.
Users can manually switch among headlines by selecting a corresponding dot that is displayed under the
headlines.
Users can personalize their Role Center to show or hide the Headline part as they like.
layout
{
area(content)
{
field(Headline1; hdl1Txt)
{
}
field(Headline2; hdl2Txt)
{
}
field(Headline3; hdl3Txt)
{
}
field(Headline4; hdl4Txt)
{
}
}
}
var
hdl1Txt: Label 'This is headline 1';
hdl2Txt: Label 'This is headline 2';
hdl3Txt: Label 'This is headline 3';
hdl4Txt: Label 'This is headline 4';
}
4. You can now add the HeadlinePar t page to the RoleCenter page.
TA G DESC RIP T IO N
<qualifier></qualifier> Specifies the title that appears above the headline. If you
omit this tag, the text HEADLINE will be used by default.
The Expression property must evaluate to the correct syntax. For example, looking back at the previous
example, the label hdl1Txt could be:
field(Headline1; hdl1Txt)
{
trigger OnDrillDown()
var
DrillDownURLTxt: Label 'https://go.microsoft.com/fwlink/?linkid=867580', Locked = True;
begin
Hyperlink(DrillDownURLTxt)
end;
}
{
field(Headline1; hdl1Txt)
{
}
field(Headline2; hdl2Txt)
{
}
field(Headline3; hdl3Txt)
{
Visible=false;
}
field(Headline4; hdl4Txt)
{
}
}
By adding fields under Group controls, you can hide or show more than one headline by setting the Visible
property on the Group control. For example, the following code hides headings Headline3 and Headline4 :
group(Group1)
{
field(Headline1; hdl1Txt)
{
}
field(Headline2; hdl2Txt)
{
}
}
group(Group2)
{
Visible=false;
field(Headline3; hdl3Txt)
{
}
field(Headline4; hdl4Txt)
{
}
}
IMPORTANT
Unlike other page types, the group control has no effect on the UI on pages of type HeadlinePar t . Its primary purpose
is to enable developers to group headlines for controlling visibility.
Dynamic visibility
With dynamic visibility, you can show or hide a headline based on a condition that evaluates to true or false .
To dynamically show or hide a headline when the HeadlinePar t page opens, the headline field must be
in group control, and you set the Visible property on the group control to the Boolean variable that
determines the visibility. For example, you could add code on the page's OnAfterGetRecord trigger that
evaluates the relevance of displaying Headline3 and results in a Boolean variable being set to true or
false .
To dynamically show or hide a headline while a page is open, you set the Visible property on the field
control to the Boolean variable that determines the visibility.
group(Group1)
{
field(Headline1; hdl1Txt)
{
}
field(Headline2; hdl2Txt)
{
}
}
group(Group2)
{
// Determines visibility when the page opens
Visible=ShowHeadline3;
field(Headline3; hdl3Txt)
{
// Determines visibility while the page is open
Visible=ShowHeadline3;
}
field(Headline4; hdl4Txt)
{
}
}
See Also
Pages Overview
Page Object
Creating Cues and Action Tiles on Role Centers
2/6/2023 • 6 minutes to read • Edit Online
This article provides an overview of Cues and Action tiles. Learn about the tasks involved in creating and
customizing them for displaying on Role Centers, as illustrated in the following figure:
NOTE
Modifying actions in Cue groups on page extensions isn't supported.
Designing Cues
A Cue provides a visual representation of aggregated business data, like the number of open sales invoices.
Cues are interactive, meaning that you can select the Cue to drill down to data or open another page, run code,
and more. Cues display data that is contained in a table field. This data can be raw data or calculated data.
Normal and wide layout
There are two layout options that influence how Cues appear in the client: normal and wide.
The normal layout displays Cues as tiles. With this layout, Cue groups are automatically arranged to fill in
the width of the workspace, which means there can be more than one group horizontally across the
workspace.
The wide layout is designed to display large values, such as monetary values. The wide layout gives you a
way emphasize a group of Cues. Wide and normal Cue groups can be interleaved. However, wide groups
that precede all normal groups will appear in their own section of the workspace, spanning the entire
width - providing space for the large values. Wide groups that are placed after normal groups will behave
just like the normal layout groups. So, it's good practice to place Cue groups that use the wide layout,
above those Cues that use the normal layout. The wide layout is specified by setting the CuegroupLayout
property to wide .
NOTE
The wide layout is only supported in the Web client.
The Caption and CaptionML properties of the cuegroup control are ignored when the layout is wide.
NOTE
The examples in this section will set up a Cue that extracts the number of open sales invoices from the Sales Header
table.
fields
{
field(1;PrimaryKey; Code[250])
{
DataClassification = ToBeClassified;
}
field(2; SalesInvoicesOpen ; Integer)
{
FieldClass = FlowField;
CalcFormula = count("Sales Header" where("Document Type"=Filter(Invoice), Status=FILTER(Open)));
}
}
keys
{
key(PK; PrimaryKey)
{
Clustered = true;
}
}
}
NOTE
You can't use the CaptionClass property for this purpose.
5. If you want to set the cuegroup to use the wide layout, set the CuegroupLayout property to wide .
Repeat steps 2-4 to add more Cue groups.
6. Initialize the Cue fields.
To initialize the fields, for example, you can add the following AL code to the OnOpenPage Trigger.
RESET;
if not get then begin
INIT;
INSERT;
end;
Example
layout
{
area(content)
{
cuegroup(SalesCueContainer)
{
Caption='Sales Invoices';
// CuegroupLayout=Wide;
field(SalesCue; SalesInvoicesOpen)
{
Caption='Open';
DrillDownPageId="Sales Invoice List";
}
}
}
}
trigger OnOpenPage();
begin
RESET;
if not get then begin
INIT;
INSERT;
end;
end;
}
cuegroup(SalesActionontainer)
{
Caption='New Sales Invoice';
actions
{
action(ActionName)
{
RunObject=page "Sales Invoice";
Image=TileNew;
trigger OnAction()
begin
end;
}
}
}
A value that has the format Tile[color] will set the Action tile to use the circle icon and a background
that is specified by [color] . For example, TileBlue will display a circle icon in a blue background.
A value that has the format Tile[picture] will set the Action tile to use an icon that is specified by
[picture] and a neutral background color. For example, TileCamera will display a camera icon on the
neutral background.
NOTE
If you use a value that isn't valid or recognized, the Action tile will default to display the circle icon on the neutral
background.
See Also
FlowFields
Page Object
Pages Overview
Table Object
Pages Overview
2/6/2023 • 7 minutes to read • Edit Online
In Dynamics 365 Business Central, pages are the main way to display and organize data. Pages are the primary
object that a user will interact with and have a different behavior based on the type of page that you choose.
Pages are designed independently of the device they are to be rendered on, and in this way the same page can
be reused across phone, tablet, and web clients.
A page is defined in code as an object composed of controls, properties, actions, and triggers. You can also use
Designer in Dynamics 365 Business Central to create a page. For more information, see Using Designer.
Whether you are creating a new page, or extending an existing page, you will add a new .al file to your project
and describe the page object in code. The difference is basically that for a new page, you need to define the
entire page, whereas when modifying an existing page, you only add the extra functionality or modify the
existing.
The structure of a page is hierarchical and breaks down in to three sections. The first block contains metadata for
the overall page. The metadata describes the page type and the source table it is showing data from. The next
section; the layout, describes the visual parts on the page. The final section details the actions that are published
on the page.
Furthermore, the page has properties. Properties work in the same way for pages as they do for other Dynamics
365 Business Central objects. For more information, see Page Properties.
TIP
For information about designing pages, see Page Types and Layouts.
Page metadata
For a new page object, you must at least specify the type of page; PageType and the data source; SourceTable of
the page. And you can also set other metadata at the beginning of the declaration of the page object.
Types of pages
Which page type you choose depends on the application task that you want to support, the content that you
want to display, and how you want to display it. The Role Center page is the main or home page and it helps the
user focus on the most important daily tasks and activities. Other types of pages, such as list pages or card
pages are typically linked from the home page for easy access. The following page types are available:
PA GE T Y P E DESC RIP T IO N
PA GE T Y P E DESC RIP T IO N
Card A Card page is used to view and edit one record or entity
from a table.
ListPart Similar to a List page, a List Part page displays content from
a table in a list format. The difference is that you use the List
part page as another page in a FactBox or as a part of the
Role Center page.
StandardDialog The StandardDialog is a simple page type that you use when
users only need to input data and do not need to perform
other actions from the page.
NOTE
For backwards compatibility we continue to support adding non-part pages as parts. We do, however, recommend that
you redesign your page to only use Card part or List part, as we may remove support in a future update.
Page layout
The page layout of the page object determines what the page will look like and is specified in the layout
section. The layout contains one or more area sections that define a certain placement on the page.
You can choose between the following area categories:
A REA T Y P E P L A C EM EN T O N T H E PA GE
Content The content area displays the content of, for example, a
RoleCenter or a List page.
Page actions
All pages contain menu items and navigation controls called actions. In Dynamics 365 Business Central, actions
are displayed at the top of each page in the ribbon or in the navigation pane. The actions section of the page
describes what the user is able to do on a page and must be designed with the user's need for process support
in mind.
Actions can be displayed in the ribbon of all pages and grouped together under the following actions tabs:
Home
Actions
Navigate
Report
Creating actions can include adding activity buttons/cues to a page, configuring navigation items on a user role
center, or adding Reports to a page. To learn how you can enable users to quickly locate the actions they want to
use, see Actions.
layout
{
area(content)
{
group(Reward)
{
InstructionalText = 'Fill in the fields so that you can reward customers with discounts.';
field("Reward Id"; "Reward ID")
{
ApplicationArea = All;
ToolTip = 'Specifies the unique ID of the reward.';
}
field(Description; Description)
{
ApplicationArea = All;
ToolTip = 'Specifies what this type of reward is used for.';
}
In this example, the app.json file has specified a link to where the sales-rewards target file is published, such as
"contextSensitiveHelpUrl": "https://mysite.com/documentation" .
Pages are the main way to display and organize visual data in Dynamics 365 Business Central. They are the
primary object that a user will interact with and have a different behavior based on the type that you choose.
Pages are designed independently of the device they are to be rendered on, and in this way the same page can
be reused across phone, tablet, and web clients.
The structure of a page is hierarchical and breaks down in to three sections. The first block contains metadata for
the overall page; the type of the page and the source table it is showing data from. The next section; the layout,
describes the visual parts on the page. The final section details the actions that are published on the page.
When developing a solution for Dynamics 365 Business Central, you will follow the code layout for a page as
shown in the page example below, but for more details on the individual controls and properties that are
available, see Page Property Overview.
If you want to, for example, add functionality to a page that already exists in Business Central, you can create a
page extension object that changes an existing page object. For more information, see Page Extension Object.
Depending on how much you want to change on an existing page, you can also create a page customization
object, which offers modifications on actions and layout. For more information, see Page Customization Object.
IMPORTANT
Only pages with the Extensible Property set to true can be extended.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
Snippet support
Typing the shortcut tpage will create the basic layout for a page object when using the AL Language extension
in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Views
Views in Dynamics 365 Business Central are used on list pages to define a different view of the data on a given
page. Views can be defined for Pages, Page Extensions, and Page Customization. For more information, see
Views.
Page example
page 50101 SimpleCustomerCard
{
PageType = Card;
SourceTable = Customer;
ContextSensitiveHelpPage = 'my-feature';
layout
{
area(content)
{
group(General)
{
field("No."; "No.")
{
ApplicationArea = All;
CaptionML = ENU = 'Hello';
trigger OnValidate()
begin
if "No." < '' then
Message('Number too small')
end;
}
field(Name; Name)
{
ApplicationArea = All;
}
field(Address; Address)
{
ApplicationArea = All;
}
}
}
}
actions
{
area(Navigation)
{
action(NewAction)
{
ApplicationArea = All;
RunObject = codeunit "Document Totals";
}
}
}
}
See Also
AL Development Environment
Views
Adding Help Links from Pages, Reports, and XMLports
Page Extension Object
Page, Page Fields, and Page Extension Properties
Page Properties
Developing Extensions
Configure Context-Sensitive Help
Page Extension Object
2/6/2023 • 4 minutes to read • Edit Online
The page extension object extends a Dynamics 365 Business Central page object and adds or overrides the
functionality.
The structure of a page is hierarchical and breaks down into three sections. The first block contains metadata for
the overall page; the type of the page and the source table it is showing data from. The next section; the layout,
describes the visual parts on the page. The final section details the actions that are published on the page.
For more information about the Page and Page Extension objects, see Pages Overview.
IMPORTANT
Only pages with the Extensible Property set to true can be extended.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
IMPORTANT
The API page type should not be extended by creating a page extension object. Instead, create a new API by adding a
page object.
NOTE
Modifying actions in Cue groups on page extensions is not supported.
Snippet support
Typing the shortcut tpageext will create the basic layout for a page extension object when using the AL
Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Views
Views in Dynamics 365 Business Central are used on list pages to define a different view of the data on a given
page. Views can be defined for Pages, Page Extensions, and Page Customization. For more information, see
Views.
K EY W O RDS SY N TA X A P P L IES TO
Example
To modify the existing fields and groups on a page, you use the modify keyword. See the code snippet below
for addlast , modify and action syntax. In the following example, the actions section creates a new group in
the ribbon and places it last in the Creation group.
pageextension 70000020 CustomerCardExtension extends "Customer Card"
{
layout
{
// Adding a new control field 'ShoeSize' in the group 'General'
addlast(General)
{
field("Shoe Size"; ShoeSize)
{
Caption = 'Shoe size';
trigger OnValidate();
begin
if (ShoeSize < 10) then
Error('Feet too small');
end;
}
}
trigger OnAction();
begin
Message('My message');
end;
}
}
}
}
}
trigger OnValidate();
begin
if (rec.ShoeSize < 0) then
begin
message('Shoe size not valid: %1', rec.ShoeSize);
end;
end;
}
}
trigger OnBeforeInsert();
begin
if not HasShoeSize then
ShoeSize := Random(42);
end;
}
trigger OnValidate();
begin
if (ShoeSize < 10) then
Error('Feet too small');
end;
}
// display-only control (without underlying datasource)
field(ShoesInStock; 10)
{
ApplicationArea = All;
Caption = 'Shoes in stock';
}
}
modify("Address 2")
{
Caption = 'New Address 2';
}
}
actions
{
{
addlast(Creation)
{
group(MyActionGroup)
{
Action(MyAction1)
{
ApplicationArea = All;
Caption = 'Hello!';
trigger OnAction();
begin
Message('My message');
end;
}
Action(MyAction2)
{
ApplicationArea = All;
You can reference Report and XMLPort objects and use these objects in the RunObject property, as well as,
declare variables of the types Repor t and XMLPor t and call AL methods on them. This page extension object
extends the Customer List page object by adding two actions; the first action calls the Customer - List report,
the second action calls the Expor t Contact XMLPort.
See Also
Page Object
Views
Page, Page Fields, and Page Extension Properties
Extending Pages Previously Based on the Date Virtual Table Developing Extensions
AL Development Environment
Adding Pages and Reports to Tell me
2/6/2023 • 4 minutes to read • Edit Online
The Business Central client includes the Tell me feature that lets users find objects by entering search terms.
When you have added a page or a report in your extension, you most likely want it to be discoverable to users
in Tell me . In AL, you make a page or report searchable from Tell me by setting the UsageCategory property in
code. The UsageCategor y setting will make the page or report searchable, and the value chosen for the setting
will further sub categorize the item.
Tell me finds pages and reports by searching the captions that are specified on page and report objects by the
CaptionML property.
TIP
The UsageCategor y is also used to categorize pages and reports shown in the role explorer of the client. The role
explorer includes two actions: Repor ts and Analysis and Administration . Pages and reports set to
Repor tsAndAnalysis will show when the Repor ts and Analysis action is selected. Pages and reports set to
Administration will show when the Administration action is selected. For more information, see Finding Pages with
the Role Explorer.
VA L UE DESC RIP T IO N
Lists The page or report is listed as Lists under the Pages and
Tasks category.
Tasks The page or report is listed as Tasks under the Pages and
Tasks category.
Example
The following example creates a SimpleItemList page and sets a UsageCategory property to the page, so that
the SimpleItemList page is discoverable through search using the Tell me feature. Also, the example sets the
AdditionalSearchTerms property to add two search terms for the page.
layout
{
area(content)
{
group(General)
{
field("No.";"No.") {}
field(Name;Name) {}
field(Description;Description) {}
}
}
}
}
Optional settings
In addition to making a page or report searchable, you can control the access of an object by providing Read ,
Inser t , Modify , Delete , and Execute (RIMDX) permissions by adding the AccessByPermission property.
Likewise, control the application area access on the specified object by adding the ApplicationArea Property.
The AccessByPermission property and ApplicationArea property are the optional settings, which can be
applied with the UsageCategor y property. These settings are used to set restrictions on an object when you
enable the Search functionality.
If you are using the Dynamics NAV Development Environment, you can also set UsageCategor y ,
AdditionalSearchTerms , AccessByPermission , and ApplicationArea properties on pages and reports to
control their search.
After you change these properties by using the Dynamics NAV Development Environment, before the changes
take effect in the client, you must run Build Object Search Index from the Tools menu.
See Also
Adding Menus to the Navigation Pane
UsageCategory Property
Page Object
Report Object
AL Development Environment
Page Types and Layouts
2/6/2023 • 15 minutes to read • Edit Online
Understanding how Business Central displays a page dependent on its page type is important to be able to
create a good user experience. There are also several page properties and variations of the page structures that
can help create an intuitive and efficient user interface.
In this article, we're focusing on how pages appear when a user accesses Business Central from a desktop
browser. But it's an important point that the same page types apply across the different form factors of apps,
and the Business Central page type layouts automatically adapt to work well on different devices, like on a
phone or a tablet.
Card Master, reference, and set Single entity Titled entity with FastTabs.
up data management. Card May embed parts.
page example
Document Transaction and other Single entity Titled entity with FastTabs.
document management. Should have the document
lines ListPart immediately
follow the header section(s).
ListPlus Statistics, details, and Single entity Titled entity with at least
related data management. one ListPart . Can have
fields above or below the
part(s).
List Entity overviews and Collection of entities/entries A single list with a caption.
navigation, and inline May have field groups and
editing of simple entities. subpages above and below
List page example the list's Repeater .
Worksheet Line-based data entry tasks Collection of entities A single list or table with a
(such as journals) and caption. May have field
inquiries. groups and subpages
above and below the
worksheet's Repeater .
PA GE T Y P E EXA M P L ES O F USE M A IN DATA DISP L AY C H A RA C T ERIST IC S
StandardDialog Routine dialog that starts or Single or collection A cancelable dialog with an
progresses a task. instruction to the user. Can
have one or more groups of
fields and parts.
NavigatePage Multi-step dialog (also Single or collection Can have one or more
known as a "Wizard"). groups of fields and parts.
The entity-oriented page types have actions (in top and in The collection-oriented page types provide actions in
action bar) that affect the entity or context given by the title action bar (and on the rows' action menu) that take effect on
of the page. the selected row(s) in the collection.
Entity-oriented pages
In Business Central, entity-oriented pages are used to support users when their tasks revolve around a single
business entity. The most typical entity-oriented page is the Card , which provides details about a single
customer or other master data, and the Document , which represents a single transaction, or other important
business event, for example, a sales transaction.
ListPlus is also an entity-oriented page type. Unlike Card and Document pages, the ListPlus page type is for
pages that have a prominent ListPart and either few or no header fields.
The CardPart page type is an entity-oriented page type for inclusion in another page, for example, in a FactBox.
IMPORTANT
Because entity-oriented pages represent a single entity, such as a customer or an item, don't use a Repeater group in
the construction of entity-oriented pages. If you do, some of the repeater's features may not work properly, and it may
not get the expected size. However, an entity-oriented page can embed a ListPart part page that, in turn, contains a
repeater control. Learn more about how to user repeater controls Working with Repeater Controls.
If you currently have an entity-oriented page that uses a repeater, in most cases, you can just change the page type from
Card to List , or CardPart to ListPart . In some cases, it is more complicated. For example, if the page has actions
that act on the grid or variables that are used in the grid.
Collection-oriented pages
In Business Central, collection-oriented pages are used to support users when their tasks involve multiple
entities or records at the same time. The most typical collection-oriented page type is the List (for example
showing customers, items, and so on.) from which the user can seek out the entities to work with.
The Worksheet is the other prominent collection-oriented page type, suited for data entry (for example, in
journal pages) and other tasks related to managing a set of entities/entries based on custom fields above and/or
below the collection.
The ListPart page type is a collection-oriented page type for inclusion in another page, for example, in a
FactBox.
Dialog pages
The page types in Business Central that are available exclusively for displaying dialogs, such as the
StandardDialog and ConfirmationDialog page types, can represent an entity or a collection. The title caption and
actions are suited for both types.
Composing pages
Within a page, the developer can combine page fields into groups. Groups help the user overview the page by
placing related fields together. And within a group, subgroups further increase the structure of the data
displayed in a page.
Besides adding fields and groups to a page, it's possible to embed another page of type CardPart or ListPart .
(These two page types can in turn not embed other pages.)
When pages are created that embed parts, Business Central divides the available screen real estate between the
page's groups of fields and any embedded pages. Screen space is divided between field groups and embedded
pages, so that the user can get access to the full contents of the page and collapse/expand specific sections of
interest.
How space allocation takes place for a given page depends on the chosen page type, the structure of page
contents (field groups and page parts), and on the size of the browser window.
A page is Content + Actions + FactBoxes
For all pages (excluding RoleCenter , dialogs, and part pages) there's a common structure to the areas of a page
where content, FactBoxes, and actions can be displayed.
The content area provides rich layout capabilities, which are described in the coming sections. The FactBoxes
area is limited to showing a list of parts, usually in a vertical arrangement. The header consists of the title, action
bar, and controls for filtering, views, and so on.
For more information about page areas, see Pages Overview.
Field groups and page parts
In the following sections, you find descriptions of typical page layouts, recommendations for how to organize
the contents, and illustrations of the principles by which the sections of page share screen real estate. The types
of content on a page are illustrated this way:
SY M B O L SEC T IO N N OT ES
SY M B O L L AY O UT B EH AVIO R N OT ES
Size to content within certain limits The part will use a scrollbar if content
exceeds available space.
Which of the section sizing behavior is used is dependent on the chosen page type. For each of the page types
described in the sections below, we present the typical layouts, and the way that the sections are sized.
Sections are placed vertically from top A ListPart can be embedded. In this When a ListPart is embedded as the
to bottom of the page. case, the ListPart's height is limited. last part on the page, it will expand to
fill space.
Document layouts
EXA M P L E 1 EXA M P L E 2 EXA M P L E 3
Sections are placed vertically from top Multiple ListParts can be embedded. In When no ListPart is embedded, the
to bottom of the page. The lines this case, the first ListPart is allowed Document layout follows the Card
ListPart comes after the header the most space. layout exactly.
section(s).
EXA M P L E 1 EXA M P L E 2 EXA M P L E 3
NOTE
The Document page type allows the first ListPart on the page to use additional vertical space before showing a scrollbar.
This allows more space for showing the document lines without requiring the user to scroll.
Page sections are placed from top to When placing two or more ListParts, When placing two ListParts in a group,
bottom. The first ListPart fills vertical they'll share available vertical space. they share horizontal space.
space.
From the user's perspective, the following are qualities of a well-designed ListPlus page:
Has a page title that clearly identifies the context for the information presented in the page.
Is optimized for showing one set of details, and giving the user means to work with them.
Presents information in the page in such a way that the hierarchy can be understood when read from top to
bottom.
If present, fields that control which data is presented in another FastTab come before that FastTab.
If present, fields that show data dependent on the chosen row (in the ListPart) come after the ListPart.
The repeater control assumes full When a field group or cardpart is When a listpart is embedded, space is
vertical space. embedded, space for repeater is shared equally between part and
reduced. repeater.
From the user's perspective, the following are qualities of a well-designed List page:
Defines a set of columns that is optimized for viewing and filtering the given collection. Optimize the column
order for data entry if the list is editable.
Has a page title that clearly names or identifies the collection of entities/entries presented.
If a summary or more detail related to the selected row are shown, these appear below the list.
If custom viewing options are available, these appear above the list.
Has one or two FactBoxes to give essential collection statistics, and relevant related details for the selected
row.
NOTE
The Worksheet page type doesn't support the same part and group compositions as the List page type.
Worksheet pages must contain a single Repeater group. In addition, a worksheet can embed groups of fields,
CardParts, and ListParts. Below are examples of list page compositions, showing how space is divided. Parts can
be combined in more ways than shown here to suit different scenarios.
The repeater control takes full vertical A group, CardPart, or ListPart can be Groups and/or parts are embedded
space, but leaving space for a group or embedded below the repeater that above and below, leaving the
CardPart above. then assumes the remaining vertical remaining vertical space for the
space. repeater.
From the user's perspective, the following are qualities of a well-designed worksheet page:
Defines a set of columns that is optimized for overviewing and managing the given collection. Columns are
ordered relative to their importance.
Has fields above the grid that specify filtering options or specify the default values effective during data entry
and editing in the grid.
If summary fields or more details of the selected row are shown, these appear below the repeater.
Generally, Business Central displays dialogs on the screen in a frame that is more narrow and not taking up full
vertical height, compared to how pages appear ordinarily. Aside from that, pages lay out their contents
according to the same principles, whether displayed as a dialog or not.
Given the size of the screen where the dialog appears, more or less of the page contents will be visible without
scrolling. When a page contains much content, it's possible for the user to increase the dialog size with the
maximize button.
NOTE
The dialogs created from the ConfirmationDialog and StandardDialog page types are not currently providing a maximize
button.
See Also
Page, Page Fields, and Page Extension Properties
PageType Property
Actions Overview
Using Designer
Adding a FactBox to a Page
Designing Role Centers
Designing List Pages
2/6/2023 • 8 minutes to read • Edit Online
The List page type displays records from an underlying table, either as rows and columns or as individual tiles.
Overview
Structure
Behavior points
Developer tips
Designing for devices
You design list pages when you want to provide users with a collection of data, enabling them to get an
overview of and find entities to work with, such as customers, vendors, or sales orders. Typically, a list page will
link to an associated card page that lets users view or modify specific entities in the list.
There are different ways to incorporate a list page into that application:
Make the list page available from the navigation of a Role Center page.
This gives users quick access to the page. With this implementation, the list page opens in the content
area of the Role Center page, where the Role Center's navigation area is still present and accessible at the
top of the page. For more information about Role Centers, see Designing Role Centers.
Make the list page available from an action on another page.
With this implementation, the list page opens in a separate window in front of the current page.
Make the list page searchable from the Tell me what you want to do feature.
With this implementation, the list page also opens in a separate window. For more information, see
Adding Pages and Reports to Search.
Customizing a list pages from the client
In the client, users can personalize list pages by rearranging or hiding records or FactBoxes as they like. For
more information, see Personalizing Your Workspace.
As a developer or administrator, you can use Designer to customize the list page the same way that individual
users personalize their own work spaces. The difference is that changes you make are applied to all users. For
more information, see Using Designer.
Simple List Page Code Example
2/6/2023 • 2 minutes to read • Edit Online
The AL code in this article creates a simple list page that displays records from an existing table.
For a more detailed explanation of the list page, see Designing List Pages.
// Makes the page searchable from the Tell me what you want to do feature.
UsageCategory = Lists;
// Specifies the card page Sample Customers to be uses for modifying or creating new customer records.
CardPageId = 50112;
layout
{
area(Content)
{
// Sets the No., Name, Contact, and Phone No. fields in the Customer table to be displayed as
columns in the list.
repeater(Group)
{
field("No."; "No.")
{
ApplicationArea = All;
}
field(Name; Name)
{
ApplicationArea = All;
}
field(Contact; Contact)
{
ApplicationArea = All;
}
field(Phone; "Phone No.")
{
ApplicationArea = All;
}
}
}
actions
{
// Adds an action on the Actions menu of the action bar that opens the page Customer Ledger Entries.
area(Processing)
{
action("Ledger Entries")
{
ApplicationArea = All;
RunObject = page "Customer Ledger Entries";
trigger OnAction();
begin
end;
}
}
// Promotes an action for creating a sales quote to promoted action menu called New.
area(Creation)
{
action("New Sales Quote")
{
ApplicationArea = All;
RunObject = page "Sales Quote";
Promoted = true;
PromotedCategory = New;
Image = NewSalesQuote;
trigger OnAction();
begin
end;
}
}
// Adds an action on the Report menu that opens the Top 10 List report.
area(Reporting)
{
action("Top 10 List")
{
ApplicationArea = All;
RunObject = report "Customer - Top 10 List";
trigger OnAction();
begin
end;
}
}
}
}
See Also
AL Development Environment
Page Extension Object
Actions Overview
Adding Pages and Reports to Tell Me
Personalizing Your Workspace
Using Designer
Working with Repeater Controls
2/6/2023 • 4 minutes to read • Edit Online
A repeater control is used to define a list of records from the source table of a page. Records are displayed as
rows and columns, where each row is a record and each column is a field.
You add a repeater() control within the area(Content) control of a page, and then you nest a field() control
for each of the fields from the table specified in the SourceTable Property that you want to include. The order of
the field controls determines the order in which they appear on the page.
A list is a characteristic element of the layout of pages of the type List and ListPar t . You define the type of a
page using the PageType Property. List pages are designed for using a single repeater() control, which must be
defined at the beginning of the content area. If you include more than one repeater or another control like a
group or grid, the page might not behave as expected. If you want to design a page that includes controls in the
content area other than a repeater, then try using a Worksheet page type instead. For more information, see
Pages Types and Layout.
Pages of the type API are also designed to integrate a repeater control, but they can't be displayed in the user
interface.
The following figure illustrates how a list created by a repeater is displayed in the Web Client.
Limitations
The Web client doesn't support displaying repeater controls that contain other Parts or FlowFilter fields.
The repeater control is only supported by the Web client in collection-oriented pages List, Worksheet, and
ListPart. The repeater control isn't supported on entity-oriented page types, like Card , CardPart , Document ,
or Navigation . In fact, if you use a repeater on an entity-oriented page, you'll get UICop Warning AW0008. If
you want to include data as a list on one of these page type, create a ListPart page that contains repeater
control, and then use the ListPart in the entity-oriented page.
Example
The following example shows how the repeater control is used to define a list page for the Customer table.
page 50111 SampleCustomerList
{
PageType = List;
ApplicationArea = All;
SourceTable = Customer;
UsageCategory = Lists;
CardPageId = 50112;
Caption = 'Sample Customers';
layout
{
area(Content)
{
// Sets the No., Name, Contact, and Phone No. fields in the Customer table to be displayed as
columns in the list.
repeater(Group)
{
field("No."; "No.")
{
ApplicationArea = All;
}
field(Name; Name)
{
ApplicationArea = All;
}
field(Contact; Contact)
{
ApplicationArea = All;
}
}
}
}
}
actions
{
area(Processing)
{
action("Ledger Entries")
{
ApplicationArea = All;
RunObject = page "Customer Ledger Entries";
trigger OnAction();
begin
end;
}
}
}
You can use page customizations to modify the layout of a page for concrete users. The following code hides the
"Phone No." column from the users with Accountant profile.
profile Accountant
{
Description = 'Functionality for finance staff performing any AR or AP work and managerial reporting.';
RoleCenter = "Accountant Role Center";
Customizations = MyCustomization;
}
See Also
Pages Overview
Designing List Pages
Page Customization Object
Displaying Data as Tiles for Lists
2/6/2023 • 4 minutes to read • Edit Online
In the client, on List type pages, users can view the page in the tile view. The tile view shows records as tiles (or
bricks) instead of as rows. Tiles optimize space and readability of data. Tiles are especially useful for images, like
on a page that show items, customers, and contacts. Business Central also provides Microsoft Teams integration,
which enables users to display an interactive, visual representation of records in a Teams chat. These features
both use the same design concept, which is based on defining a Brick field group on the entity's source table.
By default, the tile view will display the first five fields that are defined in page's repeater control. This article
describes how you can customize the tile view for list type pages.
NOTE
The Brick field group is also used to define the fields that appear when a record is shown in a Microsoft Teams
conversation. For more information, see Extending Teams Cards.
fieldgroups
{
fieldgroup(Brick; <field 1>, <field 2>, <field 3>, <field 4>, <field 5 >, <image field>, <verbose
text field>
{
}
}
There's no limit on the number of fields you can display in a tile. However, we recommend that you limit tiles to
five data fields and one image field.
IMPORTANT
By default, the Field Group named DropDown is interpreted as Brick when a Brick definition has not been set. The
DropDown is typically set on entities such as customer, vendor, and items. For more information, see Field Groups (Drop-
Down Controls).
Field layout in tiles
The order of the fields determines how they appear in the layout of the tile, no matter the order in the page
object. Depending on the number of columns that you define in the Field Group , the layout will dynamically
change. This concept is illustrated in the following figure:
T IL E TA L L T IL E
Example
The following code is a simple example of a table that includes Field Group control for displaying data in the
tile view of a list page. The following figure illustrates how a tall tile with an image will appear on the page.
fields
{
field(1; Number; Integer)
{
}
keys
{
key(PK; Number)
{
}
}
fieldgroups
{
fieldgroup(Brick; Number, Description, Inventory, Image, DescriptionLong)
{
}
}
}
}
layout
{
area(Content)
{
repeater(GroupName)
{
field(Number; Number)
{
ApplicationArea = All;
}
field(Description; Description)
{
ApplicationArea = All;
}
field(Inventory; Inventory)
{
ApplicationArea = All;
Style = Attention;
}
field(DescriptionLong; DescriptionLong)
{
ApplicationArea = All;
}
}
}
}
}
See Also
Designing List Pages
Working With Media on Records
Views
2/6/2023 • 4 minutes to read • Edit Online
Views in Dynamics 365 Business Central are used on list pages to define a different view of the data on a given
page. Views can be defined for Pages, Page Extensions, and Page Customization. Views are defined on page
extension objects to provide an alternative view of data and/or layout on an existing page. In views on page
customization objects, they can be used to provide an alternative view for a certain profile.
A view offers:
Filtering on multiple table fields on the source table defined for the page.
Sorting of the data on multiple table fields, but only in one direction; either ascending or descending.
Layout changes, modifying page columns, moving them, etc.
Views are defined directly in code, on the list page that they modify. The defined view or views are available to
the user through Filter Pane on a page and appear in the sequence that they're defined in code.
NOTE
allowDebugging does not apply to views. Views defined in an extension with allowDebugging set to false can still
be copied using Designer.
Snippet support
Typing the shortcut tview will create the basic layout for a view when using the AL Language extension in
Visual Studio Code.
Filters = where ("Balance (LCY)" = filter (> 500), Name = filter ('G*'));
NOTE
All filters are applied to the table field(s), not the page field(s), which allows filtering on a table field not shown on the
page.
Layout changes
By default, a view will have the same field layout as the page's All view, which means it will show the same
columns, in the same order, with the same widths. The layout will also have the same freeze column. This
behavior is a basic experience in the case where defining a specific layout for the view isn't important. It's
controlled by the SharedLayout property on the page view, which in this case is set to true . This layout is
referred to as a shared layout view . The following example code illustrates a shared layout view :
view(SharedLayoutView)
{
// This view only define filters, but no specific layout.
// User personalization are applied on this view.
Caption = 'View With Shared Layout';
Filters = where ("Balance (LCY)" = filter (> 500), Name = filter ('G*'));
}
By contrast, you set the SharedLayout to false to design a unique layout view that defines its own layout and is
independent from all other views. Any changes coded in the layout section are applied in the view. User
personalizations made on the page aren't applied on the view. For example:
view(UniqueView)
{
Caption = 'View With Unique Layout';
Filters = where ("Balance (LCY)" = filter (> 500), Name = filter ('G*'));
// By settings this property to false, the view gets its own independent layout.
// User personalization are not applied on this view.
// Instead, the layout defined below is applied.
SharedLayout = false;
layout
{
movefirst(Control1; "Balance Due (LCY)")
}
}
IMPORTANT
SharedLayout must be set to false to use a custom layout on the view (the layout section). A compiler error is
reported otherwise.
View example
The following example shows a page customization of the Customer List page, which is available for a specific
role center only; the My Role Center . Change the role center view under My Settings . The definition of the
view adds a caption that's displayed on the left side in the UI. The view sorts the customer balance in ascending
mode and the view modifies the layout by moving the customer balance first and adding a freeze column after
it.
IMPORTANT
The definition of the view section must come after any definition of layout and actions, otherwise you will get a compiler
error AL0577.
profile MyProfile
{
Caption = 'My Role Center';
RoleCenter = "Order Processor Role Center";
Customizations = MyCustomization;
}
actions
{
// Add any actions to the page
}
views
{
addfirst
{
view(BalanceLCY)
{
Caption = 'Ordered Balance LCY';
OrderBy = ascending ("Balance (LCY)");
Filters = where ("Balance (LCY)" = filter (> 500), Name = filter ('G*'));
SharedLayout = false;
layout
{
// Change the layout of the view
modify(Control1)
{
FreezeColumn = "Balance (LCY)";
}
}
}
}
}
Limitations
In general, views can in several ways be compared to page customizations. Here are the limitations of views:
For views, you can modify the same control properties as for page customization objects independently of
where the view has been defined (page, page extension, or page customization level). This condition is
validated by the compiler.
It isn't possible to use variables or methods in a view. When writing client-side expressions for properties like
Visibility , it will only be possible to use constant values or table field references. This condition is validated
by the compiler.
It isn't possible to create new controls for a page from a view.
See Also
AL Development Environment
Developing Extensions
Page Object
Page Extension Object
Page Customization Object
SharedLayout Property
Migrating from Legacy Views to Modern Views
2/6/2023 • 4 minutes to read • Edit Online
IMPORTANT
Legacy views have been deprecated and will be removed in Business Central 2023 release wave 2 (version 23). You can
experience this change already in 2022 release wave 2 (version 21) by enabling Legacy list views are hidden on the
Feature Management page. Learn more at Enabling Upcoming Features Ahead of Time.
Modern views were introduced with Business Central April 2019 release wave and are the recommended design
going forward. Legacy views are list views that were created by developers in previous versions of Business
Central by placing them on the Role Center page object. Business Central displays legacy views side by side with
modern views directly on the list page. But legacy views offer a degraded experience and fewer options
compared to modern views.
actions
{
area(sections|embedding|processing)
{
action(<action_name>)
{
Caption = '<page_caption>';
RunObject = Page "<page_name>";
RunPageView = <filters_and_sorting>;
For example, here's a code snippet of a role center page action that adds a legacy view on the Sales
Order List page:
actions
{
area(embedding)
{
action(SalesOrdersShptNotInv)
{
Caption = 'Shipped Not Invoiced';
RunObject = Page "Sales Order List";
RunPageView = WHERE("Shipped Not Invoiced" = CONST(true));
}
layout
{
area(content)
{
cuegroup("<cue_group_name>")
{
field(<cue_data_field>; Rec.<cue_data_field>)
{
// List page that opens from cue
DrillDownPageID = "<list page>";
}
Once you've identified the source of a legacy view, the next step is to recreate it as a modern view, as described
at Views.
See Also
List Views FAQ
Business Central April '19 release plans - List Views
Business Central April '19 release plans - Save and personalize list views
AL Development Environment
Developing Extensions
Adding Custom Filter Tokens
2/6/2023 • 3 minutes to read • Edit Online
In the client, when filtering lists using the filter pane, users can enter filter tokens, which are special words that
resolve to one or more values. This powerful feature makes filtering easier by reducing the need to navigate to
other pages to look up values to enter as filter criteria.
There are several useful filter tokens available in Business Central. For example, entering %mycustomers in a
Customer No. field will resolve to the set of customers in the user's My Customers list such as 1001|1002 ,
making it easy to find relevant sales orders for customers 1001 and 1002.
You can add custom filter tokens and make these available in any language and across the application. To add
your custom filter token, you need to define the token word that users will enter as filter criteria, and define a
handler that resolves the token to a concrete value at runtime. For more information, see Filter Tokens in our
ALAppExtensions repository on GitHub.
TIP
Filter criteria will often contain symbols along with filter tokens. We recommend that you only modify the filter token you
have introduced and preserve the rest of the filter string.
Example
This example shows how you can use the guidelines above to create the %MYTOKEN filter token. This will
return a filter with the accounts marked as favorite by the user.
NOTE
To keep this sample short and simple, the entire filter string is overwritten.
codeunit 50101 MyAccountFilterTokenSimple
{
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Filter Tokens", 'OnResolveTextFilterToken', '', true,
true)]
local procedure FilterMyAccounts(TextToken: Text; var TextFilter: Text; var Handled: Boolean)
var
MyAccount: Record "My Account";
MaxCount: Integer;
begin
if StrLen(TextToken) < 3 then
exit;
Handled := true;
MaxCount := 20;
MyAccount.SetRange("User ID", UserId());
To try it out in the client, open the Charts of Accounts page, filter on No. field, and type in a substring that
starts the same way with the chosen token word, like %MYTO .
Design considerations
Resolving tokens is intended to be fast, simple, and reliable. When implementing event subscribers to resolve
filter tokens, keep in mind that these events can be triggered from any user task in Business Central, and in
some cases may be triggered repeatedly such as when searching across columns. To improve usability and
reduce the impact on performance, do consider the following practices:
Avoid implementing tokens that are only relevant to few business tasks, or assume they are used in the
context of a specific page.
Avoid implementing tokens that are time-consuming to resolve. Examples of this include looking up records
in large or poorly indexed tables, or fetching data from a remote service.
Avoid implementing tokens that are complex or unreliable and may result in error.
Avoid displaying pages, dialogs or any other form of interactive UI.
See Also
Sorting, Searching and Filtering Lists
Designing Indented Hierarchy Lists
2/6/2023 • 4 minutes to read • Edit Online
Overview
Using the indentation properties in AL, you can display rows in a parent-child structure.
A row that's indented from a row above is considered a child of that row. The row above is considered the
parent. Indenting rows can help organize related records in the list and make it more readable for the user.
You can display indented hierarchy lists on any page type, including List pages, Worksheets, and ListParts. Pages
can also be editable.
There are two kinds of indented hierarchy lists: fixed and collapsible. In a fixed hierarchy, rows that are indented
are always shown. In a collapsible, users can collapse and expand parent rows to show and hide child records.
In the figure, indentation is applied to the second column. Setting up the fixed indented hierarchy involves
configuring two properties on the page object: IndentColumn and IndentationControls.
The IndentationColumn Property determines which records get indented and by how much. You set the
property to either a field in the page's source table or to a variable. The important thing, is that property
resolves to an integer. This integer determines the indentation level.
The IndentationControls property specifies which column in the list gets indented. You can only specify
one column.
Example
In this example, you indent records based on the value of the Indent column and apply the indentation to
Name column. You set the IndentationColumn and IndentationControls on the repeater of the page, as shown in
the following code:
page 50100 MyPage
{
PageType = List;
ApplicationArea = All;
UsageCategory = Lists;
SourceTable = MyTable;
Editable = true;
layout
{
area(Content)
{
repeater(Control1)
{
IndentationColumn = Indent;// IndentationColumn = IndentVariable;
IndentationControls = Name;
field(Number; Number)
{
}
field(Name; Name)
{
}
field(Indent; Indent)
{
}
}
}
}
//trigger OnAfterGetRecord()
//begin
//IndentVariable := Indent;
//end;
//var
//IndentVariable: Integer;
}
You can achieve the same results using a variable instead of the table field for the IndentationColumn property.
Look at the commented lines of code in the example above.
For a more detailed implementation example, see the Chart of Accounts page in the base application (link
requires sign-in to Business Central online).
Setting up a collapsible hierarchy is similar to the fixed indented list, except for the properties that you set. A
collapsible hierarchy involves three properties: IndentColumn, ShowsAsTree, and TreeInitialState.
Like in fixed indented hierarchy, the IndentationColumn Property is an integer data type field or variable that
determines which records get indented and by how much.
The ShowAsTree Property makes the hierarchy collapsible.
The TreeInitialState Property, which is optional, specifies whether the list is collapsed or expanded when the
page opens.
Unlike fixed indented lists, a collapsible hierarchy always indents the left-most visible column in the repeater. The
IndentationControls property is ignored. If users customize the page by moving another column first, the moved
column will be indented instead.
Example
In this example, you'll indent records based on the value of the Indent column. Records will indent on the
Number column and parent records will be collapsible. You add the IndentationColumn, ShowAsTree, and
TreeInitialState properties to the pages' repeater:
layout
{
area(Content)
{
repeater(Control1)
{
IndentationColumn = Indent; // IndentationColumn = IndentVariable;
ShowAsTree = true;
TreeInitialState = CollapseAll;
field(Number; Number)
{
}
field(Name; Name)
{
}
field(Indent; Indent)
{
}
}
}
}
//trigger OnAfterGetRecord()
//begin
//IndentVariable := Indent;
//end;
//var
//IndentVariable: Integer;
}
You can achieve the same results using a variable instead of the table field for the IndentationColumn property.
Look at the commented lines of code in the example above.
For a more detailed implementation example, see the Assisted Setup page in the base application (link requires
sign-in to Business Central online).
Collapsed or Expanded lists
Users can change whether the page opens with rows collapsed or expanded, essentially overriding the
TreeInitialState property. They change the behavior by selecting the Toggle Expand All / Collapse All button
in the header of the first column, or using the button in the top-left corner of the repeater. It stays this way, until
they delete personalization on the page.
See Also
IndentationColumn Property
IndentationControls Property
ShowAsTree Property
TreeInitialState Property
Page and Page Extension Properties
Teaching tips and in-app tours for onboarding users
2/6/2023 • 9 minutes to read • Edit Online
A key element in educating users about Business Central pages and concepts is the tour. A tour is a sequence of
teaching tips.
Teaching tips can be defined at the page level, the page teaching tip, and be followed by teaching tips at the
control level, the control teaching tips. Both types of teaching tips are defined by the .AL properties AboutTitle
and AboutText , and an extension can overwrite teaching tips in the default version.
The following illustration shows how choosing the page title will reopen the teaching tip so that the user can
retake the tour.
How to write page teaching tips
There are different rules for teaching tips for lists versus cards and documents.
L IST PA GE W IT H T EA C H IN G T IP C A RD PA GE W IT H T EA C H IN G T IP
What can I do on this page in general? What can I do on this page with this particular field
or action?
Is there a related entity I should know about?
What is the desired outcome of the task in this page?
The title for a list page teaching tip will typically use
the plural form, such as About sales invoices The title for a card or document page teaching tip will
typically be [entity name] + details, such as About
sales invoice details
T EA C H IN G T IP P O IN T IN G TO A N IN P UT F IEL D T EA C H IN G T IP P O IN T IN G TO A N A C T IO N
AboutTitle: Who you are selling to Content example for the Post action:
AboutText: This can be an existing customer, or you can AboutTitle: When all is set, you post
register a new from here. Customers can have special prices AboutText: After entering the sales lines and other
and discounts that are automatically used when you enter information, you post the invoice to make it count. After
the sales lines. posting, the sales invoice is moved to the Posted Sales
Invoices list.
The teaching tip can point to a field that may or may With multiple similar actions,such as Post and Post
not have data. & New , call out the simplest version only.
A control teaching tip can explain an important Avoid action language that tells users to do
value's meaning, such as what leaving the field blank something that isn't active during the tour. Don't say:
does. Now post the invoice. Instead, explain what to be
aware of when posting.
Avoid stating the obvious and avoid action language
that tells users to do something that isn't active
during the tour. For example, don't say Enter the
customer name here. Instead, explain what to be
aware of when adding a customer.
You can add teaching tips for FactBoxes just like pages by using the AboutTitle and AboutText properties is AL.
Adding teaching tips to FactBoxes
Teaching tips are supported on all page types that are supported in FactBoxes, including pages that display cues.
Specifically, you can add teaching tips to following elements:
On the part control that contains the page or cue.
The page or cue that is included in the part control.
Controls, like fields, on the page or cue.
When adding teaching tips, consider the following limitations:
You can't add teaching tips to actions or control add-ins in FactBoxes.
For FactBox teaching tips to activate, the hosting page must have a page teaching tip. The page doesn't need
any control teaching tips.
How FactBox teaching tips fit into tours
The teaching tips for FactBoxes become part of the tour on the hosting page. For more information, see Teaching
tips flow.
2022 release wave 1 adds support for rich text formatting for teaching tips. In this section, we take a look at the
rules and guidelines to follow when using rich text in teaching tips, such as bold, italic, or links.
Bold
Bolded text can call out the most important points, such as
Page names, such as Customer Card
Key features, such as Search
Field names, such as Customer
Keyboard shortcuts, such as Alt+Q
Best practices for use of bolded text
Use bolded text sparsely to avoid "shouting".
If a page name or key feature is title cased, it might be a candidate. However, consider if using bold is
needed to help understanding the message.
Consider the difference between a page name such as the **Posted Sales Invoices** list (bolded and
capitalized page name) as opposed to what the list contains such as the list of posted invoices (not
capitalized and not bolded).
If the feature is already mentioned in the title, consider if it's necessary to highlight the word again in the
body text. Bolding a word once in a tip is usually enough.
Italics
Italic text can be used to bring attention to key terms or field values, such as the following:
Key term, such as general ledger
Field value, such as Closed
TO O LT IP P O IN T IN G AT A F IEL D C A P T IO N T EA C H IN G T IP P O IN T IN G TO A F IEL D
Every field and action has a tooltip. Only the most important fields/actions have a
teaching tip.
Answers the question What is this?
Answers the question What can I do with this field or
Relevant for everything since every field/action has a action?
definition.
Isn't relevant for every field/action.
For more information about tooltips, see Help users get unblocked.
See also
Get Users Started with the Checklist
Guidelines for tooltip text
Onboarding experiences in Business Central
AboutTitle Property
AboutText Property
Designing Card and Document Pages
2/6/2023 • 7 minutes to read • Edit Online
The card page type displays selected fields from an underlying table. The document page type is very similar in
structure to the card page, but in addition to fields, it also includes a part that includes another page, called a
sub-page.
Overview
Structure
Behavior points
Developer tips
Designing for devices
Card pages
You design card pages when you want to enable users to view, create, and modify records (master and reference
data) in a table, such as a customer, vendor, or item.
Document pages
Design document pages when you want to represent a transaction or other important event in the domain of
business. Document pages are the computerized counterpart to paper-based documents, such as quotes,
invoices, orders, and so on. As such, document pages often have associated workflow or audit trail
requirements.
Associate with a list page
Both page types are typically associated with list pages (like the customers or sales orders list) that uses the
same table as their source. From the list page, users can select a record and open it the card or document page
for viewing and editing.
Customizing a card and document pages from the client
In the client, users can personalize card pages by rearranging or hiding content as they like. For more
information, see Personalizing Your Workspace.
As a developer or administrator, you can use Designer to customize a card and document page the same way
that individual users personalize their own work spaces. The difference is that changes you make are applied to
all users. For more information, see Using Designer.
Simple Card Page Code Example
2/6/2023 • 2 minutes to read • Edit Online
The AL code in this article creates a simple card page that displays records from an existing table.
For a more detailed explanation of the list page, see Designing Card and Document Pages.
layout
{
area(Content)
{
//Defines a FastTab that has the heading 'General'.
group(General)
{
field("No."; "No.")
{
ApplicationArea = All;
}
field(Customer; Name)
{
ApplicationArea = All;
}
}
}
field(Phone; "Phone No.")
{
ApplicationArea = All;
}
}
}
}
actions
{
area(Processing)
{
end;
}
action("Banks Account")
{
ApplicationArea = All;
RunObject = page "Customer Bank Account List";
Promoted = true;
end;
}
}
area(Reporting)
{
end;
}
}
}
var
myInt: Integer;
}
See Also
AL Development Environment
Page Extension Object
Actions Overview
Adding Pages and Reports to Search
Personalizing Your Workspace
Using Designer
Teaching tips and in-app tours for onboarding users
2/6/2023 • 9 minutes to read • Edit Online
A key element in educating users about Business Central pages and concepts is the tour. A tour is a sequence of
teaching tips.
Teaching tips can be defined at the page level, the page teaching tip, and be followed by teaching tips at the
control level, the control teaching tips. Both types of teaching tips are defined by the .AL properties AboutTitle
and AboutText , and an extension can overwrite teaching tips in the default version.
The following illustration shows how choosing the page title will reopen the teaching tip so that the user can
retake the tour.
How to write page teaching tips
There are different rules for teaching tips for lists versus cards and documents.
L IST PA GE W IT H T EA C H IN G T IP C A RD PA GE W IT H T EA C H IN G T IP
What can I do on this page in general? What can I do on this page with this particular field
or action?
Is there a related entity I should know about?
What is the desired outcome of the task in this page?
The title for a list page teaching tip will typically use
the plural form, such as About sales invoices The title for a card or document page teaching tip will
typically be [entity name] + details, such as About
sales invoice details
T EA C H IN G T IP P O IN T IN G TO A N IN P UT F IEL D T EA C H IN G T IP P O IN T IN G TO A N A C T IO N
AboutTitle: Who you are selling to Content example for the Post action:
AboutText: This can be an existing customer, or you can AboutTitle: When all is set, you post
register a new from here. Customers can have special prices AboutText: After entering the sales lines and other
and discounts that are automatically used when you enter information, you post the invoice to make it count. After
the sales lines. posting, the sales invoice is moved to the Posted Sales
Invoices list.
The teaching tip can point to a field that may or may With multiple similar actions,such as Post and Post
not have data. & New , call out the simplest version only.
A control teaching tip can explain an important Avoid action language that tells users to do
value's meaning, such as what leaving the field blank something that isn't active during the tour. Don't say:
does. Now post the invoice. Instead, explain what to be
aware of when posting.
Avoid stating the obvious and avoid action language
that tells users to do something that isn't active
during the tour. For example, don't say Enter the
customer name here. Instead, explain what to be
aware of when adding a customer.
You can add teaching tips for FactBoxes just like pages by using the AboutTitle and AboutText properties is AL.
Adding teaching tips to FactBoxes
Teaching tips are supported on all page types that are supported in FactBoxes, including pages that display cues.
Specifically, you can add teaching tips to following elements:
On the part control that contains the page or cue.
The page or cue that is included in the part control.
Controls, like fields, on the page or cue.
When adding teaching tips, consider the following limitations:
You can't add teaching tips to actions or control add-ins in FactBoxes.
For FactBox teaching tips to activate, the hosting page must have a page teaching tip. The page doesn't need
any control teaching tips.
How FactBox teaching tips fit into tours
The teaching tips for FactBoxes become part of the tour on the hosting page. For more information, see Teaching
tips flow.
2022 release wave 1 adds support for rich text formatting for teaching tips. In this section, we take a look at the
rules and guidelines to follow when using rich text in teaching tips, such as bold, italic, or links.
Bold
Bolded text can call out the most important points, such as
Page names, such as Customer Card
Key features, such as Search
Field names, such as Customer
Keyboard shortcuts, such as Alt+Q
Best practices for use of bolded text
Use bolded text sparsely to avoid "shouting".
If a page name or key feature is title cased, it might be a candidate. However, consider if using bold is
needed to help understanding the message.
Consider the difference between a page name such as the **Posted Sales Invoices** list (bolded and
capitalized page name) as opposed to what the list contains such as the list of posted invoices (not
capitalized and not bolded).
If the feature is already mentioned in the title, consider if it's necessary to highlight the word again in the
body text. Bolding a word once in a tip is usually enough.
Italics
Italic text can be used to bring attention to key terms or field values, such as the following:
Key term, such as general ledger
Field value, such as Closed
TO O LT IP P O IN T IN G AT A F IEL D C A P T IO N T EA C H IN G T IP P O IN T IN G TO A F IEL D
Every field and action has a tooltip. Only the most important fields/actions have a
teaching tip.
Answers the question What is this?
Answers the question What can I do with this field or
Relevant for everything since every field/action has a action?
definition.
Isn't relevant for every field/action.
For more information about tooltips, see Help users get unblocked.
See also
Get Users Started with the Checklist
Guidelines for tooltip text
Onboarding experiences in Business Central
AboutTitle Property
AboutText Property
Designing Assisted Setup Guides
2/6/2023 • 11 minutes to read • Edit Online
In Business Central, you use the NavigatePage page type to create an assisted setup. An assisted setup, also
called a wizard, is a page that consists of one or more user input pages or steps. These steps are linked together,
enabling users to carry out infrequently performed tasks, such as configuration or specific business tasks. In the
client, the NavigatePage page doesn't an action bar. It's designed to have buttons at the bottom that let users
move back and forth through the steps by selecting the Back and Next buttons, until they finish by selecting the
Finish button.
An example in Business Central is the Company Setup assisted setup, page 1803.
SourceTable Set to the name of the table that stores the data for the
assisted setup.
Caption Set to the title that you want to show on the top of each
step of the assisted guide.
}
group(Step2)
{
Caption = '';
InstructionalText = '';
Visibility = Step2Visible;
field(Field2; "Field2")
{
ApplicationArea = All;
Caption = '';
}
}
group(Step3)
{
Caption = '';
InstructionalText = '';
Visibility = Step3Visible;
}
}
}
var
Step1Visible: Boolean;
Step2Visible: Boolean;
Step3Visible: Boolean;
Step: Option Start,Fill,Finish;
The individual group() controls define the content to display for the step, like text and data entry
fields. For example, use the Caption and InstructionalText properties to add text. Use field() controls
for source table fields.
The order of the group() controls doesn't necessarily determine the order of the steps in the assisted
setup. You'll add AL code to define the logic for when each step appears.
You can include group() controls within the root-level group() controls. These subgroups can be
useful for adjusting the layout fields on a step and adding captions and instructional text.
Because only one step can be shown at a time, you have to add logic to control when each step is shown.
To control the visibility, add the following code:
For each step, define a global boolean variable or a step number condition and apply it the group's
Visible property. The example, uses the boolean variables Step1Visible , Step2Visible , and
Step2Visible .
You'll then have to add AL code to change these variables depending on which step the user is
working on.
Define a global option variable that has a value for each step.
You'll use this variable in code to track which step is active.
NOTE
Multiline fields shown inside a step are shown without a gray background. This behavior allows you to write a list
of items or any formatted text that requires new lines.
trigger OnAction()
begin
NextStep(true);
end;
}
action(Next)
{
Enabled = NextEnable;
InFooterBar = true;
Image = NextRecord;
trigger OnAction()
begin
NextStep(false);
end;
}
action(Finish)
{
Enabled = FinishEnable;
InFooterBar = true;
Image = Approve;
trigger OnAction()
begin
Finished();
end;
}
}
}
var
BackEnable: Boolean;
NextEnable: Boolean;
FinishEnable: Boolean;
var
ToDoRec: Record "To-do";
In this example, the StoreRecordVar procedure is called from the Finished procedure used on the
actions.
trigger OnInit();
begin
...
LoadTopBanners();
end;
[IntegrationEvent(false, false)]
internal procedure OnRegisterAssistedSetup()
begin
end;
To add an assisted setup guide to the Assisted Setup page, add a codeunit that subscribes to the
OnRegisterAssistedSetup event. The following code illustrates how you can add the ToDoAssistedSetup
assisted setup guide. The example also creates a new category called Tasks on the Assisted Setup page a link
to ToDoAssistedSetup will be listed:
Example
This code example shows how to use a NavigatePage type page to create an assisted setup guide with three
steps, as illustrated in the following figures. The assisted setup lets users add entries to a to-do list, which is
stored in table To-Do . The code for the first step includes a part that reuses the page Attendee Wizard
Subform of the base application. This part allows users, when they first start the setup, to select the salesperson
that the to-do is for.
ST EP 1 ST EP 2 ST EP 3
Code
layout
{
area(Content)
{
group(Step1)
{
Visible = Step1Visible;
group("Welcome")
{
Caption = 'Welcome to the to-do assisted setup';
group(group11)
{
Caption = '';
InstructionalText = 'Use this guide to register a to-do task for you and your
team.';
}
}
group("Let's go")
{
Caption = 'Let''s go';
group(group12)
{
Caption = '';
InstructionalText = 'Select Next to get started.';
}
}
}
group(Step2)
{
Caption = 'Enter information about the to-do task';
Visible = Step2Visible;
group("11")
{
Caption = 'Add attendees and fill in details';
part(AttendeeSubForm; "Attendee Wizard Subform")
{
}
}
}
field("No."; Rec."No.")
{
ApplicationArea = All;
Visible = false;
}
field("Type"; Rec."Type")
{
ApplicationArea = All;
Caption = 'What type is the to-do?';
}
field("Date"; Rec."Date")
{
ApplicationArea = All;
Caption = 'What''s the start date?';
}
field("Description"; Rec.Description)
{
ApplicationArea = All;
Caption = 'Describe your to-do';
}
field("Start Time"; Rec."Start Time")
{
ApplicationArea = All;
Caption = 'What''s the start time?';
}
field("Duration"; Rec."Duration")
{
ApplicationArea = All;
Caption = 'How long does it last?';
}
field("Team To-do"; Rec."Team to-do")
{
ApplicationArea = All;
Caption = 'Team to-do';
}
field("All Day Event"; Rec."All Day Event")
{
ApplicationArea = All;
Caption = 'All Day Event';
}
field("Ending Date"; Rec."Ending Date")
{
ApplicationArea = All;
Caption = 'What''s the end date?';
}
field("Ending Time"; Rec."Ending Time")
{
ApplicationArea = All;
Caption = 'What''s the end time?';
}
// }
}
group(Step3)
{
Caption = 'That''s it!';
InstructionalText = 'Select Finish to save the to-do.';
Visible = Step3Visible;
}
group(StandardBanner)
{
Caption = '';
Editable = false;
Visible = TopBannerVisible and not FinishActionEnabled;
field(MediaResourcesStandard; MediaResourcesStandard."Media Reference")
{
ApplicationArea = All;
Editable = false;
ShowCaption = false;
}
}
group(FinishedBanner)
{
Caption = '';
Editable = false;
Visible = TopBannerVisible and FinishActionEnabled;
field(MediaResourcesDone; MediaResourcesDone."Media Reference")
{
ApplicationArea = All;
Editable = false;
ShowCaption = false;
}
}
}
}
actions
{
area(Processing)
{
action(Back)
{
ApplicationArea = All;
Caption = '&Back';
Enabled = BackEnable;
InFooterBar = true;
Image = PreviousRecord;
trigger OnAction()
begin
NextStep(true);
end;
}
action(Next)
{
ApplicationArea = All;
Caption = '&Next';
Enabled = NextEnable;
InFooterBar = true;
Image = NextRecord;
trigger OnAction()
begin
NextStep(false);
end;
}
action(Finish)
{
ApplicationArea = All;
Caption = '&Finish';
Enabled = FinishEnable;
InFooterBar = true;
Image = Approve;
trigger OnAction()
begin
Finished();
end;
}
}
}
trigger OnInit()
var
begin
EnableControls();
LoadTopBanners();
end;
trigger OnOpenPage()
begin
ToDoRec.Get();
ToDoRec.Init;
Rec := ToDoRec;
CurrPage.Update();
end;
var
BackEnable: Boolean;
NextEnable: Boolean;
FinishEnable: Boolean;
Step1Visible: Boolean;
Step2Visible: Boolean;
Step3Visible: Boolean;
Step: Option Start,Fill,Finish;
ToDoRec: Record "To-do";
TopBannerVisible: Boolean;
FinishActionEnabled: Boolean;
MediaRepositoryDone: Record "Media Repository";
MediaRepositoryStandard: Record "Media Repository";
MediaResourcesDone: Record "Media Resources";
MediaResourcesStandard: Record "Media Resources";
EnableControls();
end;
end;
end;
}
codeunit 50100 "AddToDoAssistedSetup"
{
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Guided Experience", 'OnRegisterAssistedSetup', '',
true, true)]
local procedure OnRegisterAssistedSetup()
var
AssistedSetup: Codeunit "Guided Experience";
GuidedExperienceType: Enum "Guided Experience Type";
AssistedSetupGroup: Enum "Assisted Setup Group";
VideoCategory: Enum "Video Category";
begin
if not AssistedSetup.Exists(GuidedExperienceType::"Assisted Setup",
ObjectType::Page,
Page::"ToDoAssistedSetup") then
AssistedSetup.InsertAssistedSetup(
'Add a to-do',
'Create a task for your team',
'Register a task for your team and assign people',
1,
ObjectType::Page,
Page::ToDoAssistedSetup,
Page::ToDoAssistedSetup,
AssistedSetupGroup::Tasks,
'',
VideoCategory::Uncategorized,
'');
end;
}
See Also
Page Parts Overview
2/6/2023 • 5 minutes to read • Edit Online
Parts are a special category of page designed to be embedded within another page. The hosting page can be
composed of one or more page parts. Parts are useful when designing richer user experiences, by displaying
information from a table that is different from the source table of the hosting page. Using parts is a great way to
reuse your code across multiple pages.
PA GET Y P E P URP O SE H O ST IN G PA GE T Y P ES
CardPar ts Flexible canvas that can be used to Role Centers; FactBoxes on pages of
display almost any page controls, such type Card, Document, Worksheet, List,
as fields, cue tiles, charts, images, or ListPlus; Step in a Wizard.
control add-ins.
Power BI Repor t Par ts Used for displaying Power BI reports. Role Centers; Fact boxes; Card pages
Design considerations
Part size
The size of a part is automatically determined by the user interface and will vary depending on where the part
has been embedded on the page, other content surrounding the part, and the overall available space of the
display target. Developers can't specify the preferred, minimum, or maximum height or width of a part.
Part actions
A part can define actions that operate on the fields within the part or navigate to another page. The area in
which a part is embedded on a page determines how the action menu is displayed.
In the FactBoxes or RoleCenter area of the hosting page, parts display a condensed action menu.
In the Content area of the hosting page, parts will only display an expanded action menu if they satisfy the
following rules:
parts are hosted on a card or document page.
parts aren't placed within a FastTab.
Collapsed or expanded parts
The area in which a part is embedded on a page determines whether the part can be collapsed.
In the FactBoxes or RoleCenter area of the hosting page, parts can't be collapsed.
In the Content area of the hosting page, parts can only be collapsed if they satisfy the following rules:
parts are hosted on a task dialog, card, or document page.
parts aren't placed within a FastTab.
Dynamics 365 Business Central automatically determines whether parts are initially displayed as expanded or
collapsed. For example, when a document page is opened the first time, the first two parts or FastTabs are
automatically expanded and all other parts and FastTabs are shown as collapsed to provide an optimal starting
experience. Users can change the state of a part to be expanded or collapsed directly within the user interface,
but developers can't specify the starting state.
Choosing the visibility of parts
Parts can be hidden on the hosting page to provide an optimal starting experience. For example, a part could be
hidden because it contains secondary content, or content that is needed by only some categories of users. To
hide a part, set the Visible property of the part to false on the hosting page.
When you design a page with hidden parts, users can choose to display those parts again using personalization
and role customization features in the user interface. Parts can be made visible programmatically using an
expression, for example, depending on whether the feature has been set up by administrators. Learn more about
Dynamic Visibility of Controls.
NOTE
Parts embedded on Role Center pages can't be made visible using expressions, because the hosting Role Center page can't
execute code.
See Also
AL Development Environment
Page Types and Layouts
FactBoxes
Headlines
List Parts
Card Parts
Power BI Report Parts Page Extension Object
Personalizing Your Workspace
Using Designer
Working with List Parts
2/6/2023 • 2 minutes to read • Edit Online
A ListPart page is a type of page part used to display a list of records embedded within another page. It consists
of a repeater, which presents the records of the source table as rows and columns, and optionally, of an action
bar.
A list part can be contained in Role Centers, in the FactBox and content area of other pages, in a tabular step in a
Wizard and as a subpage in a Document page. Depending on the type of the hosting page, a list part is subject
to different design constraints, which determine its position and dimensions. For more information, see Design
Considerations.
Example
The following code sample illustrates how to create a ListPart page, "Pending Shipments" , and how to
integrate it in the card page "Customer Card" .
page 50101 "Pending Shipments"
{
PageType = ListPart;
SourceTable = "Sales Header";
// Filter on the sales orders that are pending completion.
SourceTableView = WHERE("Completely Shipped" = CONST(False));
layout
{
area(Content)
{
repeater(General)
{
field("No."; "No.")
{
ApplicationArea = All;
}
field("Order Date"; "Order Date")
{
ApplicationArea = All;
}
field("Location Code"; "Location Code")
{
ApplicationArea = All;
}
}
}
}
}
layout
{
area(Content)
{
group(General)
{
field("No."; "No.")
{
ApplicationArea = All;
}
field(Name; Name)
{
ApplicationArea = All;
}
}
group(Shipments)
{
part("Pending Shipments"; "Pending Shipments")
{
// Filter on the sales orders that relate to the customer in the card page.
SubPageLink = "Sell-to Customer No." = FIELD("No.");
}
}
}
}
}
See Also
Page Parts Overview
Page Types and Layouts
Designing List Pages
Page Object
Page Extension Object
Adding a FactBox to a page
CardPart Pages
AL Development Environment
Using Designer
Working with Card Parts
2/6/2023 • 2 minutes to read • Edit Online
A CardPart page is a type of page part embedded within another page used to display additional data relevant
to the page that hosts it. It can display the data in the form of almost any page control, such as fields, cue tiles,
charts, images, or control add-ins. You can also define actions to operate on the card part page.
A card part can be placed in Role Centers, in the FactBox and content area of other pages or in a tabular step in a
Wizard. Depending on the type of the hosting page, a card part is subject to different design constraints, which
determine its position and dimensions. For more information, see Design Considerations.
C O N T RO L DEF IN IT IO N
Example
The following code sample illustrates how to create a CardPart page, "Customer Sales History" , and how to
integrate it in the FactBox area of the card page "Customer Card" .
layout
{
area(Content)
{
// Display data as cue tiles
cuegroup(Overview)
{
field("No. of Quotes"; "No. of Quotes")
field("No. of Quotes"; "No. of Quotes")
{
ApplicationArea = All;
// Make the cue interactive
DrillDownPageID = "Sales Quotes";
}
field("No. of Orders"; "No. of Orders")
{
ApplicationArea = All;
DrillDownPageID = "Sales Order List";
}
field("No. of Invoices"; "No. of Invoices")
{
ApplicationArea = All;
DrillDownPageID = "Sales Invoice List";
}
}
}
}
}
layout
{
area(Content)
{
group(General)
{
field("No."; "No.")
{
ApplicationArea = All;
}
field(Name; Name)
{
ApplicationArea = All;
}
}
}
See Also
Page Parts Overview
Page Types and Layouts
Page Object
Page Extension Object
Adding a FactBox to a page
ListPart Pages
AL Development Environment
Using Designer
Creating a Role Center Headline
2/6/2023 • 5 minutes to read • Edit Online
You can set up a Role Center to display a series of headline texts that appear one by one for a predefined period
of time.
The headlines can provide users with up-to-date information and insight into the business and daily work.
Typical categories of headlines might include:
My performance
My workday
Organizational health
Productivity tips
Cross-tenant insights (performance relative to peers)
Getting started information
IMPORTANT
Headlines will only appear in the Web client; they will not be shown on other client types.
NOTE
Headlines can display numbers and letters only. For example, headlines cannot display images.
Design concept
In development
In short, the Headline is basically a page that contains one or more fields. The page must be the HeadlinePar t
type page. Each field defines an individual headline to be displayed. The source for a field can be an expression
or a field in an underlying table.
The HeadlinePar t page is designed for Role Centers, that is, pages that have the type RoleCenter . If you
use a HeadlinePar t page on another page type, the part will not render in the client.
Using the OnDrillDown trigger, headlines can be made interactive, meaning that users can select the
headline to dig deeper into numbers or values that are shown in the headline or link to another page or
URL.
You can dynamically toggle visibility of a specific headline, for example based on its relevancy, by setting
the Visible property on the field.
There are only a few field properties that apply to fields that are used on a HeadlinePar t type page,
including Expression, Visible, ApplicationArea, Drilldown, and DrillDownPageID. All other properties are
ignored.
In the client
The Role Center will start by displaying the first visible headline that is defined on the HeadlinePart page. The
headline will appear for 5 seconds, then the next headline will appear for 5 seconds, and so on. When all the
headlines have been displayed, it will cycle back to the first headline, and continue from there.
If a headline is interactive, users can select the headline to open the target defined in the headline.
Users can pause on a headline by pointing to it.
Users can manually switch among headlines by selecting a corresponding dot that is displayed under the
headlines.
Users can personalize their Role Center to show or hide the Headline part as they like.
layout
{
area(content)
{
field(Headline1; hdl1Txt)
{
}
field(Headline2; hdl2Txt)
{
}
field(Headline3; hdl3Txt)
{
}
field(Headline4; hdl4Txt)
{
}
}
}
var
hdl1Txt: Label 'This is headline 1';
hdl2Txt: Label 'This is headline 2';
hdl3Txt: Label 'This is headline 3';
hdl4Txt: Label 'This is headline 4';
}
4. You can now add the HeadlinePar t page to the RoleCenter page.
TA G DESC RIP T IO N
<qualifier></qualifier> Specifies the title that appears above the headline. If you
omit this tag, the text HEADLINE will be used by default.
The Expression property must evaluate to the correct syntax. For example, looking back at the previous
example, the label hdl1Txt could be:
field(Headline1; hdl1Txt)
{
trigger OnDrillDown()
var
DrillDownURLTxt: Label 'https://go.microsoft.com/fwlink/?linkid=867580', Locked = True;
begin
Hyperlink(DrillDownURLTxt)
end;
}
{
field(Headline1; hdl1Txt)
{
}
field(Headline2; hdl2Txt)
{
}
field(Headline3; hdl3Txt)
{
Visible=false;
}
field(Headline4; hdl4Txt)
{
}
}
By adding fields under Group controls, you can hide or show more than one headline by setting the Visible
property on the Group control. For example, the following code hides headings Headline3 and Headline4 :
group(Group1)
{
field(Headline1; hdl1Txt)
{
}
field(Headline2; hdl2Txt)
{
}
}
group(Group2)
{
Visible=false;
field(Headline3; hdl3Txt)
{
}
field(Headline4; hdl4Txt)
{
}
}
IMPORTANT
Unlike other page types, the group control has no effect on the UI on pages of type HeadlinePar t . Its primary purpose
is to enable developers to group headlines for controlling visibility.
Dynamic visibility
With dynamic visibility, you can show or hide a headline based on a condition that evaluates to true or false .
To dynamically show or hide a headline when the HeadlinePar t page opens, the headline field must be
in group control, and you set the Visible property on the group control to the Boolean variable that
determines the visibility. For example, you could add code on the page's OnAfterGetRecord trigger that
evaluates the relevance of displaying Headline3 and results in a Boolean variable being set to true or
false .
To dynamically show or hide a headline while a page is open, you set the Visible property on the field
control to the Boolean variable that determines the visibility.
group(Group1)
{
field(Headline1; hdl1Txt)
{
}
field(Headline2; hdl2Txt)
{
}
}
group(Group2)
{
// Determines visibility when the page opens
Visible=ShowHeadline3;
field(Headline3; hdl3Txt)
{
// Determines visibility while the page is open
Visible=ShowHeadline3;
}
field(Headline4; hdl4Txt)
{
}
}
See Also
Pages Overview
Page Object
Add Power BI Report Parts to Pages
2/6/2023 • 7 minutes to read • Edit Online
APPLIES TO: Business Central 2022 release wave (v21) and later. For earliers versions, see Adding Power BI
Report Parts to Pages (Legacy).
Business Central integrates with Microsoft Power BI, enabling users to create Power BI reports based on
Business Central data. Users can view the reports from their Power BI workspaces, but also from the Business
Central client. For an overview about Power BI integration, see Business Central and Power BI.
Displaying a Power BI report in a Business Central page requires the page includes a Power BI Repor t part.
This part makes the connection to the Power BI Service, and lets users choose which report to display. Business
Central comes equipped with several pages that already include the Power BI Repor t part. For a list of these
pages, see Power BI FAQ.
For example, the following code adds a Power BI Report part to the Team Member Role Center page by using
a page extension.
pageextension 50101 TeamMemberRCPwrBiExt extends "Team Member Role Center"
{
layout
{
addfirst(rolecenter)
{
// Add the Power BI Report part on the role center page
part(PowerBIReportPart"; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports';
}
}
}
}
The following code adds a Power BI Report part to the Sales Invoices List page by using a page extension.
The InputSelection variant specifies the table field that uniquely identifies records in the list page. This field
should resolve to the primary key of the source table.
Example 1
This example extends the Sales Invoices page to include a Power BI Report part and uses the
SetCurrentListSelection method to use the update data in the report based on the primary key No. of the
Sales Invoice table.
pageextension 50100 SalesInvoicesListPwrBiExt extends "Sales Invoice List"
{
layout
{
addfirst(factboxes)
{
part("Power BI Report FactBox"; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports';
}
}
}
trigger OnAfterGetCurrRecord()
begin
// Gets data from Power BI to display data for the selected record in the list
// based on the primary key, in this case the "No." field.
CurrPage."Power BI Report FactBox".PAGE.SetCurrentListSelection(Rec."No.");
end;
}
For example, suppose you wanted to add two Power BI Report parts to the Team Member Role Center page.
In this case, you could use the following code:
pageextension 50101 TeamMemberRCPwrBiExt extends "Team Member Role Center"
{
layout
{
addfirst(rolecenter)
{
part(PowerBIReportPart; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports';
SubPageView = where(Context = const('TeamMemberReportsPart1'));
}
part(PowerBIReportPart2; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports';
SubPageView = where(Context = const('TeamMemberReportsPart2'));
}
}
}
}
You can do the same for FactBoxes on list and card type page. For example, suppose you wanted to add two
Power BI Report parts in the FactBox of the Sales Invoices List . In this case, you could use the following code:
}
part("Power BI Report FactBox 2"; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports 2';
SubPageView = where(Context = const('DetailedSalesInvoiceReports2'));
}
}
}
trigger OnAfterGetCurrRecord()
begin
CurrPage."Power BI Report FactBox 1".PAGE.SetCurrentListSelection(Rec."No.");
CurrPage."Power BI Report FactBox 2".PAGE.SetCurrentListSelection(Rec."No.");
end;
}
By calling SetPageContext , you can get the same results as you do with the SubPageView property. For example:
pageextension 50100 SalesInvoicesListPwrBiExt extends "Sales Invoice List"
{
layout
{
addfirst(factboxes)
{
part("Power BI Report FactBox 1"; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports 1';
}
part("Power BI Report FactBox 2"; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports 2';
}
}
}
trigger OnOpenPage()
begin
CurrPage."Power BI Report FactBox 1".PAGE.SetPageContext('DetailedSalesInvoiceReports1');
CurrPage."Power BI Report FactBox 2".PAGE.SetPageContext('DetailedSalesInvoiceReports2');
trigger OnAfterGetCurrRecord()
begin
CurrPage."Power BI Report FactBox 1".PAGE.SetCurrentListSelection(Rec."No.");
CurrPage."Power BI Report FactBox 2".PAGE.SetCurrentListSelection(Rec."No.");
end;
}
Example 2
Suppose you want to display the same reports on the Sales Invoices page and Sales Orders page. In this
case, you could use the following line of code in both the Sales Invoices and Sales Orders pages, where
Sales is the common context identifier:
pageextension 50100 SalesInvoicesListPwrBiExt extends "Sales Invoice List"
{
layout
{
addfirst(factboxes)
{
part("Power BI Report FactBox"; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports';
SubPageView = where(Context = const('sales'));
}
}
}
trigger OnAfterGetCurrRecord()
begin
CurrPage."Power BI Report FactBox".PAGE.SetCurrentListSelection(Rec."No.");
end;
}
trigger OnAfterGetCurrRecord()
begin
CurrPage."Power BI Report FactBox".PAGE.SetCurrentListSelection(Rec."No.");
end;
}
See Also
Get Started with AL
Adding a FactBox to a Page
Pages Overview
Publishing and Installing an Extension
Adding a FactBox to a Page
2/6/2023 • 6 minutes to read • Edit Online
A FactBox is the area that is located on the right-most side of a page and it is divided into one or more parts that
are arranged vertically. This area is used to display content including other pages, charts, and system parts such
as Notes, and Links. Typically, you can use a FactBox to display information that is related to an item on the main
content page. For example, on a page that shows a sales order list, you can use a FactBox to show sell-to
customer sales history for a selected sales order in the list as shown below.
NOTE
Only one FactBox area control is allowed on a page.
WARNING
You can add a part to the FactBox area that displays an existing page of the CardPart or ListPart type only. If you attempt
to use another page type, you will get an error.
Example
layout
{
area(FactBoxes)
{
part(MyPart; "Acc. Sched. KPI Web Srv. Lines")
{
ApplicationArea = All;
SubPageView = SORTING ("Acc. Schedule Name");
}
systempart(Links; Links)
{
ApplicationArea = All;
}
systempart(Notes; Notes)
{
ApplicationArea = All;
}
}
}
}
TIP
When used on Lists, FactBoxes can be used to show information about the entire list, or more contextually about the
user’s current selection; the currently selected rows. You can control the filter which gets passed to the FactBox that
determines its contextual contents.
System Parts
There are two system parts that you can define by using the systempart() keyword: Links and Notes :
VA L UE DESC RIP T IO N
VA L UE DESC RIP T IO N
Links Allows the user to add links to a URL or path on the record
shown in the page. For example, on an Item card, a user can
add a link to the supplier's item catalog. The links will appear
with the record when it is viewed. When a user chooses a
link, the target file opens.
Notes Allows the user to write a note on the record shown in the
page. For example, when creating a sales order, a user can
add a note about the order. The note will appear with the
item when it is viewed.
NOTE
The systempart keyword also includes an Outlook and MyNotes value, for example,
systempart(Outlook; Outlook) . These values are only supported by the Dynamics NAV Client connected to Business
Central (which has been deprecated after Business Central Spring 2019). These values are ignored in the Business Central
Web client.
layout
{
area(content)
{
repeater(Control)
{
field("No."; "No.")
{
ApplicationArea = All;
}
}
area(FactBoxes)
{
part(CustomerList; "Customer Details FactBox")
{
ApplicationArea = All;
SubPageLink = "No." = FIELD ("No.");
}
}
}
}
Performance considerations
Having a page composed of multiple FactBox pages that each process data from different sources can degrade
performance. To improve responsiveness and the time it takes to load the page, Business Central 2020 release
wave 2 and later optimizes the sequence in which content is loaded. The sequence is as follows:
1. Content on the hosting page is loaded first, and users can immediately begin interacting with it.
2. The FactBox pane is loaded next, where each FactBox is loaded independently in sequence starting from the
top.
a. FactBoxes having the Visible property evaluate to false won't be loaded.
b. FactBoxes that aren't within view are only loaded when the user scrolls them into view. If the FactBox
pane is collapsed, no FactBoxes are loaded until the user expands the FactBox pane.
Below are some practical tips to help you make the most of this optimization:
Consider hiding any FactBoxes that represent secondary content that only some users will require. Learn
more about Choosing the Visibility of Parts.
For FactBoxes that require heavy processing, consider processing in the page background task. Learn more
about Using Page Background Tasks.
Avoid having triggers on the hosting page that call into a FactBox because this condition forces the FactBox to
ignore performance optimizations and load along with the content of the hosting page, adding to the total
loading time.
FAQ about performance
Are any FactBox triggers run when the FactBox is hidden?
No. The trigger is only run when the FactBox is visible and within the user's view.
How often are triggers run if the FactBox pane is expanded, collapsed, and then expanded again?
In this scenario, the OnOpenPage trigger is only run the first time. Once a FactBox is loaded, it isn't loaded again
for as long as the page remains open.
Are FactBoxes processed asynchronously?
No. This optimization is simply a controlled sequence in which triggers are run, still within the same session as
the hosting page. For more information about asynchronous processing in the background, see Designing page
parts for page background tasks.
Does this optimization work with SubPageLink or SubPageView properties?
The use of these properties has no effect on the sequence of loading content on a page. Using properties such
as SubPageView is preferred to writing trigger code to update a FactBox.
Does this optimization apply to parts that aren't FactBoxes?
This optimization doesn't apply to Role Center pages. When parts are used in the content area of a page, such as
on a Card page, they aren't loaded if their Visible property evaluates to false .
Can I force a FactBox to load along with page content?
There's no AL API to force FactBoxes to load along with the content of the hosting page.
Can I set the FactBox pane to start collapsed on all pages?
No. The default state of the FactBox pane is set by the Business Central platform and modifed by the user.
Does the experience vary on different browsers?
Each browser has its own definition of whether a FactBox is considered within view or not. For example, opening
Business Central in a new browser tab and quickly switching back to the original tab may pause loading of any
FactBoxes in the new tab.
Does this optimization apply to other form factors?
This applies to desktop, tablet, and phone clients.
See Also
Pages Overview
Page and Page Extension Properties Overview
Designing Role Centers
Using Designer
Arranging Fields on a Fasttab
Actions Overview
Field Arrangement on FastTabs
2/6/2023 • 3 minutes to read • Edit Online
FastTabs in Dynamics 365 Business Central allow users to find key information on a page by displaying the data
in separate groups. This article describes how individual fields are arranged on a FastTab and ways that you can
change the layout.
Organizing data using FastTabs helps users to find key information quickly, while at the same time giving an
overview of areas that otherwise would remain hidden. For example, the customer card page displays customer
information in the following categories: General, Communication, Invoicing, Payments, Shipping, and Foreign
Trade. Each category is a separate FastTab that can be expanded or collapsed, making it easier for users to focus
on one subject at a time. On task pages, a FastTab typically represents a single step in a task.
Pages automatically adjust to the available space on the screen. If horizontal space is reduced, a FastTab will
adapt and distribute fields into a single column. Similarly, a FastTab will automatically distribute fields into more
than two columns to take advantage of wider screens.
FastTab example
Creating a FastTab is easy. A FastTab is a group control directly within the content area of a card, document, or
task page. The following example shows how you can create a FastTab containing a pair of fields.
page 50101 SimpleCustomerCard
{
PageType = Card;
SourceTable = Customer;
layout
{
area(content)
{
group(GeneralFastTab)
{
CaptionML = ENU = 'General';
field(Name; Name)
{
ApplicationArea = All;
}
field(Address; Address)
{
ApplicationArea = All;
}
}
}
}
}
NOTE
If a group doesn't specify the CaptionML property or this is set to an empty value, it's considered to be a group used
only for structural purposes. This includes FastTabs. Structural FastTabs look and behave differently, for example, they can't
be collapsed by users unless they include the Show more action.
See Also
Arranging Fields Using Grid and Fixed Controls
Pages Overview
Using Designer
Table in Dynamics 365 Business Central
Arranging Fields in Rows and Columns Using the
Grid Control
2/6/2023 • 3 minutes to read • Edit Online
By default, fields in a FastTab are arranged automatically in two columns that are based on the number of fields.
For more information, see Field Arrangement on a FastTab. You can use a Grid control or a Fixed control to
arrange fields in rows and columns on a page and design it to look like a grid-like format or a matrix-like
format. To understand the differences between the two controls to help you determine which control to use, see
Comparing Grid and Fixed controls.
NOTE
Grid control for arranging page fields is partially supported.
Using the Grid control, you can arrange the fields manually in one or more rows and columns. The Grid control
gives you the following options:
Set up your grid row-by-row or column-by-column.
Span a field across multiple rows and columns.
Show or hide field captions.
The following screenshot shows how the resulting page looks like from the Web client.
Setting fields to span multiple rows and columns
You can set a field to span multiple rows or columns. When you set a field to span multiple rows, the field
occupies the cells in the rows below it, and existing fields in the occupied cells are moved to the right. When you
set a field to span multiple columns, the field occupies the cells in the columns to the left, and existing fields in
the occupied cells are moved to the right. You can also set a field to span multiple rows and columns.
IMPORTANT
The Dynamics 365 Business Central web client does not support row and column spanning for fields. If the page displays
in the Dynamics 365 Business Central web client, the fields appear without spanning.
For example, the following figure illustrates a Grid control that consists of six fields arranged in three rows.
If you set Field 2 to span two rows, then the following layout is displayed:
When you set a field to span multiple columns, the field occupies the cells in the columns to the right, and
existing fields in the occupied cells are moved to the right. Using the previous Grid example, if you set Field 2
to span two columns instead of two rows, the following layout is displayed:
You can also set a field to span multiple rows and columns. For example, if you set Field 2 to span two rows and
two columns, the following layout is displayed:
+
To set a field to span rows and columns
When you set the Grid control, the fields of that group can be set to span rows or columns.
To set a field to span one or more rows, set the value of the RowSpan property to the number of rows.
For more information, see RowSpan Property.
To set a field to span one or more columns, set the value of the ColumnSpan property to the number of
columns. For more information, see ColumnSpan Property.
NOTE
The RowSpan and ColumnSpan properties on fields in the grid layout are not supported in the Dynamics 365 Business
Central web client. The Rows layout on the grid control itself is not supported.
See Also
Field Arrangement on FastTabs
Arranging Fields Using Grid and Fixed Controls
Arranging Fields in Rows and Columns Using the Fixed Control.
Arranging fields in rows and columns using the fixed
control
2/6/2023 • 3 minutes to read • Edit Online
By default, fields on a FastTab are arranged automatically in two columns based on the number of fields. For
more information on how the fields are placed on a page, see Field Arrangement on a Fasttab. To manually
arrange fields, you can either use a Grid control to design the page to look like a grid-like format, or a fixed
control to design the page to look like a matrix-like format. To understand the differences between the two
controls to help you determine which control to use, see Comparing Grid and Fixed controls.
IMPORTANT
Fields in a fixed layout are not editable even if the Editable property is set to true . However, if the field drills down to a
page where the field source is defined, then you can modify the field. For more information, see Editable Property.
You can also use a fixed control to display information in the details section of a Worksheet page. If you're using
the CRONUS International Ltd. demonstration database, then you can see examples of these uses in page 151,
Customer Statistics, and page 40, Item Journal.
Adding fields
You can add fields directly in the fixed control. However, when you add fields directly in the fixed control, all the
fields will display in an equal size and the larger fields will get compressed. The following illustration shows the
resulting field layout on a page.
The group control caption appears as the column header, and the field control captions appear as the row
headers. If you add two more group controls that contain fields, then the layout on the page will resemble the
following illustration.
NOTE
Only the captions of fields in the first column define the row headings. Therefore, only the field captions for the first group
control appear. The field captions in other group controls are ignored.
NOTE
The fields in the fixed controls in the illustration are not in a group control. If they were in a group control, then they
would follow the same principle as described in the previous section about how to group fields.
IMPORTANT
In previous versions, having a fixed control directly under a content area was supported. However, in Dynamics 365
Business Central, you must make sure that the fixed control is nested in a Group control. For more information, see
Supported Structure for Using the Grid and Fixed Controls.
See Also
Field Arrangement on a FastTab
Pages Overview
Arranging Fields Using Grid and Fixed Controls
Arranging Fields in Rows and Columns Using the GridLayout Control
Field Groups (DropDown Controls)
2/6/2023 • 2 minutes to read • Edit Online
A field group in table or table extension objects defines the fields to display in a drop-down control on pages
that use the table.
In a table object, you define field groups by first adding a fieldgroups control, and then adding one or more
fieldgroup(<Name>; <Field>) keyword for each group, where:
<Name> can be either DropDown , for adding fields to the drop-down control, or Brick to display data as tiles.
<Field> is a comma-separated list of the fields, by name, to include in the group.
NOTE
A field group can also be used to specify fields that display when list type pages are shown in the tile view. For more
information, see Displaying Data as Tiles.
fieldgroups
{
fieldgroup(DropDown; Field1, Field2)
{
}
fieldgroup(Brick; Field1, Field2)
{
}
}
NOTE
The fieldgroups keyword cannot be inserted before the key control.
IMPORTANT
The syntax for using a DropDown, must be exactly DropDown with the right capitalization.
In a table extension object, the fieldgroups control allows you to add more fields to a field group defined for
the table object. This can be done by using the addlast(<name>; <field>) keyword.
WARNING
The server will remove the duplicates, if multiple extensions attempt to add the same field more than once. A field can
only be added to the field group once.
fieldgroups
{
addlast(DropDown; V02Max) { }
}
}
See Also
Debugging in AL
Developing Extensions
Microsoft .NET Interoperability from AL
Field Calculation Methods
2/6/2023 • 5 minutes to read • Edit Online
CalcFields method
CalcFields updates FlowFields. FlowFields are automatically updated when they are the direct source expressions
of controls, but they must be explicitly calculated when they are part of a more complex expression. For more
information about Flowfields, see FlowFields.
CalcFields has the following syntax.
When you use FlowFields in AL methods, you must use the CalcFields method to update them.
In the following example, the SETRANGE method sets a filter and then the CalcFields method calculates the
Balance and Balance Due fields by using the current filter and performing the calculations that are defined as the
CalcFormula properties of the FlowFields. This example requires that you create the following variable.
Customer.Get('01454545');
Customer.SetRange("Date Filter",0D,TODAY);
Customer.CalcFields(Balance,"Balance Due");
Message('The Balance is %1 and your Balance Due is %2',Customer.Balance,Customer."Balance Due");
CalcSums method
CalcSums calculates the sum of one or more fields that are SumIndexFields in the record.
CalcSums has the following syntax.
custledgerentry.SetCurrentKey("Customer No.");
custledgerentry.SetRange("Customer No.",'10000','50000');
custledgerentry.SetRange("Posting Date",0D,TODAY);
custledgerentry.CalcSums("Sales (LCY)");
Message('%1 calculated sales',custledgerentry."Sales (LCY)");
FieldError method
FieldError triggers a run-time error after it displays a field-related error message.
FieldError has the following syntax.
Record.FieldError(Field, [Text]);
This method is very similar to the Error method. However, in the FieldError method, if the name of a field is
changed, for example, translated to another language, in the Table Designer, the message from the FieldError
method will reflect the current name of the field.
The following examples show how to use the FieldError method. These examples require that you create the
following variable.
Item.Get('70000');
If Item.Class <> 'HARDWARE' then
Item.FieldError(Class);
If item 70000 has a Class other than HARDWARE, then you receive the following error message:
Class must not be OTHER in Item No. ='70000'.
If the text or code field contains the empty string, then you receive the following error message:
You must specify Class in Item No.='70000'.
If the field is a numeric field and is empty, it is treated as if it contains the value 0 (zero), and then you receive the
following error message:
Class must not be 0 in Item No.='70000'.
You can change the default text that is displayed in the error message. The following example shows how to use
the FieldError method and change the default text. This example requires that you create the following variable.
VA RIA B L E DATA T Y P E
Class Code
FieldName
FieldName returns the name of a field. It has the following syntax.
Name := Record.FieldName(Field);
You could just use the name of the field. However, using FieldName lets you create messages that always contain
the name of the field, even if the name of the field is changed.
This example shows how to use FieldName together with FieldError.
Init
Init initializes a record. It has the following syntax.
Record.Init();
If a default value for a field has been defined by using the InitValue property, this value is used for the
initialization. Otherwise, the default value of each data type is used.
NOTE
Init does not initialize the fields of the primary key.
TestField method
TestField tests whether a field contains a specific value. It has the following syntax.
Record.TestField(Field, [Value]);
If the test fails, that is, if the field does not contain the specified value, an error message is displayed and a run-
time error is triggered. This means that any changes that were made to the record are discarded. If the value that
you test against is an empty string, the field must have a value other than blank or 0 (zero).
The following example tests the Language Code field for customer number 10000 in the Customer table and
tests whether the Language Code is ZX. This example requires that you create the following variable.
VA RIA B L E DATA T Y P E SUBT Y P E
customer.Get('10000');
customer.TestField("Language Code",'ZX');
Validate method
Validate calls the OnValidate trigger of a field. It has the following syntax.
Record.Validate(Field [, NewValue]);
When you enter an account number in a ledger, code in a table trigger is executed to transfer the name of the
account from the chart of accounts. If you enter an account number in a batch job, the code which transfers the
name of the account is not automatically executed. The following example executes the appropriate field-level
trigger code. This example requires that you create the following variable.
The Validate method is useful for centralizing processing, which makes your application easier to maintain.
For example, if the OnValidate trigger of the Total Amount field performs a calculation that uses values from
three other fields as operands, the calculation must be performed again if the contents of any one of these fields
changes. You should avoid entering the calculation formula in the OnValidate triggers of each field because this
can create errors if the calculation formula has to be changed later and you have to update the code in all the
triggers. Instead, you should enter the calculation formula in the OnValidate trigger of only one of the fields and
call this trigger code from the OnValidate triggers of the other fields.
See Also
AL Methods
Formatting Decimal Values in Fields
2/6/2023 • 5 minutes to read • Edit Online
This article describes how you can format the decimal values that appear in fields on table, pages and reports.
For example, you can change how the data appears in a Cue on the Role Center page. To format data, you use a
combination of the AutoFormatType Property, AutoFormatExpression Property, and DecimalPlaces Property of
the field. These properties work together to enable you to specify the following:
Display amounts and unit amounts in another currency.
Specify the number of decimal places.
Specify whether to display a thousand separator.
Specify characters before and after the value, such as currency signs or %.
Implementation overview
When a field is used on a page or report, you can set the AutoFormatType and AutoFormatExpr properties
directly on the page field or report field (column), or you can set them on the underlying table field. If you
specify the properties on the table field, then the format applies wherever the field is used. Specifying the
properties on the page or report field will only apply the format to the specific page or report. If you specify the
properties on the table field and the page or report field, then the settings on the page or report field take
precedence.
When you use the AutoFormatType and AutoFormatExpression properties to format a field, two events are
raised by the system codeunit 45 Auto Format : OnResolveAutoFormat and OnAfterResolveAutoFormat.
0 Set to the number of decimal places Use this configuration when you want
that you want to display for the value. to format the decimal value according
the Standard Format 0 (which is the
default format) with a specific number
of decimal places.
AutoFormatType = 0;
DecimalPlaces = 0;
1 Set to return a currency code, such as Use this configuration when you want
USD or IDR. The blank currency code to format the data as an amount. For
'' denotes LCY and is the default example, a sales order will use two
value. decimals when the currency is defined
as US dollar and no decimals when the
currency is defined as IDR (Indonesian
rupiah). For example:
AutoFormatType = 1;
AutoFormatExpression = 'IDR';
10 Set to the property according to the Use SubType 1 to add the currency
following syntax: symbol and use the amount type
precision. You use SubType 2 for unit
'[SubType][,<currencycode or amount precision. For example, set the
expression>[,<PrefixedText>]]'
property to '1,USD' to add the $
symbol, like $543.21 .
SubType can be 1 , 2 , another
number, or omitted: AutoFormatType = 10;
AutoFormatExpression = '1,USD';
1 sets the value to an amount type
(see 1 above). 2 sets the value to a If you omit the SubType, you can use
unit amount type (see 2 above). The this configuration to customize the
syntax for these two settings is: format based on one of the standard
formats. This option enables you to
'SubType,<currencycode[,
<PrefixedText>]'
specify characters before and after the
decimal value, such as currency signs $
and percent %.
If you omit the subtype or use a
number other than 1 or 2, the syntax
For example, if you want to prefix the
is:
decimal value with a $ , include a
thousand separator, and have a
'<CustomNumber>, <expression>[,
<PrefixedText>]' maximum of two decimal places, such
as $76,453.21 , then you can set the
where <expression> sets the properties to:
precision and one of the standard
AutoFormatType = 10;
formats. For more information, see
Standard Formats. AutoFormatExpression =
'$<precision, 2:2><standard
format, 0>'
AutoFormatType = 10;
AutoFormatExpression =
'<precision, 1:1><standard
format,0>%'
11 Set the property to the standard Use this option when you want full
format as explained below. For control over the formatting. The
example: format string will be applied exactly as
specified in the AutoFormatExpr
'<Precision,3:3><Standard property.
Format,0>'
Precision
The precision determines the minimum and maximum number of decimal points for values. The precision takes
the format <precision,minimum:maximum> . For example, <precision,minimum:maximum> sets the data with a
minimum of 2 and a maximum of 3 decimal places.
Standard formats
The following table describes the standard formats that are available for the AutoFormatExpr property when
the AutoFormatType property is set to 10.
See Also
AutoFormatType Property
AutoFormatExpression Property
DecimalPlaces Property
Actions overview
2/6/2023 • 7 minutes to read • Edit Online
In Dynamics 365 Business Central, actions are displayed at the top of each page, referred to as the action bar. In
this article, you learn about different types of actions, and how you can enable users to quickly locate the actions
they want to use.
The actions can be displayed in different menus on the action bar.
You can choose from the following action menus to place the actions in the specified area.
Actions menu area(processing) Role Center, list, card, User tasks Post a sales order
and task pages
New document area(creation) List, card, Role Center Actions that appear New sales invoice
group in Actions pages, and task under the New
menu pages group. Opens a new
Dynamics 365
document.
Navigate menu area(navigation) List, card, and task Links to other pages Prices
pages in Dynamics 365
Business Central.
Report menu area(reporting) Role Center, list, card, A list of available Customer Top 10 List
and task pages reports.
Navigation menus area(sections) Role Center pages The top-level Posted sales invoices
navigation consists of
one or more root
items that expand to
display a submenu of
links to other pages.
Types of Actions
TIP
If you used to work in Microsoft Dynamics NAV, you can get an overview of the mapping between actions in the
Differences in the Development Environments topic.
Each page has a different set of actions depending on the page type, and the processes that the page supports.
In order to create the appropriate set of actions for a particular page, you should have a good understanding of
your customer's business processes.
Each process in an organization has several actions associated with it. You should try to create a full set of
actions that mirror all tasks and processes that are performed.
For example, the Sales Orders list page at CRONUS International contains all actions related to processing sales
orders. During user configuration and personalization, some of these actions may be hidden or promoted to the
ribbon. Therefore, you must create a full set of actions for the customer.
NOTE
With Business Central 2022 release wave 2, the way that you promote actions on pages or page extensions has changed.
Promoting actions is defined in a specific section of the page definition and contains a reference to the action. For more
information, see Promoted Actions.
Pages can have the following actions as described in each section below.
Actions menu
The Actions menu is a displayed in the action bar on all page types, and contains relevant tasks for the current
page. Typically, you add processing tasks and creation tasks in the Actions menu. To add processing actions such
as posting a sale order, you must use the processing action area. They're regular daily tasks. Therefore, they
must be on the Actions menu. For examples on how to add actions to the Actions menu, see Adding Actions to a
Page.
Some examples from the Customer page are as follows:
Sales Invoice
Sales Quote
Sales Credit Memo
Ledger Entries
Invoice Discounts
Prices
Line Discounts
You can add actions to the Actions menu, group actions together under action sub menus, or promote them to
the ribbon. For examples of how to use actions, see Page Object and Page Extension Object.
New Document menu
The New Document menu is often displayed both as a top-level menu in the actions bar and as a sub menu in
the Actions menu. You can use this menu to open new documents within Dynamics 365. You can add an action
to create a new document such as creating a new sales invoice. This action displays in a separate menu called
New document in the Actions menu. To add to the New document menu, you must use the creation action
area.
For example, on the Customers page, if the order processor wants to create a new invoice, the order processor
can open the new page directly from the Actions menu, which is useful when creating new sales invoices daily.
Navigate menu
The Navigate menu is displayed after the Actions menu in the action bar. Rather than providing tasks for the
user, this menu provides additional information by taking the user to a specific page in Dynamics 365. To add a
page link in the Navigate menu, you must use the navigation action area. These actions act like a bookmark to
enable quick access to view a page.
NOTE
You should not add a Navigation action to a Role Center page.
Report menu
The Report menu is displayed after the Navigate menu in the action bar. The Reports menu lists the reports
most relevant to a page. If a user doesn't require a Report menu, then the menu is hidden. Sometimes it's
relevant to promote the most important reports to the top-level in the action bar to save the user from too
many clicks. To create an action in the Report menu, you must use the reporting action area.
Promoted Actions
NOTE
With Business Central 2022 release wave 2, the way that you promote actions on pages or page extensions has changed.
Promoting actions is defined in a specific section of the page definition and contains a reference to the action. For more
information, see Promoted Actions.
Promoted actions are actions that are set up on the Actions, Navigate, or Reports menus in the action bar, but
are also configured to display in custom menus in the action bar. Although the actions are set up on the Actions,
Navigate, or Report menus, you can choose to hide them on these menus and only show them in custom
menus. Promoted actions can be used on Card, Document, List, ListPlus, and Worksheet pages to provide quick
access to common tasks that appear under the Home tab.
With Business Central 2022 release wave 2, it's possible to define page actions that trigger a Power Automate
instant flow by using custom actions. Custom actions are defined next to other actions, but use the
customaction keyword instead. The syntax is as follows:
customaction(MyFlowAction)
{
CustomActionType = Flow;
FlowId = '<the-GUID-identifying-the-Power-Automate-Flow>';
FlowEnvironmentId = '<the-GUID-identifying-the-Power-Automate-environment>';
}
For a customaction , the CustomActionType Property must be set to Flow . The FlowId Property and the
FlowEnvironmentId Property must specify the IDs of the flow and the environment of the flow. These properties
make up the target flow identity, allowing the client to trigger the flow when the custom action is invoked.
TIP
You can get the flow and environment IDs in Power Automate. Sign in to Power Automate and open the flow for editing.
Then, get the environment ID and flow ID from the URL in the browser address, which has a format like:
https://make.powerautomate.com/environments/<environment ID>/flows/<environment ID> .
To learn more about Power Automate flows with Business Central, see Power Automate Integration Overview.
actions
{
area(Report)
{
action(Report 1)
{
RunObject = report "Report1";
}
NOTE
Prior to Dynamics 365 Business Central 2019 Wave 2, in the client, submenus were automatically placed before single
actions on the same level. This means, for example, group Group2 appears before the action Repor t 2 .
Actions at runtime
An action can trigger code to run, such as posting a document or otherwise modifying a record in a table. When
a user chooses an action, one of the following pieces of logic will happen in addition to the code that the action
itself triggers:
If the page is empty and no longer shows any records, the page is reinitialized with default values.
If the page does show records, and the current state is within the page filters boundary, the
OnAfterGetRecord trigger is run on the page.
If the current record that the page showed is now outside the filter but there are other records within the
filter, the OnFindRecord trigger is called, and the OnAfterGetRecord trigger is run on the next record
with the given filters.
The logic runs in the transaction that the action triggered. This can cause the application code to result in users
locking the whole table when they thought they were only modifying one record.
To avoid users accidentally locking tables, you can use the SetSelectionFilter method before your code passes
the record variable to the processing codeunit, for example. The following code example illustrates the code on
the OnAction trigger on an action on a page.
if confirm('Are you sure you want to call this codeunit?', true) then begin
CurrPage.SetSelectionFilter(Rec);
codeunit.Run(50000, Rec);
end;
See Also
AL Development Environment
Developing Extensions in AL
Pages Overview
Promoted Actions
Adding actions to a page
2/6/2023 • 6 minutes to read • Edit Online
This topic shows how to create new actions, how to add actions to a page, and how to preview them in the
Dynamics 365 web client. In Dynamics 365, actions can be displayed in the action bar of all pages and grouped
together under the following actions menus:
Promoted action categories (legacy)
Actions
Navigate
Report
NOTE
With Business Central 2022 release wave 2, the way that you promote actions on pages or page extensions has changed.
Promoting actions is defined in a specific section of the page definition and contains a reference to the action. For more
information, see Promoted Actions.
Before putting an action on a page you should think about the business processes that the action supports. For
example, on page 42, the Sales Orders list page, the Actions button contains actions for all tasks related to
processing sales orders. Creating these actions can make it easier for the order processor to perform their daily
tasks, such as posting sales orders and creating new customer orders.
For more information about different types of actions and where to use them, see Actions Overview.
TIP
After you have added actions to a page, you can use Designer to alter the actions, like moving an action to or from a
promoted category, hiding and action or action group, and more. For more information, see Using Designer.
NOTE
Actions can only be linked to a page, or to a group control. Actions cannot be linked to fields, or parts on a page.
actions
{
// Adds the action called "My Actions" to the Action menu
area(Processing)
{
action("My Actions")
{
Promoted = true;
PromotedCategory = Process;
ApplicationArea = All;
trigger OnAction()
begin
Message('Hello World');
end;
}
}
area(Creation)
{
// Adds the action "My New document" to the New Document group in the Actions menu.
action("My New document")
{
ApplicationArea = All;
RunObject = page "Customer Card";
Image = "1099Form";
}
}
area(Navigation)
{
// Adds the action called "My Navigate" to the Navigate menu.
action("My Navigate")
{
ApplicationArea = All;
RunObject = page "Customer Card";
}
}
area(Reporting)
{
// Adds a submenu called "My Label" to the Report menu.
group(NewSubGroup)
{
Caption = 'My label';
group(MyGroup)
{
// Adds the action "My Report" to the My Label submenu.
action("My Report")
{
ApplicationArea = All;
RunObject = page "Customer Card";
}
}
}
}
}
}
NOTE
Actions can be assigned to a page by setting the RunObject property, or by adding a trigger to a Codeunit. For more
information, see RunObject Property and Codeunit Triggers.
The promoted action menus are always displayed first so the promoted actions provide quick access to common
tasks, and users don't have to browse through a menu to access them. Add the Promoted property to add
actions to the promoted action menu. For more information on how to add promoted actions, promoted
categories, and examples, see Promoted Actions.
You can assign different icons for your actions from the Dynamics 365 image library. For more information, see
Image Property.
action(DoThisAction)
{
ApplicationArea = All;
ShortCutKey = 'Shift+Ctrl+D';
trigger OnAction()
var
begin
DoThis();
end;
}
NOTE
Actions are used in different contexts to drive different experiences in the user interface. Be aware that keyboard shortcuts
are not supported across all contexts. For example, the ShortcutKey property is not supported for actions defined in
area(sections) or area(embedding) .
This article provides guidelines for organizing actions when creating, extending, and customizing pages in
Business Central. The guidelines follow the principles and precedence of Microsoft 365 applications, such as
Outlook, with the primary goal of providing a familiar and efficient command presentation to the Business
Central users.
See also
Page Types and Layouts
Actions in AL
Adding Actions to a Page
How to Promote Actions
Organizing Promoted Actions
Common Promoted Action Groups
Action Bar Improvements
Behavioral Changes for Promoted Actions
Pages with Action Bar Improvements
Promoted Actions
2/6/2023 • 8 minutes to read • Edit Online
You can promote actions that are used more often than others and thereby ensure quick access to them. This
type of actions is called promoted actions. Promoted actions are set up on the Actions, Navigate, or Report
menus in the action bar, but are also configured to display on the Home tab. You can, however, choose to hide
them on the Actions, Navigate, or Report menus and only show them on the Home tab.
Promoted actions can be used on Card, Document, List, ListPlus, and Worksheet pages to provide quick access
to common tasks that appear under the Home tab.
With Business Central 2022 release wave 2, the way that you promote actions on pages or page extensions has
changed. Promoting actions is defined in a specific section of the code for a page and it contains a reference to
the action. The new syntax provides more visibility in code, because the promoted actions are grouped in a
separate section. And to the end user, the personalization experience is improved, adding options for promoting
actions.
In Business Central the new action bar is enabled when the feature flag Modern Action Bar on the Feature
Management page is set to Enabled. The flag can be switched off to simulate legacy behavior, but the
promoted action code in the base application uses the actionref syntax.
NOTE
The legacy syntax for defining promoted actions is still supported in releases going forward, but it's recommended to
implement the new syntax.
NOTE
Removing the Promoted property on a published action is considered a breaking change. For more information, see
AppSourceCop Error AS0031 and UICop Warning AW0013.
To define promoted actions, you specify an area(Promoted) in the actions section of a page or a page
extension. Inside the area(Promoted) section, you can specify one or more actionref sections. An actionref is
an object type that references an action on the page, and by adding it in the promoted area section it's promoted
in the UI. An actionref can only be defined in the area(Promoted) section. You can either create groups in the
area(Promoted) for the actionref references, or you can add actionref sections directly. An actionref
inherits the properties of the referenced action. For page extensions, you can add to existing groups and you can
add new groups.
For more information about behavioral changes introduced with the new action bar, see Behavioral Changes for
Promoted Actions.
Split buttons for actions
As part of the new programming model for promoted actions, you can combine multiple actions into a split
button to help organize the actions that you're promoting, thereby reducing clutter and improving coherence
and closeness of related actions. A split button can be defined for a page action group, which renders as a
combination of a button and a menu. Use the ShowAs property to specify that a certain page action group
should render as a split button. For more information, see ShowAs Property.
Syntax example
This example illustrates a page with the promoted area syntax. In the example the area(Processing) section
defines the MyBaseAction action for the page, which triggers a Hello world message. The MyBaseAction will be
available from under the Processing group in the action bar and it will be promoted because it's added to the
area(Promoted) section, which defines the actions to promote. The example illustrates that you can group your
actionref sections, or specify them ungrouped. The actionref(MyPromotedActionRef; MyBaseAction) promotes
the defined MyBaseAction so that it, in addition to being placed in the Processing group, also is promoted for
easy access on the page.. Also, the example illustrates using a split button for Group2 where two actionref s
group(Group2)
{
ShowAs = SplitButton;
actionref(MySplitButtonPromotedActionRef; MyBaseAction)
{
}
actionref(MyOtherSplitButtonPromotedActionRef; MyBaseAction)
{
}
}
}
area(Processing)
{
action(MyBaseAction)
{
Visible = true;
trigger OnAction()
begin
Message('Hello world!');
end;
}
}
}
}
You can promote any command from the existing actions menus to the ribbon. If there are no promoted actions,
the ribbon remains hidden. To promote an action on the Home tab, you set the Promoted property of the
action. If you want to display the action only on the Home tab, then you add an extra step to set the
PromotedOnly property. For more information, see Promoted Property and PromotedOnly Property.
Promoted actions can be grouped. You can add promoted actions by different grouped categories. Typically,
promoted actions are displayed in the ribbon of a page. You can organize promoted actions into different
categories, where each category is indicated by a caption in the ribbon. You define up to 10 categories for a
page. The following figure illustrates a page that has promoted actions under the following categories.
New Document
Request Approval
Customer
You assign a promoted action to a category by setting the PromotedCategor y property of the action. By
default, these category names correspond to the captions that are displayed for the category on the page in
Dynamics 365 Business Central. You'll typically want to change the captions, especially the Category4 through
Category10 captions. See the table below for the default PromotedCategor y values. To change the default
captions, set the PromotedActionCategories property. You type the values of the
PromotedActionCategories where each caption is separated with a comma as shown below:
PromotedActionCategories =
'New_caption,Process_caption,report_caption,category4_caption,category5_caption,category6_caption,category7_
caption,category8_caption,category9_caption,category10_caption';
The position of the caption in the list determines its corresponding category setting in the PromotedCategor y
property for the actions as described in the table below.
You can change category captions on a page-by-page basis and for each Dynamics 365 Business Central
Windows client language.
For more information about these properties, see PromotedCategory Property and PromotedActionCategories
Property.
actions
{
area(Creation)
{
action("Sales Quote")
{
Promoted = true;
PromotedCategory = Category5; // PromotedActionCategories = New Document
PromotedOnly = true;
PromotedIsBig = true;
Image = NewSalesQuote;
ApplicationArea = All;
trigger OnAction()
begin
Message('Create sales quote');
end;
}
action("Sales Invoice")
{
Promoted = true;
PromotedCategory = Category5; // PromotedActionCategories = New Document
Image = SalesInvoice;
ApplicationArea = All;
trigger OnAction()
begin
end;
}
}
area(Processing)
{
action("Send Approval Request")
{
Promoted = true;
PromotedOnly = true;
PromotedCategory = Category6; // PromotedActionCategories = Request Approval
Image = SendApprovalRequest;
ApplicationArea = All;
trigger OnAction()
begin
end;
}
action("Cancel Approval Request")
{
Promoted = true;
PromotedCategory = Category6; // PromotedActionCategories = Request Approval
Image = CancelApprovalRequest;
ApplicationArea = All;
trigger OnAction()
begin
end;
}
}
area(Navigation)
{
action(Contact)
{
Promoted = true;
PromotedCategory = Category7; // PromotedActionCategories = Customer
PromotedIsBig = true;
Image = CustomerContact;
ApplicationArea = All;
trigger OnAction()
begin
end;
}
action("Account Details")
{
Promoted = true;
PromotedCategory = Category7; // PromotedActionCategories = Customer
Image = Account;
ApplicationArea = All;
trigger OnAction()
begin
end;
}
}
}
}
For more examples of how to use actions, see Page Object and Page Extension Object.
See Also
Actions Overview
Adding Actions to a Page
Behavioral Changes for Promoted Actions
Actions in AL
Adding Actions to a Page
Actions in the User Interface
How to Promote Actions
Organizing Promoted Actions
Common Promoted Action Groups
Action Bar Improvements
Organizing Promoted Actions
2/6/2023 • 4 minutes to read • Edit Online
The following article gives guidance on which actions you should promote, how to organize the actions, and
where to place the promoted actions.
Within each group of actions, choose a sequence of actions that respect their relative importance. Start with
actions that a user is likely to use first, or often, when opening a page. Common action groups are the exception
to this recommendation, as they must instead have a consistent sequence of actions across the pages where
they appear.
Use subgroups within a group when the total number of actions in a group is more than 7.
Updates or creates data or info A) The action is an expected part of a Promote the action to its expected
(possibly via an intermediate dialog common action group on the page, for common action group. For example,
page) and with clear feedback that the example Post . promote the Post action to the
action took place. common action group named
Examples: Post, Suggest lines, Indent “Posting.”
Opens a relevant or related page (not A) The page that opens has Action should be placed in the
a dialog) and that has no apparent information that is specific to the common entity action group, which is
side effects. current record/row in the page. the one bearing the name of the main
Examples: Statistics, Dimensions entity of the page, for example,
Customer.
- B) The page that opens has the same Action should be placed in the
information regardless of current common Navigate action group.
record/row in the page.
Is an action that runs a report, either (no variation) Place report actions in the common
directly or via an intermediate dialog action group Reports.
page (request page).
See also
Actions in AL
Adding Actions to a Page
Actions in the User Interface
How to Promote Actions
Common Promoted Action Groups
Action Bar Improvements
Behavioral Changes for Promoted Actions
Pages with Action Bar Improvements
Common Promoted Action Groups
2/6/2023 • 3 minutes to read • Edit Online
Business Central defines the following common action groups as part of the standard application functionality.
The list isn't exhaustive, but shows the most common action groups, their typical use, and the recommended use
of the split button capability.
C O M M O N A C T IO N GRO UP C H A RA C T ERIST IC S SH O W A S SP L IT B UT TO N
See also
Actions in AL
Adding Actions to a Page
Actions in the User Interface
How to Promote Actions
Organizing Promoted Actions
Action Bar Improvements
Behavioral Changes for Promoted Actions
Pages with Action Bar Improvements
Action bar improvements
2/6/2023 • 3 minutes to read • Edit Online
With Business Central 2022 release wave 2, we’ve organized the action bar menus to keep related actions
together and avoid the same action being available in multiple menus. This helps reduce clutter and confusion,
especially for users new to Business Central.
The use of a Navigate menu has been reduced, and, where applicable, its contents merged with the entity menu.
The entity menu is the one bearing the name of the entity displayed on a page. Going forward, the Navigate
menu will only hold links to pages that aren't directly related to the current record yet useful to quickly navigate
to when at a given place.
Certain actions have been given a more prominent placement in the action bar. This reduces the number of
selects to reach often-used actions and makes relevant actions more discoverable.
Split buttons are well-known from other Microsoft products as a combination of a button and a menu and are
introduced in Business Central 2022 release wave 2 in certain places. This type of control gives you quick one-
click reach to the first action in a menu via the left button part and access to other related actions via the right
dropdown part.
The ways that users can customize menus to suit their purpose and preference are improved with the new
action bar. That means earlier limitations to which and where actions could be moved no longer apply, which
greatly empowers users in personalizing pages and in configuring profiles.
The improvements listed above are available to current Business Central users as soon as they get the upgrade
to release wave 2, 2022.
See also
Actions in AL
Adding Actions to a Page
Actions in the User Interface
How to Promote Actions
Organizing Promoted Actions
Common Promoted Action Groups
Action Bar Improvements
Behavioral Changes for Promoted Actions
Behavioral Changes for Promoted Actions
2/6/2023 • 2 minutes to read • Edit Online
With Business Central 2022 release wave 2, we introduce a new syntax for defining promoted actions. The new
syntax groups the promoted actions in a separate section, so that the code is easier to scan. And on the UI, the
new syntax improves the personalization experience, by adding options for promoting actions.
Behavioral changes
N EW B EH AVIO R ( V21) P REVIO US B EH AVIO R ( V20)
During personalization, if you hide a base action, all During personalization, if you clicked "Remove" on a base
actionref s will also be hidden. action, it would disappear, which was equivalent to making
the action set to PromotedOnly = true ; it would only show
up in the promoted section.
If base actions are inside a hidden group, then the Promoted actions had an implicit copy of the Visible
actionref s will be also hidden, even if the base actions property of the base actions, which made them unrelated to
themselves are visible. the parents of the base actions. Due to this behavior, this
was not an issue in v20.
Note: This behavior is maintained when the feature flag
Modern Action Bar on the Feature Management page
is set to Disabled.
Promoted categories are never merged into the Manage If you renamed one of the promoted categories to Manage,
system group anymore. However, if there's a custom group then they were merged into the Manage system group.
called Manage, the merge is done. If there are multiple promoted categories that are renamed
to Manage, then actions inside were all merged into the
Manage system group. This could, for example, happen if
there were multiple extensions that renames different
promoted categories to Manage.
When all actions inside a group has an actionref , then Promoted actions were rendered on the right-hand side
the group is no longer rendered. This condition is applied unless PromotedOnly was set. If every action had
recursively. For example, if every action is promoted, then PromotedOnly = true , then the Actions group would also
there'll be no Actions group visible on the right-hand side. not render.
Note: In a future release actionrefs will be treated by
PromotedOnly by default in the future.
If a hidden group contains actions with dynamic visibility and Actions with dynamic visibility were initially visible. Then, if
the visibility evaluates to true without the parent, then the the parent was hidden and because their visibility was never
actions will be ghosted during design mode even if the modified, they would disappear from the page.
visibility has never been modified.
See also
Promoted Actions
Actions in AL
Adding Actions to a Page
Actions in the User Interface
How to Promote Actions
Organizing Promoted Actions
Common Promoted Action Groups
Action Bar Improvements
Pages with Action Bar Improvements
2/6/2023 • 4 minutes to read • Edit Online
This table provides an overview of all the pages in Business Central that contain the action bar improvements
with 2022 release wave 2 (version 21.0).
PA GE ID PA GE N A M E PA GE T Y P E
5 Currencies List
14 Salespersons/Purchasers List
See also
Actions in AL
Adding Actions to a Page
Actions in the User Interface
How to Promote Actions
Common Promoted Action Groups
Action Bar Improvements
Behavioral Changes for Promoted Actions
Designing Profiles
2/6/2023 • 3 minutes to read • Edit Online
A profile is the mechanism that makes a Role Center page and its associated pages and reports available to
users in the client. It enables you to build an individual experience for users based on their role in the company
by customizing the pages that they use to perform the daily tasks. In the client, profiles are referred to as Roles .
When users sign in to Business Central, they are doing so under a specific role. Users can switch the role from
the My Settings page.
Creating profiles in AL involves two different object types: profile object and page customization object.
Profile objects
A profile object specifies an ID for the profile, a display name that appears in the client, a role center page, and
the page customization objects that apply to the profile. Different profiles can use the same Role Center page.
Example
The following example creates a profile object that uses the Business Manager role center page. It uses two page
customization objects; one that modifies the Business Manager Role Center page and another that modifies
the Customer List page.
profile TheBoss
{
Description = 'This is the profile for the Boss';
RoleCenter = "Business Manager";
Customizations = MyCustomization1, MyCustomization1;
Caption = 'Boss';
}
Translating profiles
A profile's Caption and ProfileDescription properties appear in the client user-interface, so you will typically
want to translate these into different languages. Like other objects, this is done by creating XLIFF files for the
different languages from the source language. The generated XLIFF file contains a <source> tag for both the
Caption and ProfileDescription to which you can add a <target> tag for the translated text. For more
information, see Working with Translation Files.
For example, the following code is the content of an XLIFF file for translating the example profile mentioned
above from its source language, en-US, to the target language da-DK.
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en-US" target-language="da-DK" original="profiles">
<body>
<group id="body">
<trans-unit id="Profile 3523819904 - Property 4111922599" size-unit="char" translate="yes"
xml:space="preserve">
<source>The Boss</source>
<target>Chefen</target>
<note from="Developer" annotates="general" priority="2"></note>
<note from="Xliff Generator" annotates="general" priority="3">Profile TheBoss - Property
ProfileDescription</note>
</trans-unit>
<trans-unit id="Profile 3523819904 - Property 2879900210" size-unit="char" translate="yes"
xml:space="preserve">
<source>Boss</source>
<target>Chef</target>
<note from="Developer" annotates="general" priority="2"></note>
<note from="Xliff Generator" annotates="general" priority="3">Profile TheBoss - Property
Caption</note>
</group>
</body>
</file>
</xliff>
See Also
Developing Extensions
AL Development Environment
Page Object
Page Extension Object
Page Extension Properties
Profile Object
2/6/2023 • 2 minutes to read • Edit Online
The profile object in Dynamics 365 Business Central allows you to build an individual experience for each user
profile. The Profile object performs a validation to check whether the specified role center page exists, and page
customization objects exists, when you define a new profile object. On a page customization you can add
changes to the page layout, and actions; but you cannot add variables, procedures, or triggers.
NOTE
Page customizations only apply to the RoleCenter they are specified for. In order to see them, in Dynamics 365 Business
Central under My Settings , Role Center change to the specific RoleCenter that a page customization is defined for.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
NOTE
The property allowDebugging , which is a setting under resourceExposurePolicy does not apply to page
customizations. Page customizations defined in an extension with allowDebugging set to false can still be copied
using Designer. For more information, see Resource Exposure Policy Setting.
Snippet support
Typing the shortcut tprofile will create the basic layout for a profile object when using the AL Language
extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Profile example
The following profile object example creates a profile for the MyRoleCenter Role Center, which is available in the
Role Explorer in the UI and available to end-users. The profile also depends on the customization
MyCustomization and modifies the layout of the Customer List to make the Name field invisible using the
modify method. For more information, see Profile Properties.
profile MyProfile
{
Description = 'Some internal comment that only the Dev can see';
Caption = 'My User-friendly Name';
ProfileDescription = 'A detailed description of who is this profile for, why/how to use it (etc)';
RoleCenter = MyRoleCenter;
Enabled = true;
Promoted = true;
Customizations = MyCustomization;
}
See Also
AL Development Environment
Developing Extensions
Pages Overview
Page Customization Object
Page Customization Object
2/6/2023 • 2 minutes to read • Edit Online
The page customization object in Dynamics 365 Business Central allows you to add changes to the layout and
actions on page that are accessible for a profile. See Using keywords to place actions and controls for how to
place actions and controls on a page customization object.
The page customization object has more restrictions than the page extension object; when you define a new
page customization object, you cannot add variables, procedures, or triggers.
NOTE
A single page customization can be used with multiple profiles within the same extension. Page customizations only apply
to the RoleCenters they are specified for. In order to view or changes the RoleCenters in the client, go to My Settings >
Role Center .
NOTE
Extension objects can have a name with a maximum length of 30 characters.
NOTE
Modifying actions in Cue groups on page extensions is not supported.
NOTE
The property allowDebugging , which is a setting under resourceExposurePolicy does not apply to page
customizations. Page customizations defined in an extension with allowDebugging set to false can still be copied
using Designer. For more information, see Resource Exposure Policy Setting.
Snippet support
Typing the shortcut tpagecust will create the basic layout for a page customization object when using the AL
Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Views
Views in Dynamics 365 Business Central are used on list pages to define a different view of the data on a given
page. Views can be defined for Pages, Page Extensions, and Page Customization. For more information, see
Views.
Page customization example
The following page customization example MyCustomization makes changes to Customer List . By using the
moveafter method, Blanket Orders is moved after the Orders action item. And the modify method is used to
hide the NewSalesBlanketOrder action item.
profile TheBoss
{
Description = 'The Boss';
RoleCenter = "Business Manager Role Center";
Customizations = MyCustomization;
Caption = 'Boss';
}
modify(NewSalesBlanketOrder)
{
Visible = false;
}
}
}
You can use the same page customization on another profile within the same extension package by referencing
its name from the profile definition, for example:
profile TheSalesman
{
ProfileDescription = 'The Boss';
RoleCenter = "Sales Manager Role Center";
Customizations = MyCustomization;
Caption = 'Salesman';
}
See Also
Developing Extensions
AL Development Environment
Page Object
Page Extension Object
Views
Page, Page Fields, and Page Extension Properties
Using the Client to Create Profiles and Page
Customizations
2/6/2023 • 5 minutes to read • Edit Online
Besides creating profiles and page customizations by writing AL code, you can use the client. The client is a
useful alternative, because you work with the user interface just as the users would. This method is especially
advantageous for consultants, application administrators, and less technical users.
Overview
For detailed instructions on how to use the client to create and modify profiles, see the following articles in the
Business Central application help:
Create Profiles
Customize Pages for Profiles.
A consequence of using the client is that profile changes apply only to the tenant. Extension-based profiles and
customizations, by contrast, are available for all tenants. However, the client lets you export user-created profiles
and page customizations from a tenant, then import them on another tenant.
Profiles created in the client are marked as (user-created) profiles. The export and import functionality lets
you:
Backup profile and page customizations locally.
Make further changes to profiles and page customizations away from the production environment.
Replicate profiles and page customizations on other environments and tenants.
Preview changes in sandbox environments before going into production.
IMPORTANT
You can't use the import functionality to migrate legacy profiles from Dynamics NAV or early versions of Business Central.
Exporting profiles
When you export profiles, the system exports all user-defined profiles and page customizations that have been
made in the tenant. It doesn't export profiles and page customizations introduced by extensions.
To export profiles from the client, open the Profiles (Roles) page, and select the Expor t Profiles action. A zip
file is downloaded to your computer. The file is referred to as a profile package.
Once you have the profile package, you can import it as-is to another tenant. Or, you extract the files and make
more changes to profiles and page customizations. When you're done, you compress the files into a profile
package again and import it on tenants.
NOTE
To export profiles, a user requires read permission to the Profiles page and table as a minimum. This capability allows
normal users to hand over profiles to others for troubleshooting.
Importing profiles
Importing profiles lets you add new profiles and page customizations on a tenant or replace existing ones. To
import profiles, do the following steps:
1. Get the profile package that contains the new or modified profiles.
2. Before you import a package, we recommend that you export the current profiles so you have a copy.
3. Open the Profiles (Roles) page, select the Impor t Profiles action, and follow the instructions to import
the profile package.
You don't have to import all profiles contained in the package. You can select specific profiles.
When you replace a profile, signed-in users of the profile may be interrupted briefly.
IMPORTANT
To import profiles, you must be assigned the SUPER or D365 Profile Mgmt permission set.
F IL E T Y P E DESC RIP T IO N
profile file An AL file for a user-created profile. There's a separate file for
each profile. A profile file has the format
Profile._<profile ID>_.al .
page customization file An AL file that specifies all customizations made to a page
for a specific profile. A page customization file has the format
PageCustomization._[page name]_.Configuration\
<number\>.al
.
The sections that follow explain a bit more about the file types and creating the profile package.
Profile files
Each user-created profile is exported to a separate AL file. This file contains the profile object that defines the
profile's ID, name, and Role Center. It also includes references to the page customizations it uses. For example,
let's say you created a profile with the ID MyProfile that uses the role center page 9022 Business Manager
Role Center . You then customized the Business Manager Role Center itself and the Customer list page. The
exported profile package would contain a file called PROFILE.MyProfile.al . This file would include the
following code:
profile MyProfile
{
CaptionML = ENU='My Profile';
Enabled = true;
ProfileDescriptionML = ENU='This is my sample profiles';
Promoted = true;
RoleCenter = 9022;
Customizations = Configuration1; Configuration2;
}
The Customizations property identifies the page customization objects used by the profile.
Profile extension files
Customizations made to extension-based profiles are exported to a profile extension file. This file includes a
profileextension object that specifies two types of information, depending on the changes:
Properties that specify metadata like, the CaptionML, ProfileDescriptionML, and RoleCenter.
References to configuration files that define page customizations.
For example, let's say you changed the description and customized the Customer page for the Business
Manager profile that is provided by the Base Application extension. The profile package would then contain the
file ProfileExtension._BUSINESS MANAGER.al . This file will contain code similar to the following code:
Configuration3 is a reference to a page customization file for the Customer page. For more information, see
the next section.
Page customization files
Page customizations made to user-created profiles and extension-based profiles are exported to AL files that
include a pagecustomization object. This object defines each modification to the page. Referring to the examples
above, the zip file would include three files:
PageCustomization.Business Manager Role Center .Configuration1.al
PageCustomization.Customer List .Configuration2.al
PageCustomization.Customer List .Configuration3.al
The files would include code similar to the following code:
P a g e C u st o m i z a t i o n . B u s i n e s s M a n a g e r R o l e Ce n te r.C o n fi g u r a t i o n 1 .a l
P a g e C u st o m i z a t i o n . Cu s to m e r L i s t.C o n fi g u r a t i o n 2 .a l
P a g e C u st o m i z a t i o n . Cu s to m e r L i s t.C o n fi g u r a t i o n 3 .a l
See Also
Developing Extensions
AL Development Environment
Page Object
Page Extension Object
Page Extension Properties
Control Add-in Style Guide
2/6/2023 • 5 minutes to read • Edit Online
This article offers a variety of stylistic definitions that are used throughout Dynamics 365, which you can apply
to your control add-ins to create an experience that complements Dynamics 365.
Introduction
Control add-ins for Dynamics 365 extend a business solution by surfacing contextual functionality alongside
business data. Control add-ins empower users to get more done without costly context switching, no matter
which device they access Dynamics 365 from. Typical uses of control add-ins include unique data visualizations,
surfacing controls from a third party service, or displaying related content from another data source.
Apart from the functionality, an important aspect of creating a control add-in is making sure the control add-in
looks good and blends seamlessly into Dynamics 365. To achieve this, you should follow these basic principles:
Apply similar patterns for command, navigation and presentation of data.
Favor content over chrome
Design for all platforms and input methods.
Make it accessible to all users.
Make it enjoyable and keep users in control.
Dynamics 365 uses a set of specific colors and fonts. You can employ these colors and fonts in your control add-
ins to give it a style that matches the rest of client's user interface.
Colors
Choosing the right color gives the interface visual continuity. Color can be used to convey information to users,
indicate interactivity, give feedback, and more. The following sections describe the colors used in Dynamics 365.
The colors can be used on all aspects of a UI element, such background, border, text, and more.
Main colors
The following colors represent the Dynamics 365 theme main palette.
C O LO R NAME USE H EX VA L UE
Style colors
The following colors are used to express or accent conditions or user activity in the UI. For example, these colors
are used as sentiments, or color indication, on Cues.
C O LO R DESC RIP T IO N H EX VA L UE
Standard #212121
Accent #00B7C3
Strong #212121
Favorable #35AB22
Ambiguous #9F9700
Unfavorable #EB6965
Attention #EB6965
Subordinate #A7ADB6
C O LO R DESC RIP T IO N H EX VA L UE
Yellow #C9C472
Green #88CE81
C O LO R DESC RIP T IO N H EX VA L UE
Red #E97768
Blue #75B5E7
Sky 75D8E7
Egg EEEA86
Orange #E89E63
Violet #DBBDEB
Teal #39B294
Grass #73BA5A
Scarlet #E65E6D
Chart colors
The following table describes the colors used in charts.
C O LO R DESC RIP T IO N H EX VA L UE
- #505C6D
- #008089
Yellow #C9C472
Red #E97768
Blue #75B5E7
Sky 75D8E7
Egg EEEA86
Violet #DBBDEB
Teal #39B294
Grass #73BA5A
Applying colors
To apply a color scheme to the control add-in, you specify CSS rule-sets that use the following properties:
For example, to change the background of a part of your UI to use the Secondary (#505C6D) color, write the
following CSS:
.my-ui-part {
background-color: #505C6D;
}
If you want to change the text color of a caption to the Primary (#00B7C3) color, use the following CSS:
.my-caption {
color: #00B7C3;
}
Typography
The main goal of typography is to provide clean and readable text in the user interface. Similar to colors,
typography can also be used to convey or communicate conditions to the user.
Font Families
Dynamics 365 uses the following font families to specify the typeface and weight for text elements, such as
headings, captions, messages, and so on:
EXA M P L E NAME VA L UE
EXA M P L E NAME VA L UE
largest-plus-font-size 37.5pt
largest-font-size 30pt
large-plus-font-size 22.5pt
large-font-size 18pt
medium-plus-font-size 15pt
medium-font-size 13.5pt
small-plus-font-size 12pt
small-font-size 10.5pt
smallest-font-size 9pt
IMPORTANT
To ensure that the correct fonts are used on devices, do not omit fonts or change the order of the fonts.
Example
This examples illustrates how to use CSS to style a simple HTML UI part of a control add-in. The example
includes three UI controls, as shown in the following HTML code:
<div class="addin">
<div class="control">
<div class="caption">Name:</div>
<div class="value">
<input type="text" name="name">
</div>
</div>
<div class="control">
<div class="caption">Surname:</div>
<div class="value">
<input type="text" name="name">
</div>
</div>
<div class="control">
<div class="submit">Submit</div>
</div>
</div>
The following is CSS code for styling the controls, including padding, background colors, and fonts:
.addin {
padding: 1em;
background-color: #505C6D; /* Sets the background color to "Secondary" */
}
.addin .control {
border-color: #00B7C3; /* Sets the border color to "Primary" */
}
See Also
Control Add-in Best Practices
Introducing the Dynamics 365 Business Central
Mobile App
2/6/2023 • 3 minutes to read • Edit Online
The app displaying the Business Central tablet client and Business Central phone client is targeted at users in
small and medium sized businesses that want to access data from a tablet or a phone. The main advantages of
this offering are portability and flexibility, which allows end users to perform tasks when they are away from
their desk. Having a Dynamics 365 Business Central solution that runs on a smaller device also brings it in the
hands of many more users and your app is easy to distribute.
IMPORTANT
The Business Central tablet client and Business Central phone client do not replace the Business Central Web client.
Instead, they offer a touch interface for a limited set of application scenarios compared to the Business Central Web client.
The Business Central Web client supports more complex business processes and heavier data entry than it is
possible on the Business Central tablet client and Business Central phone client. Business Central is also
designed for intensive use, and the user can have multiple windows open at the same time, but this is neither
possible in Business Central phone client or Business Central tablet client. For more information, see Differences
and Limitations When Developing Pages for the Business Central Mobile App.
The design for the Business Central tablet client is optimized for the touch experience and reduced use of the
on-screen keyboard. On the other hand, the design for the Business Central phone client is about touch
optimization, given its smaller screen size. The Business Central phone client layout is designed to support one-
hand and both hands use, which allows the important data and buttons to be available within thumbs reach.
NOTE
In this documentation, you will see mentions of Business Central tablet client, Business Central phone client, and
Dynamics 365 Business Central Mobile App. Business Central tablet client and Business Central phone client describe the
interface tailored to the category of mobile device, which is one of the tools available for developers for designing mobile
solutions, whereas Dynamics 365 Business Central Mobile App is the common name for the app across all devices; the
end result made with these tools.
See Also
Getting Started Developing for the Dynamics 365 Business Central Mobile App
Differences and Limitations When Developing Pages for the Dynamics 365 Business Central Mobile App
Deciding on Your Tablet and Phone Strategy
2/6/2023 • 3 minutes to read • Edit Online
To offer users a great mobile experience, you must decide on a strategy for how to accomplish this based on an
analysis of your users' needs. This topic explains the different options for developing for the Business Central
tablet client and Business Central phone client, but the documentation you will find in this section is primarily
focused on the first of these scenarios.
F O R M O RE IN F O RM AT IO N ,
DEVELO P M EN T ST RAT EGY W H AT A L SO TO C O N SIDER EXA M P L ES SEE
Business Central Dynamics 365 Business - For salespeople tracking Introducing the Dynamics
platform Central only supports a customers, looking up item 365 Business Central
Use the AL Language specific number of page details, and capturing Mobile App
development environment types, and this can be a orders.
to modify and extend the limitation in some type of Getting Started Developing
Business Central tablet development projects. - For technicians on the for the Dynamics 365
client and Business Central road using and re-ordering Business Central Mobile
phone client.This scenario spare parts. App
resembles developing for
Business Central Web client. - For simple approval
The main advantages of this scenarios.
strategy are:
Power App The standard Business For field salesforce in need Connecting to Your
Use the Power Apps Central connector for Power of user experience that is Business Central Data to
platform connected to Apps only supports built in more customized or tightly Build a Business App Using
Business Central either APIs, so you may need to connected to 3rd party Power Apps
using the Business Central use custom connector software or hardware.
connector in Power Apps or feature to access your Create a canvas app from a
custom connector and custom APIs. template in Power Apps
access your modify data.
Connected mobile app Cost to learn development A simple touch interface for OData Web Services Data
Based on OData web tools and languages outside users to scan their access Modification
services or SOAP web AL, preparing new card for time registration.
services technologies, write development environments. OData Web Services
an app that interacts with
Dynamics 365 Business Cost of licensing any of SOAP Web Services
Central. Visual Studio these tools, and having to
includes project templates maintain code for different Web Services
for this kind of app. operating systems.
Remarks
If you are developing using the AL language, use a browser for continuous development and test of the Business
Central tablet client and the Business Central phone client solution that you are working on. Switching to
running in a browser is an easy and efficient way to test what new and modified pages look like. Running the
Business Central tablet client and Business Central phone client in a browser is only recommended for
development scenarios. For more information, see Opening the Dynamics 365 Business Central Tablet or Phone
Client from a Browser.
See Also
Getting Started Developing for the Dynamics 365 Business Central Mobile App
Introducing the Business Central Mobile App
Getting Started Developing for the Dynamics 365
Business Central Mobile App
2/6/2023 • 2 minutes to read • Edit Online
The Business Central tablet client and Business Central phone client are built on the same framework as the
Business Central Web client, such that they are all based on the same Dynamics 365 Business Central pages.
Developing for Business Central tablet client and Business Central phone client is not much different from
developing pages for Business Central Web client either, since it is also done from the AL Language
development environment.
Steps for Developing for the Business Central tablet client and
Business Central phone client
The first step to take when you are developing for the Business Central tablet client and Business Central phone
client is to consider the design and implementation of the solution:
What is the business scenario that you want to support?
Do you want to extend your existing data model?
Should the solution work well on both a desktop computer, on the tablet and also on a phone?
What design should the Role Center that will be the central dashboard for the solution have?
Understanding the business scenario is important to build the best solution. Design your solution for users who
are most typically occasional users who need an overview of their daily work status and perform relatively
simple or light data entry. Many of these preparations resemble those for developing for Business Central Web
client, but in an even smaller scale.
Once the data model, users, permissions, and profiles are in place, you can start developing the Role Center. You
can either reuse an existing Role Center or create a new one. This will depend on the business scenario. The
Business Central tablet client and the Business Central phone client are designed to be smart about laying out
the same Role Center depending on the display target.
When developing for the Business Central phone client you want to think even more about design and usability
on a very small screen. On the phone the app will always by default start a page in view mode, meaning that the
user actively must switch to edit mode.
There are some best practices and limitations to consider in particular caused by the smaller screen size and
touch experience. For more information, see Differences and Limitations When Developing Pages for the
Dynamics 365 Business Central Mobile App. On devices that run the Business Central Mobile App and have a
camera and location capability you also have a couple of additional options. For more information, see
Implementing the Camera in AL and Implementing Location in AL.
To complete designing your Business Central Mobile App solution, you should consider offering users Help, to
guide them through pages or workflows. For more information about adding help to your solution, see Extend
and Collaborate on the Help for Dynamics 365 Business Central.
The next steps are to consider how to deploy your solution and how to distribute it to your customers. After you
have completed your solution, you can send an e-mail to the users to let them know that they can download
Dynamics 365 Business Central from the relevant store and include the organization URL and sign-in
information. For more information, see Linking to the Dynamics 365 Business Central Mobile App.
See Also
Deciding on Your Tablet and Phone Strategy
Differences and Limitations When Developing Pages for the Dynamics 365 Business Central Mobile App
Designing for Different Screen Sizes on Tablet and
Phone
2/6/2023 • 2 minutes to read • Edit Online
When designing application pages for the Business Central tablet client and the Business Central phone client, it
is best practice to consider the size of the tablets or phones that your end users have access to. It is an
advantage if the solution works well on both small and large screen sizes, but we also recommend that you
consider thoroughly the most frequently used screen sizes for your end user experience.
Designing for small screens can be more challenging, because pages will show fewer fields, columns, and tiles.
Therefore, a good way to identify issues on how your application pages are displayed is to test on the smallest
supported screen size.
See Also
Deciding on Your Tablet and Phone Strategy
Differences and Limitations When Developing Pages for the Dynamics 365 Business Central Mobile App
Displaying Data as Tiles
Gesture Property
Differences and Limitations When Developing
Pages for the Business Central Mobile App
2/6/2023 • 4 minutes to read • Edit Online
Developing for the Business Central tablet client and Business Central phone client is similar to developing for
the Business Central Web client. However, there some natural limitations on tablets and phones, such as not
having a physical keyboard and mouse, as well as a smaller screen.
REC O M M EN DAT IO N /
C O N C EP T O N TA B L ET ON PH ONE EXA M P L E REM A RK S
Activity groups Only the Home Only the Home Home and Posted Design pages to
activity group is activity group is Documents on the expose the workflows
shown. shown. Sales Order needed by the user.
Processor For example,
Role Center. configure the profile
to show the
important list pages
under the Home
activity group.
Alternatively,
consider designing a
new Role Center if
the activities for the
activity group greatly
vary from activities in
other activity group.
Actions in the action Only Promoted Only Promoted On the Use the development
bar actions are shown. actions are shown. Small Business environment to
Role Center. promote actions.
Alternatively,
configure the profile
and add actions to
the Home tab.
FactBoxes Not shown on List Not shown on List Customer list on Make sure the same
pages or Worksheet pages or Worksheet the information is visible
pages. pages. Small Business on the corresponding
Role Center. card page of the
given record.
REC O M M EN DAT IO N /
C O N C EP T O N TA B L ET ON PH ONE EXA M P L E REM A RK S
Tell Me Not available yet. Not available yet. On Business Central Design pages to
Web client. expose the workflows
needed by the user.
For example via list
places, tiles or
actions.
Role Explorer Not available yet. Not available yet. On Business Central Design pages to
Web client. expose the workflows
needed by the user.
For example via list
places, tiles or
actions.
Select from full list Not available on Not available on On the Item Card Make sure the
lookups. Users are lookups. Users are when selecting the appropriate columns
not able to run not able to run Base Units of are visible on the
actions on a lookup actions on a lookup Measure . lookup. The user is
page, and they page, and they still able to filter,
cannot access the full cannot access the full scroll, and search
set of records. set of records. through the lookup.
Worksheet pages Available. Not available; an Sales Price Run this type of page
error message is Worksheet or from the Business
displayed. Cash Flow Central Web client, or
Worksheet. Business Central
tablet client.
Automatic input Not available. Not available. Customer Card The reason for this
focus on first editable page. behavior is to
field of a page prevent the in-app
In the Web client, keyboard from
focus will initially displaying
automatically be on and occupying screen
the first editable field space.
(such as the Name
field), enabling you to
change the value
right away.
In the Tablet or
Phone client, this
field will not be in
focus; instead, you
will have to manually
select the field first in
order to make
changes.
See Also
Displaying Data as Tiles
Implementing the Camera in AL
Implementing the Location in AL
Role Center Behaviors
Defining Action Scope for Business Central Pages
Opening the Business Central Tablet or Phone
Client from a Browser
2/6/2023 • 2 minutes to read • Edit Online
You can open the Business Central tablet client or the Business Central phone client by using a browser from a
device that has a network connection. This can make it easier to test your solution during the design phase.
IMPORTANT
The steps in this article illustrates how you can open the Business Central tablet client in a browser. The syntax and
options for opening Business Central phone client in a browser are the same; just replace tablet with phone in the
examples later in this section.
TO O P EN URL EXA M P L E
https://ComputerName:Port/WebSe
rverInstance/tablet?
tenant=TenantID
https://ComputerName:Port/WebSe
rverInstance/tablet?
tenant=TenantID&company=Comp
anyName
Or
https://ComputerName:Port/WebSe
rverInstance/tablet?
tenant=TenantID&page=ID
TO O P EN URL EXA M P L E
Or
https://ComputerName:Port/WebSe
rverInstance/tablet?
tenant=TenantID&report=ID
Or
https://ComputerName:Port/WebSe
rverInstance/tablet?
tenant=TenantID&profile=ProfileID
See Also
Introducing the Dynamics 365 Business Central Mobile App
Develop a Sales Rep Role Center for the Tablet
Client
2/6/2023 • 3 minutes to read • Edit Online
In this example, you will learn how to create a new Role Center for the Business Central tablet client. Developing
for the Business Central tablet client occurs in the AL Language development environment and is not much
different from developing for one of the other Business Central clients. This example will concentrate on how to
build a Role Center for a sales representative, which links to already existing page objects, but combined in a
way so that it works well on the tablet.
Prerequisites
To complete this example, you will need:
Business Central installed with a developer license
Business Central Web Server components
CRONUS International Ltd. demonstration database
A supported browser. For more information, see System Requirements for Dynamics 365 Business Central
2020 Release Wave 1
Story
Simon is a partner developer working for CRONUS International Ltd. Nancy is a Sales Representative at Contoso
Consulting. Simon has to build a new Role Center to support Nancy in her job. When at work, Nancy spends
part of her time on the road with only her tablet available on customer visits. Nancy needs access to KPIs on the
front page. She needs easy access to filter for the customers who she will visit. When at the customer site, she
creates sales quotes. Simon wants to build a Role Center that can be used on a tablet and he wants to reuse as
much code and as many page objects as possible.
The following code illustrates how Simon implements the Role Center.
page 50106 "Sales Rep Role Center"
{
PageType = RoleCenter;
layout
{
// Add already existing pages to help Nancy access activities, customers, and charts to the Role
Center.
area(RoleCenter)
{
part("O365 Activities"; "O365 Activities")
{
}
// Add actions that link to other pages, which Nancy uses in her daily work on the tablet.
actions
{
area(Creation)
{
action("Sales Quote")
{
Caption = 'New';
RunObject = Page "Sales Quote";
Image = Quote;
Promoted = true;
}
action("Customer List")
{
Caption = 'Customers';
RunObject = Page "Customer List";
Promoted = true;
// Sales Quote as an action item available from the action pane in the New group
PromotedCategory = New;
}
action("Item List")
{
Caption = 'Items';
RunObject = Page "Item List";
Promoted = true;
PromotedCategory = New;
}
}
}
}
For more information about the specifics of Role Center structure and design, see Designing Role Centers.
Simon now wants to test the Sales Rep Role Center that he created, and for testing purposes he uses a browser
window. He enters a URL that specifically opens the page 50006 from tablet.aspx. His URL now resembles this:
https://MyBCWeb:8080/BC210/tablet.aspx?page=50006. For more information, see Opening the Business
Central Tablet or Phone Client from a Browser.
Next steps
Nancy now has a Role Center that gives her access to most of the information that she needs when she is on the
road. The next step for Simon is to refine the Sales Rep Role Center by adding more functionality, for example,
the ability to retrieve more lists or making sure that Nancy can smoothly continue to work when she is back at
the office on her desktop computer.
See Also
Designing for Different Screen Sizes on Tablet and Phone
Differences and Limitations When Developing Pages for the Business Central Mobile App
Designing Role Centers
Role Center Behaviors
Entitlements and Permission Sets Overview
2/6/2023 • 5 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
Business Central uses two main concepts for defining access to functionality: Entitlements and permissions.
Entitlements describe which objects in Business Central a customer is entitled to use according to the
license that they purchased from Microsoft or according to the Azure Active Directory role that they have
assigned in Microsoft 365 Admin Center, such as Global Administrator. Entitlements are only used in the
online version of Business Central.
Permissions describe which objects an administrator or a partner has given the user.
Permission sets combine objects permissions in logical groups (or sets), which can then be assigned to
the users explicitly or through a user group.
For more information about assigning licenses, see Licensing in Dynamics 365 Business Central. For more
information about how to create and assign permissions, see Assign Permissions to Users and Groups.
NOTE
In the current version of Dynamics 365 Business Central entitlements can only be included with Microsoft apps (enforced
by the AppSource cop rules and the technical validation checks that we run for the apps submitted to AppSource). These
objects will become available for the ISV apps when we introduce ability to monetize AppSource apps in one of our future
releases.
Upgrade considerations
Starting with Business Central 2021 release wave 1 (v18.0), the Business Central demo database, which is
shipped with our on-premises installation, doesn't contain any data in the Permission Set and Permission
tables in the application database. Instead, the System permission sets and permissions are provided as AL
objects of type PermissionSet and PermissionSetExtension , included with Microsoft apps.
The application database tables that used to store the entitlements won't contain any data either, because
entitlements are now defined as AL objects.
Business Central server configuration file (CustomSettings.config) includes a setting that allows on-premises
administrators to decide whether they want to continue using the permissions defined as data or as AL objects:
The default value for this setting is true , meaning that the server will be retrieving all System permission sets
and permissions from the AL objects of type PermissionSet and PermissionSetExtension . With the value for this
setting set to true , the permissions data, in case it is still present in the application database, will be
disregarded.
It's not possible to customize the System permission sets and permissions used in the online version of
Business Central. End-users can only copy these types to new permission sets, which they can then adjust to
their needs. For more information, see Assign Permissions to Users and Group.
In the on-premises version of Business Central, even though it's not recommended, the partners can customize
the permission sets and permissions shipped in the application database. In this case, as for any upgrade before,
the changes in Microsoft permissions should be merged with the customized permissions by partners during
upgrade.
Although starting with Business Central 2021 release wave 1 (v.18.0), System permissions are no longer
shipped as data in the application database, the partners can use the same procedure as before to export the
new permissions that are defined using AL objects. The new permission sets and permissions can be exported
into XML file by running XMLport 9171 Import/Export Permission Sets, making it possible to compare and
merge the customized permission sets in your old database with the newly shipped permission sets. Find more
details, see Export and Import Permission Sets and Permissions.
How to upgrade permission sets
When upgrading to version 18, first decide whether you want to use the permissions defined as data or switch
to permissions defined as AL objects. Then, follow the guidelines at Upgrading Permission Sets for details on
how to do the upgrade.
See Also
Get Started with AL
Entitlement Object
PermissionSet Object
PermissionSet Extension Object
Composing Permission Sets
2/6/2023 • 4 minutes to read • Edit Online
Permissions define a specific level of access to data and objects in the application, like read, insert, modify, and
delete permission on table data. Permission sets combine these permissions in logical groups that can then be
assigned to users. Permission sets in AL are created using the permissionset object, and existing permission sets
are extended using the permissionset extension object. In the client, administrators can't modify these AL-based
permission sets, but they can copy them and modify the copies (see Assign Permissions to Users and Groups).
Design concepts
There are different approaches to creating permission sets.
Fundamental permission sets
One approach is to create a kind of self-contained permission set that includes all the permissions you want to
grant to specific data and objects. These permissions are defined explicitly in the Permissions property of the
permission set or permission set extension object. This approach creates a structure considered to be flat
structure.
The disadvantage with this approach by itself is that if you have to change a permission, like C and D in the
figure, you have to make the change in every permission set that uses the permission.
Composite permission sets
Another approach is to use the IncludedPermissionSets property and ExludedPermissionSets property to create
permission sets that are composed of the other permission sets. Any changes made to the included or excluded
permission sets are automatically propagated to the permission sets that use them. In this manner, you create
permission sets that have hierarchical structure, as illustrated in the following figure. Looking at the figure,
permission set 5 is composed from all permission sets, minus the permissions in permission set 3.
Composite permission sets are easier to maintain and keep up-to-date compared to fundamental permission
sets—especially when building off Microsoft permission sets. This approach enables you to create concise,
reusable permission sets that control access to specific features, which act as building blocks for expanding
other permission sets.
Bringing approaches together
Ultimately, you'll use a combination of these approaches to meet your permission requirements. Many of the
default permission sets from Microsoft follow this approach. The following figure illustrates how different
permission sets (in this case, standard Dynamics 365 permission sets) can be used to compose two custom
permission sets (EMPLOYEE and HR). The permission sets have been simplified for illustration purposes.
Include permission sets
You use the IncludedPermissionSets property to create a permission set that includes permissions from other
permission sets. The property is available on permission set and permission set extension objects.
The following code example illustrates a permission set Sales Person that includes permissions that grant
access, at various levels, to data in different tables. The Assignable property is set to true , which allows the
permission set to be assigned to a user. The Permissions property is set to the list of objects to give permissions
to. The RIMD access assigned to data in the Customer table provides full access, whereas, for example, access is
limited for data in the Currency table only allowing full read and modify permission.
Permissions =
tabledata Customer = RIMD,
tabledata "Payment Terms" = RMD,
tabledata Currency = RM,
tabledata "Sales Header" = RIM,
tabledata "Sales Line" = RIMD;
}
With the IncludedPermissionSets property, you can specify that the permission set Sales Person is also
included in MyPermissionSet .
permissionset50135MyPermissionSet
{
Assignable = true;
Caption = 'My PermissionSet';
IncludedPermissionSets= "Sales Person";
Permissions=
tabledataVendor=RIm,
codeunit SomeCode =x,
codeunit AccSchedManagement=X;
}
The resultant permissions for the MyPermissionSet permission set are then:
permissionset50136MyPermissionSet2
{
Assignable = true;
Caption = 'My PermissionSet 2';
IncludedPermissionSets= "MyPermissionSet";
ExcludedPermissionSets = "Sales Person";
Permissions=
tabledataMyTable =RIMD,
}
The resultant permissions defined by the MyPermissionSet2 permission set are then:
tabledataMyTable = RIMD,
tabledataVendor=RIm,
codeunit SomeCode =x,
codeunit AccSchedManagement=X;
TIP
When including and excluding multiple permission sets, it can be difficult to get an overview of what the resultant
permissions will be. To help, use the View all permissions action from the the permission set in the client.
See Also
Developing Extensions
AL Development Environment
Entitlements and Permission Set Overview
Permission Set Extension Object
Permissions on Database Objects
Assignable Property
IncludedPermissionSets
Permissions Property
Permission Set Object
2/6/2023 • 2 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
The permission set object in Business Central describes permissions on objects. Permission sets are building
blocks used to compose assignable permission sets and entitlements. Assignable permission sets are
permissions that an admin can assign to users in Business Central, using the Permission Sets page. An
entitlement is a collection of permission sets that constitute a set of meaningful permissions for a user.
Some permission sets can be non-assignable, meaning that they aren't discoverable and assignable in the UI in
Business Central, instead they can be used as building blocks to compose functional assignable permission sets.
For information about which permissions can be assigned to objects, see Permissions on Database Objects.
Snippet support
Typing the shortcut tpermissionset will create the basic layout for a permission set object when using the AL
Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
When adding new AL objects, it's easy to forget to update the permissions. With the
al.generatePermissionSetForExtensionObjects command, you can generate or update a permission file for the
active project in Visual Studio Code. Choose to create a new permission file or select an existing file to make
updates to. For more information, see AL Language Extension Configuration.
Permissions =
tabledata Customer = RIMD,
tabledata "Payment Terms" = RMD,
tabledata Currency = RM,
tabledata "Sales Header" = RIM,
tabledata "Sales Line" = RIMD;
}
The following example of a permission set illustrates assigned permissions to run codeunits. With the
IncludedPermissionSets property, we specify that the permission set Sales Person is also included in
MyPermissionSet .
permissionset50135MyPermissionSet
{
Assignable = true;
Caption = 'My PermissionSet';
IncludedPermissionSets= "Sales Person";
Permissions=
tabledataVendor=RIm,
codeunit SomeCode =x,
codeunit AccSchedManagement=X;
}
You can also use the ExludedPermissionSets property to exclude permissions defined in other permission sets.
To learn more, see Composing Permission Sets From Other Permission Sets.
See Also
Developing Extensions
AL Development Environment
Entitlements and Permission Set Overview
Permission Set Extension Object
Permissions on Database Objects
Assignable Property
IncludedPermissionSets
Permissions Property
Permission Set Extension Object
2/6/2023 • 2 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
The permission set extension object in Business Central adds permissions to an existing permission set defined
in AL. A permission set extension object cannot remove permissions from an existing permission set, it can only
add permissions. If you, for example, add an extension to Business Central, you can use permission set extension
objects to grant permissions to the objects in your extension. This means that the admin of Business Central
does not have to assign additional permission sets to the users, because that automatically happens when the
extension is installed, and the permissions go away if the extension is uninstalled.
For information about which permissions can be assigned to objects, see Permissions on Database Objects.
Snippet support
Typing the shortcut tpermissionsetextension will create the basic layout for a permission set extension object
when using the AL Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
See Also
Developing Extensions
AL Development Environment
Entitlements and Permission Set Overview
Permission Set Object
Permissions on Database Objects
Assignable Property
Permissions Property
Permissions on Database Objects
2/6/2023 • 2 minutes to read • Edit Online
This section provides an overview of permissions on objects in Dynamics 365 Business Central.
Permissions
If you have been granted permission to read a page, then you can open the page and view the data that it
displays. If, however, you do not have write permission, you are not allowed to enter data into this page.
Sometimes, when you open a page it displays information from several tables. To access this page, you must
have permission to view all the data displayed by the page. You might not have permission to read directly from
all the tables that the page uses. In this case, you must have indirect permission to read from the tables in
question. Having indirect permission to a table means that you cannot open the table and read from it but can
only view the data it contains indirectly through another object, such as a page or report, that you have direct
permission to access.
Dynamics 365 Business Central has a number of standard predefined security permission sets. You can use
these permission sets as defined or you can change a permission sets to suit your particular needs. You can also
create your own permission sets and assign them the permissions that you want.
Permissions on Objects
The following table describes the permissions that can be assigned for specific objects. When assigning
permissions by using the object types PermissionSet Object and PermissionSet Extension Object these
permissions have been shortened. The table illustrates the abbreviations used.
Permissions on tabledata are specified with the following abbreviations:
Read You can read data. R for direct read access, r for
indirect read access.
Insert You can insert data. I for direct insert permission, i for
indirect insert permission.
Delete You can delete data. D for direct delete permission, d for
indirect delete permission.
Execute You can run this object. X for direct execute permissions, x
for indirect execute permissions.
Wildcard
The wildcard can be used as a shortcut to assign multiple permissions at a time, such as:
Permissions = codeunit * = X;
IMPORTANT
The wildcard must be used with caution, because when it is used in a permission set it grants the permission to all objects
of that type across all permissions. If a permission set with a wildcard is included in an entitlement, it only covers the
objects of that type in the current extension.
Example
All of the permissions illustrated above can be combined into a group of permissions for any given object. For
example:
...
Permissions =
tabledata Customer = RIMD, // Full access
tabledata "Payment Terms" = RMD, // Full read, modify, and delete access - no insert
tabledata Currency = rimd, // Full indirect access
tabledata "Sales Header" = RIM, // full read, insert, and modify access - no delete
tabledata "Sales Line" = RIMD, // Full access
report "Sales Statistics" = X; // Full access
...
See Also
Get Started with AL
Entitlements and Permission Set Overview
Permission Set Object
Permissions on Database Objects
Inherent Permissions
2/6/2023 • 2 minutes to read • Edit Online
With inherent permissions, developers can now grant permissions to a method or event while code executes. As
soon as the code execution is completed, permissions are revoked. Inherent permissions simplify the overall
management and maintenance work of permission sets. With it, a specific AL method or event can get the
elevated permissions necessary to finish the task at hand without getting permission errors. And it helps tighten
overall security by limiting long-term user permissions and giving permissions to the code process instead.
Let’s say a salesperson wants to make a report that includes certain critical pieces of information. In the
background, a method will run a query to fetch the information from the table holding classified data. With
inherent permissions, instead of managing permissions for that salesperson, a developer can add the
permission permanently into the specific code path. This method will be granted permissions for the given
object, which in this case is a table. Now, whenever an authorized person runs this method, the needed
permissions are in place to complete the request.
NOTE
For now, the InherentPermissions attribute is available for Business Central on-premises only. It'll be added to Business
Central online in a later version.
TIP
It's better to use the inherent permissions for small dedicated procedures or system tasks that don't risk data exposure to
users.
Syntax
[InherentPermissions(PermissionObjectType: PermissionObjectType, ObjectId: Integer, Permissions: Text [,
InherentPermissionsScope: InherentPermissionsScope])]
To learn more about the syntax of the InherentPermissions attribute, see InherentPermissions Attribute.
Example
Let's look at a code example for the InherentPermissions attribute.
Referring to the example explained above, let's say the report needs to show which location has more sales for
the quarter. As it's not ideal to grant access to all data belonging to customers, read permission is granted to the
method instead. It will only fetch the customer's location and leave other details (such as name, address, and so
on) private.
Inherent Entitlements
The inherent permissions and inherent entitlements together, grant more flexibility to the developers that they
can assign permissions to their methods, events, and objects. Developers can define inherent entitlements for
their objects like codeunit, table, page, and so on. In this way, the developers equip all users to have enough
access that they can carry out essential tasks without any halt. And regardless of what access their present
license or entitlement grant them. To learn more about inherent entitlements, see InherentEntitlements Property.
NOTE
Specifying InherentPermissionsScope is optional and the default is Both that includes permissions and entitlements. To
read about different types of scope, see InherentPermissionsScope Option.
See also
Entitlements and Permission Sets Overview
Permission Set Object
Exporting Permission Sets to XML
2/6/2023 • 2 minutes to read • Edit Online
Permission sets that exist in Dynamics 365 Business Central can be exported and packaged for your extension
directly from the client, instead of defining XML by hand. These permission sets are also known as tenant
permissions, and are shown in the UI as Extension permissions. The underlying functionality of permissions
has changed with the latest version of Dynamics 365 Business Central.
IMPORTANT
With the latest version of Dynamics 365 Business Central permissions are no longer defined as data in the application
database. Permissions that can be created by using AL objects are called system permissions. For more information, see
Entitlements and Permission Sets Overview.
NOTE
If you do this repeatedly, Visual Studio Code will probe for overwriting the file, there is no support for merging
manual corrections into newly generated content.
O B JEC T T Y P E N UM B ER
TableData 0
Table 1
Report 3
Codeunit 5
XMLPort 6
Page 8
Query 9
FieldNumber 11
PageExtension 14
O B JEC T T Y P E N UM B ER
TableExtension 15
Enum 16
EnumExtension 17
Profile 18
ProfileExtension 19
See Also
Entitlements and Permission Sets Overview
Permissions on Database Objects
Permissions Property
TestPermissions Property
Events in AL
2/6/2023 • 3 minutes to read • Edit Online
The use of events is a proven and established programming concept that can ease application upgrade and limit
or even eliminate the need for code modifications in customized applications because of application platform
changes.
You can use events to design the application to react to specific actions or behavior that occur. Events enable you
to separate customized functionality from the application business logic. By using events in the application
where customizations are typically made, you can lower the cost of code modifications and upgrades to the
original application.
Code modifications to customized functionality can be made without having to modify the original
application.
Changes to the original application code can be made with minimal impact on the customizations.
Events can be used for different purposes, such as generating notifications when certain behavior occurs or the
state of an entity changes, distributing information, and integrating with external systems and applications. For
example, in the CRONUS International Ltd. demonstration database, events are used extensively for workflow
and Dynamics 365 for Sales integration.
The following table describes all the different event types:
The process for implementing these events is slightly different. To learn about the different types, see Event
Types.
See Also
Publishing Events
Raising Events
Subscribing to Events
Isolated Events
Developing Extensions Using the New Development Environment
Event Types
2/6/2023 • 8 minutes to read • Edit Online
Dynamics 365 Business Central supports different types of events for different purposes.
Business events
A business event is a custom event that is raised by AL code. It defines a formal contract that carries an implicit
promise not to change in future releases. It is the expectation that business events are published by solution
ISVs, including Microsoft.
Business events can be compared with publicly released APIs on which 3rd party solution providers develop
integrations and additions. Therefore, the downstream cost of making changes to a business event
implementation can be considerable for those who use the event in their applications. There may be some cases
where changes are required; however, you should keep these to an absolute minimum.
Development considerations
A typical business event reflects changes in “state” with regards to a process. This makes them very well suited
for workflow. An example of a business event could be when a sales order has been posted. It is important to
note that business events should not be tied to the implementation-details, such as the tables or fields in which
the data is stored. Preferably, the event publisher developer should be free to change the implementation, while
still keeping the business event intact. To learn about the syntax and example on how to use the BusinessEvent
type, see BusinessEvent Attribute.
Business events should be documented with the solution, including the before-state and after-state of the
events.
Integration events
An integration event is also a custom event that is raised by AL code, like a business event, except that it does
not carry the same promise of not changing, nor does it have the restriction not to expose implementation
details.
The main purpose of integration events is to enable the integration of other solutions with Dynamics 365
Business Central without having to perform traditional code modifications.
Development considerations
An integration event can be changed to a business event later. At which time, it must adhere to the same implied
contract and commitment as any business event. It can also simply be designed-in hook points for external add-
ons. To learn about the syntax and example on how to use the IntegrationEvent type, see IntegrationEvent
Attribute.
Development considerations
To learn about the syntax and example on how to use the InternalEvent type, see InternalEvent Attribute.
Global events
Global events are predefined system events that are automatically raised by various base application codeunits.
For example, codeunit 40 LoginManagement includes several global method triggers, such as CompanyOpen,
CompanyClose, and GetSystemIndicator. For most of these global method triggers, there are one or two global
events: a before and after event. For example, there is an OnBeforeCompanyOpen event and an
OnAfterCompanyOpen event. The global events are defined as integration event publishers by local methods in
the following codeunits.
OnAfterLogInEnd
OnBeforeLogInStart
OnBeforeCompanyOpen
OnAfterCompanyOpen
OnBeforeCompanyClose
OnAfterCompanyClose
42 TextManagement OnBeforeMakeTextFilter
OnAfterMakeDateTimeFilter
OnAfterMakeDateFilter
OnAfterMakeTextFilter
OnAfterMakeTimeFilter
OnResolveCaptionClass
44 ReportManagement OnAfterGetPrinterName
OnAfterDocumentPrintReady
OnAfterGetPaperTrayForReport
OnAfterGetPrinterName
OnAfterHasCustomLayout
OnAfterDocumentReady
OnAfterDocumentDownload
OnAfterSetupPrinters
OnCustomDocumentMergerex
OnAfterSubstituteReport
C O DEUN IT ID C O DEUN IT N A M E EVEN T
45 AutoFormatManagement OnAfterAutoFormatTranslate
49 GlobalTriggerManagement OnAfterGetGlobalTableTriggerMask
OnAfterOnGlobalInsert
OnAfterOnGlobalModify
OnAfterOnGlobalDelete
OnAfterOnGlobalRename
OnAfterGetDatabaseTableTriggerSetup
OnAfterOnDatabaseInsert
OnAfterOnDatabaseModify
OnAfterOnDatabaseDelete
OnAfterOnDatabaseRename
OnBeforeOnDatabaseInsert
OnBeforeOnDatabaseModify
OnBeforeOnDatabaseDelete
OnBeforeOnDatabaseRename
Trigger events
Unlike business and integration events which must be programmed, trigger events are predefined events.
Trigger events are published by the runtime and they cannot be raised programmatically. There are two types of
trigger events: database trigger events and page trigger events.
NOTE
Trigger events do not appear as methods in AL for a table or page object.
O RDER IT EM EXA M P L E
See Also
Events in AL
Publishing Events
Raising Events
Subscribing to Events
Isolated Events
Publishing Events
2/6/2023 • 3 minutes to read • Edit Online
The first phase of implementing an event is publishing the event. Publishing an event exposes it in the
application. It provides hook up points for subscribers to register to the event, and eventually handle the event if
it's raised. An event is published by adding an AL method that is set up as an event publisher.
Business and integration events require that you manually create an event publisher method for each
event that you want to publish. An event publisher method declares the event in the application and
makes it available for subscription. However, it doesn't raise the event. After an event is published, you
can raise it in your application from where event subscribers can react and handle the event.
Trigger events don't require that you create publisher methods. Trigger events are predefined event
publisher methods that are called automatically at runtime. So trigger events are readily available to
subscribers by default.
IMPORTANT
If you include the event publisher method in a page object, the page must have a source table. Otherwise, you
can't successfully create an event subscriber method to subscribe to the event.
or
[BusinessEvent(IncludeSender : Boolean)]
TIP
Use the teventint snippet for an integration event or the teventbus snippet for a business event to get
started.
For more information about integration and business events, see Event Types.
4. Add parameters to the method as needed.
You can include as many parameters of any type as necessary.
Make sure to expose enough information. Parameters enable subscriber methods to add value to the
application. However, don't expose unnecessary parameters that may constrain you from changing or
extending methodically in the future.
You can now add code to the application that raises the event by calling the event publisher method. You can
also create subscriber methods that handle the event when it's raised.
Example
This example creates the codeunit 50100 MyPublishers to publish an integration event. The event is published
by adding the global method called OnAddressLineChanged . The event takes a single text data type parameter.
NOTE
This example is part of a larger, simple scenario where when users change the address of a customer on the page 21
Customer Card , you want to check that the address doesn't include a plus sign (+). If it does, you want to display a
message. To accomplish this, you will publish an event that is raised when the Address field on Customer Card is
changed, and add an event subscriber method to that includes logic that checks the address value and returns a message
to the user if it contains a plus sign. For a complete description of this scenario and all the code involved, see Event
Example.
The next step is to raise this event in the application. To see an example for how this event is raised, go to Raising
Event Example.
See Also
Raising Events
Subscribing to Events
Events Dynamics 365
Raising Events
2/6/2023 • 2 minutes to read • Edit Online
After an event has been published by an event publisher method, you can modify the application to raise the
event where it is needed. Subscribers of an event will not react on the event until it is raised in the application.
To raise an event, you add logic in AL code of the application to call the event publisher method that declares the
event. The procedure for calling the event publisher method is the same as calling any other method in AL.
When the code that calls the event publisher method is run, all event subscriber methods that subscribe to the
event are run. If there are multiple subscribers, the subscriber methods are run one at a time in no particular
order. You cannot specify the order in which the subscriber methods are called.
If there are no subscribers to the published event, then the line of code that calls the event publisher method is
ignored and not executed.
Snippet support
Typing the shortcut teventsub will create the basic event subscriber syntax when using the AL Language
extension in Visual Studio Code.
TIP
Typing the keyboard shortcut Ctrl+Space displays IntelliSense to help you fill in the attribute arguments and to discover
which events are available to use.
Example
This example uses a page extension object 50100 MyCustomerExt to modify the page 21 Customer Card so
that an event is raised when a user changes the Address field. This example assumes that the event has already
been published by the event publisher method OnAddressLineChanged in a separate codeunit called 50100
MyPublishers .
NOTE
This example is part of a larger, simple scenario where when users change the address of a customer on the page 21
Customer Card , you want to check that the address does not include a plus sign (+). If it does, you want to return a
message to the user. For a description of this scenario and all the code involved, see Event Example.
In the code that follows, the page extension object modifies the OnBeforeValidate trigger of the Customer
Card page to raise the event OnAddressLineChanged which includes the new value of the Address field.
pageextension 50100 MyCustomerExt extends "Customer Card"
{
layout
{
modify(Address)
{
trigger OnBeforeValidate();
var
Publisher: Codeunit MyPublishers;
begin
Publisher.OnAddressLineChanged(Rec.Address);
end;
}
}
}
To learn about how the event used in this example is published, see Publishing Events Example.
The next step would be to subscribe to the event to handle to condition. To see an example of how to subscribe
to this event, see Subscribing to Events Example.
See Also
Publishing Events
Subscribing to Events
Events in AL
Subscribing to Events
2/6/2023 • 5 minutes to read • Edit Online
To handle events, you design event subscribers. Event subscribers determine what actions to take in response to
an event that has been raised. An event subscriber is a method that listens for a specific event that is raised by
an event publisher. The event subscriber includes code that defines the business logic to handle the event. When
the published event is raised, the event subscriber is called and its code is run.
Subscribing to an event tells the runtime that the subscriber method must be called whenever the publisher
method is run, either by code (as with business and integration events) or by the system (as with trigger events).
The runtime establishes the link between an event raised by the publisher and its subscribers, by looking for
event subscriber methods.
There can be multiple subscribers to the same event from various locations in the application code. When an
event is raised, the subscriber methods are run one at a time in no particular order. You can't specify the order in
which the subscriber methods are called.
Set the arguments according to the following table. For optional arguments, if you don't want to set a
value, use an empty value ( '' ). In this case, the default value, if any, is used.
<Published Event Element Name> Specifies the table field that the no
trigger event pertains to. This
argument only requires a value for
database trigger events, that is,
when the
<Event Publisher Object Type>
is set to Table and the
<Published Event Name>
argument is a validate trigger event,
such as OnAfterValidateEvent .
TIP
There are a couple of things that can make defining an event subscriber method easier. You can use the
teventsub snippet to get started. Then, typing the keyboard shortcut Ctrl+Space displays IntelliSense to help
you fill the attribute arguments and discover which events are available. Or, use the Shift+Alt+E keyboard
shortcut to look up the event you want to subscribe to and insert the code.
5. Optionally, set the codeunit's EventSubscriberInstance property to specify how the event subscriber
method will be bound to the instance of this codeunit.
For more information, see EventSubscriberInstance Property.
Example 1
This example creates the codeunit 50101 MySubscribers to subscribe to an event that has been published by
the event publisher method called OnAddressLineChanged in the codeunit 50100 MyPublishers . The event is
raised by a change to the Address field on page 21 Customer Card . This example assumes:
The codeunit 50100 MyPublishers with the event publisher method OnAddressLineChanged already exists.
For an example, see Publishing Event Example.
The code for raising the OnAddressLineChanged event has been added to the Customer Card page. For an
example, see Raising Event Example.
The following code creates a codeunit called 50101 MySubscribers that includes an event subscriber method,
called CheckAddressLineOnAddressLineChanged . The method includes code for handling the published event.
NOTE
This example is part of a larger, simple scenario where when users change the address of a customer on the page 21
Customer Card , you want to check that the address does not include a plus sign (+). If it does, you want to return a
message to the user. For a description of this scenario and all the code involved, see Event Example.
Example 2
This example achieves the same as example 1, except it subscribes to the page trigger event
OnBeforeValidateEvent on the Address field instead. By using the page trigger, you avoid creating an event
publisher and adding code to raise the event. The event is raised automatically by the system.
codeunit 50101 MySubscribers
{
EventSubscriberInstance = StaticAutomatic;
See Also
Publishing Events
Raising Events
Event Types
Events in AL
EventSubscriberInstance Property
EventSubscriber Attribute
Isolated Events in AL
2/6/2023 • 2 minutes to read • Edit Online
You can define a business, integration, or internal event to be an isolated event. An isolated event ensures the
event publisher continues its code execution after calling an event. If an event subscriber's code causes an error,
its transaction and associated table changes will be rolled back. The execution continues to the next event
subscriber, or it will be handed back to the event's caller.
When an event is raised, the platform gets the first event subscriber. When the event is isolated, an isolated
transaction starts, then the event subscriber is invoked. If an error occurs, the transaction is rolled back, and the
flow is repeated for the next event subscriber. Otherwise, the transaction is committed and the flow is repeated
for the next event subscriber.
NOTE
Read-only transactions are allowed to call isolated events directly, but write transactions should explicitly be
committed before invoking an isolated event. Other wise, the isolated event will be invoked like an
normal event, that is, errors inside an event subscriber will cause the entire operation to fail.
Rollback
Only changes done via Modify/Delete/Insert calls on records of type TableType: Normal will be automatically
rolled back. Other state changes, like HTTP calls, variable alterations, changes to single instance codeunit's
members, won't be rolled back.
For example, if an integer variable that's passed by VAR is modified by a failing event subscriber, its changes will
persist.
Extension installation and upgrade
When the operation is installing, uninstalling, or upgrading extensions, isolated events aren't run isolated. The
events run normally instead.
The reason for this behavior is that these operations require that all operations within them are done in one
transaction. So explicit Commit calls can't be made during the operations.
To define an isolated event, set the Isolated argument, which is to true , for example:
[InternalEvent(true, true)]
Example
codeunit 50145 IsolatedEventsSample
{
trigger OnRun()
var
Counter: Integer;
cust : Record Customer;
begin
// Precondition: Customer table isn't empty.
if (cust.IsEmpty) then
Error('Customer table is empty.');
MyIsolatedEvent(Counter);
// Code only reaches this point because the above event is isolated and error thrown in
FailingEventSubscriber is caught.
if (Counter <> 2) then
Error('Both event subscribers should have incremented the counter.');
[InternalEvent(false, true)]
local procedure MyIsolatedEvent(var Counter: Integer)
begin
end;
Error('Fail!');
See Also
Publishing Events
Raising Events
Subscribing to Events
Developing Extensions Using the New Development Environment
Discoverability of Events
2/6/2023 • 2 minutes to read • Edit Online
You subscribe to events to extend application and interact with the base application and other extensions. This
topic describes how to discover events that you can subscribe to without writing the code manually. Using the
Event Recorder , you can record the events that are published and raised while performing the actions of your
scenario. For example, record the events raised when you post a purchase order and identify the events that you
need for your extension. You can retrieve the events in the form of AL snippet code and use them in Visual
Studio Code directly.
NOTE
The event recorder captures all events that are raised in the same session. If the actions performed by the user are in
another session, then the event recorder will not capture them.
NOTE
The recorded events are not saved. When you refresh the page, the recorded events disappear.
Recorded Events
All the recorded events display in the order they were called. The Event Recorder page provides information on
the events that were raised including the details whether the raised events were trigger events or custom events.
The custom events are either Business Events or Integration Events. For more information, see Event Types.
You can identify the Event types, additionally, you can discover which object types and methods raised the
events with the details like calling methods, object types, and object names. For more information about Events,
see Events in AL.
See Also
Events in AL
Publishing Events
Raising Events
Subscribing to Events
Debugging in AL
Developing Extensions
Event Example
2/6/2023 • 2 minutes to read • Edit Online
This article includes a simple code example to explain how to use Business Central events. The example uses an
event to verify a customer's address. When a user changes the address of a customer on the page 21
Customer Card , an event is used to check that the address doesn't include a plus sign (+). If it does, a message
is displayed in the client. In this example, you'll add code that:
Publishes an event that is raised when the Address field on Customer Card is changed.
Raises the event from the Customer Card page
Subscribes to the event to check the address value and return a message to the user if it contains a plus sign.
// The following code creates codeunit that publishes the `OnAddressLineChanged` event.
// The following code extends the Customer Card page to raise the `OnAddressLineChanged` event
// when the Address field is changed.
pageextension 50100 MyCustomerExt extends "Customer Card"
{
layout
{
modify(Address)
{
trigger OnBeforeValidate();
var
Publisher: Codeunit MyPublishers;
begin
Publisher.OnAddressLineChanged(Rec.Address);
end;
}
}
}
See Also
Publishing Events
Raising Events
Subscribing to Events
Events Dynamics 365
Walkthrough: Implementing New Workflow Events
and Responses
2/6/2023 • 12 minutes to read • Edit Online
If a business scenario requires a workflow event or a workflow response that is not supported in a Business
Central solution, you must implement it by extending the application code.
In the Workflow page, the workflow administrator creates a workflow by listing the involved steps on the lines.
Each step consists of a workflow event, moderated by event conditions, and a workflow response, customized by
response options. You define workflow steps by filling fields on workflow lines from fixed lists of event and
response values representing scenarios that are supported by the application code. For more information, see
Set Up Workflows in the business functionality content.
The following procedure describes how to add a new workflow event and a new workflow response and then
register the involved object relations, so that the new elements can be used in workflows. You can then share
your code as an app or a per-tenant extension, for example. The workflow administrator can then select the new
workflow event and response from the Workflow page to incorporate them in new or existing workflow steps.
IMPORTANT
To ensure that custom workflow records are upgraded correctly, you must add new workflow events, workflow responses,
and workflow table relations to dedicated extension points, as described in this procedure. During an upgrade to the next
version, the libraries of workflow events, responses, and table relations are removed and then recreated with the latest
content from Microsoft. By adding your custom workflow records using subscriptions to the Microsoft-provided extension
points, you ensure that your custom record library gets recreated after an upgrade.
NOTE
This topic refers to two types of events:
Workflow event: An occurrence in the application that users in the client can select from the Workflow page to define
workflow steps. For more information, see Workflows in Dynamics 365 Business Central in the business functionality
content.
Event: The declaration of the occurrence or change in the application. Workflow events typically subscribe to events.
For more information, see Events in AL.
The development work involved in creating a new workflow event and a related workflow response consists of
the following tasks, as a minimum:
1. Create a workflow event
a. Create a workflow event code that identifies the workflow event
b. Add the workflow event code to the Workflow Event table
c. Create and publish an event that the workflow event subscribes to
d. Raise the event
e. Subscribe to the event and implement the workflow event
2. Create a workflow response
a. Create a workflow response code that identifies the workflow response
b. Add the workflow response code to the Workflow Response table
c. Implement the workflow response
d. Enable that the workflow response can be executed
e. Add a new workflow response option
3. Register workflow event/response combinations needed for the new workflow response
4. Register workflow event hierarchies needed for the new workflow event
5. Creating table relations between entities used when the new workflow event and response are used
NOTE
Data and code samples in this procedure refer loosely to a workflow step of sending a notification when a purchase
header is posted. However, the procedure alone does not result in a complete solution. The purpose of the walkthrough is
simply to illustrate the process.
Workflow event
In this section, we'll create a code to identify the workflow event, add the workflow event to the library, create an
event that the workflow event subscribes to, raise the event, and then subscribe to the event and implement the
workflow event.
Each subsection takes you through the discrete steps.
To create a workflow event code that identifies the workflow event
1. Create a new .al file, such as MyWorkflowEvents.codeunit.al, and add a codeunit that will be used for new
workflow events. Name it to reflect that it is used to identify the new workflow event, such as
MyWorkflowEvents .
2. Add a method in the codeunit. Optionally, use the shortcut tprocedure . Name the method to reflect that
it is used to identify the workflow event, such as MyWorkflowEventCode , and make it take 128 characters of
code as a parameter.
TIP
The terminology can be a bit confusing here. This method is not an AL event. It's a method that declares the workflow
event, and it will subscribe to an AL event that, when triggered, will trigger the workflow event.
Select the event type that is relevant for the workflow event, such as Integration. For more information,
see Event Types.
To raise the event
1. Create an object or an extension object to add the code that will raise the event that triggers the workflow
event, such as the Purch.-Post codeunit.
The following code raises the event by extending the Purchase Order page object in a new file,
MyPurchOrder.PageExt.al .
The following code illustrates the new workflow event that subscribes to your previously created event:
Another task that you can perform at this point is to specify which filter fields appear in the Workflow Event
Conditions page.
For more information, see Subscribing to Events.
You have now created a new workflow event. Next, we'll create a new workflow response that relates to the
workflow event.
Workflow response
Create a new .al file, such as MyWorkflowResponses.codeunit.al, with code to identify the workflow response,
add the workflow response code to the library, implement the workflow response, and then enable that the
workflow response can be executed.
To create a workflow response code that identifies the workflow response
1. Add a new codeunit that will be used for the new workflow responses. Name it to reflect that it handles
your new responses, such MyWorkflowResponses .
2. Add a method in the codeunit. Name the method to reflect that it is used to identify the workflow
response, such as MyWorkflowResponseCode with a return value of code (128).
To add the workflow response code to the Workflow Response table
1. Add another method in the codeunit that will be the event subscriber. Name it to reflect that it is used to
add the workflow response to the library, such as AddMyWorkflowResponsesToLibrary and set it to subscribe
to the OnAddWorkflowResponsesToLibrary method in the Workflow Response Handling` codeunit.
[...]
var
WorkflowResponseHandling: Codeunit "Workflow Response Handling";
3. In the method, write code that registers the response, so that you end up with something like the
following code.
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Workflow Response Handling",
'OnAddWorkflowResponsesToLibrary', '', true, true)]
local procedure AddMyWorkflowResponsesToLibrary()
var
WorkflowEventHandling: codeunit "Workflow Event Handling";
begin
WorkflowResponseHandling.AddResponseToLibrary(MyWorkflowResponseCode, Database::"Purchase
Header", 'Send a notification.', 'GROUP 0');
End
end;
NOTE
In the To add a new workflow response option section, you will change the GROUP value to 50100. This way, you'll be
able to see the workflow in action.
3. Create a page extension object that extends page 1523, Workflow Response Options , such as
MyworkflowStepArgument.PageExt.al.
4. Add a group and a control for the new field.
Here, the Visibility property of the group is set to "Response Option Group" = 'GROUP 50100' , but you can
set it to another value.
5. Go back to MyWorkflowResponses.codeunit.al and the ´AddMyWorkflowResponsesToLibrary` method.
6. In the method code, change 'GROUP 0' to 'GROUP 50100' .
7. To use the new option in the MyWorkflowResponse method, proceed to add a local parameter and a local
variable and show a message as the response.
You have now created the actual workflow event and response. Proceed to perform various tasks that
enable them to be used in workflows.
In the method, write code that registers event/response combinations that you want to support in your
application, using a CASE statement, such as the code in the example above.
You can also do this work from the user interface on page 1507 Workflow-Event-Response-
Combinations .
In the method, write code that registers event hierarchies that you want to support in your application,
using a CASE statement, such as the code in the example above.
You can also do this work from the user interface on page 1506 Workflow-Event-Hierarchies .
In the method, write code that registers table relations that you want to support in your application, such
as the example above.
You can also do this work from the user interface on page 1509 Workflow Table-Relations .
You have now enabled a new workflow scenario by implementing the required workflow event and response in
the application code. The workflow administrator can now select the workflow event and workflow response
from the Workflow page to define new or edit existing workflows. For more information, see Set Up Workflows
in the business functionality content.
See Also
Workflows in Dynamics 365 Business Central
Set Up Workflows
Event Example
Events in AL
Page Extension Object
Table Extension Object
Codeunit Object
Table Object
Get Started with AL
Development and Administration for Dynamics 365 Business Central
Notifications
2/6/2023 • 5 minutes to read • Edit Online
Notifications provide a programmatic way to send non-intrusive information to the User Interface (UI) in the
Web client. Notifications differ from messages initiated by the Message method. Messages are modal, which
means users are typically required to address the message and take some form of corrective action before they
continue working. On the other hand, notifications are non-modal. Their purpose is to give users information
about a current situation, but do not require any immediate action or block users from continuing with their
current task. For example, you could have a notification that a customer's credit limit is exceeded.
Notifications in the UI
In the UI, notifications appear in the Notification bar (similar to validation errors) at the top of the page on
which a user is currently working. The user can then choose to dismiss the notification, which clears it. Or, if
actions are defined on notification, the user can choose one of the actions.
There can be multiple notifications. The notifications appear in chronological order from top to bottom.
Notifications remain for the duration of the page instance or until the user dismisses them or takes action on
them.
Notifications that are defined on sub-pages, for example in parts and FactBoxes, appear in the same
Notification bar.
Validation errors on the page will be shown first.
M ET H O D DESC RIP T IO N
The Send method call should be the last statement in the notification code, after any AddAction or SetData
method calls for the notification instance.
NOTE
GlobalScope is currently not supported. This will be implemented in a future release.
DataValue := MyNotification.GetData('Created');
DataValue := MyNotification.GetData('ID');
Example
This simple example illustrates how notifications work and provides some insight into how you can use them.
This example extends page 42 Sales Order of the CRONUS International Ltd. demonstration database
according to the following:
The code compares a customer's balance with their credit limit. If the balance exceeds the credit limit, a
notification is sent to the client.
The notification includes an action, which has the caption Change credit limit , that opens page 21
Customer Card . This enables the user to increase the credit limit.
To complete the example, follow these steps:
1. Create a page extension object that extends page 42 Sales Order , and add the notification code on the
OnOpenPage trigger.
pageextension 50100 CreditBalanceNotification extends "Sales Order"
{
trigger OnOpenPage()
var
Customer: Record Customer;
CreditBalanceNotification: Notification;
OpenCustomer: Text;
Text003: Label 'The current balance exceeds the credit limit.';
Text004: Label 'Change credit limit';
begin
Customer.Get("Sell-to Customer No.");
if Customer."Balance (LCY)" > Customer."Credit Limit (LCY)" then begin
//Create the notification
CreditBalanceNotification.Message(Text003);
CreditBalanceNotification.Scope := NotificationScope::LocalScope;
//Add a data property for the customer number
CreditBalanceNotification.SetData('CustNumber', Customer."No.");
//Add an action that calls the ActionHandler codeunit, which you define in the next step.
CreditBalanceNotification.AddAction(Text004, Codeunit::"ActionHandler", 'OpenCustomer');
//Send the notification to the client.
CreditBalanceNotification.Send();
end;
end;
}
2. Create a codeunit called ActionHandler for handling the notification action. Add a global method called
OpenCustomer that has a Notification data type parameter called CreditBalanceNotification for
receiving the Notification object, and include the following code on the method:
end;
See Also
Notification Data Type
Developing Extensions
Get Started with AL
Reports Overview
2/6/2023 • 2 minutes to read • Edit Online
You can use reports to print or display information from a database. Use reports to structure and summarize
information to print documents, such as invoices. For example, create a report that lists all customers and orders
that have been added by each customer. Also, create a report that is automatically filled with the relevant
information for an invoice.
Reports can also be used to process data without printing or displaying content. For example, use a report to
automate updating all prices in an item list. It can be easier to create a report to process data instead of a
codeunit to do the same processing because you can use:
Request page functionality to select options and filters for data items, which are available in a report but
are difficult to add to a codeunit. For more information, see Request Pages.
Report data items instead of writing code to open tables and retrieve records.
Data modeling, which is available when you design reports.
Creating reports
Creating a report involves two primary tasks. First, you create a report object and design the dataset. The
dataset determines the data that is extracted or calculated from the Dynamics 365 Business Central database
tables that can be used in a report. After the dataset has been designed, you design the visual layout of the
report. There are three types of report layouts that you can create: layouts using report definition language
(RDL), Word report layouts, and Excel report layouts. Another option is to extend the functionality of an existing
report with a Report Extension Object by adding columns to the existing report dataset, adding new data items,
adding to the request page, or adding a new layout.
Getting started
The following table includes links to help you get started with designing the reports.
TO SEE
Learn the overview of the report design process Report Design Overview
Understand the report structure and designing the layout Report Object
for a report.
Understanding the data model and dataset of a report Defining a Report Dataset
Learn how to create a report using a Word layout Creating a Word Layout Report
Learn how to create a report using an RDL layout report. Creating an RDL Layout Report
Learn about creating a report based on an Excel layout. Creating an Excel Layout Report
TO SEE
Learn how to create a report using a customer defined Creating a custom Layout Report
layout type.
Learn how to define multiple report layouts for one report. Defining Multiple Report Layouts
See Also
Report Object
Report Extension Object
Creating a Report
Request Pages
Creating an RDL Layout Report
Creating a Word Layout Report
Creating an Excel Layout Report
Defining Multiple Report Layouts
Utilizing Read Scale-Out for Better Performance
Report Design Overview
2/6/2023 • 2 minutes to read • Edit Online
Report object
You create a report object in the AL Language development environment to define the data model, or dataset of
a report. You can structure and summarize information in a report and print documents, such as sales quotes
and invoices. For more information, see Report Object.
Report dataset
In order to define the underlying data model, you use the report dataset. A report dataset determines the data
that is extracted or calculated from the Dynamics 365 Business Central database tables that can be used in a
report. You build the report dataset by adding data items and columns. For more information, see Report
Dataset. You can also extend a dataset from an existing report, to add more columns for example. For more
information, see Report Extension Object.
TIP
It is possible to use a query object as the data source for a report. This can in many cases improve the performance of
data retrieval when running the report.
Report layouts
The visual layout determines the content and format of a report when it is viewed and printed. You build the
layout of a report by arranging data items and columns and specifying the general format, such as text font and
size. A report that is viewed, printed, or saved from a Dynamics 365 Business Central client must have a report
layout. There are three types of report layouts: layouts using report definition language (RDL), Word report
layouts, and Excel report layouts. You can also extend an existing report, for example, to add a new layout. For
more information, see Report Extension Object.
NOTE
The layout in a report extension will not automatically be used when the report extension is deployed. To use the report
extension layout, in Business Central, go to the Repor t Layout Selection page to choose to use the new layout for the
report in question by choosing it from the Custom Layout Description drop-down box.
RDL layout
To create an RDL layout report, you use Visual Studio Report Designer or Microsoft SQL Server Reporting
Services Report Builder. For more information, see Creating an RDL Layout Report.
IMPORTANT
RDL layouts can result in slower performance with document reports, regarding actions that are related to the user
interface (for example. like sending emails) compared to Word layouts. When developing layouts for document reports,
we recommend that you design Word layouts instead of RDL. With Word layouts, reports are not impacted by the
security constraints on sandbox app domains like they are with RDL layouts. From a service perspective, RDL layouts are
not trusted, so they will run in a sandbox app domain that only lives for the current report invocation.
See Also
Reports
Report Object
Report Extension Object
Report Data Type
Creating an RDL Layout Report
Creating a Word Layout Report
Request Pages
Report Object
2/6/2023 • 4 minutes to read • Edit Online
Reports are used to print or display information from a database. You can use a report to structure and
summarize information, and to print documents, such as sales quotes and invoices.
Creating a report consists of two primary tasks; the first task is to create the underlying data model and the next
is to define the visual layout that displays the data. The report object defines the underlying data model and
specifies which database tables and fields to pull data from. When the report is run, that data is displayed in a
specified layout; the visual layout, which determines the content and format of a report when it's viewed and
printed.
For more information about defining database tables and fields, see Defining a Report Dataset. For more
information about the Report data type, see Report Data Type.
You build the layout of a report by arranging data items and columns, and specifying the general format, such as
text font and size. There are three types of report layouts; client report definition, also called RDL layouts, Word
layouts, and Excel layouts. RDL layouts are defined in Visual Studio Report Designer or Microsoft SQL Server
Reporting Services Report Builder. Word layouts are created using Word. Word layouts are based on a Word
document that includes a custom XML part representing the report dataset. Excel layouts are created in Excel
based on the report dataset, utilizing the Excel capabilities such as sliders, diagrams, charts, pivot tables, and
PowerQuery. One report can contain multiple report layout definitions. For more information, see Defining
Multiple Report Layouts.
If you want to modify an existing report, for example, add new columns, add to the request page, or add a new
layout, you can create a report extension instead. For more information, see Report Extension Object.
TIP
It is possible to use a query object as the data source for a report. This can in many cases improve the performance of
data retrieval when running the report.
Snippet support
Typing the shortcut treport will create the basic layout for a report object when using the AL Language
extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Report example
The following example is a report that prints the list of customers. The report object defines a dataset of
columns from the Customer table. This example defines a report that uses an RDL report layout. For more
information about creating an RDL report layout, see Creating an RDL Layout Report. For more information on
creating a report that uses Word Layout, see Creating a Word Layout Report. For information about creating an
Excel layout, see Creating an Excel Layout Report.
report 50103 "Customer List"
{
CaptionML=ENU='Customer List';
DefaultLayout = RDLC; // if Word use WordLayout property
RDLCLayout = 'MyRDLReport.rdl';
dataset
{
dataitem(Customer;Customer)
{
RequestFilterFields="No.","Search Name","Customer Posting Group";
column(CompanyName;CompanyName)
{
}
column(CurrReport_PageNo;Customer."no.")
{
}
column(Customer_TableCaption_CustFilter;TableCaption + ': ' + CustFilter)
{
}
column(CustFilter;CustFilter)
{
}
column(Customer_No;"No.")
{
}
column(Customer_Customer_Posting_Group;"Customer Posting Group")
{
}
column(Customer_Customer_Disc_Group;"Customer Disc. Group")
{
}
column(Customer_Invoice_Disc_Code;"Invoice Disc. Code")
{
}
column(Customer_Customer_Price_Group;"Customer Price Group")
{
}
column(Customer_Fin_Charge_Terms_Code;"Fin. Charge Terms Code")
{
}
column(Customer_Payment_Terms_Code;"Payment Terms Code")
{
}
column(Customer_Salesperson_Code;"Salesperson Code")
{
}
column(Customer_Currency_Code;"Currency Code")
{
}
column(Customer_Credit_Limit_LCY;"Credit Limit (LCY)")
{
DecimalPlaces=0:0;
}
column(Customer_Balance_LCY;"Balance (LCY)")
{
}
column(CustAddr_1;CustAddr[1])
{
}
column(CustAddr_2;CustAddr[2])
{
}
column(CustAddr_3;CustAddr[3])
{
}
column(CustAddr_4;CustAddr[4])
{
}
}
column(CustAddr_5;CustAddr[5])
{
}
column(Customer_Contact;Contact)
{
}
column(Customer_Phone_No;"Phone No.")
{
}
column(CustAddr_6;CustAddr[6])
{
}
column(CustAddr_7;CustAddr[7])
{
}
column(Customer_ListCaption;Customer_ListCaptionLbl)
{
}
column(CurrReport_PageNoCaption;CurrReport_PageNoCaptionLbl)
{
}
column(Customer_NoCaption;FieldCaption("No."))
{
}
column(Customer_Customer_Posting_GroupCaption;Customer_Customer_Posting_GroupCaptionLbl)
{
}
column(Customer_Customer_Disc_GroupCaption;Customer_Customer_Disc_GroupCaptionLbl)
{
}
column(Customer_Invoice_Disc_CodeCaption;Customer_Invoice_Disc_CodeCaptionLbl)
{
}
column(Customer_Customer_Price_GroupCaption;Customer_Customer_Price_GroupCaptionLbl)
{
}
column(Customer_Fin_Charge_Terms_CodeCaption;FieldCaption("Fin. Charge Terms Code"))
{
}
column(Customer_Payment_Terms_CodeCaption;Customer_Payment_Terms_CodeCaptionLbl)
{
}
column(Customer_Salesperson_CodeCaption;FieldCaption("Salesperson Code"))
{
}
column(Customer_Currency_CodeCaption;Customer_Currency_CodeCaptionLbl)
{
}
column(Customer_Credit_Limit_LCYCaption;FieldCaption("Credit Limit (LCY)"))
{
}
column(Customer_Balance_LCYCaption;FieldCaption("Balance (LCY)"))
{
}
column(Customer_ContactCaption;FieldCaption(Contact))
{
}
column(Customer_Phone_NoCaption;FieldCaption("Phone No."))
{
}
column(Total_LCY_Caption;Total_LCY_CaptionLbl)
{
}
trigger OnAfterGetRecord();
begin
CalcFields("Balance (LCY)");
FormatAddr.FormatAddr(
CustAddr,Name,"Name 2",'',Address,"Address 2",
CustAddr,Name,"Name 2",'',Address,"Address 2",
City,"Post Code",County,"Country/Region Code");
end;
}
}
requestpage
{
SaveValues=true;
ContextSensitiveHelpPage = 'my-feature';
layout
{
}
actions
{
}
}
labels
{
LabelName = 'LabelText', Comment = 'Foo', MaxLength = 999, Locked = true;
}
trigger OnPreReport();
var
CaptionManagement : Codeunit 42;
begin
CustFilter := CaptionManagement.GetRecordFiltersWithCaptions(Customer);
end;
var
FormatAddr : Codeunit 365;
CustFilter : Text;
CustAddr : ARRAY [8] OF Text[50];
Customer_ListCaptionLbl : Label 'Customer - List';
CurrReport_PageNoCaptionLbl : Label 'Page';
Customer_Customer_Posting_GroupCaptionLbl : Label 'Customer Posting Group';
Customer_Customer_Disc_GroupCaptionLbl : Label 'Cust./Item Disc. Gr.';
Customer_Invoice_Disc_CodeCaptionLbl : Label 'Invoice Disc. Code';
Customer_Customer_Price_GroupCaptionLbl : Label 'Price Group Code';
Customer_Payment_Terms_CodeCaptionLbl : Label 'Payment Terms Code';
Customer_Currency_CodeCaptionLbl : Label 'Currency Code';
Total_LCY_CaptionLbl : Label 'Total (LCY)';
}
TIP
From the Business Central client, you can export report results as raw data to a Microsoft Excel file. The file contains all
columns of the dataset, but without the layout applied. Use the file to help validate that the report returns the expected
data, and to ensure that the report layout controls match the dataset value types. To export a report, run the report and
select the Send to > Microsoft Excel Document (data only) on the request page. For more information, see
Working with Reports - Send to Excel.
Schedule reports
It's possible to schedule a report to run at your desired date and time by using AllowScheduling property. By
setting the property to true, you'll get the Schedule action button to set the date and time for your report. To
learn more about scheduling a report, see AllowScheduling Property and Schedule a report.
See also
Report Extension Object
Request Pages
Report Properties
Creating an RDL Layout Report
Creating a Word Layout Report
Adding Help Links from Pages, Reports, and XMLports
Page Extension Object
Page Properties
Developing Extensions
AL Development Environment
Report Extension Example
2/6/2023 • 3 minutes to read • Edit Online
The following article illustrates how an existing table and report is extended by using extension objects. The
code snippets shown in this example don't provide a full end-to-end scenario that can be deployed; they're
intended to illustrate the way to extend existing functionality by using the Table Extension Object and Report
Extension Object.
fields
{
field(1; Name; Text[256]) { }
field(2; Color; Enum FoodColor) { }
field(3; Flavour; Text[256]) { }
field(4; "Vegan Friendly"; Boolean) { }
field(5; "Vegetarian Friendly"; Boolean) { }
field(7; Price; Decimal)
{
DecimalPlaces = 2;
}
keys
{
key(PK; Name)
{
Clustered = true;
}
}
}
value(0; White) { }
value(1; Red) { }
value(2; Black) { }
value(3; Brown) { }
value(4; Orange) { }
value(5; Green) { }
value(6; Blue) { }
}
dataset
{
dataitem(FoodTable; BaseFoodTable)
{
column(Name; Name) { }
column(Color; Color) { }
column(Flavour; Flavour) { }
column(Vegan_Friendly; "Vegan Friendly") { }
column(Vegetarian_Friendly; "Vegetarian Friendly") { }
column(Price; Price) { }
dataitem(Restaurant; Restaurant)
{
DataItemLink = ID = field(Restaurant);
column(RestaurantName; Name) { }
}
}
}
}
dataset
{
add(FoodTable)
{
column(GMO_Free; "GMO Free") { }
column(Organic; Organic) { }
column(Calories; Calories) { }
}
addfirst(Restaurant)
{
dataitem(Producer; Producer)
{
DataItemLink = ID = field(ProducerID);
DataItemLinkReference = FoodTable;
column(ProducerName; Name) { }
}
}
}
}
The example code above illustrates how additive changes to tables that are used on reports can use report
extension objects to reflect these changes.
See Also
Reports Overview
Report Object
Report Extension Object
Request Pages
OnPostReport (Report Extension) Trigger
OnPreReport (Report Extension) Trigger
OnAfterAfterGetRecord (Report Extension Data Set Modify) Trigger
OnAfterPostDataItem (Report Extension Data Set Modify) Trigger
OnAfterPreDataItem (Report Extension Data Set Modify) Trigger
OnBeforeAfterGetRecord (Report Extension Data Set Modify) Trigger
OnBeforePostDataItem (Report Extension Data Set Modify) Trigger
OnBeforePreDataItem (Report Extension Data Set Modify) Trigger
Defining a Report Dataset
2/6/2023 • 2 minutes to read • Edit Online
You use a report object in the AL Language development environment to define the data model, or dataset, of a
report. The dataset determines the data that is extracted or calculated from the Dynamics 365 Business Central
database tables that can be used in a report. For more information, see Report Object.
Snippet support
Typing the shortcut treport will create the basic layout for a report object when using the AL Language
extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
TIP
From the Business Central client, you can export report results as raw data to a Microsoft Excel file. The file contains all
columns of the dataset, but without the layout applied. Use the file to help validate that the report returns the expected
data, and to ensure that the report layout controls match the dataset value types. To export a report, run the report and
select the Send to > Microsoft Excel Document (data only) on the request page. For more information, see
Working with Reports - Send to Excel.
// Example of how to use a query as the data source for a report dataset.
dataset
{
dataitem(Integer; Integer)
{
column(CustomerName; MyQuery.CustomerName)
{
}
column(SomeFieldFromAnotherTable; MyQuery.SomeFieldFromAnotherTable)
{
}
trigger OnPreDataItem()
begin
MyQuery.Open();
end;
trigger OnAfterGetRecord()
begin
if not MyQuery.Read() then
CurrReport.Break();
end;
}
}
var
MyQuery: Query "CustomerQuery";
See Also
Report Object
Report Extension Object
Reports Overview
Report Design Overview
Request Pages
2/6/2023 • 4 minutes to read • Edit Online
A request page is a page that is run before the report or XMLport starts to execute. Request pages enable end
users to specify options and filters for a report and an XMLport. Request pages are defined as part of designing
a Report object, a Report Extension Object, or an XMLport object. The syntax is shown further down in this
article. You design the filters on request pages by using the following report and XMLport properties:
RequestFilterHeading Property Sets a caption for the request page tab that is related to a
report's data item or an XMLport's table element.
NOTE
Request pages for XMLports are not supported by the Business Central Web client in versions prior to Dynamics 365
Business Central 2019 release wave 2. If you try to run an XMLport with a Request page from the web client in these
versions, you receive an error that the XMLport page type is not supported. Alternatively, XMLport request pages do
work in the Dynamics NAV Client connected to Business Central.
By default, a request page is displayed, unless the UseRequestPage is set to false ; then the report or XMLport
will start to print as soon as it's run. In this case, end users can't cancel the report or XMLport run. It's still
possible to cancel the report or XMLport, but some pages may print.
By default, without having set anything else, a request page will always display the following buttons:
Send to
Print
Preview
Cancel
Additionally, you can add more options on the request page to allow the end user to filter the data displayed.
NOTE
Only on the Windows client, filtering is possible even if RequestFilterFields is not set.
Defining the RequestFilterFields property in the dataitem() part of the report code is done as illustrated in
the following code example:
NOTE
It is recommended to add columns that the end-users of the report will frequently set filters on.
For more information about the report object, see Report Object.
Defining the RequestFilterFields property in the tableelement() part of an XMLport is done in a similar way:
For more information about the XMLport object, see XMLport Object.
By default, for every data item in the report and table element in a XMLport, a FastTab for defining filters and
sorting is created on the request page. To remove a FastTab from a request page, don't define any
RequestFilterFields for the data item or table element and set the DataItemTableView property in a report or
the SourceTableView property in an XMLport to define sorting. The request page is displayed, but there's no tab
for this data item or table element.
If a DataItemTableView or SourceTableView isn't defined, then end-users can select a sort column and sort order
at runtime.
In a complex report or XMLport that uses data from several tables, the functionality may depend on a specific
key and sort order. Design your reports and XMLports so that end-users can't change the sort order in a way
that affects their functionality.
For data items and table elements whose source table contains calculated fields, such as amounts and quantities,
the Filter totals by: section is automatically included on the request page, which allows you to adjust various
dimensions that influence calculations.
TIP
For information about how to enter filter criteria on the request page, see Filtering in the Business Central application
help.
NOTE
You can use the SaveValues property together with the AllowScheduling property to set up the request page to
support multiple previews. When both properties are true , users can preview the report from the request page as
many times as the like, without having the request page close. This capability lets users change filters, see what the
generated report will look like, and then try again. If either property is set to false , the report won't support multiple
previews and the request page closes once the user previews the report. In this case, the request page includes a
Preview and Close button instead of Preview .
...
requestpage
{
SaveValues = true;
layout
{
area(content)
{
group(Options)
{
Caption = 'Options';
field(PostingDate; PostingDateReq)
{
ApplicationArea = Basic, Suite;
Caption = 'Posting Date';
ToolTip = 'Specifies the posting date for the invoice(s) that the batch job creates.
This field must be filled in.';
}
}
}
}
trigger OnOpenPage()
begin
if PostingDateReq = 0D then
PostingDateReq := WorkDate;
end;
var
PostingDateReq: Date;
}
...
See Also
Report Object
Report Extension Object
XMLport Object
Reports Overview
Report Design Overview
RunRequestPage Method
RequestFilterHeading Property
RequestFilterHeadingML Property
RequestFilterFields Property
DataItemTableView
Report Triggers and Runtime Operations
2/6/2023 • 8 minutes to read • Edit Online
This article describes the triggers and operations that are executed when a report is run. The triggers and
operations will depend on a few things, like:
Whether the report has request page
What action the user takes on the request page, like preview, print, and schedule
What preview mode the report uses
Some triggers are invoked in the report, while others are invoked on the request page. Understanding the
sequence of the triggers and operations will help you design reports that work as expected.
The following figure illustrates the general report trigger flow for Business Central version 20 and later.
When you start the report run, the OnInitReport Trigger is called. If the OnInitReport doesn't end the processing
of the report, then the request page for the report is run, if one is enabled. The page triggers for the request
page are called. On the request page, you select the options that you want for this report. You can also decide to
cancel the report run. If you decide to continue, then the OnPreReport Trigger is called. At this point, no data has
yet been processed. When the OnPreReport trigger has been run, the first data item is processed unless the
processing of the report was ended in the OnPreReport trigger.
TIP
For more information about the print triggers and operations, see Developing Printer Extensions in Business Central.
preview & close The preview & close mode is the only mode supported in
Business Central 2020 release wave 1 (version 16) and
earlier. This mode invokes the preview action within the
current report instance, referred to as the primary instance.
In this mode, the request page closes when the user
previews the report. The user will then have to run the
report again if the preview doesn't show the expected result.
In the client, a request page that uses this mode will include
the Preview & Close button.
In the client, a request page that uses this mode will include
the Preview button.
For more information to help your design, see Key Design Guidelines and Considerations.
How the mode is set
By default, reports use the multiple-preview mode. The mode is determined by two report properties:
SaveValues and AllowScheduling, as outlined in the following table:
NOTE
The GetPrinterName procedure in the diagram isn't an actual AL-enabled trigger. Instead, it's a call from platform to the
application code that subscribes to the GetPrinterName event, which will return the selected printer name for the current
report.
The following figure illustrates the flow associated with an RDLC report layout type.
Key design guidelines and considerations
Multiple -preview mode
Avoid the following implementations:
Set global variables in page triggers
Use the OnQueryClose page trigger to change global variables in the report
Depend on instance methods to be called to set state variables before report invocation
The request pages that have SaveValues property set to false .
If you have reports that use any of these implementations, refactor them to ensure report content
renders as expected.
NOTE
If a legacy report depends on global variable state, the developer can use a single instance codeunit to transfer
variable state between the two running instances. The state is the set in the primary object and read from the
child object.
For more information about the flow, see Request page and preview triggers and operations.
Only visible user interface elements are transferred to the preview in child instances.
User interaction triggers from the visible request page, like lookup, validate, and other page triggers,
aren't invoked in head-less request page flow in the child instance. Design these triggers so that they
don't affect variables that are hidden in the object. For more information, see Visible and head-less
request page flows.
OnInitRepor t trigger calls
OnInitRepor t trigger is run when the report initially invoked, and again for every preview of the report
in the child instance. This condition, in some cases, can mean that before the report is even executed, the
OnInitRepor t trigger has already run twice. For more information, see Detailed child instance triggers
and operations in multiple-preview mode.
The design of some reports may make it impossible or undesirable to run in the multiple-preview mode.
In these cases, the report should run in the preview & close mode. So as a developer, you set the
AllowScheduling property to false in the report object declaration. Optionally, you can set the
SaveValues property of request page to false , in which case, the mode will revert to preview & close
mode. However, this configuration isn't recommended, because it removes the ability to save current
settings for later use.
For more information, see Request Page Preview Modes.
General
Defining methods that have the same name in the report and table
If you have two methods with the same name, one defined in a report and the other in a table that is
referenced by the report, you cannot invoke the method defined in the report directly. By default, a call to
the method invokes the method that's defined in the table. This behavior occurs when the method is
called from a source expression or a trigger.
See Also
Report Triggers Report Data Item Triggers
Report Object
Triggers
Adding Pages and Reports to Tell me
2/6/2023 • 4 minutes to read • Edit Online
The Business Central client includes the Tell me feature that lets users find objects by entering search terms.
When you have added a page or a report in your extension, you most likely want it to be discoverable to users
in Tell me . In AL, you make a page or report searchable from Tell me by setting the UsageCategory property in
code. The UsageCategor y setting will make the page or report searchable, and the value chosen for the setting
will further sub categorize the item.
Tell me finds pages and reports by searching the captions that are specified on page and report objects by the
CaptionML property.
TIP
The UsageCategor y is also used to categorize pages and reports shown in the role explorer of the client. The role
explorer includes two actions: Repor ts and Analysis and Administration . Pages and reports set to
Repor tsAndAnalysis will show when the Repor ts and Analysis action is selected. Pages and reports set to
Administration will show when the Administration action is selected. For more information, see Finding Pages with
the Role Explorer.
VA L UE DESC RIP T IO N
Lists The page or report is listed as Lists under the Pages and
Tasks category.
Tasks The page or report is listed as Tasks under the Pages and
Tasks category.
Example
The following example creates a SimpleItemList page and sets a UsageCategory property to the page, so that
the SimpleItemList page is discoverable through search using the Tell me feature. Also, the example sets the
AdditionalSearchTerms property to add two search terms for the page.
layout
{
area(content)
{
group(General)
{
field("No.";"No.") {}
field(Name;Name) {}
field(Description;Description) {}
}
}
}
}
Optional settings
In addition to making a page or report searchable, you can control the access of an object by providing Read ,
Inser t , Modify , Delete , and Execute (RIMDX) permissions by adding the AccessByPermission property.
Likewise, control the application area access on the specified object by adding the ApplicationArea Property.
The AccessByPermission property and ApplicationArea property are the optional settings, which can be
applied with the UsageCategor y property. These settings are used to set restrictions on an object when you
enable the Search functionality.
If you are using the Dynamics NAV Development Environment, you can also set UsageCategor y ,
AdditionalSearchTerms , AccessByPermission , and ApplicationArea properties on pages and reports to
control their search.
After you change these properties by using the Dynamics NAV Development Environment, before the changes
take effect in the client, you must run Build Object Search Index from the Tools menu.
See Also
Adding Menus to the Navigation Pane
UsageCategory Property
Page Object
Report Object
AL Development Environment
Substituting Reports
2/6/2023 • 2 minutes to read • Edit Online
In versions prior to Business Central 2021 release wave 1 extensibility is not supported for report objects.
Therefore, if you want to make any changes to the dataset or the layout of a base application report, you must
create a new version of the report and apply the changes on the new object. Then you can override the base
report with your own customized version by subscribing to the OnAfterSubstituteRepor t event published by
Codeunit 44 – Repor tManagement . From Business Central 2021 release wave 1, report extensi
NOTE
The event is called OnAfterSubstituteRepor t to match the pattern followed by other events in the
Repor tManagement codeunit, but the subscriber will be invoked before the substitution takes place.
Good practices
Consider using the same caption for both reports, given by the Caption Property. Consequently, any links
and action captions that lead to the report will match the report itself. This is also relevant for bookmarks
linked to a report, since they maintain the caption of the original report, even if it has been substituted for
one with another caption.
Consider enhancing the code of the subscriber method to check if the report has already been replaced with
another extension. This is done by comparing the ReportId and NewReportId parameters before making the
change, such that if the value of the NewReportId parameter is different from the value of the ReportId
parameter and different from -1, it means that the report has already been substituted for another subscriber
of the OnAfterSubstituteRepor t event.
IMPORTANT
Make sure that if a report is called on code, you use a compatible report to replace it to avoid run time errors.
See Also
Report Data Type
Subscribing to Events
Events in AL
GetSubstituteReport Method
Get Started with AL
Testing Reports
2/6/2023 • 2 minutes to read • Edit Online
Testing your report requires you to run it and to verify the data output. This practice helps you ensure that your
customers are presented with complete and accurate data.
Before extensions, the output of a report was saved to a file, but extensions deployed to Dynamics 365 Business
Central cannot access the file system and therefore must save the output of a report to a stream. Codeunit
131007 Library - Report Dataset offers a high-level API for running and testing the output of reports that does
not require direct access to the file system.
Example
The following example shows how to initialize the codeunit 131007 Library - Report Dataset by using the
RunReportAndLoad method. This method is preferred as it will run the report and initialize the
Library - Report DataSet codeunit. To verify the output, call either the AssertElementWithValueExists or the
AssertElementWithValueNotExist method. The other methods in the library should work as well if they do not
contain “Tag” in the name. RUNREQUESTPAGE and [RequestPageHandler] are optional and you can use them when
you want to open the request page.
TIP
If you want to run the report separately and load the data from the input stream manually, you can use the
LoadDataFromInstream method.
[Test]
[HandlerFunctions('RemittanceAdviceJournalRequestPageHandler')]
procedure TestingReports();
var
XmlParameters: Text;
LibraryReportDataset: Codeunit "Library - Report Dataset";
GenJournalLine: Record "Gen. Journal Line";
begin
// Run the Report Remittance Advice - Journal.
XmlParameters := Report.RunRequestPage(Report::"Remittance Advice - Journal");
LibraryReportDataset.RunReportAndLoad(Report::"Remittance Advice - Journal", GenJournalLine,
XmlParameters);
[RequestPageHandler]
procedure RemittanceAdviceJournalRequestPageHandler(var RemittanceAdviceJournal: TestRequestPage 399);
begin
// Empty handler used to close the request page. We use default settings.
end;
}
Any changes done in the handler above will result in the XmlParameters being changed and applied
automatically when the report runs. Examples of the implementation in the existing tests are in Codeunit 133770
and Codeunit 134141 .
Remarks
TestRequestPage.SaveAsXML uses a different format than Report.SaveAsXML or Report.SaveAs by serializing the
output of Repor t Previewer . This is a component that will be deprecated in the future and replaced with the
new methods that can be used for the new tests. Another difference is that TestRequestPage.SaveAsXML requires
files to be saved to disk and loaded, while other methods work in memory, making them more efficient.
NOTE
The existing tests still need support and the codeunit solves this problem by supporting both formats for now.
TestRequestPage.SaveAsXML uses Tags for values, while the new format uses attributes. This means that you cannot use
any public method that contains "Tag" in the name to test the reports generated in the memory.
See Also
Reports Overview
Testing Pages
Test Codeunits and Test Methods
Creating a Word Layout Report
2/6/2023 • 3 minutes to read • Edit Online
When you create a new report, there are two main tasks. First, you define the report dataset of data items and
columns. Then, you design the report layout. These steps will show how to create a report based on a Word
layout. For more information about the report object, see Report Object and Report Extension Object.
Later in this article you can read more how to enable multiple report layouts. For more information, see
Enabling the Microsoft Word rendering engine.
NOTE
The Different first page and Different odd and even options for headers and footers in Word aren't supported for
HTML conversion. If you select either of these options, the header and footer won't appear in rendered output, such as an
Email Body.
1. Create a new extension to the Customer List page that contains code to run the report and a report
object by adding the following lines of code:
dataset
{
dataitem(Customer; Customer)
{
column(Name; Name)
{
}
}
}
}
NOTE
If you do not see the Developer tab, go to Options , then Customize Ribbon , and in the Main tabs section,
select the Developer check box.
7. In Word, to the right, in the Custom XML par t lookup, locate the report, and then open the layout.
8. Right-click on the Customer table, and in Inser t Content Control , select Repeating to add the
repeater data item.
9. Right-click on the Name field and in Inser t Content Control , select Plain Text to add the column as a
text box.
10. Save the report layout when you're done and then close it.
11. Back in Visual Studio Code, press Ctrl+F5 to compile and run the report.
You'll now see the generated report in preview mode.
NOTE
If the report layout is not generated, open the settings.json from Visual Studio Code. Use Ctrl+Shift+P , then
choose Preferences: Open User Settings , locate the AL Language extension . Under Compilation Options ,
choose Edit in settings.json and add the following line:
"al.compilationOptions": {
"generateReportLayout": true
}
TIP
From the Business Central client, you can export report results as raw data to a Microsoft Excel file. The file contains all
columns of the dataset, but without the layout applied. Use the file to help validate that the report returns the expected
data, and to ensure that the report layout controls match the dataset value types. To export a report, run the report and
select the Send to > Microsoft Excel Document (data only) on the request page. For more information, see
Working with Reports - Send to Excel.
The rendering of Word reports is controlled by an application feature key. Enabling the key
RenderWordReportsInPlatform in the Feature Management page in Business Central will switch the Microsoft
Word report rendering to the new platform rendering, which supports multiple layouts and new triggers for
Save and Download actions.
NOTE
Application rendering is obsolete and will be deprecated in a future release. It is recommended to stay on the old platform
if you have extensions that use custom Word layouts and therefore cannot use the new platform, for example, because of
dependencies on the OnBeforeMergeDocument or OnBeforeMergeWordDocument events.
The following AL snippet can be used in code to implement rendering differentiation in extensions.
var
FeatureKey: Record "Feature Key";
PlatformRenderingInPlatformTxt: Label 'RenderWordReportsInPlatform', Locked = true;
// code snippet
if (FeatureKey.Get(PlatformRenderingInPlatformTxt) and (FeatureKey.Enabled = FeatureKey.Enabled::"All
Users")) then
// Platform rendering of Word reports, Custom layout types will be handled by the OnCustomDocumentMerger
event
....
else
// App rendering - The report type will be treated like a Word file and rendered by the application
...
For more information about feature management, see Enabling Upcoming Features Ahead of Time.
See Also
Setting up Hyperlinks in Word Report Layouts
Report Design Overview
Report Object
Report Extension Object
Developing a Custom Report Render
Creating an RDL Layout Report
Creating an Excel Layout Report
Creating an RDL Layout Report
2/6/2023 • 2 minutes to read • Edit Online
When you create a new report for Dynamics 365 Business Central, there are two things you have to consider;
defining the report dataset of data items and columns, and then designing the report layout. These steps will
show you how to create a very simple report based on an RDL layout. For more information about the report
object, see Report Object. And to learn how to extend an existing report, see Report Extension Object.
IMPORTANT
RDL layouts can result in slower performance with document reports, regarding actions that are related to the user
interface (for example. like sending emails) compared to Word layouts. When developing layouts for document reports,
we recommend that you design Word layouts instead of RDL. With Word layouts, reports are not impacted by the
security constraints on sandbox app domains like they are with RDL layouts. From a service perspective, RDL layouts are
not trusted, so they will run in a sandbox app domain that only lives for the current report invocation.
To create and modify RDL report layouts, you use SQL Server Report Builder or Microsoft RDLC Report
Designer. For information about required versions of these tools, see System Requirements.
dataset
{
dataitem(Customer; Customer)
{
column(Name; Name)
{
}
}
}
}
4. Build the extension (Ctrl+Shift+B ). The MyRDLReport.rdl file will be created in the root of the current
project.
5. Open the generated report layout file in Microsoft SQL Ser ver Repor t Builder .
6. Edit the layout by inserting a table.
7. Add the Name column from the Datasets folder into the table and save the .rdl file.
8. Back in Visual Studio Code, press Ctrl+F5 to compile and run the report in Dynamics 365 Business
Central.
You will now see the generated report in preview mode.
NOTE
If the report layout is not generated, open the settings.json from Visual Studio Code. Use Ctrl+Shift+P , then
choose Preferences: Open User Settings , locate the AL Language extension . Under Compilation Options ,
choose Edit in settings.json and add the following line:
"al.compilationOptions": {
"generateReportLayout": true
}
TIP
From the Business Central client, you can export report results as raw data to a Microsoft Excel file. The file contains all
columns of the dataset, but without the layout applied. Use the file to help validate that the report returns the expected
data, and to ensure that the report layout controls match the dataset value types. To export a report, run the report and
select the Send to > Microsoft Excel Document (data only) on the request page. For more information, see
Working with Reports - Send to Excel.
See Also
Report Design Overview
Report Object
Creating a Word Layout Report
Creating an Excel Layout Report
Defining Multiple Report Layouts
Creating an Excel Layout Report
2/6/2023 • 3 minutes to read • Edit Online
When you create a new report, there are two main tasks to consider. First, you define the report dataset of data
items and columns. Then, you design the report layout. With the Excel report layout, you can create a basic
report that prints a dataset and leave it up to the end-user to further modify it by using the full palette of
capabilities in Excel such as sliders, diagrams, charts, pivot tables, and PowerQuery to design the report. This
offers flexibility and freedom for the end-user, being able to change the look and feel of a report, adding
additional views, filtering, and sorting on data. Such a layout designed by the end-user, can be imported and
used as a new layout. The following steps will show how to create a basic report based on an Excel layout.
The example illustrates how compilation triggers a starter template for the Excel layout. If an existing layout is
referenced with the LayoutFile property the layout is validated based on the schema of the report dataset.
For more information about the report object, see Report Object and for report extension objects, see Report
Extension Object.
2. Now, press Ctrl+Shift+P , and then choose AL: Package . The MyExcelContactList.xlsx will be
generated, as you can see in the right pane of Visual Studio Code.
TIP
Another way of generating the data set to build a layout on, is to run a report in Business Central and on the
request page, then choose the Microsoft Excel Document (data only) option, and you will get the same
starting point. Then you can design the layout, save as a new layout, and include in your AL project.
3. Right-click the generated MyExcelContactList.xlsx file, and choose Reveal in File Explorer . This will
open File Explorer.
4. Choose the MyExcelContactList.xlsx file in File Explorer and open it in Excel.
Excel now opens and you should see the dataset of the Contact List. Note that it is important to not
change the dataset in Excel, only the layout.
5. In Excel, go to the Inser t tab, choose PivotTable , and then choose From Table/Range with the default
options of Data and New worksheet . Choose the OK button.
6. From the PivotTable Fields pane to the right, choose a suitable number of fields to add to the report.
7. Save the report and close the Excel window.
8. Back in Visual Studio Code, press Ctrl+F5 to compile and launch Business Central.
9. Now, to choose the changed report layout, search for the Repor t Layout Selection page, and then
search for the Contact List (ID 5050) report.
10. In the Layout Type column, choose Excel , and then choose the Run Repor t from the action bar.
11. On the request page, choose the Download button, and once the report is downloaded, open it.
12. In Excel, you should now see the Contact List report as a pivot table, sorted as you specified in step 6.
NOTE
If the report layout is not generated, open the settings.json from Visual Studio Code. Use Ctrl+Shift+P , then
choose Preferences: Open User Settings , locate the AL Language extension . Under Compilation Options ,
choose Edit in settings.json and add the following line:
"al.compilationOptions": {
"generateReportLayout": true
}
It is possible to specify multiple layouts for a report. For more information, see Defining Multiple Report
Layouts.
See also
Report Design Overview
Report Object
Creating a Word Layout Report
Creating an RDL Layout Report
Defining Multiple Report Layouts
ExcelLayout Property
LayoutFile Property
Defining Multiple Report Layouts
2/6/2023 • 2 minutes to read • Edit Online
In AL you have the option of defining multiple layouts for one report in code. This means that you can offer
multiple versions of a layout for different purposes. Defining multiple layouts applies to both report objects, and
report extension objects. The layouts can be of different types, meaning that you can have, for example, a Word
layout and an Excel layout for one report, or multiple Excel layouts for one report. This enables creating report
extensions that only add layouts to an existing report and packaging it as an extension .al file.
Read more about enabling multiple report layouts and implementing rendering differentiation in extensions, see
Enabling the Microsoft Word rendering engine.
NOTE
If you do not specify a caption, the layout name will be displayed to the user.
If the extension is translated, the Caption and Summary properties are included in the .xliff file and translated as
well. For more information, see Working with Translation Files.
TIP
Reports using the previous property-based layout specification can be converted to use the rendering section by using
a code action. To use this, ensure code that actions are switched on in your AL extension settings and place the cursor on
any of the old layout properties to use the action. Layouts of type RDLC, Word, Excel, and Custom can be specified with
the new rendering syntax. For more information, see AL Language Extension Configuration.
Layout definition in AL
The following example illustrates how the EmpReportExt report extends the "Employee - List" list by adding
four report layouts as options for printing this report. The report extension only adds the layouts, the dataset
remains the same as the existing Employee List report.
reportextension 50102 EmpReportExt extends "Employee - List"
{
rendering
{
layout(LayoutExcelPivot)
{
Type = Excel;
Caption = 'ExcelPivot';
Summary = 'Employee list shown in Pivot table in Excel';
LayoutFile = 'EmpShownAsPivot.xlsx';
}
layout(LayoutExcel)
{
Type = Excel;
Caption = 'ExcelColumns';
Summary = 'Employee list sorted by last name in Excel';
LayoutFile = 'EmpSortedByLastName.xlsx';
}
layout(LayoutWord)
{
Type = Word;
Caption = 'WordList';
Summary = 'Employee list sorted by last name in Word';
LayoutFile = 'EmpSortedByLastName.docx';
}
}
}
If one or more of the layouts do not exist, they will be generated when pressing Ctrl+Shift+P , and then
choosing AL: Package . The layouts will appear in your project in the right pane of Visual Studio Code. The
generated reports contain the dataset from the report, and you can modify and model the reports in each of the
layout types as you want.
Creating layouts in Excel, RDL, or Word is further described in the topics shown under See also.
See also
Creating an Excel Layout Report
Creating an RDL Layout Report
Creating a Word Layout Report
Developing a Custom Report Render
2/6/2023 • 2 minutes to read • Edit Online
This article describes the concept of a custom report render. The custom report render manages the rendering
of a generated report dataset with a layout type specified by an extension. The actual rendering will take place in
the application by using the OnCustomDocumentMergerEx event provided by the ReportManagement codeunit. The
layout must be specified in the rendering section in the report definition.
Sample AL code
The simplest possible custom document render can be implemented as in the following sample. The example
will use the existing application logic to render XML datasets into Microsoft Word or PDF documents using a
given template (Word template).
Init();
ObjectPayload.Get('layoutname', Token);
LayoutName := Token.AsValue().AsText();
ObjectPayload.Get('layoutmodel', Token);
LayoutModel := Token.AsValue().AsText();
DocumentTypeParts := DocumentType.AsValue().AsText().Split('/');
// Notice that the Extension below have to be remapped to a standard file extension based on the
document mimetype.
Extension := DocumentTypeParts.Get(DocumentTypeParts.Count);
TempBlob.CreateOutStream(DataOutStream);
// The
case ReportAction of
ReportAction::SaveAsPdf, ReportAction::Preview, ReportAction::Print:
begin
if not DocumentReportMgt.TryXmlMergeWordDocument(LayoutData, XmlData, DataOutStream)
then
error('Unable to handle custom document merge');
DocumentReportMgt.ConvertWordToPdf(TempBlob, ObjectID);
TempBlob.CreateInStream(DataInStream);
CopyStream(DocumentStream, DataInStream);
IsHandled := true;
end;
ReportAction::SaveAsHtml:
begin
if not DocumentReportMgt.TryXmlMergeWordDocument(LayoutData, XmlData, DataOutStream)
then
error('Unable to handle custom document merge');
DocumentReportMgt.ConvertWordToHtml(TempBlob);
TempBlob.CreateInStream(DataInStream);
CopyStream(DocumentStream, DataInStream);
IsHandled := true;
end;
ReportAction::SaveAsWord:
begin
if not DocumentReportMgt.TryXmlMergeWordDocument(LayoutData, XmlData, DocumentStream)
if not DocumentReportMgt.TryXmlMergeWordDocument(LayoutData, XmlData, DocumentStream)
then
error('Unable to handle custom document merge');
IsHandled := true;
end;
else
error('Unsupported report action %0', ReportAction);
end;
end;
See Also
Working With and Troubleshooting Payloads
OnCustomDocumentMergerEx Event
Events in AL
Publishing Events
Raising Events
Subscribing to Events
Walkthrough: Designing a Report from Multiple
Tables
2/6/2023 • 22 minutes to read • Edit Online
A report object is composed of a report dataset and a visual layout. You design a report by first defining the
dataset and then designing the visual layout. You define the dataset for reports directly in AL code. You can
design the layout in Visual Studio Report Designer or Microsoft SQL Server Reporting Services Report Builder
for an RDL layout, in Microsoft Word for a Word layout, and in Microsoft Excel for an Excel layout. After you
design a report, you can make it available to applications that are running on the Business Central Web client. A
report can be designed from one table or multiple tables. This walkthrough demonstrates how to design a
report from multiple tables.
Story
Viktor is a developer who is working for CRONUS International Ltd. Viktor has been asked by his manager to
create a report that shows data from the Customer (ID 18), Cust. Ledger Entry (ID 21),
Detailed Cust. Ledger Entry (ID 379), and the Sales Header (ID 36) tables. The report should meet the
following requirements:
The report must display customer information at the top of the report.
For each customer, the report must show a list of ledger entries.
For each ledger entry, the report must show a list of detailed ledger entries under the ledger entries.
The report must display basic sales document headers information for the selected customer.
Each section of the data for each customer must begin on a new page.
The Amount field from the Cust. Ledger Entry table should be totaled and displayed for each customer.
If there are no records to display, the report must not display that data sections. For example, if there are
no sales documents for a customer, the sale header section must be skipped.
Amount fields must not display zero values.
The orientation of the report should be landscape.
The following illustration shows an example of the second page of the report.
dataset
{
dataitem(Customer; Customer)
{
// Sort the table view based on the "No." field.
DataItemTableView = Sorting("No.");
// Include the "No." field on the filter tab of the request page.
RequestFilterFields = "No.";
// Print data only if at least one of the CustLedgerEntry and SalesHeader data items generates
output.
PrintOnlyIfDetail = True;
// For each field that you want to display you add a column control.
column(No_Customer; "No.")
{
// Include the caption of the "No." field in the dataset of the report.
IncludeCaption = true;
}
column(Name_Customer; Name)
{
IncludeCaption = true;
column(Address_Customer; Address)
{
IncludeCaption = true;
column(EMail_Customer; "E-Mail")
{
IncludeCaption = true;
}
dataitem(CustLedger; "Cust. Ledger Entry")
{
}
column(CustomerNo_CustLedgerEntry; "Customer No.")
{
IncludeCaption = true;
}
column(PostingDate_CustLedgerEntry; "Posting Date")
{
IncludeCaption = true;
}
column(DocumentType_CustLedgerEntry; "Document Type")
{
IncludeCaption = true;
column(Description_CustLedgerEntry; Description)
{
IncludeCaption = true;
column(Amount_CustLedgerEntry; Amount)
{
IncludeCaption = true;
}
}
column(No_SalesHeader; "No.")
{
IncludeCaption = true;
column(Amount_SalesHeader; Amount)
{
IncludeCaption = true;
}
}
}
}
NOTE
Changing the color of report elements helps you identify elements on the report preview. You can set different
color properties for table header, detail rows, text boxes, and so on.
Viktor will set the properties of the List control to hold the dataset, group the data by Customer No. and
set up how the groups should be displayed.
To set the list control properties
1. Select the List control, right-click the shaded border to the left of the List control, and then choose Tablix
Proper ties .
2. In the Tablix Proper ties window, on the General tab, under Dataset name , select DataSet_Result
from the drop-down list, and then choose the OK button.
3. Select the List control, right-click the shaded border to the left of the list control, choose Row Group ,
and then Group Proper ties .
4. In the Group Proper ties window, on the General tab, under Group expressions:, choose the Add
button, and then select [No_Customer] from the Group on: drop-down list. This groups all the data in
the List control by customer number.
5. On the Page Breaks tab, select Between each instance of a group , and then choose the OK button.
Viktor is now ready to add the customer data. The table will display one customer at a time, therefore Viktor
must put all the fields into table header rows. The table data and footer rows will be disabled.
To add customer data
1. From the Toolbox pane, drag a Table control into the List control and resize the table to about the half
the width of the list control. This table will contain the customer data.
The following illustration shows the list control and the table.
The table contains two table rows, a header row (first row), and a data row (second row). The three
parallel lines in the left border of the second row identify the data row.
2. Select any table row, right-click the shaded border, and then choose Tablix Proper ties to open the
Tablix Proper ties window.
3. On the General tab, verify that the Dataset name field is set to DataSet_Result , and then choose the
OK button.
The table has three columns. Viktor will add a fourth column to the table to hold all the customer data.
4. Right-click the middle column header, choose Inser t Column , and then select Right to insert the fourth
column into the table.
5. Select the second table row (the data row), right-click the row, choose Delete Rows to delete the data
row, and then choose the OK button in the Delete Rows window to delete the row and its associated
groups.
6. Select the remaining table row, right-click the shaded border on the left, choose Inser t Row , and then
choose Below to insert another table header row.
7. Repeat step 6 to insert a third table header row. There should now be three header rows in the table.
8. Right-click the first cell (row 1, column 1) in the table, and then choose Expression to open the
Expression window.
9. In the Categor y column, select Parameters , in the Item column, verify that All is selected, and then in
the Values column, double-click No_CustomerCaption . Verify that the Set expression for : Value box
contains the following value: =Parameters!No_CustomerCaption.Value . This cell will display the customer
No. caption in the report.
10. Modify the expression to =First(Parameters!No_CustomerCaption.Value) . Choose the OK button.
NOTE
All caption fields must begin with =First so that the first value for the caption fields in the data set is retrieved
and used as caption. If the First function is not used, the report will return the current value for a field. The current
value however may be incorrect. For example, the current value could be empty.
11. Right-click the second cell (row 1, column 2) in the table, and then choose Expression to open the
Expression window.
12. In the Categor y column, select Field(DataSet_Result) , in the Item column verify that All is selected,
and then in the Values column double-click No_Customer . Verify that the Set expression for : Value
box contains the following value =Fields!No_Customer.Value . Choose the OK button. This cell will display
the Customer No..
13. Repeat steps 8 through 12 to the enter captions and values in the following cells.
NOTE
Columns 1 and 3 will contain the captions and columns 2 and 4 will contain the values.
RO W C O L UM N C A P T IO N VA L UE
2 1 Name_CustomerCaption None
2 2 None Name_Customer
1 3 Address_CustomerCaptio None
n
1 4 None Address_Customer
2 3 PhoneNo_CustomerCapti None
on
2 4 None PhoneNo_Customer
3 3 Email_CustomerCaption None
RO W C O L UM N C A P T IO N VA L UE
3 4 None Email_Customer
14. Select all table rows (not the whole table), and then on the View menu, choose Proper ties Window to
open the Proper ties window in Visual Studio.
15. In the Proper ties window, under Fill , set the BackgroundColor property to Plum . You can choose any
color.
The layout that Viktor has designed to this point resembles the following illustration.
16. On the Build menu, choose Build Web site to build the project. Inspect the Output pane and make sure
that there are no build errors. Close Visual Studio.
NOTE
It is a good practice to build the project periodically during the report design to make sure that there are no build
errors.
Viktor will run the report and preview what he's done to this point.
17. Go back to your project in Visual Studio Code and Reload the Window.
18. In the launch.jsonfile set the "startupObjectId" to the Id of the report object and the
"startupObjectType" to Report .
NOTE
You may have to resize the report body and the list controls to make them larger.
3. Select the table, right-click the shaded border, choose Tablix Proper ties . On the General tab, verify that
the Dataset name field is set to DataSet_Result , and then choose the OK button.
4. Select the table data row, choose Inser t Row and then choose Outside Group – Below . This adds
another data row to the table. You now have one header row and two data rows.
5. Delete the first row (header row) in the table and then insert columns in the table so that the total
number of columns is 11.
6. Choose the first data row, right-click the shaded border to the left, choose Add Group , and then choose
Parent Group .
7. In the Tablix group window, select Group by , select Entr yNo_CustLedgerEntr y from the drop-down
list. Select Add group header , and then choose the OK button.
8. Right-click the first row, choose Inser t Row , and then choose Inside Group – Above . This header will
hold the captions for the Customer Ledger entries.
9. Right-click the cell in the row1, column 2, and then choose Expression to open the Expression window.
10. In the Categor y column, select Parameters and then in the Values column double-click
Entr yNo_CustLedgerEntr yCaption . The Set expression for : Value box contains the following value:
=Parameters!EntryNo_CustLedgerEntryCaption.Value
C O L UM N C A P T IO N EXP RESSIO N
3 CustomerNo_CustLedgerEntryCaption
4 PostingDate_CustLedgerEntryCaption
5 DocumentType_CustLedgerEntryCaption
6 DocumentNo_CustLedgerEntryCaption
7 Description_CustLedgerEntryCaption
9 CurrencyCode_CustLedgerEntryCaption
10 Amount_CustLedgerEntryCaption
11 OriginalAmtLCY_CustLedgerEntryCaption
12 RemainingAmtLCY_CustLedgerEntryCaption
13. Right-click the left-most grouping cell (the cell that contains the Entr yNo_CustLedgerEntr y field) in the
table, select Text Box Proper ties , in the Text Box Properties window, select the Visibility tab, under the
Change display options , select the Hide option.
14. Select the first row in the table, in the Proper ties pane, under Fill , set the BackgroundColor property
to Dim Grey .
15. Right-click the cell in the row2, column 2, and then choose Expression to open the Expression window.
16. In the Categor y column, select Fields (DataSet_Result) , in the Values column, double-click
Entr yNo_CustLedgerEntr y , and then choose the OK button. The Set expression for : Value box
contains the following value: =Fields!EntryNo_CustLedgerEntry.Value
17. Repeat steps 15 and 16 for row 3 to add fields from the ledger entry dataset. Put the fields under the
corresponding captions.
18. Select the row that you filled in and set the BackgroundColor property to Silver .
19. Build the project, inspect the Output pane, and make sure that there are no build errors.
20. Select the second table row, right-click the shaded border to the left, choose Inser t Row , and then
choose Below . The table should now have three group rows, one group data row, and one table footer
row. This row will store the captions of Detailed Cust. Ledg. Entr y data item.
21. Add the captions and fields for the Detailed Cust. Ledger Entr y table as shown in the following table.
EntryNo_DetailedCustLedgEntryCaption EntryNo_DetailedCustLedgEntry.Value
EntryType_DetailedCustLedgEntryCaption EntryType_DetailedCustLedgEntry.Value
PostingDate_DetailedCustLedgEntryCaption. PostingDate_DetailedCustLedgEntr.Value
DocumentType_DetailedCustLedgEntryCaption DocumentType_DetailedCustLedgEntry.Value
DocumentNo_DetailedCustLedgEntryCaption DocumentNo_DetailedCustLedgEnt.Value
TransactionNo_DetailedCustLedgEntryCaption TransactionNo_DetailedCustLedgEntry.Value
JournalBatchName_DetailedCustLedgEntryCaption JournalBatchName_DetailedCustLedgEntry.Value
AmountLCY_DetailedCustLedgEntryCaption AmountLCY_DetailedCustLedgEntr.Value
DebitAmountLCY_DetailedCustLedgEntryCaption DebitAmountLCY_DetailedCustLedgEntry.Value
CreditAmountLCY_DetailedCustLedgEntryCaption CreditAmountLCY_DetailedCustLedgEntry.Value
22. Shrink the column that contains the Customer No. field of the Cust. Ledger Entry to about half of its
size.
23. Right-click the column header that contains the Customer No. field, choose Inser t Column , and then
choose Right .
24. Select the cell that contains the Customer No. caption and the empty cell that you created, and then
choose Merge Cells to merge the two cells.
25. Repeat step 24 to merge the cell that contains the value of the Customer No. field and the empty cell
that you created.
26. Assign the expression from the Entr yType caption and field cells of the Detailed Cust. Ledg. Entry to the
empty cell that you created to the right. You may have to cut the expressions and paste them into the
empty cells.
27. Repeat 26 to move the Entr yNo caption and field 1 cell to the right. This makes sure that the EntryNo
and the EntryType data are located directly under the CustomerNo cell.
The following illustration shows EntryNo and the EntryType cells directly under the CustomerNo cell
28. Repeat steps through 27 to put the Transaction No. and Journal Batch Name captions and fields
under the Description data. This creates a blank cell under the CurrencyCode field.
29. Select the third row and set the BackgroundColor property to Yellow and then set the
BackgroundColor property of the fourth row to Khaki .
Viktor will now hide all empty cells and add the totals to the footer row. To hide empty cells Viktor will
add a filter that selects rows that have [EntryNo] value that is greater than zero.
To hide empty cells and add totals
1. Select the first row, right-click the shaded border to the left of the row, choose Row Group , and then
choose Group Proper ties .
2. In the Group Proper ties window, select the Filters tab, and then choose the Add button.
3. Set Expression to [Entr yNo_CustLedgerEntr y] , change Text to Integer , set Operator to > , set Value
to 0 , and then choose the OK button.
The filter that is set applies to the other rows in the table.
4. In the Group Proper ties window, under the Filters tab, verify that the Expression box contains
[EntryNo_CustLedgerEntry].
Viktor will now add the total of the amount field to the footer row of the table, format the cells and hide
the total cell if customer ledger entry isn't available.
5. In the last row of the table, right-click the empty cell under the Amount (LCY) field, and then choose
Expression .
6. In the Categor y column, select Fields (DataSet_Result) , in the Values column double-click
Amount_CustLedgerEntr y , and then change the expression in the Set expression for : Value box to
the following value: =Sum(Fields!Amount_CustLedgerEntry.Value) . Choose the OK button.
7. In the Proper ties window, locate the Format property, choose the drop-down arrow and select
Expression .
8. In the Expression window, enter the following formatting expression in Set expression for : Value box:
=Fields!Amount_CustLedgerEntryFormat.Value . Choose the OK button.
NOTE
Alternatively, you set this value by double-clicking Amount_CustLedgerEntr yFormat in the Values field of
Fields(DataSet) category.
9. Select the two empty cells to the left of the total cell, right-click the cells, and then choose Merge Cells .
10. Right-click the merged cell, choose Expression , choose the Parameters category, and then set the
caption to Total_Caption
11. Set the BackgroundColor property of the cells that contain the total and total caption to Red .
If you run the report now, the total amount cell will be displayed even if there are no ledger entries. Viktor
will add an expression to hide the footer row when there are no ledger entries.
12. Select the last row, in the Proper ties window, locate the Hidden property, choose the drop-down arrow,
and then choose Expression .
13. In the Expression window, in the Set expression for : Hidden box, enter the following expression to
hide the row: =Fields!EntryNo_CustLedgerEntry.Value = 0 . Choose the OK button. This hides the row if
there are no entry values.
14. Right-click the left-most cell in the last table row, select Text Box Proper ties , select the Visibility tab,
under Change display options , select the Hide option, and then choose the OK button.
The next step is to add the data from the Sales Header table.
To add the sales header data
1. From the Toolbox , drag a Table control to the List control, and then put the table control under the table
that contains the Cust. Ledger Entr y table
2. Right-click a column and add columns to create five columns for the table.
3. Delete the first header row from the table.
4. Right-click the data row, choose Tablix Proper ties , verify that the DataSet name is set to
DataSet_Result , and then choose the OK button.
5. Right-click the data row, choose Add Group , and then choose Parent Group to open the Tablix group
window.
6. Select the Group by: option and then choose the fx button to open the Expression window.
7. In the Categor y column, select Parameters , and then in the Values , column double-click
Sales_Document_Caption . Verify that the Set expression for : Value box contains the following
value: =Parameters!Sales_Document_Caption.Value . Choose the OK button.
8. In the Tablix group window, select Add group header , and then choose the OK button.
9. Right-click the first row in the table, choose Inser t Row , and then choose Inside Group – Above .
10. Reduce the size of the first column, and then in the Proper ties window, under Visibility , set the Hidden
property to True . This hides the first column.
11. In the first table row, merge all the cells except the first grouping cell.
12. Right-click the merged cell, and then choose Expression .
13. In the Categor y column, select Parameters , and then in the Values column double-click
Sales_Document_Caption . Verify that the Set expression for : Value box contains the following
value: =Parameters!Sales_Document_Caption.Value . Choose the OK button.
14. Modify the expression to =First(Parameters!Sales_Document_Caption.Value) .
15. Right-click the cell in row2, column 2, and then choose Expression to open the Expression window.
16. In the Categor y column, select Parameters , and then in the Values column double-click
DocumentType_SalesHeader . Verify that the Set expression for : Value box contains the following
value: Parameters!DocumentType_SalesHeaderCaption.Value .
17. Modify the expression to the following value: =First(Parameters!DocumentType_SalesHeaderCaption.Value)
and then choose the OK button.
18. Right-click the cell that is under the caption that you created, choose Expression . In the Categor y
column, select Fields (DataSet_Result) , and then in the Values column double-click
DocumentType_SalesHeader . Choose the OK button. Verify that the Set expression for : Value box
contains the following value: =Fields!DocumentType_SalesHeader.Value
19. Repeat steps 15 through 18 and add the following captions and the corresponding fields.
No_SalesHeaderCaption No_SalesHeader
PostingDate_SalesHeaderCaption PostingDate_SalesHeader
PricesIncludingVAT_SalesHeaderCaption PricesIncludingVAT_SalesHeader
Amount_SalesHeaderCaption Amount_SalesHeader
20. Select the first two rows and in the Proper ties window, set the BackgroundColor property to Lime .
21. Select the data row (last row), in the Proper ties window, set the BackgroundColor property to
Turquoise .
Viktor will now set a filter that hides empty rows.
To set a filter hide empty row
1. Select any row from this table, right-click the shaded border to the left of the table, and then choose
Tablix Proper ties .
2. Choose the Filters tab and then choose the Add button.
3. In the Expression list box, select No_SalesHeader , set Operator to > , set Value to 0 , and then choose
the OK button.
4. Save the report.
2. Press the F5 key to compile and run the report in Dynamics 365 Business Central.
3. If you haven't switched off the UseRequestPage Property you'll be shown a request page in the Web
Client.
The following illustration shows an example of the request page that is displayed when the report is run.
If you choose the Preview button on the request page, the report will be displayed with the RLD layout
created.
Viktor can now add advanced features to the report. He can add features such as displaying the company name
and logo on every page on the report. He might also want to add features that enable users to apply filters on
the request page.
See Also
Report Overview
Defining a Report Dataset
Creating an RDL Layout Report
Adding Barcodes to Reports
2/6/2023 • 7 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
This article explains how to add barcodes to reports using the barcode functionality in Business Central.
Overview
The barcode functionality lets you convert an alphanumeric value in a report dataset into a barcode on a
generated report. The functionality is provided by the Barcode module of the System Application. The module
includes the objects and tools that you need to add barcodes to reports. This section provides a brief overview
of the Barcode module. For more information about the module, see the AL Extensions on GitHub.
Barcode providers and encoders API
There are two key components involved in barcodes: the barcode provider and the barcode encoder. A barcode
provider includes a library of different barcode fonts and symbologies available for use in reports. Barcode
encoders are the components of the provider that encode the data strings of a report dataset to a specific font
specification and symbology.
The Barcode module provides an API that lets you create custom barcode providers and encoders for one-
dimensional and two-dimensional fonts. The API consists of several public objects, including:
Interfaces for the barcode providers and encoders
Enums for the barcode symbologies
A table object for storing encode settings. For example, you can enable an extended character set or
checksums in Code39, or change the code set used in Code128.
Built-in providers and font support
The Barcode module also includes the following predefined providers and encoders that implement the
interfaces. These providers support several fonts from IDAutomation.
Codeunit 9215 IDAutomation 1D Provider is the barcode provider for IDAutomation one-dimensional
fonts
Codeunit 9221 IDAutomation 2D Provider is the barcode provider for IDAutomation two-dimensional
fonts
With Business Central online, the IDAutomation fonts are automatically available as part of the service. So you
can start adding barcodes to reports right away. For a description of the available fonts, see Barcode Fonts with
Business Central Online.
For Business Central on-premises, you'll have to purchase and install the barcode fonts. If you choose the
IDAutomation fonts, you can use the same built-in providers and encoders as Business Central online - without
making any changes. Or, you can purchase fonts from other providers, then use the API to create custom
barcode providers and encoders.
Getting started
The tasks involved in creating a report that displays a barcode are as follows:
1. (optional) Install the fonts on your development computer or virtual machine.
You don't need the barcode fonts installed on the computer you're using when developing a report and
its layouts. Without the font, the report won't show the barcode. But if you then test the report, for
example in an online sandbox, it will be shown on the report.
2. If you don't want to use the built-in IDAutomation providers and encoders, create your own provider and
encoders using the API.
When creating your own, adhere to the interface in the Barcode module. Use the built-in providers and
encoders as a starting point. Consider contributing to the open-source project if you do.
3. In AL code, add the barcode to a report or report extension object.
a. Determine the source of the data string that you want to display as a barcode in the report, for
example, like a field in the underlying table.
b. Add a column to the report dataset to hold the encoded string for the barcode.
c. Encode the data string as the barcode.
To represent a string as a barcode in a report, you encode it according to the symbology you want.
For this step, you add code to:
Declare the provider by using the barcode provider interface
Declare the barcode font by using the barcode symbology enum
Call the font encoder on the data string
For an example of how it's done, see Adding the barcode to the report dataset.
4. In the report layout, add the barcode field and apply the barcode font to the field.
For more information, see Adding the barcode to the report layout.
dataset
{
dataitem(Items; Item)
{
DataItemTableView = SORTING("No.");
RequestFilterFields = "No.";
RequestFilterHeading = 'Items';
column(Description; Description)
{
}
trigger OnAfterGetRecord()
var
BarcodeString: Text;
BarcodeSymbology: Enum "Barcode Symbology";
BarcodeFontProvider: Interface "Barcode Font Provider";
begin
// Declare the barcode provider using the barcode provider interface and enum
BarcodeFontProvider := Enum::"Barcode Font Provider"::IDAutomation1D;
var
// Variable for the barcode encoded string
EncodedText: Text;
}
Adding the barcode to the report layout
When done modifying the report or report extension objects, build the project to create the layout documents.
Then create the report layouts as usual (see Creating an Word Layout Report or Creating an RDL Layout Report).
To display the barcode the layout, you'll have to do two things:
1. Add the barcode encoded string column from the dataset to the layout.
Referring to the example above, you'd add the Barcode column.
2. Apply the barcode font to the barcode column by using the text features of Word or Report Builder.
For Word layouts:
In Word, select barcode column control, press Ctrl+D, then enter or select the barcode font name.
The following code snippet illustrates how to make the same modifications directly in the .rdl file
from Visual Studio Code:
...
<TablixCell>
<CellContents>
<Textbox Name="Barcode">
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!Barcode.Value</Value>
<Style>
<FontFamily>IDAutomationHC39M</FontFamily>
...
When using IDAutomation fonts, specifying the font is different for one-dimensional and two-
dimensional fonts:
One-dimensional barcode fonts can have several versions, where each version has a different name.
For example, Code 39 includes IDAutomationHC39S , IDAutomationHC39M , and many more. In
this case, set the font to match the specific font version you want.
Two-dimensional barcodes, other than Maxicode, use the same font name. To specify a two-
dimensional font, use IDAutomation2D .
For Maxicode two-dimensional barcode, use IDAutomation2D MaxiCode .
IMPORTANT
When modifying a report layout for production environment, it's important that the font you specify is installed
on the Business Central service. Otherwise, the barcode won't display correctly on the report. So for Business
Central online, be sure to specify a purchased font name (like IDAutomationHC39M ); not an evaluation font
name (like IDAutomationSHC39M Demo ). For more information, see Font versions and names.
See Also
Request Pages
Creating an RDL Layout Report
Creating a Word Layout Report
Developing Extensions
AL Development Environment
Formatting Decimal Values in Fields
2/6/2023 • 5 minutes to read • Edit Online
This article describes how you can format the decimal values that appear in fields on table, pages and reports.
For example, you can change how the data appears in a Cue on the Role Center page. To format data, you use a
combination of the AutoFormatType Property, AutoFormatExpression Property, and DecimalPlaces Property of
the field. These properties work together to enable you to specify the following:
Display amounts and unit amounts in another currency.
Specify the number of decimal places.
Specify whether to display a thousand separator.
Specify characters before and after the value, such as currency signs or %.
Implementation overview
When a field is used on a page or report, you can set the AutoFormatType and AutoFormatExpr properties
directly on the page field or report field (column), or you can set them on the underlying table field. If you
specify the properties on the table field, then the format applies wherever the field is used. Specifying the
properties on the page or report field will only apply the format to the specific page or report. If you specify the
properties on the table field and the page or report field, then the settings on the page or report field take
precedence.
When you use the AutoFormatType and AutoFormatExpression properties to format a field, two events are
raised by the system codeunit 45 Auto Format : OnResolveAutoFormat and OnAfterResolveAutoFormat.
0 Set to the number of decimal places Use this configuration when you want
that you want to display for the value. to format the decimal value according
the Standard Format 0 (which is the
default format) with a specific number
of decimal places.
AutoFormatType = 0;
DecimalPlaces = 0;
1 Set to return a currency code, such as Use this configuration when you want
USD or IDR. The blank currency code to format the data as an amount. For
'' denotes LCY and is the default example, a sales order will use two
value. decimals when the currency is defined
as US dollar and no decimals when the
currency is defined as IDR (Indonesian
rupiah). For example:
AutoFormatType = 1;
AutoFormatExpression = 'IDR';
10 Set to the property according to the Use SubType 1 to add the currency
following syntax: symbol and use the amount type
precision. You use SubType 2 for unit
'[SubType][,<currencycode or amount precision. For example, set the
expression>[,<PrefixedText>]]'
property to '1,USD' to add the $
symbol, like $543.21 .
SubType can be 1 , 2 , another
number, or omitted: AutoFormatType = 10;
AutoFormatExpression = '1,USD';
1 sets the value to an amount type
(see 1 above). 2 sets the value to a If you omit the SubType, you can use
unit amount type (see 2 above). The this configuration to customize the
syntax for these two settings is: format based on one of the standard
formats. This option enables you to
'SubType,<currencycode[,
<PrefixedText>]'
specify characters before and after the
decimal value, such as currency signs $
and percent %.
If you omit the subtype or use a
number other than 1 or 2, the syntax
For example, if you want to prefix the
is:
decimal value with a $ , include a
thousand separator, and have a
'<CustomNumber>, <expression>[,
<PrefixedText>]' maximum of two decimal places, such
as $76,453.21 , then you can set the
where <expression> sets the properties to:
precision and one of the standard
AutoFormatType = 10;
formats. For more information, see
Standard Formats. AutoFormatExpression =
'$<precision, 2:2><standard
format, 0>'
AutoFormatType = 10;
AutoFormatExpression =
'<precision, 1:1><standard
format,0>%'
11 Set the property to the standard Use this option when you want full
format as explained below. For control over the formatting. The
example: format string will be applied exactly as
specified in the AutoFormatExpr
'<Precision,3:3><Standard property.
Format,0>'
Precision
The precision determines the minimum and maximum number of decimal points for values. The precision takes
the format <precision,minimum:maximum> . For example, <precision,minimum:maximum> sets the data with a
minimum of 2 and a maximum of 3 decimal places.
Standard formats
The following table describes the standard formats that are available for the AutoFormatExpr property when
the AutoFormatType property is set to 10.
See Also
AutoFormatType Property
AutoFormatExpression Property
DecimalPlaces Property
Entitlements and Permission Sets Overview
2/6/2023 • 5 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
Business Central uses two main concepts for defining access to functionality: Entitlements and permissions.
Entitlements describe which objects in Business Central a customer is entitled to use according to the
license that they purchased from Microsoft or according to the Azure Active Directory role that they have
assigned in Microsoft 365 Admin Center, such as Global Administrator. Entitlements are only used in the
online version of Business Central.
Permissions describe which objects an administrator or a partner has given the user.
Permission sets combine objects permissions in logical groups (or sets), which can then be assigned to
the users explicitly or through a user group.
For more information about assigning licenses, see Licensing in Dynamics 365 Business Central. For more
information about how to create and assign permissions, see Assign Permissions to Users and Groups.
NOTE
In the current version of Dynamics 365 Business Central entitlements can only be included with Microsoft apps (enforced
by the AppSource cop rules and the technical validation checks that we run for the apps submitted to AppSource). These
objects will become available for the ISV apps when we introduce ability to monetize AppSource apps in one of our future
releases.
Upgrade considerations
Starting with Business Central 2021 release wave 1 (v18.0), the Business Central demo database, which is
shipped with our on-premises installation, doesn't contain any data in the Permission Set and Permission
tables in the application database. Instead, the System permission sets and permissions are provided as AL
objects of type PermissionSet and PermissionSetExtension , included with Microsoft apps.
The application database tables that used to store the entitlements won't contain any data either, because
entitlements are now defined as AL objects.
Business Central server configuration file (CustomSettings.config) includes a setting that allows on-premises
administrators to decide whether they want to continue using the permissions defined as data or as AL objects:
The default value for this setting is true , meaning that the server will be retrieving all System permission sets
and permissions from the AL objects of type PermissionSet and PermissionSetExtension . With the value for this
setting set to true , the permissions data, in case it is still present in the application database, will be
disregarded.
It's not possible to customize the System permission sets and permissions used in the online version of
Business Central. End-users can only copy these types to new permission sets, which they can then adjust to
their needs. For more information, see Assign Permissions to Users and Group.
In the on-premises version of Business Central, even though it's not recommended, the partners can customize
the permission sets and permissions shipped in the application database. In this case, as for any upgrade before,
the changes in Microsoft permissions should be merged with the customized permissions by partners during
upgrade.
Although starting with Business Central 2021 release wave 1 (v.18.0), System permissions are no longer
shipped as data in the application database, the partners can use the same procedure as before to export the
new permissions that are defined using AL objects. The new permission sets and permissions can be exported
into XML file by running XMLport 9171 Import/Export Permission Sets, making it possible to compare and
merge the customized permission sets in your old database with the newly shipped permission sets. Find more
details, see Export and Import Permission Sets and Permissions.
How to upgrade permission sets
When upgrading to version 18, first decide whether you want to use the permissions defined as data or switch
to permissions defined as AL objects. Then, follow the guidelines at Upgrading Permission Sets for details on
how to do the upgrade.
See Also
Get Started with AL
Entitlement Object
PermissionSet Object
PermissionSet Extension Object
Permission Set Object
2/6/2023 • 2 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
The permission set object in Business Central describes permissions on objects. Permission sets are building
blocks used to compose assignable permission sets and entitlements. Assignable permission sets are
permissions that an admin can assign to users in Business Central, using the Permission Sets page. An
entitlement is a collection of permission sets that constitute a set of meaningful permissions for a user.
Some permission sets can be non-assignable, meaning that they aren't discoverable and assignable in the UI in
Business Central, instead they can be used as building blocks to compose functional assignable permission sets.
For information about which permissions can be assigned to objects, see Permissions on Database Objects.
Snippet support
Typing the shortcut tpermissionset will create the basic layout for a permission set object when using the AL
Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
When adding new AL objects, it's easy to forget to update the permissions. With the
al.generatePermissionSetForExtensionObjects command, you can generate or update a permission file for the
active project in Visual Studio Code. Choose to create a new permission file or select an existing file to make
updates to. For more information, see AL Language Extension Configuration.
Permissions =
tabledata Customer = RIMD,
tabledata "Payment Terms" = RMD,
tabledata Currency = RM,
tabledata "Sales Header" = RIM,
tabledata "Sales Line" = RIMD;
}
The following example of a permission set illustrates assigned permissions to run codeunits. With the
IncludedPermissionSets property, we specify that the permission set Sales Person is also included in
MyPermissionSet .
permissionset50135MyPermissionSet
{
Assignable = true;
Caption = 'My PermissionSet';
IncludedPermissionSets= "Sales Person";
Permissions=
tabledataVendor=RIm,
codeunit SomeCode =x,
codeunit AccSchedManagement=X;
}
You can also use the ExludedPermissionSets property to exclude permissions defined in other permission sets.
To learn more, see Composing Permission Sets From Other Permission Sets.
See Also
Developing Extensions
AL Development Environment
Entitlements and Permission Set Overview
Permission Set Extension Object
Permissions on Database Objects
Assignable Property
IncludedPermissionSets
Permissions Property
Permission Set Extension Object
2/6/2023 • 2 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
The permission set extension object in Business Central adds permissions to an existing permission set defined
in AL. A permission set extension object cannot remove permissions from an existing permission set, it can only
add permissions. If you, for example, add an extension to Business Central, you can use permission set extension
objects to grant permissions to the objects in your extension. This means that the admin of Business Central
does not have to assign additional permission sets to the users, because that automatically happens when the
extension is installed, and the permissions go away if the extension is uninstalled.
For information about which permissions can be assigned to objects, see Permissions on Database Objects.
Snippet support
Typing the shortcut tpermissionsetextension will create the basic layout for a permission set extension object
when using the AL Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
See Also
Developing Extensions
AL Development Environment
Entitlements and Permission Set Overview
Permission Set Object
Permissions on Database Objects
Assignable Property
Permissions Property
Permissions on Database Objects
2/6/2023 • 2 minutes to read • Edit Online
This section provides an overview of permissions on objects in Dynamics 365 Business Central.
Permissions
If you have been granted permission to read a page, then you can open the page and view the data that it
displays. If, however, you do not have write permission, you are not allowed to enter data into this page.
Sometimes, when you open a page it displays information from several tables. To access this page, you must
have permission to view all the data displayed by the page. You might not have permission to read directly from
all the tables that the page uses. In this case, you must have indirect permission to read from the tables in
question. Having indirect permission to a table means that you cannot open the table and read from it but can
only view the data it contains indirectly through another object, such as a page or report, that you have direct
permission to access.
Dynamics 365 Business Central has a number of standard predefined security permission sets. You can use
these permission sets as defined or you can change a permission sets to suit your particular needs. You can also
create your own permission sets and assign them the permissions that you want.
Permissions on Objects
The following table describes the permissions that can be assigned for specific objects. When assigning
permissions by using the object types PermissionSet Object and PermissionSet Extension Object these
permissions have been shortened. The table illustrates the abbreviations used.
Permissions on tabledata are specified with the following abbreviations:
Read You can read data. R for direct read access, r for
indirect read access.
Insert You can insert data. I for direct insert permission, i for
indirect insert permission.
Delete You can delete data. D for direct delete permission, d for
indirect delete permission.
Execute You can run this object. X for direct execute permissions, x
for indirect execute permissions.
Wildcard
The wildcard can be used as a shortcut to assign multiple permissions at a time, such as:
Permissions = codeunit * = X;
IMPORTANT
The wildcard must be used with caution, because when it is used in a permission set it grants the permission to all objects
of that type across all permissions. If a permission set with a wildcard is included in an entitlement, it only covers the
objects of that type in the current extension.
Example
All of the permissions illustrated above can be combined into a group of permissions for any given object. For
example:
...
Permissions =
tabledata Customer = RIMD, // Full access
tabledata "Payment Terms" = RMD, // Full read, modify, and delete access - no insert
tabledata Currency = rimd, // Full indirect access
tabledata "Sales Header" = RIM, // full read, insert, and modify access - no delete
tabledata "Sales Line" = RIMD, // Full access
report "Sales Statistics" = X; // Full access
...
See Also
Get Started with AL
Entitlements and Permission Set Overview
Permission Set Object
Permissions on Database Objects
Inherent Permissions
2/6/2023 • 2 minutes to read • Edit Online
With inherent permissions, developers can now grant permissions to a method or event while code executes. As
soon as the code execution is completed, permissions are revoked. Inherent permissions simplify the overall
management and maintenance work of permission sets. With it, a specific AL method or event can get the
elevated permissions necessary to finish the task at hand without getting permission errors. And it helps tighten
overall security by limiting long-term user permissions and giving permissions to the code process instead.
Let’s say a salesperson wants to make a report that includes certain critical pieces of information. In the
background, a method will run a query to fetch the information from the table holding classified data. With
inherent permissions, instead of managing permissions for that salesperson, a developer can add the
permission permanently into the specific code path. This method will be granted permissions for the given
object, which in this case is a table. Now, whenever an authorized person runs this method, the needed
permissions are in place to complete the request.
NOTE
For now, the InherentPermissions attribute is available for Business Central on-premises only. It'll be added to Business
Central online in a later version.
TIP
It's better to use the inherent permissions for small dedicated procedures or system tasks that don't risk data exposure to
users.
Syntax
[InherentPermissions(PermissionObjectType: PermissionObjectType, ObjectId: Integer, Permissions: Text [,
InherentPermissionsScope: InherentPermissionsScope])]
To learn more about the syntax of the InherentPermissions attribute, see InherentPermissions Attribute.
Example
Let's look at a code example for the InherentPermissions attribute.
Referring to the example explained above, let's say the report needs to show which location has more sales for
the quarter. As it's not ideal to grant access to all data belonging to customers, read permission is granted to the
method instead. It will only fetch the customer's location and leave other details (such as name, address, and so
on) private.
Inherent Entitlements
The inherent permissions and inherent entitlements together, grant more flexibility to the developers that they
can assign permissions to their methods, events, and objects. Developers can define inherent entitlements for
their objects like codeunit, table, page, and so on. In this way, the developers equip all users to have enough
access that they can carry out essential tasks without any halt. And regardless of what access their present
license or entitlement grant them. To learn more about inherent entitlements, see InherentEntitlements Property.
NOTE
Specifying InherentPermissionsScope is optional and the default is Both that includes permissions and entitlements. To
read about different types of scope, see InherentPermissionsScope Option.
See also
Entitlements and Permission Sets Overview
Permission Set Object
Exporting Permission Sets to XML
2/6/2023 • 2 minutes to read • Edit Online
Permission sets that exist in Dynamics 365 Business Central can be exported and packaged for your extension
directly from the client, instead of defining XML by hand. These permission sets are also known as tenant
permissions, and are shown in the UI as Extension permissions. The underlying functionality of permissions
has changed with the latest version of Dynamics 365 Business Central.
IMPORTANT
With the latest version of Dynamics 365 Business Central permissions are no longer defined as data in the application
database. Permissions that can be created by using AL objects are called system permissions. For more information, see
Entitlements and Permission Sets Overview.
NOTE
If you do this repeatedly, Visual Studio Code will probe for overwriting the file, there is no support for merging
manual corrections into newly generated content.
O B JEC T T Y P E N UM B ER
TableData 0
Table 1
Report 3
Codeunit 5
XMLPort 6
Page 8
Query 9
FieldNumber 11
PageExtension 14
O B JEC T T Y P E N UM B ER
TableExtension 15
Enum 16
EnumExtension 17
Profile 18
ProfileExtension 19
See Also
Entitlements and Permission Sets Overview
Permissions on Database Objects
Permissions Property
TestPermissions Property
Entitlement Object
2/6/2023 • 2 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
The entitlement object in Business Central describes which objects in Business Central a customer is entitled to
use according to the license that they purchased or the role that they have in AAD.
An entitlement consists of a number of PermissionSet Objects put together to constitute a set of meaningful
permissions for a user. An entitlement can only include permission set objects which reference the objects that
are included within the same app. This is to ensure that the entitlements included with one app cannot alter or
redefine the entitlements included with another app.
Entitlements can only be used with the online version of Business Central.
NOTE
In the current version of Business Central entitlements can only be included with Microsoft apps (enforced by the
AppSource cop rules and the technical validation checks that we run for the apps submitted to AppSource). These objects
will become available for the ISV apps when we introduce ability to monetize AppSource apps in one of our future
releases.
Snippet support
Typing the shortcut tentitlement will create the basic layout for an entitlement object when using the AL
Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Entitlement examples
This example illustrates a simple entitlement object with the Type property set to Role , which means that the is
entitlement is associated with an AAD role. When Type is set to Role , the RoleType property is used to
distinguish between local and delegated assignments of the role, in this case it is Delegated . The
ObjectEntitlements property defines the list of permissions that the entitlement includes.
entitlement BC_Role_Delegated
{
Type = Role;
RoleType = Delegated;
Id = '1a2aaaaa-3aa4-5aa6-789a-a1234567aaaa';
ObjectEntitlements =
”D365 BUS PREMIUM - BaseApp”;
}
See Also
Developing Extensions
AL Development Environment
Entitlements and Permission Set Overview
Permission Set Extension Object
Page Background Tasks
2/6/2023 • 17 minutes to read • Edit Online
To improve the performance of a page, you can develop the page to run read-only computations and long
processes asynchronously in background tasks. Background tasks make a page quicker to open and more
responsive, faster for users to enter information. Users aren't blocked from working while waiting for the
computations to finish. Typical places where you might use background tasks are on cues and pages in
FactBoxes.
Parameters := Page.GetBackgroundParameters()
Use the EVALUATE method to convert the parameters to the required data type calculations.
Defining and setting the results
The results that are computed by the codeunit must be in the form of a dictionary of text. When the codeunit
completes successfully, the results are passed to the parent session in a call to the OnPageBackgroundCompleted
trigger, which will be explained later in this article.
The basic steps for defining the results are as follows:
1. Define a variable of the data type Dictionary of [Text, Text] for holding the results.
2. Use the Add to add key-value pairs for the results to the dictionary.
3. Call the SETBACKGROUNDTASKRESULT method to set the results in the background task.
Example
In this example, the page background task codeunit is used to get the current system time. Then, after waiting a
short period of time, it gets the system time again. The waiting period is defined by an input parameter (called
Wait ) that was passed to the background task from the parent session.
codeunit 50100 PBTWaitCodeunit
{
trigger OnRun()
var
Result: Dictionary of [Text, Text];
StartTime: Time;
WaitParam: Text;
WaitTime: Integer;
EndTime: Time;
begin
if not Evaluate(WaitTime, Page.GetBackgroundParameters().Get('Wait')) then
Error('Could not parse parameter WaitParam');
StartTime := System.Time();
Sleep(WaitTime);
EndTime := System.Time();
Result.Add('started', Format(StartTime));
Result.Add('waited', Format(WaitTime));
Result.Add('finished', Format(EndTime));
Page.SetBackgroundTaskResult(Result);
end;
}
var
TaskParameters: Dictionary of [Text, Text];
begin
TaskParameters.Add('Wait', '1000');
...
end
2. Define a global variable of the data type Integer that will be used to assign the background task an
identification number.
You don't have to assign a value to this variable. The ID is assigned automatically when the background
task is enqueued.
3. Call the ENQUEUEBACKGROUNDTASK method.
First, determine where in the code that you want to call the background task from. Typically, you call the
ENQUEUEBACKGROUNDTASK method from a page trigger.
IMPORTANT
It's important that the ID of the current record of the page remains static after the ENQUEUEBACKGROUNDTASK
method call is made and while the background task is running; otherwise the task will be cancelled. For this
reason, we recommend that you don't enqueue the background task from the OnOpenPage or OnValidate
triggers. Instead, use the OnAfterGetCurrRecord trigger.
Once you've determined the location, add the following code to enqueue the background task:
PageBackgroundTaskErrorLevel::Ignore
specifies that errors are
ignored and have no effect
in the client.
PageBackgroundTaskErrorLevel::Warning
gives errors a severity level
of warning. Warnings appear
as a notification in the client.
PageBackgroundTaskErrorLevel::Error
gives errors a severity level
of error. Errors appear as a
notification in the client. This
value is the default.
NOTE
Use this pattern cautiously to avoid endless looping and applying excessive load on the server. Also, consider the Child
Sessions Max Queue Length limit of the server instance. If this limit is exceeded, enqueuing will fail.
field(starttime;starttime)
{
ApplicationArea = All;
Caption = 'Start Time';
Editable = false;
}
field(durationtime;durationtime)
{
ApplicationArea = All;
Caption = 'Duration';
Editable = false;
}
field(endtime;endtime)
{
ApplicationArea = All;
Caption = 'End Time';
Editable = false;
}
}
}
var
// Global variable used for the TaskID
WaitTaskId: Integer;
trigger OnAfterGetCurrRecord()
var
//Defines a variable for passing parameters to the background task
TaskParameters: Dictionary of [Text, Text];
begin
TaskParameters.Add('Wait', '1000');
PA RA M ET ER DESC RIP T IO N
starttime := started;
durationtime := waited;
endtime := finished;
PBTNotification.Message('Start and finish times have been updated.');
PBTNotification.Send();
end;
end;
Handling errors
Within the page background task flow, errors can occur in three different locations:
The page background task codeunit.
NOTE
A background task timeout will also result in an error.
With errors that occur in the page background codeunit, you can control how the errors affect the client UI and
the resultant data. For example, some errors are more severe than others. Users should be notified when an
error occurs in some cases. Other times, the error can be ignored.
Errors that occur while executing the OnPageBackgroundTaskError or OnPageBackgroundTaskCompleted always
display in the client with the severity level of error ( PageBackgroundTaskErrorLevel:Error ).
Handling errors that occur in the background task
When an error occurs in the page background task codeunit, the OnPageBackgroundTaskError trigger of the page
in the parent session is automatically called with information about the error. To handle these errors, you can
either use the OnPageBackgroundTaskError trigger as-is, that is with no custom code, or you can add custom code
to the trigger to handle the errors separately.
The OnPageBackgroundTaskError trigger has the following signature:
PA RA M ET ER DESC RIP T IO N
ErrorCode Specifies the error code assigned to the error that occurred
in the background task, for example, NDBCS:Deadlock or
DB:FatalCode . The error code is assigned by the Business
Central Server instance.
ErrorText Specifies the error message of the error that occurred in the
background task.
ErrorCallStack Specifies the error's call stack on the Business Central Server
instance.
else if (ErrorText = 'Child Session task was terminated because of a timeout.') then begin
IsHandled := true;
PBTErrorNotification.Message('It took too long to get results. Try again.');
PBTErrorNotification.Send();
end
end;
var
CustomerCard: TestPage "Customer Card";
Pages of the type API are used to create versioned, webhook-supported, OData v4 enabled REST web services.
This type of page cannot be displayed in the user interface, but is intended for building reliable integration
services. When creating this page type, you must specify a number of properties that provide information for
the web service endpoint. Use the snippet tpage - Page of type API to get the right template and the list of
these properties automatically filled in. This page type cannot be extended by creating a page extension object.
Instead, you must create a new API by adding a page object.
Pages of the type API can be used to develop a custom API. For more information, see Developing a Custom
API.
Naming conventions
For the API page type, the following naming conventions exist:
camelCase for naming attributes, tables, as well as APIPublisher, APIGroup, EntityName, and EntitySetName.
Alphanumeric characters allowed (A-Z+a-z+0-9) in above elements.
APIVersion follows the pattern vX.Y or beta.
At design time, the compiler will show warnings on casing violations and errors on naming violations. Once an
API page is deployed, the corresponding $metadata is exposed on the endpoint of the page.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
layout
{
area(Content)
{
repeater(GroupName)
{
field(id; Id)
{
Caption = 'ID';
}
field(name; Name)
{
Caption = 'Name';
}
}
}
}
}
See Also
AL Development Environment
API Query Type
Developing a Custom API
Page Extension Object
APIPublisher Property
APIGroup Property
APIVersion Property
EntityName Property
EntitySetName Property
Developing Extensions
API Query Type
2/6/2023 • 2 minutes to read • Edit Online
Queries of the type API are used to generate web service endpoints and this type of query cannot be used to
display data in the user interface. A query of the API type can be used to join data from different data sources.
The data can only be viewed. When creating this query type, you must specify a number of properties that
provide information for the web service endpoint. Use the snippet tquery - Query of type API to get the right
template and the list of these properties automatically filled in.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
elements
{
dataitem(QueryElement1; Customer)
{
column(customerId; Id)
{
Caption = 'Id', Locked = true;
}
column(customerNumber; "No.")
{
Caption = 'No', Locked = true;
}
column(name; Name)
{
Caption = 'Name', Locked = true;
}
dataitem(QueryElement10; "Cust. Ledger Entry")
{
DataItemLink = "Customer No." = QueryElement1."No.";
SqlJoinType = LeftOuterJoin;
DataItemTableFilter = "Document Type" = FILTER (Invoice | "Credit Memo");
column(totalSalesAmount; "Sales (LCY)")
{
Caption = 'TotalSalesAmount', Locked = true;
Method = Sum;
}
filter(dateFilter; "Posting Date")
{
Caption = 'DateFilter', Locked = true;
}
}
}
}
}
See Also
AL Development Environment
API Page Type
APIPublisher Property
APIGroup Property
APIVersion Property
EntityName Property
EntitySetName Property Query Object
Developing Extensions
Implementing the Camera in AL
2/6/2023 • 3 minutes to read • Edit Online
You can access the camera of a device from the Business Central Web client in the browser and from the
Business Central Mobile App. This allows the user to take pictures and handle them directly from the same
device, and in that way, improve accuracy of capturing data closest to the source, and reduce end-to-end time to
perform tasks.
You can also add access to the camera to a specific page from the AL Language development environment. For a
Dynamics 365 Business Central existing implementation of this, see the Picture factbox on the Item Card ,
which lets you take a picture of a specific item and store it together with the item.
IMPORTANT
The camera access is only available on devices that have a camera.
Example
This example illustrates how to implement the camera capability on a page in AL. The example implements three
actions to take a picture: Take Picture , Take Picture High Quality , and Take Picture Low Quality . However,
it does not include code that saves the picture to the database.
The example also shows how to specify options for the camera functionality such as picture quality or source
type. For more information about the different options that can be set for the camera, see CameraOptions
Overview.
NOTE
To enable the camera functionality, it is required that you add the path of the folder containing the
"Microsoft.Dynamics.Nav.ClientExtensions" assembly on the Al: Assembly Probing Paths setting on the User
Settings or Workspace Settings so the compiler can access it. For more information, see Getting started with
Microsoft .NET Interoperability from AL.
The following code will create two variables; the CameraAvailable variable is a Boolean that checks whether the
current device has a camera. The Camera variable is a DotNet type that gets instantiated by adding code to the
OnOpenPage trigger. Then, it will add the actions to the page that lets the user start the camera. Finally, the trigger
Camera::PictureAvailable is defined to handle the incoming picture.
layout
{
area(content)
{
//...
}
}
}
actions
{
area(Processing)
{
action(TakePicture)
{
Visible = CameraAvailable;
Promoted = true;
PromotedCategory = Process;
PromotedIsBig = true;
Image = Camera;
trigger OnAction()
begin
Camera.RequestPictureAsync();
end;
}
action(TakePictureHigh)
{
Visible = CameraAvailable;
Promoted = true;
PromotedCategory = Process;
PromotedIsBig = true;
Image = Camera;
trigger OnAction()
begin
CameraOptions := CameraOptions.CameraOptions();
CameraOptions.Quality := 100;
Camera.RequestPictureAsync(CameraOptions);
end;
}
action(TakePictureLow)
{
Visible = CameraAvailable;
Promoted = true;
PromotedCategory = Process;
PromotedIsBig = true;
Image = Camera;
trigger OnAction()
begin
CameraOptions := CameraOptions.CameraOptions();
CameraOptions.Quality := 10;
Camera.RequestPictureAsync(CameraOptions);
end;
}
}
trigger OnOpenPage()
begin
// The IsAvailable() enables the camera functionality based on its presence.
if Camera.IsAvailable() then begin
Camera := Camera.Create();
CameraAvailable := True;
end;
end;
// The PictureName contains the name of the file including its extension on the device.
// The naming scheme depends on the device platform.
// The PictureFilePath contains the path to the picture in a temporary folder on the server for the
current user.
// The PictureAvailable trigger handles the picture for when the camera has captured it and it has been
// The PictureAvailable trigger handles the picture for when the camera has captured it and it has been
uploaded.
trigger Camera::PictureAvailable(PictureName: Text; PictureFilePath: Text)
begin
IncomingFile.Open(PictureFilePath);
Message('Picture size: %1', IncomingFile.Len());
IncomingFile.Close();
// It is important to clean up by using the File.Erase command to avoid accumulating image files.
File.Erase(PictureFilePath);
end;
var
[RunOnClient]
[WithEvents]
Camera: DotNet UT_CameraProvider;
CameraOptions: DotNet UT_CameraOptions;
// Checks whether the current device has a camera.
CameraAvailable: Boolean;
IncomingFile: File;
}
dotnet
{
assembly("Microsoft.Dynamics.Nav.ClientExtensions")
{
type("Microsoft.Dynamics.Nav.Client.Capabilities.CameraProvider"; "UT_CameraProvider")
{
type("Microsoft.Dynamics.Nav.Client.Capabilities.CameraOptions"; "UT_CameraOptions")
{
}
}
}
For information about troubleshooting access to camera, see Troubleshooting: Camera and Location.
See Also
Getting started with Microsoft .NET Interoperability from AL
Implementing Location in AL
CameraOptions Overview
RunOnClient property
WithEvents property
Implementing Location in AL
2/6/2023 • 2 minutes to read • Edit Online
You can access the location information of a device from the Business Central Web client in the browser and
from the Business Central Mobile App. This functionality could be useful in scenarios such as calculating routes
from the current location or planning the next round of customer visits based on their addresses.
You can also add access to location information to a specific page from the AL Language development
environment. For a Dynamics 365 Business Central existing implementation of this, see the Show On Map link on
the Customer Card , which displays a map that shows where your customer is located based on the GPS
coordinates and gives directions to reach its location.
IMPORTANT
Location information is only available on devices that are able to obtain location coordinates, such as using GPS
capabilities.
Example
This example illustrates how to implement the location capability on a page in AL. The example implements a
GetLocation action on a page that returns the coordinates of the current customer's address, but does not save
this information to the database.
The example also shows how to specify options for the location functionality such as setting a timeout or
enabling high accuracy. For more information about the different options that can be set for location, see
LocationOptions Overview.
NOTE
To enable the location functionality, it is required that you add the path of the folder containing the
"Microsoft.Dynamics.Nav.ClientExtensions" assembly on the Al: Assembly Probing Paths setting on the User
Settings or Workspace Settings so the compiler can access it. For more information, see Getting started with
Microsoft .NET Interoperability from AL.
The following code will create two variables; the LocationAvailable variable is a Boolean that checks whether
the current device has location capabilities. The Location variable is a DotNet type that gets instantiated by
adding code to the OnOpenPage trigger. Then, it will add an action to the page that lets the user retrieve the
location information. Finally, the trigger Location::LocationChanged is defined to handle the incoming location
information.
layout
{
area(content)
{
{
//...
}
}
actions
{
area(Processing)
{
action(GetLocation)
{
Visible = LocationAvailable;
Promoted = true;
PromotedCategory = Process;
PromotedIsBig = true;
Image = Map;
trigger OnAction()
begin
LocationOptions := LocationOptions.LocationOptions;
LocationOptions.EnableHighAccuracy();
Location.RequestLocationAsync();
end;
}
}
trigger OnOpenPage()
begin
if Location.IsAvailable() then begin
Location := Location.Create();
LocationAvailable := true;
end;
end;
var
[RunOnClient]
[WithEvents]
Location: DotNet LocationProvider;
LocationAvailable: Boolean;
LocationOptions: DotNet UT_LocationOptions;
}
dotnet
{
assembly("Microsoft.Dynamics.Nav.ClientExtensions")
{
type("Microsoft.Dynamics.Nav.Client.Capabilities.LocationProvider"; LocationProvider)
{
type("Microsoft.Dynamics.Nav.Client.Capabilities.Location"; Location)
{
}
type("Microsoft.Dynamics.Nav.Client.Capabilities.LocationOptions"; UT_LocationOptions)
{
}
}
}
For information about troubleshooting access to location information, see Troubleshooting: Camera and
Location.
See Also
Getting started with Microsoft .NET Interoperability from AL
LocationOptions Overview
Troubleshooting: Camera and Location
Implementing the Camera in AL
RunOnClient property
WithEvents property
Preprocessor Directives in AL
2/6/2023 • 2 minutes to read • Edit Online
In AL, like in other programming languages, preprocessor directives can be used to make code conditional, to
suppress warnings, or to enable the ability to expand and collapse in code. Preprocessor directives can be
divided into the following groups. For more information about each type, use the links provided in the following
section.
Conditional directives
Regions
Pragmas
Any code can be made conditional, including table fields, and checked using a conditional directive. To check
code using a conditional directive, you must define a symbol to check. A symbol returns a boolean value; true
or false . Symbols can be defined at the beginning of a source file and the scope of the specific symbol is the
file that it's defined within. You can also define symbols in the app.json file, and then the scope is global for the
extension.
NOTE
Built-in symbols are currently not supported in AL. Symbols must be defined in a specific file or in the app.json file.
NOTE
User personalization and profile configuration (including profile copy) are not meant to work with directives, which means
that they are ignored by the platform in the cases of #pragma, #region, #endregion and fail with an error when they are
not supported for #if, #elif, #define, etc.
Conditional directives
The following conditional preprocessor directives are supported in AL.
Defining preprocessorSymbols
Symbols can be defined globally in the app.json file. A symbol can also be defined using the #define directive
in code, but if symbols are defined in the app.json file, they can be used globally. The following example defines
DEBUG as a global symbol. This can then be used from code as illustrated in the following Conditional code
example. A symbol has a boolean value that means it evaluates to true or false .
The app.json syntax is:
For example:
"preprocessorSymbols": [ "DEBUG","PROD"]
Example
#if DEBUG
trigger OnOpenPage()
begin
Message('Only in debug versions');
end;
#endif
See Also
Development in AL
AL Development Environment
Conditional directives
Region Directive in AL
Pragma Directive in AL
Deprecating Explicit and Implicit With Statements
Best Practices for Deprecation of Code in the Base App
ObsoleteState Property
ObsoleteReason Property
ObsoleteTag Property
Obsolete Attribute
Region Directive in AL
2/6/2023 • 2 minutes to read • Edit Online
Region
The #region directive is used to mark a block of code that you can expand or collapse. This can, for example, be
useful for larger files for better readability or for focusing on code that you're currently working on. The
#endregion specifies the end of a #region block of code.
NOTE
On the first line of the #region a text comment can be added to describe the purpose of the block of code, see the
following example.
Syntax
#region [comment]
code
#endregion
Remarks
A #region block must be terminated with a #endregion directive.
A #region block can't overlap with an #if block. However, a #region block can be nested in an #if block,
and an #if block can be nested in a #region block.
Example
In this example, the #region directive makes a code block that is up for refactoring collapsible.
See Also
Development in AL
AL Development Environment
Pragma Directive in AL
Conditional directives
Deprecating Explicit and Implicit With Statements
Pragma Directive in AL
2/6/2023 • 2 minutes to read • Edit Online
Pragma
The #pragma directive gives the compiler special instructions for the compilation of the file in which it appears.
The #pragma directive has many actions that can be used with the pragma instructions in the following sections,
which are disable , restore , and enable .
AL supports the following pragma instructions:
Pragma ImplicitWith
Pragma Warning
See Also
Development in AL
AL Development Environment
Region Directive in AL
Conditional directives
Deprecating Explicit and Implicit With Statements
AL Development Environment
2/6/2023 • 2 minutes to read • Edit Online
This section describes all of the objects that are available with the AL Language development environment for
Dynamics 365 Business Central.
TIP
If you are looking for the C/SIDE documentation, visit our Dynamics NAV library.
Learn about how to define new table objects for your Table Object
extension.
Learn about how to modify and extend existing table Table Extension Object
objects.
Learn about how to create new page objects for your Page Object
extension.
Learn about how to modify and extend existing page Page Extension Object
objects.
Learn about how to create page customization objects. Page Customization Object
Learn about how to create report extension objects. Report Extension Object
Learn about how to create control add-in objects. Control Add-In Object
Learn about how to create permissionset extension objects. Permissionset Extension Object
Writing AL code
TO SEE
Get an overview of methods in AL grouped by the data type Data Types and Methods in AL
that they support.
See Also
Developing Extensions
Get Started with AL
FAQ for Developing in AL
AL Language Extension Configuration
Programming in AL
2/6/2023 • 2 minutes to read • Edit Online
AL is the programming language that is used for manipulating data such as retrieving, inserting, and modifying
records in a Dynamics 365 Business Central database. It controls the execution of the various application objects,
such as pages, reports, or codeunits.
With AL, you can create business rules to ensure that the data, which is stored in the database is meaningful and
consistent with the way customers do business. Through AL programming, you can:
Add new data or transfer data from one table to another, for example, from a journal table to a ledger table.
Combine data from multiple tables into one report or display it on one page.
NOTE
If the AL code is in a local method, then you cannot run it from another object.
Variable declarations
Variables in AL are declared using the var keyword, and the syntax looks like this:
var
myInt: Integer;
If you have multiple variables of the same type, these can be declared in one line, such as:
var
myInt, nextInt, thirdInt : Integer;
isValid, doCheck : Boolean;
The protected keyword can be used to make variables accessible between tables and table extensions and
between pages and page extensions. For more information, see Protected Variables.
Reusing code
Reusing code makes developing applications both faster and easier. More importantly, if you organize your AL
code as suggested, your applications will be less prone to errors. By centralizing the code, you won't
unintentionally create inconsistencies by performing the same calculation in many places, for example, in
several triggers that have the same table field as their source expression. If you have to change the code, you
could either forget about some of these triggers or make a mistake when you modify one of them.
See Also
Simple Statements
Control Statements
Methods
System-Defined Variables
Developing Extensions
Get Started with AL
FAQ for Developing in AL
2/6/2023 • 2 minutes to read • Edit Online
This topic contains a number of frequently asked questions and answers to these questions.
See Also
Get Started with AL
Keyboard Shortcuts
AL Development Environment
AL Simple Statements
2/6/2023 • 5 minutes to read • Edit Online
AL simple statements are single-line statements that are executed sequentially and don't alter the flow of code
execution. This article explains some of the simple statements in AL.
Assignment statements
Assignment statements assign a value to a variable. The value that you assign to the variable is an AL
expression. It can be a constant or a variable, or it can consist of multiple elements of AL expressions. If you use
a method call as the value to assign to a variable in an assignment statement, then the value that is assigned is
the return value of the method.
You use the ":=" operator for assignment statements.
Example
The following example assigns a constant integer value to a variable that you've defined.
Count := 1;
Example
The following example assigns a value that consists of a constant, an operator, and a variable.
Amount := 2 * Price;
Example
The following example assigns the return value of the Open Method (File) to a Boolean variable that you've
defined.
NOTE
This method is supported only in Business Central on-premises.
OK := TestFile.Open('C:\temp\simple.xml');
The return value of the Open method is optional. If you don't handle the return value in your code, then a run-
time error occurs when a method returns false . The following example causes a run-time error if the file
C:\temp\simple.xml can't be opened.
TestFile.Open('C:\temp\simple.xml');
Example
If you want to perform arithmetic operations on a variable and then assign the result to the same variable, you
can use the following syntax.
Counter := 0;
// for addition
Counter += 1;
// for subtraction
Counter -= 1;
// for multiplication
Counter *= 1:
// for division
Counter /= 1;
// instead of
Counter := Counter + 1;
The following example shows how to use this syntax on variables of the Text Data Type.
Method statements
You use method statements to run either built-in system methods or user-defined (custom) methods. Method
calls may include parameters, which are passed to the method. For more information, see Calling Methods.
AssertError statements
You use AssertError statements in test methods to test how your application behaves under failing conditions.
The AssertError keyword specifies that an error is expected at run time in the statement that follows the
AssertError keyword.
If a simple or compound statement that follows the AssertError keyword causes an error, then execution
successfully continues to the next statement in the test method. You can get the error text of the statement by
using the GetLastErrorText method.
If a statement that follows the AssertError keyword doesn't cause an error, then the AssertError statement
causes the following error and the test method that is running produces a FAILURE result:
TestAsserterrorFail: FAILURE
Example
To create a test method to test the result of a failure of a CheckDate method that you've defined, you can use the
following code. This example requires that you create a method called CheckDate to check whether the date is
valid for the customized application.
InvalidDate := 19000101D;
InvalidDateErrorMessage := Text001;
AssertError CheckDate(InvalidDate);
var
InvalidDate : Date;
InvalidDateErrorMessage : Text;
Text001 : Label 'The date is outside the valid date range.';
with <Record> do
<Statement>
When you work with records, addressing is created as record name, dot (period), and field name:
<Record>.<Field>
If you work continuously with the same record, then you can use with statements. When you use a with
statement, you can only specify the record name one time.
Within the scope of <Statement>, fields in <Record> can be addressed without having to specify the record
name.
You can nest several with statements. If you have identical names, then the inner with statement overrules the
outer with statement.
Example
This example shows two ways to write the same code that creates a record variable that you can commit later.
CustomerRec."No." := '1234';
CustomerRec.Name := 'Windy City Solutions';
CustomerRec."Phone No." := '555-444-333';
CustomerRec.Address := '1241 Druid Avenue';
CustomerRec.City := 'Windy City';
Message('A variable has been created for this customer.');
var
CustomerRec : Record Customer;
The following example shows another way to create a record variable that you can commit later:
Programming conventions
Within with-do blocks, don't repeat the name of the object by using the member variable or method.
If you nest a with-do block within another explicit or implicit with-do block, then the with-do block that you
create within another with-do block must always be attached to a variable of the same type as the variable that
is attached to the surrounding with-do block. Otherwise, it can be difficult to see what variable that a member
variable or method refers to. For example, implicit with-do blocks occur in table objects and in pages that have
been attached to a record.
Example
The following example demonstrates nested with-do blocks. Both with-do blocks are attached to a Customer
Ledger Entry record variable.
Incorrect example
The following example demonstrates incorrect code in which you can't directly tell which record variable that the
MyField field refers to.
AL code consists of one or more statements, which are executed sequentially in a top-down order. However,
you'll often need to control the direct top-down flow of the execution. One or more statements may have to be
repeated more than once, or you may have to make the execution of a certain statement conditional. To do so,
you use control structures.
The control structures in AL are divided into the following main groups, as described in this article:
AL Compound Statements
AL Conditional Statements
AL Repetitive Statements
NOTE
In the following sections, conventions for how to structure and align AL code are presented to introduce best practices. In
many cases, the structure isn't necessary to get the code to compile, but rather to improve readability.
AL compound statements
In some cases, the AL syntax only lets you use a single statement. However, if you have to run more than one
simple statements, the statements can be written as a compound statement by enclosing the them between the
begin and end keywords.
begin
<Statement 1>;
<Statement 2>;
..
<Statement n>;
end;
The individual statements are separated by a semicolon. In AL, a semicolon is used to separate statements and
not to terminate them, as in other programming languages. Nevertheless, an extra semicolon before an end
doesn't cause an error because it's interpreted by the compiler as an empty statement.
Blocks
The begin-end structure is also called a block. Blocks can be useful to refer to the other control structures in AL.
When begin follows, then, else, or do should be on the same line and preceded by one space character.
Example
Example
if (xxx = yyyyyyyyyy) and
(aaaaaaaaaa = bbb)
then begin
x := a;
x := y;
a := y;
end else begin
y := x;
y := a;
end;
AL conditional statements
You use conditional statements to specify a condition and one or more commands to execute if the condition is
evaluated as true or false. There are two types of conditional statements in AL:
if-then-else, where there are two choices
case, where there are more than two choices
If-then-else statements
if-then-else statements have the following syntax.
if <Condition> then
<Statement1>
[else
<Statement2>]
If <Condition> is true, then <Statement1> is executed. If <Condition> is false, then <Statement2> is executed.
The square brackets around else <Statement2> mean that this part of the statement is optional. The else
statement is used when different actions are executed depending on how <Condition> is evaluated.
You can build more complex control structures by nesting if-then-else statements. The following example is a
typical if-then-else statement.
if <Condition1> then
if <Condition2> then
<Statement1>
else
<Statement2>
If <Condition1> is false, then nothing is executed. If <Condition1> and <Condition2> are both true, then
<Statement1> is executed. If <Condition1> is true and <Condition2> is false, then <Statement2> is executed.
NOTE
A semicolon in front of an else statement is not allowed.
Reading several nested if-then-else statements can be confusing but generally, an else statement belongs to the
last if statement that lacks an else statement.
Programming conventions
if and then should be on the same line, else should be on a separate line.
If there are many or long expressions, then should be on a new line and be aligned with if .
When you write if expressions with then and else parts, write them so that the then result is more
probable than the else one.
If the last statement in the then part of an if-then-else statement is an exit or an error , don't
continue with an else statement.
Example
if x = y then
x := x + 1
else
x := -x - 1;
Example
Example
if x <> y then
exit(true);
x := x * 2;
y := y - 1;
Incorrect example
if x < y then
exit(true)
else begin
x := x * 2;
y := y - 1;
end;
Example
The following example shows an if-then statement without the optional else statement.
Example
The following example shows a nested if-then-else statement.
...
if Amount < 1000 then begin
if I > J then
Max := I
else
Max := J;
Amount := Amount * Max;
end;
else
...
Case statements
Case statements have the following syntax.
case <Expression> of
<Value set 1>:
<Statement 1>;
<Value set 2>:
<Statement 2>;
In this definition, the result of <Expression> is matched against each value set and <Value set> must be an
expression or a range.
NOTE
<Expression> cannot be an application object variable, since application objects don't have a comparator.
Case statements are also called multiple option statements and are typically used when you must choose
between more than two different actions. The method of the case statement is as follows:
The <Expression> is evaluated, and the first matching value set executes the associated statement, if
there's one.
If no value set matches the value of the expression and the optional else part has been omitted, then no
action is taken. If the optional else part is used, then the associated statement is executed.
The data type of the value sets must be the same as the data type of <Expression> or at least be convertible to
the same data type.
In most cases, the data type of the value sets is converted to the data type of the evaluated expression. The only
exception is if the evaluated expression is a Code variable. If the evaluated expression is a Code variable, then
the value sets aren't converted to the Code data type.
NOTE
This type conversion can cause an overflow at run time if the resulting data type cannot hold the values of the datasets.
For more information about Code variables, see Code Data Type.
Programming conventions
When you use a case statement, indent the value sets by four character spaces. If you've two or more value sets
on the same line, then separate them by commas without spaces. The last value set on a line is immediately
followed by a colon without a preceding space. The action starts on the line after the value set and is further
indented by four character spaces. If there's a begin, then it should be put on a separate line unless it follows
else. If a begin follows an else, then it should be on the same line as else.
If there are more than two alternatives, use a case statement. Otherwise, use an if-then-else statement.
Example
case Field of
Field::A:
begin
x := x + 1;
y := -y - 1;
end;
Field::B:
x := y;
Field::C,Field::D:
y := x;
else begin
y := x;
a := b;
end;
end;
Example
The following AL code prints various messages depending on the value of Number. If the value of Number
doesn't match any of the entries in the case structure, then the else entry is used as the default.
case Number of
1,2,9:
message('1, 2, or 9.');
10..100:
message('In the range from 10 to 100.');
else
message('Neither 1, 2, 9, nor in the range from 10 to 100.');
end;
Example
The following AL code shows how value sets in a case statement are evaluated if the expression is a Code data
type.
MyCode := 'ABC';
case MyCode of
'abc':
message('This message is not displayed.');
'def':
message('This message is not displayed.');
else
message('The value set does not match the expression.');
end;
This example requires that you create the following code data type variable.
var
MyCode : Code[10];
The value set 'abc' isn't converted because the evaluated expression MyCode is a code variable.
AL repetitive statements
A repetitive statement is also known as a loop. The following table shows the looping mechanisms in AL.
The data type of <Control Variable> , <Start Number> , and <End Number> must be Boolean, number, time, or
date.
Use for-to and for-downto statements when you want to execute code for a specific number of times. The
<Control Variable> controls the number of times that the code of the inner statement is executed according to
the following:
In a for-to loop statement, the <Control Variable> value is increased by one after each iteration. The
inner <Statement> is executed repeatedly until the *<Start Number> * value is greater than the
*<End Number>* value.
In a for-downto loop statement, the <Control Variable> value is decreased by one after each iteration.
The inner <Statement> is executed repeatedly until the <Start Number> value is less than the
<End Number> value.
NOTE
When the for statement is executed, <Start Number> and <End Number> are converted to the same data type as
<Control Variable> if it's required. This type conversion can cause a run-time error.
NOTE
If the value of the <Control Variable> is changed inside the for loop, then the behavior is not predictable.
Furthermore, the value of the <Control Variable> is undefined outside the scope of the for loop.
Example 1
The following code initiates a for loop that uses the integer control variable named Count.
for Count := 1000 to 100000000000000 do
var
Count : Integer;
When this statement is executed, then a run-time error occurs because the start, and end values are converted
to the same data type as the Count control variable. Count has been declared as an integer variable. The end
number 100000000000000 is outside the valid range for integers, and an error occurs.
Example 2
The following example shows how to nest for statements.
Set the Dimensions property of variable A to 5;7.
The following for statements could be used to initialize every element in a 5x7 array with the value 23.
for I := 1 to 5 do
for J := 1 to 7 do
A[I,J] := 23;
var
I : Integer;
J : Integer;
The <List> variable must be of the List, XmlNodeList, XmlAttributeCollection, or JsonArray type. The <Element>
variable must be a data type that is compatible with elements specified by the <List> .
The following code example iterates through a list of customer names and returns each customer name in a
message.
If <Condition> is true, then <Statement> is executed repeatedly until <Condition> becomes false. If
<Condition> is false from the start, then <*Statement> is never executed.
The while do statement can be used when some code should be repeated as long as an expression is true.
Programming conventions
When there's only one condition, put while and do on the same line. Put the statements on separate lines and
indented by two spaces.
When there are multiple conditions, put the conditions on separate lines, and indented by two spaces and put
do on a separate line that is aligned with while .
Example
while <expr> do
<Statement>;
Example
Example
Example
The following AL code increases the variable I until it equals 1000 and displays a message when it's finished.
var
I : integer
repeat
<Statements> until <Condition>
<Statements> is executed repeatedly until <Condition> is true.
The repeat until control structure resembles the while control structure. The difference is that because the
repeat until statement is executed from left to right, the <Statements> is always executed at least one time,
regardless of what the <Condition> is evaluated to. This contrasts with the while control structure, which
performs the evaluation before the <Statement> is executed. In the while control structure, if the first
evaluation of <Condition> returns false, then no statements are executed.
Programming conventions
Always put repeat on a separate line.
Example
Example
This code uses a repeat-until loop to count the number of entries in the Customer table.
Count := 0;
if Customer.find('-') then
repeat
Count := Count + 1;
until Customer.next <= 0;
message('The Customer table contains %1 records.',Count);
var
Count : Integer;
Customer : Record Customer;
The find method finds the first entry in the table. Each time NEXT is called, it steps one record forward. When
NEXT equals 0, there are no more entries in the table. The loop is exited, and a message displays how many
entries were found.
Exit statement
The exit statement is used to control the flow of the execution. The following syntax shows an exit statement.
exit([<Value>])
An exit statement is used to interrupt the execution of an AL trigger. The interruption occurs even when the code
is executed inside a loop or a similar structure. The exit statement is also used when a local method should
return a value.
Using exit without a parameter in a local method corresponds to using the parameter value 0. The AL method
will return the value 0 or '' (empty string).
A compile-time error occurs if exit is called by using a return parameter from either:
System-defined triggers, or
Local methods that don't return a value.
Example
The following example shows the use of the exit statement in a local method. Assume that the if statement is
used to detect an error. If the error condition is met, then execution is stopped and the local method returns the
error code 1.
Break statement
You use the break statement to terminate the iterative statement in which it appears.
break;
You typically use the break statement in the repeating statements such as for , while , or repeat to stop an
iteration or loop when certain conditions are met.
NOTE
The break statement is different than the Break Method (Report, XMLport). Although both stop an iteration or loop, the
break method will also terminate the trigger in which it's run.
Example
The following AL code increases the variable I by one for each iteration, and terminates the iteration when I
equals 10.
var
I : integer
See Also
Programming in AL
AL Simple Statements
Directives in AL
AL Essential Methods
AL Complex Types
2/6/2023 • 2 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
With the latest version of Business Central, it's possible to return most types from procedures - both user-
defined types and most built-in types.
The method in the example below, will take a name, and return the first customer record that matches the name.
The signature specifies the return type at the end of the procedure declaration, and the procedure exits by
returning the found customer record.
///<summary>
/// Getthefirstcustomerwithnamestartingwith<paramref name="Name"/>
///</summary>
///<param name="Name">Namefilter</param>
///<returns>Firstcustomer</returns>
It's also possible to use a named return value. Internally, the exit-statement as seen in the example above causes
an assignment to an allocated return value. The assignment will have a small performance cost based on the
type. Since the record type is treated as a value-type, it's better.
procedureGetCustomerByName(Name:Text) Customer:recordCustomer;
begin
Customer.SetFilter(Name,'@'+Name+'*');
Customer.FindFirst();
end;
The method GetCustomerByName() returns a Customer record. It can be used as you would expect in the
following example.
//Getthe firstcustomerwithnamestartingwith'spo'
Customer:=GetCustomerByName('spo');
The returned value doesn't have to be used in an assignment statement. It can be used as part of an expression
like in the following example.
DoSomethingWithSales(GetCustomerByName('spo').GetSalesLCY());
It doesn't only work for user-defined types like records, codeunits, etc., but also for built-in types. For example,
when using the HttpClient Data Type, it's possible to write code as illustrated below.
///<summary>
///Returnsabing-readyHttpClient
///</summary>
///<returns>BingHttpClient</returns>
procedure GetBingClient() Result: HttpClient;
begin
Result.SetBaseAddress('https://www.bing.com');
end;
///<summary>
///Gettheresponsefromarequesttobing.
///</summary>
///<returns>Theresponsemessage</returns>
///<summary>
///Gettheresponsefromwww.bing.comasanhtml-string.
///</summary>
///<returns>stringwithhtml</returns>
procedure GetBingHtml() Result: Text;
begin
GetBingResponse().Content().ReadAs(Result);
end;
See Also
Programming in AL
AL Simple Statements
Directives in AL
AL Essential Methods
HttpClient Data Type
AL Error Handling
2/6/2023 • 2 minutes to read • Edit Online
The AL language has many error handling features, which can help you deal with unexpected situations that
occur when code is run. This section contains articles about using these methods in AL to handle errors that
occur during code execution, while making sure that your application has a consistent user interface.
The following articles introduce error handling in AL:
Handling Errors using Try Methods
Collecting Errors
Progress Windows, Message, Error, and Confirm Methods
M ET H O D DESC RIP T IO N
ErrorInfo Data Type Contains a set of methods that helps identify errors, classify
these errors, send errors to telemetry and display UI
messages. Go to the data type article for an overview.
System Data Type Is a complex data type and contains multiple methods for
getting and classifying errors.
GetLastErrorCallStack Method Gets the call stack from where the last error occurred.
GetLastErrorCode Method Gets the classification of the last error that occurred.
GetLastErrorText Method Gets the last error that occurred in the debugger.
TIP
If you already know the name of a data type, use the Filter by title field in the upper left corner, above the table of
contents to find the topic faster.
Run a code unit and decide to do something if an error if not Codeunit.run() . For more information, see
occurs. Codeunit.Run return value
Check for an error and show an error dialog to the user. Dialog.Error(Message: ErrorInfo) . For more
information, see Error Method.
Check for an error and show an error dialog to the user with Using the ErrorInfo Data Type with the Error Method
added support information.
Do bulk validations in AL and not show an error dialog for Collecting Errors
each of them to the user.
Catch errors raised by other AL methods Handling Errors using Try Methods
Catch errors/exceptions that are thrown during .NET Handling .NET Exceptions using Try Methods
framework interoperability operations (on-premises only).
Log an error that happens within a database transaction Either log the error in a new session using a background
(that rollback) session, or use Session.LogMessage to log the error to
telemetry.
See also
AL Control Statements
AL Development Environment
AL methods
2/6/2023 • 5 minutes to read • Edit Online
Like other languages, AL methods are a fundamental programming element. A method, also known as a
procedure, is a named group of statements that perform an operation or task. Depending on the scope,
methods can be run, or called, from the same object in which they are declared or from other parts of the
application.
There are two types of methods: system methods (built-in) and user-defined (custom) methods.
Built-in methods are part of the platform. Built-in methods can be used for different purposes, such as
string handling, text formatting, database handling, and so on. For information about the available built-in
methods, see AL method Reference and Essential AL methods. For information about method scope, see
Scope Attribute.
Custom methods are specialized methods for your application to bind the objects, such as tables, pages,
and code units, together to form a unified whole. You can create special methods for use anywhere in the
database.
TIP
If you already know the name of, for example, a data type, method, property, or trigger, use the Filter by title field in the
upper left corner, above the table of contents to find the topic faster. Otherwise, you can scan the table of contents to find
it.
Declaring methods
The method declaration defines the method and has the following syntax:
[Attributes(arguments list)]
local procedure <method_name>(parameter list) <return_value_name> : <data_type>[<length>]
Snippet support
Typing the shortcut tprocedure will create the basic structure for a method when using the AL Language
extension in Visual Studio Code.
Attributes (optional)
An attribute is a modifier on a method declaration that specifies information that controls the method's use and
behavior. Adding an attribute on a method declaration is also known as decorating a method. For example,
decorating a method with the Integration attribute sets the method to be an event publisher. An attribute can
have one or more arguments that set properties for the method instance.
Attributes are placed before the method. For information about the available attributes, see Method Attributes.
Local and global scope
A method can be a local method or global method. A local method can only be accessed or called from inside
the object in which it is declared. A global method can be called from inside the object in which it is declared and
from other objects.
To declare a local method, start the declaration with local :
local procedure Mymethod();
procedure Mymethod();
Parameters (optional)
A parameter is one or more variables or expressions that are sent to the method through the method call. The
parameter provides information to the method, and the method can modify that information. In the method
declaration, you place the parameters in parentheses () . If there is more than one parameter, the parameters
are separated by semicolons. A parameter is defined by a data type. Some data types, such as Record , require
an additional subtype.
For example, the following method declaration includes two parameters: MyCustomer and MyDimension :
This example also illustrates how parameters can be passed by value or passed by reference. The MyCustomer
parameter is passed by value, and the MyDimension parameter is passed by reference in the example above. For
more information, see the section Parameters below.
Return values (optional)
A method can return data that can be then coded against. A return value is defined by a name (optional), data
type, and optional length depending on the data type.
For example, if the return value is a Text DataType, the text might have a length of 50.
Calling methods
You can run, or call, a built-in or a custom method by using its name in a method call statement. When a method
is called the current application sequence is suspended and the code on the method is run. When the method
code is completed, the application code sequence returns to where the method was called from. How the
method is called determines what happens when it returns.
A method can be used as part of an expression. For example, the following code uses a method named
CalculatePrice as an expression:
In this case, the CalculatePrice method must return a value that is used in evaluating the expression. This
return value is then multiplied by the Quantity variable and that result is assigned to the TotalCost variable.
A method can also be run by using a method call statement. This statement only calls the method and does not
return any value. The following is an example of calling a method named MyRunMethod :
if Quantity > 5 then
MyRunMethod;
Example 1
The following shows the syntax for a method. The first example shows a method with two mandatory
parameters.
method(Parameter1, Parameter2)
Some built-in methods have optional parameters, the syntax is shown below. The optional parameters may be
omitted starting from the right.
The method that uses the syntax above can be called by using the following code.
method(Optional1, Optional2)
Example 2
ABS is an example of an AL method that has a fixed number of parameters (1).
Example 3
The method DMY2DATE is an example of a method that can be called by using a variable number of parameters.
Depending on the use of the DMY2DATE method, one, two, or three parameters can be passed to the method
because the second and third parameters are optional. When the second and third parameters are not used,
values from the system date are used as default values.
Example 4
You can assign the return value of a method to a variable.
ReturnVal := MyMethod(Param1);
Example 5
In this example, MyMethod returns a Boolean value. You can use the return value in a conditional statement.
if (MyMethod(Param1)) then
<Statement1>
else
<Statement2>
See Also
Development Overview
AL Methods
AL Simple Statements
AL Control Statements
System-Defined Variables
2/6/2023 • 2 minutes to read • Edit Online
Dynamics 365 Business Central automatically declares and initializes several variables that you can use when
you develop applications. The following table describes the system-defined variables.
RequestOptionsPage This variable specifies the request options page for the
current report.
CurrFieldNo This variable specifies the field number of the current field in
the current table. Retained for compatibility reasons.
Using CurrPage
You can access the controls of the page through the CurrPage variable and set the dynamic properties of the
page and its controls. The CurrPage.Editable variable reflects the runtime value of the Editable property, which
can be changed at design-time, programmatically, or by the user when switching view modes on a page. The
CurrPage.Update([SaveRecord]) variable can be used to save the current record and then update the controls on
the page. When the View mode on a page is false , then the Edit, New, and Delete modes are true .
Using CurrReport
You can access properties of a report through the CurrReport variable and set them dynamically. For example,
by using CurrReport.Preview, you can determine if the report is being run in preview mode.
Using RequestOptionsPage
You can access properties of the request page through the RequestOptionsPage variable and set them
dynamically.
See Also
AL Method Reference
Properties
Preprocessor Directives in AL
2/6/2023 • 2 minutes to read • Edit Online
In AL, like in other programming languages, preprocessor directives can be used to make code conditional, to
suppress warnings, or to enable the ability to expand and collapse in code. Preprocessor directives can be
divided into the following groups. For more information about each type, use the links provided in the following
section.
Conditional directives
Regions
Pragmas
Any code can be made conditional, including table fields, and checked using a conditional directive. To check
code using a conditional directive, you must define a symbol to check. A symbol returns a boolean value; true
or false . Symbols can be defined at the beginning of a source file and the scope of the specific symbol is the
file that it's defined within. You can also define symbols in the app.json file, and then the scope is global for the
extension.
NOTE
Built-in symbols are currently not supported in AL. Symbols must be defined in a specific file or in the app.json file.
NOTE
User personalization and profile configuration (including profile copy) are not meant to work with directives, which means
that they are ignored by the platform in the cases of #pragma, #region, #endregion and fail with an error when they are
not supported for #if, #elif, #define, etc.
Conditional directives
The following conditional preprocessor directives are supported in AL.
Defining preprocessorSymbols
Symbols can be defined globally in the app.json file. A symbol can also be defined using the #define directive
in code, but if symbols are defined in the app.json file, they can be used globally. The following example defines
DEBUG as a global symbol. This can then be used from code as illustrated in the following Conditional code
example. A symbol has a boolean value that means it evaluates to true or false .
The app.json syntax is:
For example:
"preprocessorSymbols": [ "DEBUG","PROD"]
Example
#if DEBUG
trigger OnOpenPage()
begin
Message('Only in debug versions');
end;
#endif
See Also
Development in AL
AL Development Environment
Conditional directives
Region Directive in AL
Pragma Directive in AL
Deprecating Explicit and Implicit With Statements
Best Practices for Deprecation of Code in the Base App
ObsoleteState Property
ObsoleteReason Property
ObsoleteTag Property
Obsolete Attribute
Region Directive in AL
2/6/2023 • 2 minutes to read • Edit Online
Region
The #region directive is used to mark a block of code that you can expand or collapse. This can, for example, be
useful for larger files for better readability or for focusing on code that you're currently working on. The
#endregion specifies the end of a #region block of code.
NOTE
On the first line of the #region a text comment can be added to describe the purpose of the block of code, see the
following example.
Syntax
#region [comment]
code
#endregion
Remarks
A #region block must be terminated with a #endregion directive.
A #region block can't overlap with an #if block. However, a #region block can be nested in an #if block,
and an #if block can be nested in a #region block.
Example
In this example, the #region directive makes a code block that is up for refactoring collapsible.
See Also
Development in AL
AL Development Environment
Pragma Directive in AL
Conditional directives
Deprecating Explicit and Implicit With Statements
Pragma Directive in AL
2/6/2023 • 2 minutes to read • Edit Online
Pragma
The #pragma directive gives the compiler special instructions for the compilation of the file in which it appears.
The #pragma directive has many actions that can be used with the pragma instructions in the following sections,
which are disable , restore , and enable .
AL supports the following pragma instructions:
Pragma ImplicitWith
Pragma Warning
See Also
Development in AL
AL Development Environment
Region Directive in AL
Conditional directives
Deprecating Explicit and Implicit With Statements
Using Access Modifiers in AL
2/6/2023 • 2 minutes to read • Edit Online
Access modifiers are used to set accessibility of tables, table fields, codeunits, and queries, which controls
whether the object can be used from other code in your module or other modules. Access modifiers in AL are
designed to create solid APIs, by limiting the symbols that dependant modules can take a reference on. Limiting
the API surface can hide implementation details and allow for later refactoring of code without breaking external
code.
You set the object accessibility by using the Access Property. If the Access property isn't specified; default is
Public .
NOTE
In AL, access modifiers are primarily intended for designing APIs and cannot be used as a security boundary.
Access modifiers
The access modifiers that are available in AL are:
internal The object or field can be accessed only by code in the same
module, but not from another module.
Note: This accessibility level is controlled by the
internalsVisibleTo setting. For more information, see
JSON Files
local The field can be accessed only by code in the same table or
table extension where the field is defined.
Note: Applies to table fields only.
protected The field can be accessed only by code in the same table or
table extensions of that table.
Note: Applies to table fields only.
public The object or field can be accessed by any other code in the
same module and in other modules that references it.
Note: This is the default value.
IMPORTANT
Access modifiers are only taken into consideration at compile time. For example, at compile time, a table with
Access = Internal can't be used from other modules that don't have access to the internals of the module where the
table is defined, but at runtime, any module can access the table by using reflection-based mechanisms such as
RecordRef , or TransferFields . And the OnRun trigger can be run on internal codeunits by using Codeunit.Run .
Setting the object accessibility level as Access = Internal; cannot be used as a security boundary. Also see JSON Files.
See Also
AL Development Environment
Access Property
XML Comments in Code
2/6/2023 • 4 minutes to read • Edit Online
In Dynamics 365 Business Central, you can add documentation directly in your source code by including XML
elements in special comment fields before the block of code that the comment refers to. The documentation
comment must immediately precede a user-defined type that it annotates, for example a codeunit, table,
interface, or a member such as a field or method. The syntax for adding XML comments in your code is triple
slashes /// followed by one of the supported XML tags. There's IntelliSense support for writing documentation
comments that also provides a template comment on entering the third slash in the triple slash.
Documentation comments are visible when you hover over source symbols, in completion lists, and in signature
help. By adding XML comments in code, you can improve readability, add useful information about the
implementation, and help others take over code that you wrote. With XML comments, you also enable
IntelliSense in Visual Studio Code on the AL objects that you add in the code as a help to other developers,
working with or extending your code. When your code is documented using XML comments, it means that when
you've built an extension and someone extends this code, they'll get inline documentation when they call the
given object.
NOTE
Integration with documentation generator tools like DocFx and SandCastle is currently not supported.
NOTE
If you have the allowDownloadingSource setting in the app.json file set to false and you then download an app
package; the app package won't contain any XML comments.
F O RM AT T IN G XM L TA G DESC RIP T IO N SY N TA X
List syntax
<list type="bullet|number|table">
<listheader>
<term>term</term>
<description>description</description>
</listheader>
<item>
<term>term</term>
<description>description</description>
</item>
</list>
Example
The following example is taken from the Email.Codeunit.al file in the System Application. In this example, the
parameter EmailMessageId is documented using the <param> syntax.
/// <summary>
/// Provides functionality to create and send e-mails.
/// </summary>
/// <summary>
/// Enqueues an email in the outbox to be sent in the background.
/// </summary>
/// <param name="EmailMessageId">The ID of the email to enqueue</param>
procedure Enqueue(EmailMessageId: Guid)
begin
EmailImpl.Enqueue(EmailMessageId);
end;
...
Special symbols
For special symbols, such as angle brackets, to appear in text of a documentation comment, use the HTML
encoding of < and > , which is < and > respectively. The following example illustrates how.
/// <summary>
/// This property always returns a value < 1.
/// </summary>
Writing tips
Code comments improve the readability of the code that you've developed and they're useful for anyone
modifying or maintaining that code. Furthermore, code comments form the basis of auto-generated
documentation. Great code comments must do the following:
1. Never state the obvious.
2. Write a meaningful comment, use precise wording to describe why.
3. Imagine yourself in the shoes of the developer using this piece of code, what would you want to know?
4. For properties and methods, use active wording such as Sets..., Gets..., and Specifies..., and then explain what
it does.
5. List all pre-conditions for your parameters (can't be null, must be within a certain range, and so on).
6. List any post-conditions that could influence how callers deal with return values.
7. List any exceptions the method may throw (and under what circumstances).
8. If similar methods exist, explain the differences between them.
9. Call attention to anything unexpected (such as modifying global state).
10. Enumerate any side-effects, if there are any.
11. Be consistent.
12. Be concise.
13. Make sure that your comments are reviewed.
For more examples, see https://stackoverflow.com/questions/3143324/what-are-best-practices-for-
documenting-c-sharp-code-with-xml-comments.
See also
AL Development Environment
Developing Extensions in AL
Pages Overview
Microsoft Writing Style Guide
The Code Analysis Tool
2/6/2023 • 3 minutes to read • Edit Online
This article shows you how to use static code analysis tool on an AL project from within Visual Studio Code.
NOTE
By default, code analysis is run in the background.
Code analyzers
A code analyzer is a library that builds on the compiler's functionality to offer enhanced analysis of the syntax
and semantics of your code at build time. The AL Language extension for Visual Studio Code contains four
analyzers:
CodeCop is an analyzer that enforces the official AL Coding Guidelines. For more information about the
CodeCop rules, see CodeCop Analyzer Rules.
PerTenantExtensionCop is an analyzer that enforces rules that must be respected by extensions meant to
be installed for individual tenants. For more information about the PerTenantExtensionCop rules, see
PerTenantExtensionCop Analyzer Rules.
AppSourceCop is an analyzer that enforces rules that must be respected by extensions meant to be
published to Microsoft AppSource. For more information about the AppSourceCop rules, see AppSourceCop
Analyzer Rules.
UICop is an analyzer that enforces rules that must be respected by extensions that are meant to customize
the Web Client. For more information about the UserInterfaceCop rules, see UICop Analyzer Rules.
See Also
Using the Code Analysis Tools with the Ruleset
Ruleset for the Code Analysis Tool
Development in AL
Directives in AL
Debugging in AL
AL Language Extension Configuration
Ruleset for the Code Analysis Tool
2/6/2023 • 2 minutes to read • Edit Online
In an AL project, you can use a custom ruleset file to specify how code analysis will report the issues it
encounters. Different settings can affect how rules are applied and each ruleset file name must follow the
pattern <name>.ruleset.json to benefit from IntelliSense in Visual Studio Code.
NOTE
Use the truleset and trule snippets provided by the AL Language extension to create your ruleset.
An IncludedRuleSet is a complex JSON object that defines the inclusion of an external ruleset file in the
current ruleset, and has the following properties:
action Yes Error | Warning | Info | Hidd The action to apply for all
en | None | Default the diagnostics that have
an action specified in the
included ruleset that is
different from None and
Hidden .
A Rule is a complex JSON object that defines how you can process a specific diagnostic. A Rule object has the
following properties:
action Yes Error | Warning | Info | Hidd The action to apply if the
en | None diagnostic is emitted. There
can't be two rules with the
same id and different
actions in the same rule file.
Examples
The following example shows a ruleset that sets the severity of rule AA0001 : There must be exactly one
space character on each side of a binar y operator such as := + - AND OR =. provided by the
CodeCop analyzer to Error .
{
"name": "Company ruleset",
"description": "These rules must be respected by all the AL code written within the company.",
"rules": [
{
"id": "AA0001",
"action": "Error",
"justification": "This diagnostic helps to improve readability. It must be respected in all
cases."
}
]
}
The following example shows a project-specific ruleset that extends a company-wide ruleset contained in the file
company.ruleset.json and sets the severity of the rule AA0005 : Only use BEGIN..END to enclose
compound statements. provided by the CodeCop analyzer to Info .
{
"name": "Personal Project ruleset",
"description": "A list of project specific rules",
"includedRuleSets": [
{
"action": "Default",
"path": "./company.ruleset.json"
}
],
"rules": [
{
"id": "AA0005",
"action": "Info",
"justification": "For this specific project, this diagnostic should be informational."
}
]
}
See Also
Using the Code Analysis Tools
Using the Code Analysis Tools with the ruleset
AL Development Environment
Directives in AL
AL Language Extension Configuration
Using the Code Analysis Tools with the Ruleset
2/6/2023 • 3 minutes to read • Edit Online
This article helps you to customize a ruleset for the severity of diagnostics produced by the code analysis tools
that are part of the AL Language extension for Visual Studio Code.
On the View tab of Visual Studio Code, select the Problems option and you'll see a warning with the message
"There must be exactly one space character on each side of '+'." . In this case, the problem can be fixed
by running the AL Formatter command. For more information, see AL Formatter.
{
"name": "My Custom ruleset",
"rules": [
{
"id": "AA0001",
"action": "None"
}
]
}
4. In your project settings, set Rule Set Path to the path of the <name>.ruleset.json file, relative to the
project root. For more information about custom rules, see Ruleset for the Code Analysis Tool.
NOTE
Use the truleset and trule snippets provided by the AL Language extension to create your ruleset. The ruleset will
be applied to all the analyzers enabled for the current project. For more information about selectively enabling analyzers,
see The Code Analysis Tools.
Limitations
Changing the contents of the ruleset file won't be detected by the AL Language extension. To see the effects of
changing the ruleset file, you can try any of the following steps:
Reload the window.
In the project settings, change the Rule Set Path setting to an invalid path and save it. Then change it back
and save again.
See also
Ruleset for the Code Analysis Tool
Using the Code Analysis Tools
Directives in AL
Development in AL
Debugging in AL
AL Language Extension Configuration
AppSourceCop Analyzer Rules
2/6/2023 • 10 minutes to read • Edit Online
AppSourceCop is an analyzer that enforces rules that must be respected by extensions meant to be published to
Microsoft AppSource.
Rules
ID T IT L E C AT EGO RY DEFA ULT SEVERIT Y
NOTE
Several rules enforced by the AppSourceCop analyzer are incompatible with rules enforced by the PerTenantExtensionCop.
Make sure to enable only one of these at a time.
NOTE
Failing to comply with the rules whose default severity is set to Error will fail the submission of your extension to the
AppSource marketplace. It is recommended, but not mandatory to comply with the rules whose severity is marked as
Warning or Info .
Configuration
The AppSourceCop analyzer can be further configured by adding a file named AppSourceCop.json in the
project's root folder. The AL Language extension will offer IntelliSense for this file.
The following table describes the settings in the AppSourceCop.json file:
SET T IN G M A N DATO RY VA L UE
The name , publisher , version properties are used for specifying a previous version of the current package.
This package must be located in the baseline package cache folder of your extension. This cache can be specified
using the baselinePackageCachePath property. If this property is not specified, the dependency package cache
path of the extension will be used instead. The al.packageCachePath setting allows you to specify the path to the
folder that will act as the cache for the dependencies symbol files used by your project. AppSourceCop will
compare the previous version of your extension with its current version and will report any breaking changes
introduced by the current package.
The mandatoryAffixes property specifies strings that must be prepended or appended to the names of all new
objects, extension objects and fields. By using these affixes, you can prevent clashes between objects added by
your extension and objects added by other extensions.
The supportedCountries property specifies the codes that correspond to the countries for which the product
allows AppSource submissions. For more information, see Availability and supported Countries/Regions and
Translations
The properties obsoleteTagVersion , obsoleteTagPattern , and obsoleteTagPatternDescription can be used to
enable additional validation on object obsoletion. These are not required for AppSource submissions.
Example
In the following example, we will configure AppSourceCop to validate that all new elements have a name that
contains one of the specified affixes.
NOTE
Make sure that code analysis is enabled and ${AppSourceCop} is specified in the list of enabled code analyzers. For more
information see AL Language Extension Configuration.
We continue by adding the configuration file AppSourceCop.json in the project's root folder and setting its
content to the following.
{
"mandatoryAffixes": [ "Foo", "Bar" ]
}
IMPORTANT
If you are running a multi-root workspace environment, you must have one AppSourceCop.json file in the root folder of
each of the projects. For more information, see Working with multiple AL project folders within one workspace.
AS0011: The identifier 'CustomerListExt' must have at least one of the mandatory affixes 'Foo, Bar'.
Prepending Foo to the name of the page extension object will fix this error and prevent clashes between this
page extension and page extensions added by other developers.
NOTE
It is still possible to use the mandatoryPrefix and mandatorySuffix properties in the AppSourceCop.json . For more
information see AS0011.
See Also
Using the Code Analysis Tool
Ruleset for the Code Analysis Tool
Using the Code Analysis Tools with the Ruleset
CodeCop Analyzer Rules
2/6/2023 • 5 minutes to read • Edit Online
Rules
ID T IT L E C AT EGO RY DEFA ULT SEVERIT Y
See Also
Using the Code Analysis Tool
Ruleset for the Code Analysis Tool
Using the Code Analysis Tools with the Ruleset
PerTenantExtensionCop Analyzer Rules
2/6/2023 • 2 minutes to read • Edit Online
PerTenantExtensionCop is an analyzer that enforces rules that must be respected by extensions meant to be
installed for individual tenants.
Rules
ID T IT L E C AT EGO RY DEFA ULT SEVERIT Y
See Also
Using the Code Analysis Tool
Ruleset for the Code Analysis Tool
Using the Code Analysis Tools with the Ruleset
UICop Analyzer Rules
2/6/2023 • 2 minutes to read • Edit Online
UICop is an analyzer that enforces rules that must be respected by extensions meant to customize the Web
Client.
Rules
ID T IT L E C AT EGO RY DEFA ULT SEVERIT Y
See Also
Using the Code Analysis Tool
Ruleset for the Code Analysis Tool
Using the Code Analysis Tools with the Ruleset
Isolated Storage
2/6/2023 • 2 minutes to read • Edit Online
Isolated Storage is a data storage that provides isolation between extensions, so that you can keep keys/values
in one extension from being accessed from other extensions. Keys/values in the Isolated Storage are accessible
through an API. The option type used for classifying data is DataScope Option Type and the data type used is the
IsolatedStorage Data Type.
The methods supported for IsolatedStorage are:
Set(String, String, [DataScope]) Sets the value associated with the Set(String, String, [DataScope]) Method
specified key within the extension.
Get(String, [DataScope], var Text) Gets the value associated with the Get(String, [DataScope], var Text)
specified key within the extension. Method
Delete(String, [DataScope]) Deletes the value with the specified IsolatedStorage.Delete Method
key from the isolated storage within
the extension.
SetEncrypted(String, String, Encrypts and sets the value associated SetEncrypted(String, String,
[DataScope]) with the specified key. The input string [DataScope]) Method
cannot exceed a length of 215 plain
characters; be aware that special
characters take up more space.
See Also
DataScope Option Type
IsolatedStorage Data Type
File Handling and Text Encoding
2/6/2023 • 4 minutes to read • Edit Online
There are several AL methods that you can use to open files, import and export files to and from Dynamics 365
Business Central, and more. For a list of methods, see File Data Type.
The following are recommended best practices for working with files:
Use fully qualified paths to eliminate ambiguity.
Be aware of operating system file access restrictions when designing applications that use files. Consider
which users have access to files and directories and what Access Control List (ACL) that you need to apply
to file directories.
Text encoding
Text encoding is the process of transforming bytes of data into readable characters for users of a system or
program. When you import a file as text or as a stream, the text encoding format ensures that all the language-
specific characters are represented correctly in Dynamics 365 Business Central. When you export a file as text or
as a stream, the text encoding format ensures that all the language-specific characters are represented correctly
in the system or program that will read the exported file.
Encoding formats
You can specify text encoding for the following objects.
O B JEC T O R DATA T Y P E F O R M O RE IN F O RM AT IO N , GO TO
There are several industry text encoding formats and different systems support different formats. Internally,
Dynamics 365 Business Central uses Unicode encoding. For exporting and importing data with an XMLport, it
supports MS-DOS, UTF-8, UTF-16, and Windows encoding formats.
Data is imported and exported as follows:
When data is imported from an external file, it's read using the format that is specified by the
TextEncoding property or parameter, and then converted to Unicode in Dynamics 365 Business Central.
When data is exported to an external file, it's converted from Unicode in Dynamics 365 Business Central,
and then written to the file in the format that is specified by the TextEncoding property or parameter.
You should set the text encoding to the encoding format that is compatible with the system or program that
you'll be exporting to or importing from. The following sections describe the available text encoding formats.
MS -DOS encoding format
MS-DOS encoding, which is also referred to as OEM encoding, is an older format than UTF-8 and UTF-16, but
it's still widely supported.
MS-DOS encoding requires a different character set for each language. When the property is set to MS-DOS,
text is encoded by using the system locale language of the computer that is running Business Central Server
instance. So if you use MS-DOS encoding, you should set the system locale language of server instance
computer to match the language of the data that is being imported or exported. For example, if an XMLport
includes text in Danish, then you should set the system locale language of the server instance computer to
Danish before the XMLport is run.
You should choose MS-DOS with XMLports that were created in earlier versions of Dynamics 365 Business
Central.
UTF -8 encoding format
UTF-8 encoding is a Unicode Transformation Format that uses one byte (8 bits) to encode each character. UTF-8
is based on the Unicode character set, which includes most characters of all languages in a single character set.
Unlike MS-DOS, when you use UTF-8, you don't have to consider the language settings of Business Central
Server instance or the external system or program that will read or write the data.
UTF-8 is compatible with ASCII so that it will understand files written in ASCII format.
UTF-8 is the most common encoding format and the recommended setting if you aren't sure of the format that
is supported by the system that you're integrating with.
UTF -16 encoding format
UTF-16 encoding resembles UTF-8 except that UTF-16 uses 2 bytes (16 bits) to encode each character. UTF-16
is also based on the Unicode character set, so you don't have to consider the language setting of Business
Central Server instance or the external system or program that reads or writes the data.
UTF-16 includes two encoding schemes, which mandate the byte order: UTF-16LE and UTF-16BE. The schemas
are supported as follows:
When exporting, the file is written using UTF-16LE encoding.
When importing, the file is read using the UTF-16, UTF-16LE, or UTF-16BE, depending on encoding
scheme of the file itself.
A UTF-16 encoded file will typically be larger than the same file encoded with UTF-8, except for Eastern
language character sets, which will typically be smaller.
UTF-16 is incompatible with ASCII so that it will not understand files written in ASCII format.
Windows format
Windows encoding is also referred to as ANSI encoding. If you set the text encoding to Windows , you can
import and export text files that are based on the Windows codepage determined by the system locale on the
Business Central Server. As a result, you don't have to consider the language setting of Business Central Server
instance computer or the external system or program that reads or writes the data.
For example, if an XMLport can import bank files from a foreign bank in addition to a domestic bank, use
Windows encoding instead of MS-DOS encoding to avoid changing the language of the Business Central Server
instance computer.
NOTE
In Business Central online, you have no control over the system locale on Business Central Server. Here, it's recommended
to use UTF8/UTF16 for text encodings instead.
See Also
TextEncoding Property (XMLports)
File Data Type
FlowFields
2/6/2023 • 2 minutes to read • Edit Online
FlowFields display the result of the calculation described in the CalcFormula Property. For example, the Account
Balance field in the General Ledger Account table shows the balance of the account and is calculated as the sum
of the NetAmount fields for all General Journal entries in the account.
FlowFields increase performance in activities such as calculating the balance of your customers. In traditional
database systems, this involves a series of accesses and calculations before a result is available. By using
FlowFields, the result is immediately available. You can further optimize the performance of Flowfields by
enabling or disabling SIFT. For more information, see SumIndexField Technology (SIFT).
FlowFields are not physical fields that are stored in the database. They are a description of a calculation and a
location for the result to be displayed. Because the information in FlowFields exists only at run time, values in
FlowFields are automatically initialized to 0 (zero). To update a FlowField, use the CalcFields Method (Record). If a
FlowField is the direct source expression of a control on a page, then the FlowField is automatically calculated
when the page is displayed.
FlowField types
There are seven types of FlowFields. Each is described in the following table.
Example
Consider the Customer table in the following illustration. This table contains two FlowFields. The field named
Any Entries is a FlowField of the Exist type, and the Balance field is a FlowField of the Sum type.
The figure shows that the value in the Balance FlowField for customer number 10000 (Windy City Solutions) is
retrieved from the Amount column in the Customer Entry table. The value is the sum of the amount fields for
the entries that have the customer number 10000.
Sum = 10 + 20 + 30 = 60.
The values shown in the Balance column in the Customer table for customers 10010, 10020, and 10040 are
found in the same way. For customer number 10030 the value is 0 (zero), as there are no entries in the
Customer Entry table that have a Customer No. that equals 10030.
In this example, the Balance FlowField in the Customer table reflects the sum of a specific subset of the Amount
fields in the Customer Entry table. How the calculation of a FlowField is to be made, is defined in a calculation
formula. The calculation formula for the Balance field is:
Correspondingly, the Any Entries field, which indicates whether any entries exist, has the following definition:
See Also
CalcFields Method (Record)
Create FlowFields and FlowFilters
Create FlowFields and FlowFilters
2/6/2023 • 3 minutes to read • Edit Online
This topic describes the procedure and the properties used to create FlowFields and FlowFilters.
A FlowField performs a set of calculations and displays the results immediately. A FlowFilter displays the results
based on the user input to calculate the filtered values that will affect the calculation of a FlowField. The
FlowFields and FlowFilters are not physical fields; these fields act as a virtual field which does not actually exist
in the database. They are a description of a calculation and a location for the result to be displayed which is
typically derived in the CalcFormula Property.
For more information about the FlowField type, see FlowFields, and for more information about the FlowFilter
type, see FlowFilter Overview.
Calculation formula
A FlowField type is always associated with a calculation formula that determines how the FlowField is calculated.
Likewise, the FlowFilter type is associated with the calculation formula. To perform the calculations by using the
FlowField and FlowFilter type, you must derive those fields in the calculation formula which you classify in the
table. You can choose from several methods of calculations including sum (total), average, maximum value,
minimum value, record count, lookup, and more, by using the CalcFormula Property. For more information
about the syntax and formulas, see Calculation Formulas and the CalcFormula Property.
Example
In the following example, MyTable sets the Global Dimension 1 Filter and Global Dimension 2 Filter fields
whose values are based only on the dimension values included in the filter. Also, some of the following fields
formulate the currency filter to one single currency because you do not store the filter value on the entries,
hence you define the Currency Filter as a FlowFilter type. Total Amount , Amount upper bound ,
Amount lower bound , First Entry , and Customer Balance are classified as a FlowField type and here you specify
the calculations. These fields display the results immediately based on the filters that you apply in the user
interface.
field(2;"No."; Code[20])
{
Description='Serial number of the service';
}
See Also
FlowFields
FlowFilter Overview
Calculation Formulas and the CalcFormula Property
Nonclustered Columnstore Indexes
2/6/2023 • 2 minutes to read • Edit Online
Nonclustered columnstore indexes (NCCIs) let you quickly calculate the sums of numeric data type (Decimal,
Integer, BigInteger, and Duration) columns in tables. Calculations can be done in tables with millions of records.
NCCIs optimize the performance of FlowFields and query results in a Business Central application. The articles in
this section describe how NCCIs are implemented in Business Central.
See Also
NCCI and SQL Server
NCCI Tuning and Tracing
NCCI Performance
Migrating from SIFT to NCCI
FlowFields
Nonclustered Columnstore Indexes and SQL Server
2/6/2023 • 2 minutes to read • Edit Online
A nonclustered columnstore index (NCCI) is always associated with a table, and there can only be one defined
per table.
Any field that exists in the table, except BLOB data types, can be added to the NCCI.
Implementing NCCI
In contrast to SIFT keys, which rely on the indexed views feature in SQL Server, NCCIs in Business Central use
only the nonclustered columnstore indexes feature. No aggregated data is stored in the NCCI—all analytical
queries are done at runtime. This implementation also means you don't have to worry about the order of fields
added to the NCCI or design specific NNCIs for specific flow field scenarios.
With SIFT keys, any insert, update, or delete operations to the underlying table will introduce some database
locking because the indexed views must be updated as well. The more SIFT keys that are defined on the table,
the more index maintenance is needed. This problem doesn't exist with a nonclustered columnstore index.
See Also
NCCI Overview)
NCCI Tuning and Tracing
NCCI Performance
Migrating from SIFT to NCCI
Nonclustered Columnstore Indexes Tuning and
Tracing
2/6/2023 • 2 minutes to read • Edit Online
Nonclustered columnstore (NCCIs) indexes are exposed to SQL Server tracing and tuning tools. For example, the
SQL Server profiler can display information about which columnstore indexes are used in the system. This
information makes it easy for you to assess the cost of maintaining an NCCI. It allows you to make informed
decisions about any adjustments that might be required.
See Also
NCCI Overview)
NCCI and SQL Server
NCCI Performance
Migrating from SIFT to NCCI
SumIndexField Technology (SIFT)
FlowFields
Nonclustered Columnstore Indexes and
Performance
2/6/2023 • 2 minutes to read • Edit Online
This article looks at the factors you must take into consideration when you deal with nonclustered columnstore
indexes (NCCIs) and performance.
IMPORTANT
Remember to perform tests every time you make any changes to the NCCI structure. You must ensure that the changes
that you have made don't cause problems in any other areas of the application. You must also ensure that your changes
don't have a negative effect on performance.
See Also
NCCI Overview)
NCCI and SQL Server
NCCI Tuning and Tracing
Migrating from SIFT to NCCI
FlowFields
Migrating from SIFT to Nonclustered Columnstore
Indexes
2/6/2023 • 2 minutes to read • Edit Online
The nonclustered columnstore index (NCCI) is envisioned to be the successor of SumIndexField Technology
(SIFT). This article provides examples of how to replace one or more SIFT keys on a table with a nonclustered
columnstore index.
Example
This example illustrates how to replace SIFT indexes on a table with an NCCI.
The following code creates a table with two SIFT keys defined on it. The Student table is a simple model of
students with counts of ECTS points and how many courses they've passed.
table 50100 Student
{
DataClassification = CustomerContent;
fields
{
field(1; ID; Integer)
{
DataClassification = EndUserPseudonymousIdentifiers;
}
field(2; Code; Text[50])
{
DataClassification = EndUserPseudonymousIdentifiers;
}
field(3; FirstNames; Text[100])
{
DataClassification = EndUserIdentifiableInformation;
}
field(4; ECTSPoints; Integer)
{
DataClassification = CustomerContent;
}
field(5; NumberOfCourses; Integer)
{
DataClassification = CustomerContent;
}
}
// Here are the SIFT keys that the developer added to the table:
keys
{
// Defines the primary key
key(PK; ID)
{
Clustered = true;
}
// Defines a SIFT index on Code with aggregations fields for count and SUM(ECTSPoints)
key(SIFTKeyOnCode; Code)
{
SumIndexFields = ECTSPoints;
MaintainSqlIndex = false;
}
// Defines a SIFT index on FirstNames with aggregations fields for count and SUM(NumberOfCourses)
key(SIFTKeyOnNames; FirstNames)
{
SumIndexFields = NumberOfCourses;
MaintainSqlIndex = false;
}
}
}
To replace SIFT keys with an NCCI, just add all fields to the definition of the NCCI and remove the SIFT keys:
table 50100 Student
{
DataClassification = CustomerContent;
// Defines NCCI to replace the SIFT keys
ColumnStoreIndex = Code,FirstNames,ECTSPoints,NumberOfCourses;
fields
{
field(1; Code; Text[50])
{
DataClassification = EndUserPseudonymousIdentifiers;
}
field(2; FirstNames; Text[100])
{
DataClassification = EndUserIdentifiableInformation;
}
field(3; ECTSPoints; Integer)
{
DataClassification = CustomerContent;
}
field(4; NumberOfCourses; Integer)
{
DataClassification = CustomerContent;
}
}
keys
{
// Defines the primary key
key(PK; ID)
{
Clustered = true;
}
}
}
See Also
SumIndexField Technology (SIFT)
SIFT and SQL Server
SIFT Tuning and Tracing
SIFT Performance
NCCI Overview)
NCCI and SQL Server
NCCI Tuning and Tracing
NCCI Performance
SumIndexField Technology (SIFT)
2/6/2023 • 2 minutes to read • Edit Online
SumIndexField Technology (SIFT) lets you quickly calculate the sums of numeric data type (Decimal, Integer,
BigInteger, and Duration) columns in tables, even in tables with thousands of records. SIFT is used to optimize
the performance of FlowFields and query results in a Business Central application. SIFT involves performing a
series of database calls and calculations before arriving at a result. The topics in this section describes how SIFT
is implemented in Business Central.
See Also
SIFT and SQL Server
SIFT Tuning and Tracing
SIFT Performance
Migrating from SIFT to NCCI FlowFields
SIFT and SQL Server
2/6/2023 • 2 minutes to read • Edit Online
A SumIndexField is always associated with a key and each key can have a maximum of 20 SumIndexFields
associated with it. In this topic, a key that has at least one SumIndexField associated with it is a SIFT key.
IMPORTANT
Any field that has a numeric data type of Decimal, Integer, BigInteger, or Duration, can be associated with a key as a
SumIndexField.
Implementing SIFT
Business Central uses Indexed Views to maintain SIFT totals. Indexed views are a standard SQL Server feature.
An indexed view is like a SQL Server view except that the contents have been materialized (computed and
stored) to speed up the retrieval of data. For more information about indexed views, see SQL Server
Documentation.
Business Central creates one indexed view for each SIFT key that is enabled. When you create a SIFT key for a
table, you must set the MaintainSIFTIndex Property for that key to True to enable the SIFT key and create the
indexed view. After SQL Server has created the indexed view, it maintains the contents of the view when any
changes are made to the base table. If you set the MaintainSIFTIndex Property for that key to False , SQL Server
drops the indexed view and stops maintaining the totals.
The indexed view that is generated for a SIFT key is always created at the level of finest granularity. Therefore, if
you create a SIFT key for AccountNo., PostingDate , the database will store an aggregated value for each account
for each date. This means that in the worst case scenario, 365 records must be summed to generate the total for
each account for a year.
The following is an example of how Business Central creates an indexed view for a SIFT key that consists of the
AccountNo. and PostingDate fields with a total for the Amount field.
The following code example shows how the same total is retrieved through an indexed view.
SELECT SUM(SUM$Amount)
FROM GLEntry$VSIFT$1 WITH(NOEXPAND)
WHERE AccountNo=?
AND PostingDate>=?
AND PostingDate<=?
See Also
SumIndexField Technology (SIFT)
Tuning and Tracing
SIFT and Performance Migrating from SIFT to NCCI
SIFT Tuning and Tracing
2/6/2023 • 2 minutes to read • Edit Online
As a result of using indexed views, SIFT keys are exposed to SQL Server tracing and tuning tools. For example,
the SQL Server profiler can display information about which indexed views are maintained for a specific table.
This makes it easy for you to assess the cost of maintaining SIFT keys and allows you to make informed
decisions about any adjustments that might be required.
SIFT Keys
When data is inserted, updated, or deleted in a table, the SIFT keys that have been defined and enabled for that
table are maintained. Maintaining these SIFT indexes has performance overhead. The size of the performance
overhead depends on the number of keys and SumIndexFields that have been defined for each table. You should
therefore give careful consideration to the number of SIFT keys that you define and only maintain the SIFT keys
that are important for your application.
There is no need to maintain a SIFT key for a total that is only used periodically and can be easily generated by a
report. You can still program Business Central to calculate the SIFT based totals even if the SIFT key is disabled.
The calculation is performed directly on the base table.
You should consider combining indexes wherever possible.
Example
Maintaining two SIFT keys:
1. Key: "WareHouseId, ItemId, Color" SumField: "OnStock"
2. Key: "WareHouseId, ItemId, Size" SumField: "OnStock"
If there are only a few combinations of Size and Color (for example, less than 200), then one combined
index/SIFT key should be sufficient.
1. The Combined Key:
2. "WareHouseId, ItemId, Color, Size" SumFIeld: "OnStock"
When you set the MaintainSIFTIndex Property of a key to True , this will be the SIFT key and create the indexed
view to support it. However, disabling the SIFT key by setting MaintainSIFTIndex Property to False can improve
performance in certain circumstances. Setting this property to False means that the SIFT functionality must be
implemented by calculating the totals online instead of using the precalculated sums that are maintained by
SIFT.
See Also
SumIndexField Technology (SIFT)
SIFT and SQL Server
SIFT Performance Migrating from SIFT to NCCI FlowFields
SIFT and Performance
2/6/2023 • 2 minutes to read • Edit Online
This topic looks at the factors you must take into consideration when you deal with SIFT and performance.
C O ST B EN EF IT
You can prevent the SIFT indexes from being updated by setting the MaintainSIFTIndex Property of the index in
the base table to False . This means that you no longer benefit from SIFT's ability to calculate sums quickly.
However, the SIFT functionality is still available. If the base table does not grow or only grows slowly, there is no
need to set the MaintainSIFTIndex Property to True for any indexes that contain SumIndexFields. If the base
table does grow, you should set the MaintainSIFTIndex Property to True for any indexes that contain
SumIndexFields.
In Business Central , changes have been made to improve performance when accessing the database. One of
these changes is that Business Central automatically maintains a count for all SIFT indexes. For more
information about how this affects the Count and Average methods on FlowFields, see CalcFields Method. For
more information about other data access changes, see Data Access.
IMPORTANT
It is important that you remember to perform tests every time you make any changes to the SIFT structures. You must
ensure that the changes that you have made do not cause problems in any other areas of the application. You must also
ensure that your changes do not have a negative effect on performance.
See Also
SumIndexField Technology (SIFT)
SIFT and SQL Server
SIFT Tuning and Tracing
Migrating from SIFT to NCCI FlowFields
Number Sequences in Business Central
2/6/2023 • 2 minutes to read • Edit Online
In AL, you can create and manage number sequences that generate numeric identifiers for data and records.
Business Central number sequences are built on SQL Server sequences, which means that they are not
associated with any tables. Instead, the application code references the number sequence object and coordinates
the values across records.
The numbers in a number sequence are generated in ascending order at a defined interval. Numbers are used
sequentially, but numbers can be skipped. This means that numbers used on records in tables can have gaps.
These gaps, for example, can occur when transactions are rolled back or numbers are allocated but not used.
M ET H O D N A M E DESC RIP T IO N
[Insert(String, BigInteger][, BigInteger], [Boolean]) Creates a number sequence in the database, with the given
parameters.
Next(String[, Boolean]) Retrieves the next value from the number sequence.
M ET H O D N A M E DESC RIP T IO N
Current(String[, Boolean]) Gets the current value from the number sequence, without
doing any increment. The value is retrieved out of
transaction. The value will not be returned on transaction
rollback.
Examples
// Creates a NumberSequence object that starts with the value '0' and increments by '1'
NumberSequence.Insert('DefaultSequence');
// Creates a NumberSequence object that starts with the value '10' and increments by '1'
NumberSequence.Insert('StartsWithTenSequence', 10);
// Creates a NumberSequence object that starts with the value '0' and increments by '10'
NumberSequence.Insert('StartsWithZeroIncrementTenSequence', 0, 10);
// Creates a NumberSequence object that starts with the value '0', increments by '1', and is company-
specific
NumberSequence.Insert('MyCompanySequence', 0, 1, true);
See Also
Number Sequence data type
SQL Server Sequences
Extensible Enums
2/6/2023 • 4 minutes to read • Edit Online
An enumeration type, also known as an enum in programming, is a keyword used to declare a type that consists
of a set of named constants. The list of named constants is called the enumeration list. Enums can be used as
table fields, local and global variables, and parameters.
To declare an enum in AL you must specify an ID and a name. The enumeration list consists of values and each
of the values are declared with an ID and a value. The value ID is the ordinal value on the enumeration list and
must be unique. When the enum values are displayed in the UI they're sorted by the order of declaration. In
addition, if extension B extends extension A , the enum values declared in extension A are displayed before the
enum values declared in extension B .
The following example shows the declaration of an enum, which can be extended, and has the four values;
None , Bronze , Silver , and Gold .
value(0; None) { }
value(1; Bronze) { }
value(2; Silver) { }
value(3; Gold)
{
Caption = 'Gold Customer';
}
}
NOTE
While enums and enumextension objects have object IDs, these are not enforced by the license. In previous versions they
reused the range for tables, and were checked against the license at deployment time, but this is no longer the case.
Uniqueness validation is now enforced during installation, which will fail if an enum object ID clashes with an already
installed enum. Thus, as always, it is important that you use object IDs in your assigned range. This is enforced for
AppSource apps, but not for per-tenant extensions, or on-premise. The enum does not have to use the same ID as the
table it is put on.
IMPORTANT
Only enums with the Extensible Property set to true can be extended.
IMPORTANT
When creating captions for enums, it's important that the caption doesn't contain a comma. Having a comma in the
caption, such as Caption = 'Diamond Level, with bonus' , can display over multiple lines in the UI. This behavior also
causes that the actual value selected by the user in the UI, doesn't correspond to the value, which is saved in the
database.
An AppSourceCop warning will be triggered if .xlf files contain commas in enum captions. For more information, see
AppSourceCop Warning AS0087.
Enumextension object
Enums can be extended in order to add more values to the enumeration list in which case the Extensible
property must be set to true . The syntax for an enum extension, which extends the Loyalty enum with the
value Diamond , is shown below.
Usage
When referencing a defined enum from code, you use the syntax as illustrated below.
enum Loyalty
If you want to define an enum as a table field type, use the syntax illustrated below:
Or, as a variable:
var
LoyaltyLevel: enum Loyalty;
In code, you address a specific enum value like in the following example:
Example
The following example illustrates how to define an enum extension of TypeEnum , using it in a table extension
TableWithRelationExt and displaying it as a control on a new page.
enumextension 50133 TypeEnumExt extends TypeEnum
{
value(10; Resource) { }
}
layout
{
area(Content)
{
repeater(MyRep)
{
field(Id; Id)
{
ApplicationArea = All;
}
field(Type; Type)
{
ApplicationArea = All;
}
field(Relation; Relation)
{
ApplicationArea = All;
}
}
}
}
}
TIP
For another example of how to extend the usage of the TableRelation property in connection with enums, see
TableRelation Property.
P RO P ERT Y N A M E DATA T Y P E
EnumTypeId Integer
EnumTypeName Text
Some table fields share options that are semantically identical. In those cases, the EnumTypeId and
EnumTypeName must be the same across all the fields. There's no design or runtime check for collision of IDs,
but loading generated symbols, see Running C/SIDE and AL Side-by-Side, into the compiler will show collision
errors.
Conversions
Conversion to and from enum is more strict than for Options in C/SIDE.
An enum can be assigned/compared to an enum of the same type.
To be backwards compatible, we support conversion to/from any Option for now.
See Also
AL Data Types
TableRelation Property
Extensible Property
Enum Data Type
AssignmentCompatibility Property
Protected Variables
2/6/2023 • 2 minutes to read • Edit Online
The protected keyword can be used to make variables accessible between tables and table extensions and
between pages and page extensions. If you want to only expose some variables as protected , you must create
two sections of var declarations. See the syntax below.
Syntax
protected var
myInt: Integer; // protected var
var
myLocalInt: Integer; // local var
Example
The example below illustrates how to declare and use a protected variable.
layout
{
area(Content)
{
group(General)
{
field(Name; Name)
{
ApplicationArea = All;
}
}
group(Advanced)
{
Visible = ShowBalance;
field(Balance; Balance)
{
ApplicationArea = All;
}
}
}
}
protected var
[InDataSet]
ShowBalance: Boolean;
}
actions
{
addlast(Navigation)
{
action(ToggleBalance)
{
ApplicationArea = All;
trigger OnAction()
begin
ShowBalance := not ShowBalance; // Toggle ShowBalance from MyPage.
end;
}
}
}
}
See Also
AL Method Reference
Properties
Access Property
Extensible Property
Working with Labels
2/6/2023 • 2 minutes to read • Edit Online
Labels are string constants displayed in the Business Central client that can be translated into multiple
languages, such as captions, descriptions, or messages. This way, the user interface can be displayed in different
languages. For more information on how translation is carried out in Dynamics 365 Business Central, see
Multilanguage development.
Label syntax
Labels have a specific syntax defined by a text constant followed by three optional parameters. They must be
comma-separated, but the order of the parameters is not enforced. The parameters that you can set are
described in the following table.
Using labels
A label can take the form of four different AL structures. It can be the property value of certain page and report
properties, the label data type variable and a report or a page label. The different possibilities are explained in
more detail below.
Properties
The label syntax is used in properties that are set to display text on the user interface. It applies to the following
properties:
Caption Property
ToolTip Property
OptionCaption Property
AdditionalSearchTerms Property
InstructionalText Property
PromotedActionCategories Property
RequestFilterHeading Property
The following example shows the label syntax when it is used as property value for the Caption property.
Caption = 'Developer translation for %1', Comment = '%1 is extension name', locked = false, MaxLength=999;
Label data type
The Label Data Type denotes a string variable used to define error messages, questions, captions, tokens, or
other text constants displayed to the user.
The following code sample illustrates how to use the Label data type.
var
a:Label'LabelText',Comment='Foo',MaxLength=999,Locked=true;
The Label variable names should have an approved suffix. For more information, see CodeCop Rule AA0074.
Report labels
Report labels are used by RDL and Word report layouts as, for example, the caption for a field, the title for a
chart, or the title for the report itself. For a code example on how to use report labels for an RDL layout, see
Walkthrough: Designing a Report from Multiple Tables.
Report labels are defined inside the labels control of a report object, as shown in the code sample below.
labels
{
LabelName1='LabelText1',Comment='Foo',MaxLength=999,Locked=true;
LabelName2 = 'LabelText2',Comment='Foo',Locked=false;
}
Page labels
Page labels are used to display plain text on a page, such as instructions or informative texts. You can find
several examples of page labels in the Rapidstart Services Wizard in page "Config. Wizard" .
Page labels are defined by a label(Name) control inside the area(Content) part of a page. The following code
shows how to define a page label.
label(BeforeSetupCloseMessage)
{
ApplicationArea = Basic, Suite;
Caption = 'If you still need to change setup data, do not change the profile.'
}
See Also
Working with labels
Working with Translation Files
Label Data Type
Report Layouts
Table Object
2/6/2023 • 2 minutes to read • Edit Online
Tables are the core objects used to store data in Dynamics 365 Business Central. No matter how data is
registered in the product - from a web service to a finger swipe on the phone app, the results of that transaction
will be recorded in a table.
The structure of a table has four sections:
The first block contains metadata for the overall table, such as the table type.
The fields section describes the data elements that make up the table, such as their name and the type of data
they can store.
The keys section contains the definitions of the keys that the table needs to support.
The final section details the triggers and code that can run on the table.
IMPORTANT
Only tables with the Extensible Property set to true can be extended.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
IMPORTANT
System and virtual tables can't be extended. System tables are created in the ID range of 2.000.000.000 and above. For
more information about object ranges, see Object Ranges.
Snippet support
Typing the shortcut ttable will create the basic layout for a table object when using the AL Language extension
in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Table example
This table stores address information and it has four fields; Address , Locality , Town/City , and County .
table 50104 Address
{
Caption = 'Sample table';
DataPerCompany = true;
fields
{
field(1; Address; Text[50])
{
Description = 'Address retrieved by Service';
}
field(2; Locality; Text[30])
{
Description = 'Locality retrieved by Service';
}
field(3; "Town/City"; Text[30])
{
Description = 'Town/City retrieved by Service';
}
field(4; County; Text[30])
{
Description = 'County retrieved by Service';
trigger OnValidate();
begin
ValidateCounty(County);
end;
}
}
keys
{
key(PrimaryKey; Address)
{
Clustered = TRUE;
}
}
var
Msg: Label 'Hello from my method';
trigger OnInsert();
begin
end;
procedure MyMethod();
begin
Message(Msg);
end;
}
System fields
The Dynamics 365 Business Central platform will automatically add several system fields to tables. For more
information, see System Fields.
See Also
AL Development Environment
Table Overview
Table Extension Object
SqlTimestamp Property
Table Keys
Table, Table Fields, and Table Extension Properties
Table Extension Object
2/6/2023 • 2 minutes to read • Edit Online
The table extension object allows you to add additional fields or to change some properties on a table provided
by the Dynamics 365 Business Central service. In this way, you can add data to the same table and treat it as a
single table. For example, you may want to create a table extension for a retail winter sports store. In your
solution you want to have ShoeSize as an additional field on the customer table. Adding this as an extension
allows you to write code for the customer record and also include values for the ShoeSize .
Along with defining other fields, the table extension is where you write trigger code for your additional fields.
When developing a solution for Dynamics 365 Business Central , you will follow the code layout for a table
extension as shown in the example below.
IMPORTANT
Only tables with the Extensible Property set to true can be extended.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
IMPORTANT
System and virtual tables cannot be extended. System tables are created in the ID range of 2.000.000.000 and above. For
more information about object ranges, see Object Ranges.
IMPORTANT
Extending tables from Dynamics 365 for Sales is currently not supported.
Snippet support
Typing the shortcut ttableext will create the basic layout for a table extension object when using the AL
Language extension in Visual Studio Code.
Properties
Using a table extension allows you to overwrite some properties on fields in the base table. For a list of Table
properties, see Table and Table Extension Properties.
Table extension syntax
tableextension Id MyExtension extends MyTargetTable
{
fields
{
// Add changes to table fields here
}
var
myInt: Integer;
}
trigger OnBeforeInsert();
begin
if not HasShoeSize then
ShoeSize := Random(42);
end;
}
See Also
AL Development Environment
Table Overview
Table Object
Table, Table Fields, and Table Extension Properties
Table Keys
Table Keys
2/6/2023 • 12 minutes to read • Edit Online
The database management system, which is SQL Server, uses keys to identify rows in a table. Keys identify the
rows by combining one or more columns of a table. SQL also uses indexes to speed up data retrieval from rows
in a table. This article explains how to create keys and indexes for Business Central tables from AL code.
Keys in AL
In AL, a key definition is a sequence of one or more field IDs from a table. You can define keys in table objects
and table extension objects, depending on the type of key. There are two types of keys: primary and secondary.
Primary keys
A primary key uniquely identifies each record in a table. Every table has a primary key, and there can only
be one primary key per table. Primary keys are defined on table objects only. In SQL, table extension
objects inherit the primary key of the table object they extend (the base table object). So any key that you
define in a table extension object is considered a secondary key.
Secondary keys
Secondary keys create indexes in SQL. They're defined in both table objects and table extension objects.
You can define multiple secondary keys for a single table object and table extension object.
A key in table extension object can include fields from the base table object or the table extension object.
There are some limitations, however. For more information, see Limitations and Restrictions.
Primary keys
The primary key keeps track of data in a table. The primary key is composed of up to 16 fields in a record. The
combination of values in fields in the primary key makes it possible to uniquely identify each record. In AL, the
first key defined in a table object is the primary key. The primary key determines the logical order in which
records are stored, no matter the physical placement of the fields in the table object.
Logically, records are stored sequentially in ascending order and sorted by the primary key. Before adding a new
record to a table, SQL Server checks if the information in the record's primary key fields is unique. If so, it then
inserts the record into the correct logical position. Records are sorted dynamically so the database is always
structurally correct. This sorting allows for fast data manipulation and retrieval.
The primary key is always active. SQL Server keeps the table sorted in primary key order and rejects records
with duplicate values in primary key fields. That's why the values in the primary key must always be unique. It's
not the value in each field in the primary key that must be unique. Instead, it's the combination of values in all
fields that make up the primary key.
NOTE
In the development environment, it's technically possible to create a primary key based on up to 20 fields. However,
because of SQL Server limitations, only the first 16 are used.
Secondary keys
In a table object, any keys defined after the primary key are called secondary keys. All keys defined in a table
extension object are considered secondary keys.
A secondary key is implemented on SQL Server using a structure that is called an index. This structure is like an
index that is used in textbooks. A textbook index alphabetically lists important terms at the end of a book. Next
to each term are page numbers. You can quickly search the index to find a list of page numbers (addresses), and
you can locate the term by searching the specified pages. The index is an exact indicator that shows where each
term occurs in the textbook.
When you define a secondary key and mark it as enabled, an index is automatically maintained on SQL Server.
The index reflects the sorting order that is defined by the key. Several secondary keys can be active at the same
time.
A secondary key can be disabled so that it doesn't occupy database space or use time during updates to
maintain its index. Disabled keys can be re-enabled, although this operation can be time-consuming because
SQL Server must scan the whole table to rebuild the index.
The fields that make up the secondary keys don't always contain unique data. SQL Server doesn't reject records
with duplicate data in secondary key fields. So if two or more records contain identical information in the
secondary key, SQL Server uses the table's primary key to resolve this conflict.
TIP
You can see a list of potential columns that can be indexed and other useful information about them in Business Central
on Database Missing Indexes . For more information on missing indexes, see Missing Indexes in Dynamics 365
Business Central
NOTE
The Unique property isn't supported in table extension objects.
System keys
There's always a unique secondary key on the SystemId field.
Secondary keys with included fields
INTRODUCED IN: Business Central 2021 release wave 2
With non-clustered secondary keys, you can use the IncludedFields property to add fields that aren't part of the
key itself. In SQL server, these non-key fields correspond to what are called included columns. Using included
fields lets you create indexes that cover more queries, and lets you bypass the maximum number of fields in a
key.
A secondary key with included fields can improve SQL query performance, especially when SQL index contains
all columns in the query, either as key columns or included columns. The performance improves because the
query optimizer can locate all the column values within the index. And, it doesn't access table or clustered index
data, which results in fewer disk I/O operations. For more information about included columns in SQL, see
Create indexes with included columns.
Non-clustered Columnstore keys
INTRODUCED IN: Business Central 2021 release wave 2
NOTE
The Clustered property isn't supported in table extension objects.
K EY K EY T Y P E DEF IN IT IO N
When you sort by the primary key, the Customer table resembles the following table.
C USTO M ER N UM B ER C USTO M ER N A M E
001 Customer C
002 Customer A
003 Customer B
004 Customer C
If you select the secondary key for sorting, then the order is based on the contents of the Customer Name field.
Because the contents of these fields aren't unique, the records must be subsorted according to the primary key.
C USTO M ER N A M E C USTO M ER N UM B ER
Customer A 002
Customer B 003
Customer C 001
Customer C 004
NOTE
The two records that have the same Customer Name value are sorted by Customer Number.
Increase the number of secondary Retrieve data in several different Enter data because indexes for each
keys that are marked as active. sorting sequences because the data is secondary key must be maintained.
already sorted.
IF Y O U P ERF O RM A N C E IM P RO VES W H EN Y O U P ERF O RM A N C E SLO W S W H EN Y O U
Decide to use only a few keys. Enter data because a minimal number Retrieve data. You may have to define
of indexes are maintained. or reactivate the secondary keys to get
the appropriate sorting. Depending on
the size of the database, this operation
can take some time, because the index
must be rebuilt.
The decision whether to use a few or many keys isn't easy. The appropriate keys and the number of active keys
to use is a compromise between maximizing the speed of data retrieval and data updates (operations that insert,
delete, or modify data). In general, it may be worthwhile to deactivate complex keys if they're rarely used.
The overall speed depends on the following factors:
Size of the database.
Number of active keys.
Complexity of the keys.
Number of records in your tables.
Speed of your computer and its hard disk.
keys
{
key(Name1; Fields)
{
}
key(Name2; Fields)
{
}
}
Replace Name with descriptive text that you want to use to identify the key. Replace Field with the name of a
field that you want to use as the key. If you want to include multiple fields in a single key, separate each field
with a comma.
In a table object, the first key keyword defines the primary key. Subsequent key keywords define secondary
keys.
TIP
Starting in Business Central version 18, it is possible to create a table extension that only holds key definitions. You can
utilize this to add keys to tables in the base application or in AppSource extensions, where you don't have ownership of
the table definitions.
The following code illustrates simple examples of a table object and table extension object.
table 50120 MyBaseTable
{
fields
{
field(1; MyBaseField1; Integer)
{
}
field(2; MyBaseField2; Integer)
{
}
}
keys
{
key(PK; MyBaseField1) //primary key
{
Clustered = true;
}
key(Key1; MyBaseField2) //secondary key
{
}
}
}
keys
{
key(ExtKey1; MyExtField1) //secondary key
{
IncludeFields = MyExtField2,MyExtField3;
}
key(ExtKey2; MyBaseField1, MyBaseField2) //secondary key
{
}
// The following key isn't allowed because it contains fields from the base table and the table
extension
//key(ExtKey3; MyBaseField1, MyExtField2)
//{
//}
}
}
tableextension 50122 MyCustomerKeyExt extends Customer
{
// This example illustrates how to use a table extension to add a key on the Customer table from the
base application
keys
{
key(ExtKey1; "No.", "Name", City)
{
}
}
}
Key properties
There are several properties that configure the behavior of a key, such as the Enabled, Clustered, and Unique
properties:
keys
{
key(PrimaryKey; ID)
{
Clustered = true;
}
key(CustomerInfo; Name,Address,City)
{
Unique = true;
}
key(Currency; Currency Code)
{
Enabled = false;
}
}
For a more information about the different key properties, see Key Properties.
When you invoke IntelliSense for table fields, the primary key members are marked with a (PKx) in the
IntelliSense list, where x is a sequential number, which indicates the order of the field in the key. This allows
you to identify the table fields that make up the primary key and the sequency of these fields in the key.
See Also
Key Properties Tables Overview
Table Object
Table Extension Object
SystemId Field
Extensible Enums
2/6/2023 • 4 minutes to read • Edit Online
An enumeration type, also known as an enum in programming, is a keyword used to declare a type that consists
of a set of named constants. The list of named constants is called the enumeration list. Enums can be used as
table fields, local and global variables, and parameters.
To declare an enum in AL you must specify an ID and a name. The enumeration list consists of values and each
of the values are declared with an ID and a value. The value ID is the ordinal value on the enumeration list and
must be unique. When the enum values are displayed in the UI they're sorted by the order of declaration. In
addition, if extension B extends extension A , the enum values declared in extension A are displayed before the
enum values declared in extension B .
The following example shows the declaration of an enum, which can be extended, and has the four values;
None , Bronze , Silver , and Gold .
value(0; None) { }
value(1; Bronze) { }
value(2; Silver) { }
value(3; Gold)
{
Caption = 'Gold Customer';
}
}
NOTE
While enums and enumextension objects have object IDs, these are not enforced by the license. In previous versions they
reused the range for tables, and were checked against the license at deployment time, but this is no longer the case.
Uniqueness validation is now enforced during installation, which will fail if an enum object ID clashes with an already
installed enum. Thus, as always, it is important that you use object IDs in your assigned range. This is enforced for
AppSource apps, but not for per-tenant extensions, or on-premise. The enum does not have to use the same ID as the
table it is put on.
IMPORTANT
Only enums with the Extensible Property set to true can be extended.
IMPORTANT
When creating captions for enums, it's important that the caption doesn't contain a comma. Having a comma in the
caption, such as Caption = 'Diamond Level, with bonus' , can display over multiple lines in the UI. This behavior also
causes that the actual value selected by the user in the UI, doesn't correspond to the value, which is saved in the
database.
An AppSourceCop warning will be triggered if .xlf files contain commas in enum captions. For more information, see
AppSourceCop Warning AS0087.
Enumextension object
Enums can be extended in order to add more values to the enumeration list in which case the Extensible
property must be set to true . The syntax for an enum extension, which extends the Loyalty enum with the
value Diamond , is shown below.
Usage
When referencing a defined enum from code, you use the syntax as illustrated below.
enum Loyalty
If you want to define an enum as a table field type, use the syntax illustrated below:
Or, as a variable:
var
LoyaltyLevel: enum Loyalty;
In code, you address a specific enum value like in the following example:
Example
The following example illustrates how to define an enum extension of TypeEnum , using it in a table extension
TableWithRelationExt and displaying it as a control on a new page.
enumextension 50133 TypeEnumExt extends TypeEnum
{
value(10; Resource) { }
}
layout
{
area(Content)
{
repeater(MyRep)
{
field(Id; Id)
{
ApplicationArea = All;
}
field(Type; Type)
{
ApplicationArea = All;
}
field(Relation; Relation)
{
ApplicationArea = All;
}
}
}
}
}
TIP
For another example of how to extend the usage of the TableRelation property in connection with enums, see
TableRelation Property.
P RO P ERT Y N A M E DATA T Y P E
EnumTypeId Integer
EnumTypeName Text
Some table fields share options that are semantically identical. In those cases, the EnumTypeId and
EnumTypeName must be the same across all the fields. There's no design or runtime check for collision of IDs,
but loading generated symbols, see Running C/SIDE and AL Side-by-Side, into the compiler will show collision
errors.
Conversions
Conversion to and from enum is more strict than for Options in C/SIDE.
An enum can be assigned/compared to an enum of the same type.
To be backwards compatible, we support conversion to/from any Option for now.
See Also
AL Data Types
TableRelation Property
Extensible Property
Enum Data Type
AssignmentCompatibility Property
Page Object
2/6/2023 • 2 minutes to read • Edit Online
Pages are the main way to display and organize visual data in Dynamics 365 Business Central. They are the
primary object that a user will interact with and have a different behavior based on the type that you choose.
Pages are designed independently of the device they are to be rendered on, and in this way the same page can
be reused across phone, tablet, and web clients.
The structure of a page is hierarchical and breaks down in to three sections. The first block contains metadata for
the overall page; the type of the page and the source table it is showing data from. The next section; the layout,
describes the visual parts on the page. The final section details the actions that are published on the page.
When developing a solution for Dynamics 365 Business Central, you will follow the code layout for a page as
shown in the page example below, but for more details on the individual controls and properties that are
available, see Page Property Overview.
If you want to, for example, add functionality to a page that already exists in Business Central, you can create a
page extension object that changes an existing page object. For more information, see Page Extension Object.
Depending on how much you want to change on an existing page, you can also create a page customization
object, which offers modifications on actions and layout. For more information, see Page Customization Object.
IMPORTANT
Only pages with the Extensible Property set to true can be extended.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
Snippet support
Typing the shortcut tpage will create the basic layout for a page object when using the AL Language extension
in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Views
Views in Dynamics 365 Business Central are used on list pages to define a different view of the data on a given
page. Views can be defined for Pages, Page Extensions, and Page Customization. For more information, see
Views.
Page example
page 50101 SimpleCustomerCard
{
PageType = Card;
SourceTable = Customer;
ContextSensitiveHelpPage = 'my-feature';
layout
{
area(content)
{
group(General)
{
field("No."; "No.")
{
ApplicationArea = All;
CaptionML = ENU = 'Hello';
trigger OnValidate()
begin
if "No." < '' then
Message('Number too small')
end;
}
field(Name; Name)
{
ApplicationArea = All;
}
field(Address; Address)
{
ApplicationArea = All;
}
}
}
}
actions
{
area(Navigation)
{
action(NewAction)
{
ApplicationArea = All;
RunObject = codeunit "Document Totals";
}
}
}
}
See Also
AL Development Environment
Views
Adding Help Links from Pages, Reports, and XMLports
Page Extension Object
Page, Page Fields, and Page Extension Properties
Page Properties
Developing Extensions
Configure Context-Sensitive Help
Page Extension Object
2/6/2023 • 4 minutes to read • Edit Online
The page extension object extends a Dynamics 365 Business Central page object and adds or overrides the
functionality.
The structure of a page is hierarchical and breaks down into three sections. The first block contains metadata for
the overall page; the type of the page and the source table it is showing data from. The next section; the layout,
describes the visual parts on the page. The final section details the actions that are published on the page.
For more information about the Page and Page Extension objects, see Pages Overview.
IMPORTANT
Only pages with the Extensible Property set to true can be extended.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
IMPORTANT
The API page type should not be extended by creating a page extension object. Instead, create a new API by adding a
page object.
NOTE
Modifying actions in Cue groups on page extensions is not supported.
Snippet support
Typing the shortcut tpageext will create the basic layout for a page extension object when using the AL
Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Views
Views in Dynamics 365 Business Central are used on list pages to define a different view of the data on a given
page. Views can be defined for Pages, Page Extensions, and Page Customization. For more information, see
Views.
K EY W O RDS SY N TA X A P P L IES TO
Example
To modify the existing fields and groups on a page, you use the modify keyword. See the code snippet below
for addlast , modify and action syntax. In the following example, the actions section creates a new group in
the ribbon and places it last in the Creation group.
pageextension 70000020 CustomerCardExtension extends "Customer Card"
{
layout
{
// Adding a new control field 'ShoeSize' in the group 'General'
addlast(General)
{
field("Shoe Size"; ShoeSize)
{
Caption = 'Shoe size';
trigger OnValidate();
begin
if (ShoeSize < 10) then
Error('Feet too small');
end;
}
}
trigger OnAction();
begin
Message('My message');
end;
}
}
}
}
}
trigger OnValidate();
begin
if (rec.ShoeSize < 0) then
begin
message('Shoe size not valid: %1', rec.ShoeSize);
end;
end;
}
}
trigger OnBeforeInsert();
begin
if not HasShoeSize then
ShoeSize := Random(42);
end;
}
trigger OnValidate();
begin
if (ShoeSize < 10) then
Error('Feet too small');
end;
}
// display-only control (without underlying datasource)
field(ShoesInStock; 10)
{
ApplicationArea = All;
Caption = 'Shoes in stock';
}
}
modify("Address 2")
{
Caption = 'New Address 2';
}
}
actions
{
{
addlast(Creation)
{
group(MyActionGroup)
{
Action(MyAction1)
{
ApplicationArea = All;
Caption = 'Hello!';
trigger OnAction();
begin
Message('My message');
end;
}
Action(MyAction2)
{
ApplicationArea = All;
You can reference Report and XMLPort objects and use these objects in the RunObject property, as well as,
declare variables of the types Repor t and XMLPor t and call AL methods on them. This page extension object
extends the Customer List page object by adding two actions; the first action calls the Customer - List report,
the second action calls the Expor t Contact XMLPort.
See Also
Page Object
Views
Page, Page Fields, and Page Extension Properties
Extending Pages Previously Based on the Date Virtual Table Developing Extensions
AL Development Environment
Page Customization Object
2/6/2023 • 2 minutes to read • Edit Online
The page customization object in Dynamics 365 Business Central allows you to add changes to the layout and
actions on page that are accessible for a profile. See Using keywords to place actions and controls for how to
place actions and controls on a page customization object.
The page customization object has more restrictions than the page extension object; when you define a new
page customization object, you cannot add variables, procedures, or triggers.
NOTE
A single page customization can be used with multiple profiles within the same extension. Page customizations only apply
to the RoleCenters they are specified for. In order to view or changes the RoleCenters in the client, go to My Settings >
Role Center .
NOTE
Extension objects can have a name with a maximum length of 30 characters.
NOTE
Modifying actions in Cue groups on page extensions is not supported.
NOTE
The property allowDebugging , which is a setting under resourceExposurePolicy does not apply to page
customizations. Page customizations defined in an extension with allowDebugging set to false can still be copied
using Designer. For more information, see Resource Exposure Policy Setting.
Snippet support
Typing the shortcut tpagecust will create the basic layout for a page customization object when using the AL
Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Views
Views in Dynamics 365 Business Central are used on list pages to define a different view of the data on a given
page. Views can be defined for Pages, Page Extensions, and Page Customization. For more information, see
Views.
Page customization example
The following page customization example MyCustomization makes changes to Customer List . By using the
moveafter method, Blanket Orders is moved after the Orders action item. And the modify method is used to
hide the NewSalesBlanketOrder action item.
profile TheBoss
{
Description = 'The Boss';
RoleCenter = "Business Manager Role Center";
Customizations = MyCustomization;
Caption = 'Boss';
}
modify(NewSalesBlanketOrder)
{
Visible = false;
}
}
}
You can use the same page customization on another profile within the same extension package by referencing
its name from the profile definition, for example:
profile TheSalesman
{
ProfileDescription = 'The Boss';
RoleCenter = "Sales Manager Role Center";
Customizations = MyCustomization;
Caption = 'Salesman';
}
See Also
Developing Extensions
AL Development Environment
Page Object
Page Extension Object
Views
Page, Page Fields, and Page Extension Properties
Report Object
2/6/2023 • 4 minutes to read • Edit Online
Reports are used to print or display information from a database. You can use a report to structure and
summarize information, and to print documents, such as sales quotes and invoices.
Creating a report consists of two primary tasks; the first task is to create the underlying data model and the next
is to define the visual layout that displays the data. The report object defines the underlying data model and
specifies which database tables and fields to pull data from. When the report is run, that data is displayed in a
specified layout; the visual layout, which determines the content and format of a report when it's viewed and
printed.
For more information about defining database tables and fields, see Defining a Report Dataset. For more
information about the Report data type, see Report Data Type.
You build the layout of a report by arranging data items and columns, and specifying the general format, such as
text font and size. There are three types of report layouts; client report definition, also called RDL layouts, Word
layouts, and Excel layouts. RDL layouts are defined in Visual Studio Report Designer or Microsoft SQL Server
Reporting Services Report Builder. Word layouts are created using Word. Word layouts are based on a Word
document that includes a custom XML part representing the report dataset. Excel layouts are created in Excel
based on the report dataset, utilizing the Excel capabilities such as sliders, diagrams, charts, pivot tables, and
PowerQuery. One report can contain multiple report layout definitions. For more information, see Defining
Multiple Report Layouts.
If you want to modify an existing report, for example, add new columns, add to the request page, or add a new
layout, you can create a report extension instead. For more information, see Report Extension Object.
TIP
It is possible to use a query object as the data source for a report. This can in many cases improve the performance of
data retrieval when running the report.
Snippet support
Typing the shortcut treport will create the basic layout for a report object when using the AL Language
extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Report example
The following example is a report that prints the list of customers. The report object defines a dataset of
columns from the Customer table. This example defines a report that uses an RDL report layout. For more
information about creating an RDL report layout, see Creating an RDL Layout Report. For more information on
creating a report that uses Word Layout, see Creating a Word Layout Report. For information about creating an
Excel layout, see Creating an Excel Layout Report.
report 50103 "Customer List"
{
CaptionML=ENU='Customer List';
DefaultLayout = RDLC; // if Word use WordLayout property
RDLCLayout = 'MyRDLReport.rdl';
dataset
{
dataitem(Customer;Customer)
{
RequestFilterFields="No.","Search Name","Customer Posting Group";
column(CompanyName;CompanyName)
{
}
column(CurrReport_PageNo;Customer."no.")
{
}
column(Customer_TableCaption_CustFilter;TableCaption + ': ' + CustFilter)
{
}
column(CustFilter;CustFilter)
{
}
column(Customer_No;"No.")
{
}
column(Customer_Customer_Posting_Group;"Customer Posting Group")
{
}
column(Customer_Customer_Disc_Group;"Customer Disc. Group")
{
}
column(Customer_Invoice_Disc_Code;"Invoice Disc. Code")
{
}
column(Customer_Customer_Price_Group;"Customer Price Group")
{
}
column(Customer_Fin_Charge_Terms_Code;"Fin. Charge Terms Code")
{
}
column(Customer_Payment_Terms_Code;"Payment Terms Code")
{
}
column(Customer_Salesperson_Code;"Salesperson Code")
{
}
column(Customer_Currency_Code;"Currency Code")
{
}
column(Customer_Credit_Limit_LCY;"Credit Limit (LCY)")
{
DecimalPlaces=0:0;
}
column(Customer_Balance_LCY;"Balance (LCY)")
{
}
column(CustAddr_1;CustAddr[1])
{
}
column(CustAddr_2;CustAddr[2])
{
}
column(CustAddr_3;CustAddr[3])
{
}
column(CustAddr_4;CustAddr[4])
{
}
}
column(CustAddr_5;CustAddr[5])
{
}
column(Customer_Contact;Contact)
{
}
column(Customer_Phone_No;"Phone No.")
{
}
column(CustAddr_6;CustAddr[6])
{
}
column(CustAddr_7;CustAddr[7])
{
}
column(Customer_ListCaption;Customer_ListCaptionLbl)
{
}
column(CurrReport_PageNoCaption;CurrReport_PageNoCaptionLbl)
{
}
column(Customer_NoCaption;FieldCaption("No."))
{
}
column(Customer_Customer_Posting_GroupCaption;Customer_Customer_Posting_GroupCaptionLbl)
{
}
column(Customer_Customer_Disc_GroupCaption;Customer_Customer_Disc_GroupCaptionLbl)
{
}
column(Customer_Invoice_Disc_CodeCaption;Customer_Invoice_Disc_CodeCaptionLbl)
{
}
column(Customer_Customer_Price_GroupCaption;Customer_Customer_Price_GroupCaptionLbl)
{
}
column(Customer_Fin_Charge_Terms_CodeCaption;FieldCaption("Fin. Charge Terms Code"))
{
}
column(Customer_Payment_Terms_CodeCaption;Customer_Payment_Terms_CodeCaptionLbl)
{
}
column(Customer_Salesperson_CodeCaption;FieldCaption("Salesperson Code"))
{
}
column(Customer_Currency_CodeCaption;Customer_Currency_CodeCaptionLbl)
{
}
column(Customer_Credit_Limit_LCYCaption;FieldCaption("Credit Limit (LCY)"))
{
}
column(Customer_Balance_LCYCaption;FieldCaption("Balance (LCY)"))
{
}
column(Customer_ContactCaption;FieldCaption(Contact))
{
}
column(Customer_Phone_NoCaption;FieldCaption("Phone No."))
{
}
column(Total_LCY_Caption;Total_LCY_CaptionLbl)
{
}
trigger OnAfterGetRecord();
begin
CalcFields("Balance (LCY)");
FormatAddr.FormatAddr(
CustAddr,Name,"Name 2",'',Address,"Address 2",
CustAddr,Name,"Name 2",'',Address,"Address 2",
City,"Post Code",County,"Country/Region Code");
end;
}
}
requestpage
{
SaveValues=true;
ContextSensitiveHelpPage = 'my-feature';
layout
{
}
actions
{
}
}
labels
{
LabelName = 'LabelText', Comment = 'Foo', MaxLength = 999, Locked = true;
}
trigger OnPreReport();
var
CaptionManagement : Codeunit 42;
begin
CustFilter := CaptionManagement.GetRecordFiltersWithCaptions(Customer);
end;
var
FormatAddr : Codeunit 365;
CustFilter : Text;
CustAddr : ARRAY [8] OF Text[50];
Customer_ListCaptionLbl : Label 'Customer - List';
CurrReport_PageNoCaptionLbl : Label 'Page';
Customer_Customer_Posting_GroupCaptionLbl : Label 'Customer Posting Group';
Customer_Customer_Disc_GroupCaptionLbl : Label 'Cust./Item Disc. Gr.';
Customer_Invoice_Disc_CodeCaptionLbl : Label 'Invoice Disc. Code';
Customer_Customer_Price_GroupCaptionLbl : Label 'Price Group Code';
Customer_Payment_Terms_CodeCaptionLbl : Label 'Payment Terms Code';
Customer_Currency_CodeCaptionLbl : Label 'Currency Code';
Total_LCY_CaptionLbl : Label 'Total (LCY)';
}
TIP
From the Business Central client, you can export report results as raw data to a Microsoft Excel file. The file contains all
columns of the dataset, but without the layout applied. Use the file to help validate that the report returns the expected
data, and to ensure that the report layout controls match the dataset value types. To export a report, run the report and
select the Send to > Microsoft Excel Document (data only) on the request page. For more information, see
Working with Reports - Send to Excel.
Schedule reports
It's possible to schedule a report to run at your desired date and time by using AllowScheduling property. By
setting the property to true, you'll get the Schedule action button to set the date and time for your report. To
learn more about scheduling a report, see AllowScheduling Property and Schedule a report.
See also
Report Extension Object
Request Pages
Report Properties
Creating an RDL Layout Report
Creating a Word Layout Report
Adding Help Links from Pages, Reports, and XMLports
Page Extension Object
Page Properties
Developing Extensions
AL Development Environment
Profile Object
2/6/2023 • 2 minutes to read • Edit Online
The profile object in Dynamics 365 Business Central allows you to build an individual experience for each user
profile. The Profile object performs a validation to check whether the specified role center page exists, and page
customization objects exists, when you define a new profile object. On a page customization you can add
changes to the page layout, and actions; but you cannot add variables, procedures, or triggers.
NOTE
Page customizations only apply to the RoleCenter they are specified for. In order to see them, in Dynamics 365 Business
Central under My Settings , Role Center change to the specific RoleCenter that a page customization is defined for.
NOTE
Extension objects can have a name with a maximum length of 30 characters.
NOTE
The property allowDebugging , which is a setting under resourceExposurePolicy does not apply to page
customizations. Page customizations defined in an extension with allowDebugging set to false can still be copied
using Designer. For more information, see Resource Exposure Policy Setting.
Snippet support
Typing the shortcut tprofile will create the basic layout for a profile object when using the AL Language
extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Profile example
The following profile object example creates a profile for the MyRoleCenter Role Center, which is available in the
Role Explorer in the UI and available to end-users. The profile also depends on the customization
MyCustomization and modifies the layout of the Customer List to make the Name field invisible using the
modify method. For more information, see Profile Properties.
profile MyProfile
{
Description = 'Some internal comment that only the Dev can see';
Caption = 'My User-friendly Name';
ProfileDescription = 'A detailed description of who is this profile for, why/how to use it (etc)';
RoleCenter = MyRoleCenter;
Enabled = true;
Promoted = true;
Customizations = MyCustomization;
}
See Also
AL Development Environment
Developing Extensions
Pages Overview
Page Customization Object
Codeunit Object
2/6/2023 • 2 minutes to read • Edit Online
A codeunit is a container for AL code that you can use in many application objects. You typically implement
business logic in codeunits and call the codeunit from the object that needs to perform that specific logic.
Snippet support
Typing the shortcut tcodeunit will create the basic layout for a codeunit object when using the AL Language
extension in Visual Studio Code.
Codeunit example
This codeunit example checks whether a given customer has registered a shoe size. If not, the customer is
assigned a shoe size of 42.
The codeunit can be used both as a direct call to codeunit.run(customer) or as a call to the procedure inside the
codeunit createcustomer.CheckSize(customer) .
See Also
Developing Extensions
Table Extension Object
Page Extension Object
AL Development Environment
XML Comments in Code
Query Object
2/6/2023 • 4 minutes to read • Edit Online
Business Central query objects enable you to retrieve records from one or more tables and then combine the
data into rows and columns in a single dataset. Query objects can also perform calculations on data, such
finding the sum or average of all values in a column of the dataset.
There are two types of query objects: normal and API. This article describes normal query objects, which can be
used to display data in the user interface. API query objects are used to generate web service endpoints and
cannot be displayed in the user interface. For information about creating a query of the type API, see API Query
Type.
Dataitem links and joins determine which records to include in the dataset based on the values of a
common field between dataitems. You set a link between one or more fields of the dataitem tables with
the DataItemLink Property and you define the type of the link using the SQLJoinType Property. Both
properties must be set on the lower dataitem of the query object. For more information, see Linking and
Joining Data Items.
The following shows the basic structure of a query object.
query ID Name
{
elements
{
dataitem(DataItem1; Table1)
{
column(Column1; Field1)
{
}
column(Column2; Field2)
{
}
dataitem(DataItem2; Table2)
{
// Sets a link between FieldY of Table2 and FieldX of Table1.
DataItemLink = FieldY = DataItem1.FieldX;
//The dataset contains records from Table1 and Table2 where a match is found between FieldY
and FieldX.
SqlJoinType = InnerJoin;
column(Column1; Field1)
{
}
dataitem(DataItem3; Table3)
{
DataItemLink = FieldZ = DataItem2.FieldY;
SqlJoinType = InnerJoin;
column(Column1; Field1)
{
}
}
}
}
}
}
NOTE
Extension objects can have a name with a maximum length of 30 characters.
Snippet support
Typing the shortcut tquery will create the basic layout for a Query object when using the AL Language
extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Query example
The following example shows a query that displays a list of customers with sales and profit figures. The query
primarily retrieves fields from the Customer table, but also displays fields from the Salesperson Purchaser
and Countr y Region tables.
The query also uses the DataItemLink property to create a link between the Customer table, Salesperson
Code field and the Salesperson Purchaser table, Code fields and a link between the Customer table,
Countr y/Region Code field and the Countr y/Region table, Code field.
DataAccessIntent = ReadOnly; // use this to read data from the secondary database replica to speed up
performance
elements
{
dataitem(Customer; Customer)
{
column(Name; Name)
{
}
column(No; "No.")
{
}
column(Sales_LCY; "Sales (LCY)")
{
}
column(Profit_LCY; "Profit (LCY)")
{
}
column(Country_Region_Code; "Country/Region Code")
{
}
column(City; City)
{
}
column(Global_Dimension_1_Code; "Global Dimension 1 Code")
{
}
column(Global_Dimension_2_Code; "Global Dimension 2 Code")
{
}
column(Salesperson_Code; "Salesperson Code")
{
}
dataitem(Salesperson_Purchaser; "Salesperson/Purchaser")
{
DataItemLink = Code = Customer."Salesperson Code";
column(SalesPersonName; Name)
{
}
dataitem(Country_Region; "Country/Region")
{
DataItemLink = Code = Customer."Country/Region Code";
column(CountryRegionName; Name)
{
}
}
}
}
}
}
IMPORTANT
You cannot run a query that gets data from both the application database and the business data database. This also
applies to single-tenant deployments so that you do not have to rewrite queries if you decide to export the application.
For a description of which tables are considered part of the application database, see Separating Application Data from
Business Data.
See Also
Linking and Joining Data Items
Aggregating Data in Query Objects
Query Objects and Performance
Query Properties
Query DataAccessIntent
Developing Extensions
AL Development Environment
API Query Type
XMLport Object
2/6/2023 • 2 minutes to read • Edit Online
XMLports are used to export and import data between an external source and Dynamics 365 Business Central.
Sharing data between different computer systems is seamless when it is shared in an XML format. Working with
XML files can be tedious so the details of how the XML file is handled are encapsulated in XMLports.
To use an XMLport to import or export data, you first create an XMLport object. Once created, you can run the
XMLport from a page or codeunit object.
You can design XMLports to include a request page, which is a dialog box that enables the user to set a filter on
the data, sort the data, or choose whether to export or import the data. For more information about request
pages, see Request Pages.
XMLport example
The following example shows a page extension of the Permission Sets page that adds an action to the
specified page calling the XMLport Expor tPermissionSet . The XMLport exports the permission set data to an
XML file.
schema
{
textelement(PermissionSets)
{
tableElement(PSet; "Aggregate Permission Set")
{
SourceTableView = WHERE ("App Name" = FILTER (<> ''));
XmlName = 'PermissionSet';
fieldattribute(RoleID; pset."Role ID") { }
fieldattribute(RoleName; pset.Name) { }
tableelement(P; "Tenant Permission")
{
XmlName = 'Permission';
LinkTable = pset;
LinkFields = "Role ID" = FIELD ("Role ID");
textelement(ObjectType)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Object Type";
ObjectType := format(int);
end;
}
textelement(ObjectID)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Object ID";
ObjectID := format(int);
end;
}
textelement(ReadPermission)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Read Permission";
ReadPermission := format(int);
end;
}
textelement(InsertPermission)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Insert Permission";
InsertPermission := format(int);
end;
}
textelement(ModifyPermission)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Modify Permission";
ModifyPermission := format(int);
end;
}
textelement(DeletePermission)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Delete Permission";
DeletePermission := format(int);
end;
}
textelement(ExecutePermission)
{
trigger onbeforePassvariable();
var
int: Integer;
begin
int := p."Execute Permission";
ExecutePermission := format(int);
end;
end;
}
textelement(SecurityFilter)
{
trigger onbeforePassvariable();
begin
SecurityFilter := format(p."Security Filter");
end;
}
}
}
}
}
}
See Also
Developing Extensions
AL Development Environment
XMLport Overview
Using Namespaces with XMLports
Page Extension Object
Report Object
Control Add-In Object
2/6/2023 • 4 minutes to read • Edit Online
The control add-in object allows you to add custom functionality to Dynamics 365 Business Central. A control
add-in is a custom control, or visual element, for displaying and modifying data within an iframe or a page. For
example, a control add-in can display the content of a webpage, visualize data as a chart or on a map, or host a
custom web application. Control add-ins can exchange data with the Dynamics 365 server on various data types
and respond to user interaction to raise events that execute additional AL code.
// The procedure declarations specify what JavaScript methods could be called from AL.
// In main.js code, there should be a global function CallJavaScript(i,s,d,c)
{Microsoft.Dynamics.NAV.InvokeExtensibilityMethod('CallBack', [i, s, d, c]);}
procedure CallJavaScript(i: integer; s: text; d: decimal; c: char);
// The event declarations specify what callbacks could be raised from JavaScript by using the webclient
API:
// Microsoft.Dynamics.NAV.InvokeExtensibilityMethod('CallBack', [42, 'some text', 5.8, 'c'])
event Callback(i: integer; s: text; d: decimal; c: char);
}
ApplicationArea = All;
// The control add-in events can be handled by defining a trigger with a corresponding
name.
trigger Callback(i: integer; s: text; d: decimal; c: char)
begin
Message('Got from js: %1, %2, %3, %4', i, s, d, c);
end;
}
}
}
actions
{
area(Creation)
{
action(CallJavaScript)
{
ApplicationArea = All;
trigger OnAction();
begin
// The control add-in methods can be invoked via a reference to the usercontrol.
CurrPage.ControlName.CallJavaScript(5, 'text', 6.3, 'c');
end;
}
}
}
}
$.get(url).done(function(response) { } );
Correct:
$.ajax({
url: url,
xhrFields: {
withCredentials: true
}
)).done(function(data) {
$("#controlAddIn").text(data);
});
See Also
AL Development Environment
Developing Extensions
Asynchronous Considerations for Control Add-ins
Control Add-In Best Practices
InvokeExtensibility Method
GetImageResource Method
GetEnvironment Method
Pages Overview
Page Extension Object
Page Customization Object
Entitlement Object
2/6/2023 • 2 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
The entitlement object in Business Central describes which objects in Business Central a customer is entitled to
use according to the license that they purchased or the role that they have in AAD.
An entitlement consists of a number of PermissionSet Objects put together to constitute a set of meaningful
permissions for a user. An entitlement can only include permission set objects which reference the objects that
are included within the same app. This is to ensure that the entitlements included with one app cannot alter or
redefine the entitlements included with another app.
Entitlements can only be used with the online version of Business Central.
NOTE
In the current version of Business Central entitlements can only be included with Microsoft apps (enforced by the
AppSource cop rules and the technical validation checks that we run for the apps submitted to AppSource). These objects
will become available for the ISV apps when we introduce ability to monetize AppSource apps in one of our future
releases.
Snippet support
Typing the shortcut tentitlement will create the basic layout for an entitlement object when using the AL
Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
Entitlement examples
This example illustrates a simple entitlement object with the Type property set to Role , which means that the is
entitlement is associated with an AAD role. When Type is set to Role , the RoleType property is used to
distinguish between local and delegated assignments of the role, in this case it is Delegated . The
ObjectEntitlements property defines the list of permissions that the entitlement includes.
entitlement BC_Role_Delegated
{
Type = Role;
RoleType = Delegated;
Id = '1a2aaaaa-3aa4-5aa6-789a-a1234567aaaa';
ObjectEntitlements =
”D365 BUS PREMIUM - BaseApp”;
}
See Also
Developing Extensions
AL Development Environment
Entitlements and Permission Set Overview
Permission Set Extension Object
Permission Set Object
2/6/2023 • 2 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
The permission set object in Business Central describes permissions on objects. Permission sets are building
blocks used to compose assignable permission sets and entitlements. Assignable permission sets are
permissions that an admin can assign to users in Business Central, using the Permission Sets page. An
entitlement is a collection of permission sets that constitute a set of meaningful permissions for a user.
Some permission sets can be non-assignable, meaning that they aren't discoverable and assignable in the UI in
Business Central, instead they can be used as building blocks to compose functional assignable permission sets.
For information about which permissions can be assigned to objects, see Permissions on Database Objects.
Snippet support
Typing the shortcut tpermissionset will create the basic layout for a permission set object when using the AL
Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
When adding new AL objects, it's easy to forget to update the permissions. With the
al.generatePermissionSetForExtensionObjects command, you can generate or update a permission file for the
active project in Visual Studio Code. Choose to create a new permission file or select an existing file to make
updates to. For more information, see AL Language Extension Configuration.
Permissions =
tabledata Customer = RIMD,
tabledata "Payment Terms" = RMD,
tabledata Currency = RM,
tabledata "Sales Header" = RIM,
tabledata "Sales Line" = RIMD;
}
The following example of a permission set illustrates assigned permissions to run codeunits. With the
IncludedPermissionSets property, we specify that the permission set Sales Person is also included in
MyPermissionSet .
permissionset50135MyPermissionSet
{
Assignable = true;
Caption = 'My PermissionSet';
IncludedPermissionSets= "Sales Person";
Permissions=
tabledataVendor=RIm,
codeunit SomeCode =x,
codeunit AccSchedManagement=X;
}
You can also use the ExludedPermissionSets property to exclude permissions defined in other permission sets.
To learn more, see Composing Permission Sets From Other Permission Sets.
See Also
Developing Extensions
AL Development Environment
Entitlements and Permission Set Overview
Permission Set Extension Object
Permissions on Database Objects
Assignable Property
IncludedPermissionSets
Permissions Property
Permission Set Extension Object
2/6/2023 • 2 minutes to read • Edit Online
APPLIES TO: Business Central 2021 release wave 1 (v18.0) and later
The permission set extension object in Business Central adds permissions to an existing permission set defined
in AL. A permission set extension object cannot remove permissions from an existing permission set, it can only
add permissions. If you, for example, add an extension to Business Central, you can use permission set extension
objects to grant permissions to the objects in your extension. This means that the admin of Business Central
does not have to assign additional permission sets to the users, because that automatically happens when the
extension is installed, and the permissions go away if the extension is uninstalled.
For information about which permissions can be assigned to objects, see Permissions on Database Objects.
Snippet support
Typing the shortcut tpermissionsetextension will create the basic layout for a permission set extension object
when using the AL Language extension in Visual Studio Code.
TIP
Use Ctrl+Space to trigger IntelliSense and get assistance on code completion, parameter info, quick info, and member
lists.
See Also
Developing Extensions
AL Development Environment
Entitlements and Permission Set Overview
Permission Set Object
Permissions on Database Objects
Assignable Property
Permissions Property
AL Platform Overview
2/6/2023 • 2 minutes to read • Edit Online
This section introduces the different parts of the AL platform that are available for extension developers who
want to extend the business functionality of Business Central.
Platform capabilities
Business Central comes with a rich platform of system modules and capabilities that you can leverage in your
extensions. Getting familiar with the modules in the Business Central system application might save you a lot of
time as it contains implementations of many generic tasks you might need. For more information, see Overview
of the System Application.
Learning how to start background sessions using the task scheduler and job queues can help you offload work
from UI sessions. For more information, see Task Scheduler.
Instrumenting your extension using feature telemetry and custom telemetry can help you monitor the extension
after it has been deployed to production. For more information, see Creating Custom Telemetry Events.
See Also
Overview of the System Application
Task Scheduler
Job Queue
Using Azure Key Vaults for Secrets
Creating Custom Telemetry Events
Add Feature Usage Telemetry
Creating a Printer Extension
Getting started with Microsoft .NET Interoperability from AL (on-premises only)
Overview of the System Application
2/6/2023 • 4 minutes to read • Edit Online
The System Application contains modules that interact with the Dynamics 365 Business Central platform and
online ecosystem to support the business logic in the Base Application. If you are developing extensions or add-
ons for Dynamics 365 Business Central, you will probably need to use one or more of the objects in the
modules.
This topic provides an overview of the modules in the System Application. For more details about each module,
and to get a look at the code, choose the ReadMe link for the module to visit our ALAppExtensions repository
on GitHub.
NOTE
The modules in the System Application represent a significant change in what's happening under the hood in Dynamics
365 Business Central. We are aware that the changes we have made will introduce breaking changes, so we have made a
list of those that we know about, which includes suggestions for solutions. To view the breaking changes list, see Breaking
Changes.
We will continue to enhance the System Application in future releases. If you find something you think we should add,
visit our Dynamics 365 Application Ideas page. If you want us to improve something, go to the ALAppExtensions
repository and submit a pull request for it.
Note
Azure Active Directory Graph is being
retired, and we recommend that you
start using Microsoft Graph instead. To
avoid causing issues with apps that
use the Azure AD Graph module in
Business Central, we haven't changed
its name or the names of the objects it
contains. For more information about
the Azure Active Directory Graph
retirement, see Migrate Azure AD
Graph apps to Microsoft Graph.
Azure Key Vault Stores Azure Key Vault secrets for ReadMe
deployments.
User Log-In Times Keeps track of when users sign in. ReadMe
See Also
ALAppExtensions
Module Architecture
2/6/2023 • 5 minutes to read • Edit Online
Though the internal architecture of modules can, and most likely will, differ, there are rules that ensure
consistency and reliability in the architecture of application modules. To reduce coupling and increase
consistency, every module is a separate entity that has a publicly accessible facade, while the internal
implementation is not public, as shown in the following image:
Dependencies
Dependencies to other modules can only be taken to modules in the same functional layer or to lower layers.
For example, a module in the Core Application can only take dependencies to modules in the Core Application
or System Application, but never to extensions.
Target Environment
Every module must initially target the most restrictive environment, which is the cloud environment. If unsafe
operations are required, those should result in a System Application module where the unsafe operations are
wrapped with safe APIs. That is done by setting the Target to OnPrem . Modules in layers above the System
Application must have Target set to Cloud in the app.json file.
Object Accessibility
Only facade codeunits, pages, and tables required in the public API of the module can be accessible. Internal
implementation details must be marked as such by setting the access modifier to Internal, i.e. entities can be
accessed within the module but cannot be called from outside the module.
Facade Codeunits
Every module must have a facade that meets the following rules:
Access must be Public . It should be set explicitly to emphasize that this is a facade or an API-like codeunit
that exposes the core functionality in the module.
All integration and business event publishers must be in the facade as internal functions. This prevents them
from being invoked outside the module.
Event publishers should be marked as internal. Exceptions must be documented.
All external methods go in the facade.
Facades cannot contain logic or local functions.
Because the facade is the codeunit that other modules reference, it should have a short, meaningful name.
Internal implementation codeunits can be suffixed with “Impl,” for example, because they are not referenced
outside the module.
Business Logic
Implementation codeunits contain the business logic. Pages and tables can contain code, but should do so only
when it's absolutely required.
Extensibility
Extensibility must be thought into the internal implementation of every module. If a module should not be
extensible, the Extensibility property on tables, pages, and enums must be set to False to prevent those
objects from being extended.
Functions and fields in extensible tables and pages must have an access modifier, as described in the following
table.
Internal Accessed only by code in the same module, but not from
another module.
Documentation
Every publicly accessible object must be documented. For more information, see Documentation.
Tests
Every module’s public API must be tested according to Microsoft standards. For more information, see Testing.
Single Instance
Use single instance only when it’s required, or if the module is expected to be called frequently.
.NET
If a .NET type is an integral part of the module and is not referenced elsewhere, the alias for that type must be
defined in the module. If the .NET type is used in different modules, then the alias for it must be defined in the
DotNet Aliases module.
Project Setup
Every module begins with a project setup that includes the following:
Module Name : If the module represents an entity, name the module after the entity. If the module does not
represent an entity, give it a name that describes what it does. Module names can be singular or plural,
depending on whether they handle one or more entities or tasks.
Location : Determine which layer the module belongs to, and create a subfolder in a folder in that layer. For
example, Modules\System\My Module).
Source Code : Add the source code of the module in a src subfolder. For example, Modules\System\My
Module\src).
Testing
Every module must be tested through a separate test module. Only public functions that are exposed through
the facade, or other public objects such as pages, tables, xmlports, and queries, are tested by the test module.
The test module should have the same name as the module it tests, but be placed in a separate layer/package
that contains tests for all modules in the layer. For example, Modules\System Tests \My Module). Test code
cannot reside in the same layer folder structure as the module, or within the module, because it must not be
executable or part of a production environment.
Documentation Guidelines
It's important that you document your module. The following sections provide some guidelines.
Modules
The app.json file for each module must contain a user-friendly title, a short brief, and a description that states its
purpose.
Public API
Every publicly accessible object must have developer facing documentation that follows the XML documentation
comments standard.
Public Objects
Public objects, such as codeunits, tables, pages, and so on, must have a summary that states what the object is
used for.
/// <summary>
/// Lorem ipsum dolor sit amet, consectetur adipiscing elit.
/// </summary>
Public Functions
Public functions must have a summary, a parameter description, and a return value description. The following is
an example.
/// <summary>
/// Maecenas sodales posuere ligula eu maximus.
/// </summary>
/// <param name="Lorem">The current language ID</param>
/// <param name="ipsum ">The CaptionClass expression to resolve</param>
/// <returns> Fusce in tristique massa, tincidunt tempor libero.</returns>
See Also
Getting Started with Modules
Create a New Module in the System Application
Module Architecture
Get Started with Modules in the System Application
2/6/2023 • 2 minutes to read • Edit Online
This topic provides information about requirements for working with modules in the System Application.
AL
Get familiar with development in AL. For more information, see Get Started with AL.
Git
Familiarize yourself with Git. For a quick introduction, see git - the simple guide.
Setup Environment
For details about how to set up an environment for AL development, see Set up your environment.
Have an issue?
Please open an issue.
See Also
Module Architecture
Create a module
Set Up an Environment for Developing a Module
2/6/2023 • 3 minutes to read • Edit Online
This topic describes how to set up an environment for developing a module in the System Application.
Requirements
You must have a GitHub account.
You are familiar with the basics of Git, and have the application available. You will use Git to access the
GitHub repository.
Docker is installed. You will use it to run Business Central as a self-contained application.
BcContainerHelper is installed. You will use it to create a Docker container.
Demo or Partner license for Business Central
"al.assemblyProbingPaths": [
"C:/Windows/Microsoft.NET/Framework64/v4.0.30319",
"C:/bcartifacts.cache/onprem/19.0.29894.30693",
"C:/WINDOWS/assembly"
],
For more information about the settings.json, see User and Workspace Settings.
$containerName = 'mydemo'
$password = 'P@ssw0rd'
$securePassword = ConvertTo-SecureString -String $password -AsPlainText -Force
$credential = New-Object pscredential 'admin', $securePassword
$auth = 'UserPassword'
$artifactUrl = Get-BcArtifactUrl -type 'OnPrem' -country 'w1' -select 'Latest'
$licenseFile = '<Path to license file>'
New-BcContainer -accept_eula `
-containerName $containerName `
-credential $credential `
-auth $auth `
-artifactUrl $artifactUrl `
-includeTestToolkit `
-includeTestLibrariesOnly `
-licenseFile $licenseFile `
-includeAL -doNotExportObjectsToText `
-updateHosts
NOTE
If you copy the script, remember to update the path to the license file ($licenseFile). Also, if you are using a demo
license, remove the -includeTestToolkit and -includeTestLibrariesOnly options.
5. Run the script to create the Docker container. This can take some time if you are running it for the first
time.
See Also
Getting Started with Modules
Create a New Module in the System Application
Module Architecture
Create a New Module in the System Application
2/6/2023 • 4 minutes to read • Edit Online
This topic provides an overview of how to create a new module in the System Application.
Requirements
1. Familiarity with development in AL. For more information, see AL Development.
2. Your development environment is ready. For more information, see Set Up an Environment for Developing a
Module.
NOTE
Your environment must have the correct symbols. Go get those, in Visual Studio Code, press F1 , and then choose AL:
Download Symbols . Also, make a note of the ser ver and ser verInstance settings. You will add that information to
the launch.json file.
"server": "http://YourDockerContainerName",
"serverInstance": "BC",
"authentication": "UserPassword",
Open the settings.json file, and update the al.assemblyProbingPaths , as described in Set Up a Development
Environment.
Create a Branch
To create a branch, run the git checkout -b "YourFeatureBranchName" command. Afterward, you can start
creating a new module.
Add the New Module
Before you create a new module, make sure you are familiar with the general architecture of system modules.
For more information, see Module Architecture.
We'll start by creating a new folder named XmlWriter in the System folder, where we will add an app.json file.
The app.json file will contain the general details of the module.
{
"id": "215b484f-9fbf-437c-bc6e-67e2c0f283b0",
"name": "XMLWriter",
"publisher": "Microsoft",
"brief": "Write XML quickly with System.Xml.XmlTextWriter.",
"description": "Provides a fast, non-cached, forward-only way to create streams or files with XML
data that conforms to guidelines for W3C Extensible Markup Language (XML) 1.0 and Namespaces.",
"version": "17.0.0.0",
"privacyStatement": "https://go.microsoft.com/fwlink/?linkid=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
"help": "https://go.microsoft.com/fwlink/?linkid=2103698",
"url": "https://go.microsoft.com/fwlink/?linkid=724011",
"logo": "",
"dependencies": [
{
"id": "7e3b999e-1182-45d2-8b82-d5127ddba9b2",
"name": "DotNet Aliases",
"publisher": "Microsoft",
"version": "17.0.0.0"
}
],
"screenshots": [],
"platform": "17.0.0.0",
"idRanges": [
{
"from": 1483,
"to": 1484
}
],
"target": "OnPrem",
"contextSensitiveHelpUrl": "/dynamics365/business-central/"
}
NOTE
After we finish developing our module, we will need to update the app.json file to ensure that the versions and
idRanges are correct. We can easily verify the version by checking the app.json in other modules in the System
Application. The idRanges must reflect the IDs used in the module.
Next, create the src folder under System/XmlWriter . This folder will contain our source code. We will create an
internal implementation codeunit named XmlWriterImpl.Codeunit.al in the src folder.
After adding the implementation functions, the implementation codeunit will look as follows.
codeunit 1484 "XmlWriter Impl"
{
Access = Internal;
procedure WriteStartDocument()
begin
StringBuilder := StringBuilder.StringBuilder();
StringWriter := StringWriter.StringWriter(StringBuilder);
XmlTextWriter := XmlTextWriter.XmlTextWriter(StringWriter);
XmlTextWriter.WriteStartDocument();
end;
procedure WriteEndDocument()
begin
XmlTextWriter.WriteEndDocument();
end;
var
StringBuilder: DotNet StringBuilder;
StringWriter: DotNet StringWriter;
XmlTextWriter: DotNet XmlTextWriter;
}
Now that we have created our implementation codeunit, we must add public functions in a facade codeunit with
the functionality that we want to expose. Because the functions are public, we must ensure that these are tested
and documented. To do this, we need to create a facade codeunit. In this example, we'll name the codeunit
XmlWriter.Codeunit.al . The functions call the corresponding functions in the implementation codeunit.
The following is an example of the facade codeunit named XmlWriter.Codeunit.al that includes public
functions and documentation.
/// <summary>
/// Provides helper functions for System.Xml.XmlWriter
/// </summary>
codeunit 1483 "XmlWriter"
{
Access = Public;
/// <summary>
/// Creates the XmlWriter Document
/// </summary>
procedure WriteStartDocument()
begin
XmlWriterImpl.WriteStartDocument();
end;
/// <summary>
/// Closes any open elements or attributes and puts the writer back in the Start state.
/// </summary>
procedure WriteEndDocument()
begin
XmlWriterImpl.WriteEndDocument();
end;
/// <summary>
/// Writes the text within XmlWriter to the BigText variable.
/// </summary>
/// <param name="XmlBigText">The BigText the XmlWriter has to be write to.</param>
procedure ToBigText(var XmlBigText: BigText)
begin
Clear(XmlBigText);
XmlWriterImpl.ToBigText(XmlBigText)
end;
var
XmlWriterImpl: Codeunit "XmlWriter Impl";
}
Now that we have now exposed the functions, the next step is to add tests. To do that, we'll create a new folder
under System Tests , XmlWriter . We will also create an app.json file for the module details and an src folder
for our test code.
We will add the following new file under System Tests/XmlWriter/src , XmlWriterTest.Codeunit.al .
codeunit 139911 "Xml Writer Test"
{
Subtype = Test;
var
Assert: Codeunit "Library Assert";
[Test]
procedure TestWriteStartDocument()
var
XmlWriter: Codeunit "XmlWriter";
XmlBigText: BigText;
begin
// [GIVEN] Initialized XmlWriter
XmlWriter.WriteStartDocument();
[Test]
procedure TestWriteEndDocumentNoElement()
var
XmlWriter: Codeunit "XmlWriter";
begin
// [GIVEN] Initialized XmlWriter with root element
XmlWriter.WriteStartDocument();
See Also
Create a .NET Wrapper Module
Become a Contributor to Business Central
"Git" going with extensions
Walkthrough: Contributing to an extension on GitHub
Getting Started with Modules
Create a New Module in the System Application
Module Architecture
Create a .NET Wrapper Module
2/6/2023 • 4 minutes to read • Edit Online
This topic provides a description of how to contribute a .NET wrapper module to Business Central, using the
Regex module as an example. The Regex module is published in the AlAppExtensions repository, and if you
aren't already familiar with the Regex class in .NET, see the .NET documentation.
var
RegexImpl: Codeunit "Regex Impl.";
/// <summary>
/// Indicates whether the regular expression finds a match in the input string.
/// </summary>
/// <param name="Input">The string to search for a match.</param>
/// <param name="Pattern">A regular expression pattern to match.</param>
/// <returns>True if the regular expression finds a match; otherwise, false.</returns>
procedure IsMatch(Input: Text; Pattern: Text): Boolean
begin
exit(RegexImpl.IsMatch(Input, Pattern));
end;
}
var
DotNetRegex: DotNet Regex;
/// <remark>
/// For more information, visit /dotnet/api/system.text.regularexpressions.match?view=netcore-3.1.
/// </remark>
table 3965 Matches
{
TableType = Temporary;
Extensible = false;
fields
{
field(1; MatchIndex; Integer)
{
Description = 'The index of the match in the table.';
}
field(2; Index; Integer)
{
Description = 'The position in the original string where the first character of the captured
substring is found.';
}
field(3; ValueBlob; Blob)
{
Access = Internal;
Description = 'Gets the captured substring from the input string.';
}
field(4; Length; Integer)
{
Description = 'Gets the length of the captured substring.';
}
field(5; Success; Boolean)
{
Description = 'Gets a value indicating whether the match is successful.';
}
}
}
The temporary table has all the normal table procedures, and can be extended with procedures if needed. Now
we can write the Match objects, output by .NET, to this table.
var
DotNetRegex: DotNet Regex;
DotNetMatchCollection: DotNet MatchCollection;
Avoiding Constructors
The .NET Regex class includes multiple constructors, but we should not expose them in the facade. We can,
however, use constructors internally, as the code previous code example shows.
Removing constructors from a class can cause overloads. One way to get around that is to use the argument-
table pattern. For example, you can construct a temporary table with all optional parameters and internally
implement the logic to apply them.
The .NET Regex class contains three constructors that we want to support:
Regex(Pattern)
Regex(Pattern, RegexOptions)
Regex(Pattern, RegexOptions, MatchTimeout)
In .NET, RegexOptions is an enum with options for matching the pattern (case-sensitivity, ignoring whitespace,
and so on), and MatchTimeout sets a time-out interval for matching. The following example shows how to add
those options to a temporary table.
/// <summary>
/// Table with options to use with Regular Expressions
/// </summary>
table 3966 "Regex Options"
{
Extensible = false;
TableType = Temporary;
fields
{
field(1; IgnoreCase; Boolean)
{
DataClassification = SystemMetadata;
Description = 'Specifies case-insensitive matching.';
}
field(2; Multiline; Boolean)
{
DataClassification = SystemMetadata;
Description = 'Changes the meaning of ^ and $ so they match at the beginning and end
respectively of any line.';
}
...
This temporary table makes it straightforward to add overloads to the facade. For each method, there is one
procedure without an options parameter, and one overload with an options table. The following example
illustrates that for the Match procedure.
/// <summary>
/// Searches the input string for the first occurrence of the specified regular expression, using the
specified matching options.
/// </summary>
/// <param name="Input">The string to search for a match.</param>
/// <param name="Pattern">A regular expression pattern to match.</param>
/// <param name="Match">The Match object to write information about the match to.</param>
procedure Match(Input: Text; Pattern: Text; var Matches: Record Matches)
begin
RegexImpl.Match(Input, Pattern, Matches);
end;
/// <summary>
/// Searches the input string for the first occurrence of the specified regular expression, using the
specified matching options.
/// </summary>
/// <param name="Input">The string to search for a match.</param>
/// <param name="Pattern">A regular expression pattern to match.</param>
/// <param name="RegexOptions">A combination of the enumeration values that provide options for
matching.</param>
/// <param name="Match">The Match object to write information about the match to.</param>
procedure Match(Input: Text; Pattern: Text; var RegexOptions: Record "Regex Options"; var Matches:
Record Matches)
begin
RegexImpl.Match(Input, Pattern, RegexOptions, Matches);
end;
See Also
Module Architecture
Getting Started with Modules in the System Application
Set Up an Environment for Developing a Module
Create a New Module in the System Application
Change a Module in the System Application
Change a Module in the System Application
2/6/2023 • 5 minutes to read • Edit Online
Requirements
1. Familiarity with development in AL. For more information, see AL Development.
2. Your local repository and development environment are ready. For more information, see Set Up an
Environment for Developing a Module.
NOTE
Your environment must have the correct symbols. Go get those, in Visual Studio Code, press F1 , and then choose AL:
Download Symbols . Also, make a note of the ser ver and ser verInstance settings. You will add that information to
the launch.json file.
Your changes must follow the guidelines for module architecture. For more information, see Module
Architecture. When changing an existing module, do not introduce breaking changes, that is, make sure that you
do not break existing functionality. Existing tests must still pass, and you should add new tests for the
functionality that you change or add.
Set Up Visual Studio Code for Module Development
Open the launch.json , file and update the ser ver , ser verInstance , and authentication settings, as described
in Set Up Your Development Environment.
"server": "http://YourDockerContainerName",
"serverInstance": "BC",
"authentication": "UserPassword",
Open the settings.json file, and update the al.assemblyProbingPaths , as described in Set Up Your
Development Environment.
Create a Branch
To create a branch, run the git checkout -b "YourFeatureBranchName" command. Afterward, you can start
creating a new module.
if InsertLineBreaks then
Base64FormattingOptions := Base64FormattingOptions.InsertLineBreaks
else
Base64FormattingOptions := Base64FormattingOptions.None;
case TextEncoding of
TextEncoding::UTF16:
Base64String := Convert.ToBase64String(Encoding.Unicode().GetBytes(String),
Base64FormattingOptions);
TextEncoding::MSDos,
TextEncoding::Windows:
Base64String := Convert.ToBase64String(Encoding.GetEncoding(CodePage).GetBytes(String),
Base64FormattingOptions);
else
Base64String := Convert.ToBase64String(Encoding.UTF8().GetBytes(String),
Base64FormattingOptions);
end;
exit(Base64String);
end;
case TextEncoding of
TextEncoding::UTF16:
OutputString := Encoding.Unicode().GetString(Convert.FromBase64String(Base64String));
TextEncoding::MSDos,
TextEncoding::Windows:
TextEncoding::Windows:
OutputString :=
Encoding.GetEncoding(CodePage).GetString(Convert.FromBase64String(Base64String));
else
OutputString := Encoding.UTF8().GetString(Convert.FromBase64String(Base64String));
end;
exit(OutputString);
end;
We have changed the implementation codeunit, and avoided breaking existing functionality by keeping the
same behavior for existing functions.
Now we'll add public functions in the facade codeunit with the functionality that we want to expose. Because the
functions are public, we need to ensure that they are documented and tested. The functions call the
corresponding functions in the implementation codeunit. We add the following functions to System/Base64
Conver t/src/Base64Conver t.Codeunit.al :
/// <summary>
/// Converts the value of the input string to its equivalent string representation that is encoded with
base-64 digits.
/// </summary>
/// <param name="String">The string to convert.</param>
/// <param name="TextEncoding">The TextEncoding for the input string.</param>
/// <returns>The string representation, in base-64, of the input string.</returns>
procedure ToBase64(String: Text; TextEncoding: TextEncoding): Text
begin
exit(Base64ConvertImpl.ToBase64(String, TextEncoding));
end;
/// <summary>
/// Converts the value of the input string to its equivalent string representation that is encoded with
base-64 digits.
/// </summary>
/// <param name="String">The string to convert.</param>
/// <param name="TextEncoding">The TextEncoding for the input string.</param>
/// <param name="Codepage">The Codepage if TextEncoding is MsDos or Windows.</param>
/// <returns>The string representation, in base-64, of the input string.</returns>
procedure ToBase64(String: Text; TextEncoding: TextEncoding; Codepage: Integer): Text
begin
exit(Base64ConvertImpl.ToBase64(String, TextEncoding, Codepage));
end;
/// <summary>
/// Converts the specified string, which encodes binary data as base-64 digits, to an equivalent regular
string.
/// </summary>
/// <param name="Base64String">The string to convert.</param>
/// <param name="TextEncoding">The TextEncoding for the input string.</param>
/// <returns>Regular string that is equivalent to the input base-64 string.</returns>
/// <error>The length of Base64String, ignoring white-space characters, is not zero or a multiple of 4.
</error>
/// <error>The format of Base64String is invalid. Base64String contains a non-base-64 character, more
than two padding characters,
/// or a non-white space-character among the padding characters.</error>
procedure FromBase64(Base64String: Text; TextEncoding: TextEncoding): Text
begin
exit(Base64ConvertImpl.FromBase64(Base64String, TextEncoding));
end;
/// <summary>
/// Converts the specified string, which encodes binary data as base-64 digits, to an equivalent regular
string.
/// </summary>
/// <param name="Base64String">The string to convert.</param>
/// <param name="TextEncoding">The TextEncoding for the inout string.</param>
/// <param name="Codepage">The Codepage if TextEncoding is MsDos or Windows.</param>
/// <returns>Regular string that is equivalent to the input base-64 string.</returns>
/// <error>The length of Base64String, ignoring white-space characters, is not zero or a multiple of 4.
</error>
/// <error>The format of Base64String is invalid. Base64String contains a non-base-64 character, more
than two padding characters,
/// or a non-white space-character among the padding characters.</error>
procedure FromBase64(Base64String: Text; TextEncoding: TextEncoding; Codepage: Integer): Text
begin
exit(Base64ConvertImpl.FromBase64(Base64String, TextEncoding, Codepage));
end;
We have now exposed the functions. The next steps are to ensure that existing tests pass, and then add new tests
for the functionality that we added.
After verifying that the tests pass, we'll add the following tests to the System Tests/Base64
Conver t/src/Base64Conver tTest.Codeunit.al file.
[Test]
procedure StringToBase64UTF16Test()
var
ConvertedText: Text;
begin
// [SCENARIO] A string variable is converted to base-64 string, binary representation is kept in
UTF16
[Test]
procedure FromBase64UTF16StringTest()
var
ConvertedText: Text;
begin
// [SCENARIO] A base-64 string with UTF16 encoding is converted to a regular string
See Also
Become a contributor
Git going with extensions
Walkthrough: Contributing to an extension on GitHub
Create a new module
Task Scheduler
2/6/2023 • 6 minutes to read • Edit Online
The task scheduler enables you to control when certain operations or processes (in other words tasks) are run.
Basically, a task is a codeunit or report that is scheduled to run at a specific date and time. Tasks run in a
background session between the Dynamics 365 Business Central service instance and database. Behind the
scenes, the task scheduler is used by the job queue to process job queue entries that are created and managed
from the clients.
TaskScheduler.CreateTask(Integer,
Integer, Boolean, String, DateTime,
RecordId, Duration) Method
To set up a task, create codeunits that contain the logic that you want to run at a scheduled time. Once you have
the codeunits, add code to the application that calls the CreateTask method to schedule a task. The CreateTask
method can also specify the earliest date to run the task.
1 and 2 .5
3 and 4 1
5 and 6 2
7 and 8 3
RET RY AT T EM P T WA IT T IM E ( M IN UT ES) A F T ER P REVIO US AT T EM P T
9 to 99 5
On-premises
A codeunit will be retried up to nine times, according to the following intervals:
1 and 2 2
3 4
4 to 9 15
See Also
Task Scheduler Data Type
Developing Extensions
Get Started with AL
Job Queue
2/6/2023 • 2 minutes to read • Edit Online
This article describes how the job queue works in Business Central. A job queue is basically an abstraction that
uses the task scheduler from the platform to enable end users to view, create, or modify jobs that are set to run
in the background. These jobs can be set to run on a recurring schedule.
For information about how users work with the job queue in the client, see Use Job Queues to Schedule Tasks.
See Also
Task Scheduler. Task Scheduler Data Type
Developing Extensions
Get Started with AL
Using App Key Vaults with Business Central
Extensions
2/6/2023 • 2 minutes to read • Edit Online
Some Business Central extensions make web service calls to non-Business Central services. For example, one
extension might call Azure Storage to read/write blobs. Another extension might call the extension publisher's
web service to do an operation.
These web service calls are typically authenticated, which means the extension must provide a credential in the
call. The credentials enable the other service to accept or reject the call. You can consider the credentials as a
kind of secret to the extension. A secret shouldn't be leaked to customers, partners, or anybody else. So where
can the extension get the secret from? Here is where Azure Key Vault is used. Azure Key Vault is a cloud service
that works as a secure secrets store. It provides centralized storage for secrets, enabling you to control access
and distribution of the secrets.
NOTE
For Business Central online, the app key vault feature is only supported for AppSource extensions.
Getting started
Getting extensions to use secrets from Azure Key Vault involves two areas of work: setting up and configuring
Azure Key Vaults and developing the extensions to use secrets from Azure Key Vault.
Setting up and configuring Azure Key Vaults
An extension can retrieve secrets from one or two different Azure Key Vaults. These key vaults must be created
in Azure, and the Business Central service configured to access key vaults. The setup process is different for
online and on-premises. For more information, see:
Setting up App Key Vaults for Business Central online
Setting up App Key Vaults for Business Central on-premises
Developing the extensions to use secrets from Azure Key Vault
Once you have an Azure Key Vault, you can develop Business Central extensions to retrieve secrets from the key
vault. In short, this work involves specifying the key vault's URL and adding code to retrieve a secret from the
key vault.
For more information, see Using App Key Vault Secrets in Extensions.
See Also
Security Considerations With App Key Vaults
Monitoring and Troubleshooting App Key Vaults
Configuring Business Central Server - Azure Key Vault Extensions
Setting up App Key Vaults for Business Central
Online
2/6/2023 • 3 minutes to read • Edit Online
AppSource apps for Business Central can be developed to get secrets from Azure Keys Vaults. The app key vault
feature is readily available for use on the service by all App Source apps. However, there are some onboarding
tasks required.
IMPORTANT
With Business Central online, App key vaults can only be used with AppSource apps. They're not supported with per-
tenant extensions.
TIP
You must also specify secrets in a key vault if you deploy Business Central as part of the Embed App program. Especially if
you must support the Outlook add-in, in which case you must specify secrets for
TEMPORARYDOCUMENTSTORAGEACCOUNT and TEMPORARYDOCUMENTSTORAGEKEY.
For more information about developing extensions with key vaults, see Using Key Vault Secrets in Business
Central Extensions.
Import-Module AzureAD
Connect-AzureAD
Grant the key vault reader application permission to your key vaults
The next task is to grant the key vault reader application permission to read secrets from your key vaults. The
steps in this task are done from the Azure portal.
1. Open the key vault in the portal.
2. Select Access policies , then Add Access Policy .
3. Set Secret Permissions to Get .
4. Choose Select principal , and on the right, search for either the application (client) ID 7e97dcfb-bcdd-
426e-8f0a-96439602627a or the display name Dynamics 365 Business Central ISV Key Vault
Reader .
5. Select Add , then Save .
See Also
Security Considerations With App Key Vaults
Monitoring and Troubleshooting App Key Vaults
Configuring Business Central Server
Setting up App Key Vaults for Business Central On-
premises
2/6/2023 • 7 minutes to read • Edit Online
Business Central extensions can be developed to get secrets from Azure Keys Vaults. This article describes the
tasks required to set up Azure Keys Vaults for storing extension secrets and configure them in your Business
Central deployment.
For more information about developing extensions with key vaults, see Using Key Vault Secrets in Business
Central Extensions.
Prerequisites
To complete the tasks in this article, you need:
An Azure subscription with an Active Directory tenant.
You sign up for an Azure subscription at https://azure.microsoft.com. For information about getting an
Azure AD tenant, see How to get an Azure Active Directory tenant.
A security certificate
Later, you'll have to register and configure an application in Azure AD for reading key vaults. This step
requires a certificate. The certificate is used to prove the application's identity when requesting upon
request. For a production environment, obtain a certificate from a certification authority or trusted
provider.
In a test environment, if you don't have a certificate, then you can create your own self-signed certificate.
For example, on the Business Central server computer, start Windows PowerShell as an administrator.
Then at the prompt, run the following commands:
Supported account types Specifies which accounts that you would like your
application to support. For purposes of this article, select
Accounts in this organizational director y only .
When completed, the Over view displays in the portal for the new application.
Copy the Application (client) ID . You'll use this information later.
3. Upload the security certificate to the registered application.
In this step, you upload the certificate file that you obtained as part of the prerequisites.
Go to the key vault reader application overview page. Select Cer tificates & secrets > Upload
cer tificate . Follow the instructions to locate and upload the certificate.
Configure the Business Central Server to use the Apps Key Vault
feature
Next, you configure the Business Central Server instance to use the key vault reader application and its
certificate, which you registered in Azure AD, for authenticating to the key vaults.
If you're running a container-based environment, you have two options for configuring the server instance. You
can either do it manually or use the Set-BcContainerKeyVaultAadAppAndCertificate script. Using the Set-
BcContainerKeyVaultAadAppAndCertificate script is simpler and recommended.
Configure a container-based Business Central Server instance
If you are running a container-based environment, use the Set-BcContainerKeyVaultAadAppAndCertificate.ps1
script that is available in the NAV Container Helper GitHub repository at
https://github.com/microsoft/navcontainerhelper/blob/master/ContainerHandling/Set-
BcContainerKeyVaultAadAppAndCertificate.ps1.
Manually configure a Business Central Server instance
To complete this task, you'll need the user name of the service account that runs the Business Central Server.
1. If not already done, import your key vault certificate and its private keys to the local certificate store for
the Business Central server computer.
You can import the certificate either using the MMC snap-in or Import-PfxCertificate cmdlet from a
Windows PowerShell prompt.
For example, the following PowerShell command installs a certificate to the local machine's personal
store:
2. Give the service account used by the Business Central Server instance permission to access the
certificates private key.
To do this using the MMC:
a. Open the MMC snap-in for certificates. See How to: View Certificates with the MMC Snap-in.
b. Expand the Cer tificates (Local Computer) node, expand the Personal node, and then select the
Cer tificates subfolder.
c. In the right pane, right-click the certificate, select All Tasks , and then choose Manage Private
Keys .
d. In the Security dialog box, choose Add .
e. In the Select Users, Computers, Ser vice Accounts, or Groups dialog box, enter the name of
the dedicated domain user account that is associated with Business Central Server, for example,
NETWORK SERVICE. Then, choose the OK button.
f. In the Full Control field, select Allow , and then choose the OK button.
3. Make a note of the certificate thumbprint because you'll need it in the next step. See How to: Retrieve the
Thumbprint of a Certificate.
4. Configure the Business Central Server instance.
Now, you'll configure App Key Vault settings on the server instance. The following table describes the
settings that you must configure:
SET T IN G
( K EY N A M E) VA L UE
Client Certificate Store Location Set to the certificate store location where key vault
(AzureKeyVaultClientCertificateStoreLocation) certificate was stored.
Example:
LocalMachine
Client Certificate Store Name Set to the certificate store name where key vault
(AzureKeyVaultClientCertificateStoreName) certificate was stored.
Example:
MY
Client Certificate Thumbprint Set to the thumbprint for the key vault certificate.
(AzureKeyVaultClientCertificateThumbprint)
Example:
649419e4fbb87340f5a0f995e605b74c5f6d943e
Example:
ed4129d9-b913-4514-83db-82e305163bec
Enable Publisher Validation Specifies whether extensions can only use key vaults that
(AzureKeyVaultAppSecretsPublisherValidationEnabled) belong to their publishers.
Example:
true
You can configure the instance using the Business Central Server Administration tool or Set-
NAVServerConfiguration cmdlet.
To use the Set-NAVServerConfiguration cmdlet, start the Business Central Administration Shell as an
administrator, and run the following commands one at a time. Replace brackets with your own values.
Set-NAVServerConfiguration -ServerInstance <serverInstance> -KeyName
AzureKeyVaultClientCertificateStoreLocation -KeyValue <certificate store location>
Set-NAVServerConfiguration -ServerInstance <serverInstance> -KeyName
AzureKeyVaultClientCertificateStoreName -KeyValue <certifcate store>
Set-NAVServerConfiguration -ServerInstance <serverInstance> -KeyName
AzureKeyVaultClientCertificateThumbprint -KeyValue <certificate thumbprint>
Set-NAVServerConfiguration -ServerInstance <serverInstance> -KeyName AzureKeyVaultClientId -KeyValue
<application ID of key vault reader app in Azure>
Set-NAVServerConfiguration -ServerInstance <serverInstance> -KeyName
AzureKeyVaultAppSecretsPublisherValidationEnabled -KeyValue <true|false>
Restart-NAVServerInstance -ServerInstance <serverInstance>
At this point, you can run your extensions that use key vault secrets to read secrets from key vault.
TIP
If your on-premises solution uses the ImportStreamWithUrlAccess method, you must have set up an Azure blob storage
account and stored the account name and account keys in the current subscription's Azure KeyVault using the identifiers
TEMPORARYDOCUMENTSTORAGEACCOUNT and TEMPORARYDOCUMENTSTORAGEKEY. That way, your users can use
the integration with Outlook.
See Also
Using App Key Vaults with Business Central Extensions
Security Considerations With App Key Vaults
Monitoring and Troubleshooting App Key Vaults
Authentication and Credential Types
Configuring Business Central Server
Using Key Vault Secrets in Business Central
Extensions
2/6/2023 • 6 minutes to read • Edit Online
This article describes how to code an extension to retrieve secrets from Azure Key Vaults. Secrets are typically
used when the extensions calls a web service. For an overview of app key vaults and secrets, see Using App Key
Vaults with Extensions.
Developing an extension to use secrets from a key vault involves two tasks, as described in this article:
Specifying the Azure Key Vault in the extension's manifest.
Adding code to retrieve the secrets from the key vault.
Preparation
Using secrets requires that you have at least one Azure Key Vault with secrets set up and configured for
use by the service. If you don't already have an Azure Key Vault, see Setting up App Key Vaults for
Business Central online or Setting up App Key Vaults for Business Central on-premises.
For coding, you'll need the URI the Azure Key Vault that stores the secret and the name of the secret itself.
If you don't have this information, you can get it from Azure portal. For instructions, see Quickstart: Set
and retrieve a secret from Azure Key Vault using the Azure portal.
"keyVaultUrls":[
"https://mykeyvault.vault.azure.net"
]
You can specify up to two key vaults in the app.json, as shown in the following example code snippet:
"keyVaultUrls":[
"https://myfirstkeyvault.vault.azure.net",
"https://mysecondkeyvault.vault.azure.net"
]
Specifying two key vaults ensures a higher availability of secrets, especially if created in two different Azure
regions. At runtime, the Business Central platform will iterate both key vaults until the secret is successfully
retrieved. If one of the key vaults is unavailable for any reason, the extension will continue to execute because
the other key vault will most likely be available.
M ET H O D DESC RIP T IO N
TryInitializeFromCurrentApp(): Boolean Identifies the calling extension and initializes the codeunit
with the key vaults specified in the extension's manifest.
GetSecret(SecretName: Text, var SecretValue: Text): Retrieves the value of a specific secret from one of the app's
Boolean key vaults.
Look at the following example for a simple page object. The code retrieves the value of the secret named
MySecret in app key vault:
trigger OnOpenPage();
begin
if SecretProvider.TryInitializeFromCurrentApp() then begin
if SecretProvider.GetSecret('MySecret', SecretValue) then
Message('Retrievedsecret:' + SecretValue)
else
Message('Failed to retrieve secret')
end
else
Message('ERROR:' + GetLastErrorText());
end;
}
The call to the TryInitializeFromCurrentApp method determines the extension that is currently being executed,
then determines the extension's key vaults as specified in the extension manifest. After initialization, the
GetSecret call reads secrets from the key vault.
Security considerations
Keep the following information in mind when you use the App Key Vault feature with your extensions.
Mark methods as NonDebuggable
When your code works with secrets, whether from a key vault or from Isolated Storage, block the ability to
debug relevant methods by using the NonDebuggable Attribute. It prevents other partners from debugging into
your code and seeing the secrets.
Don't pass the App Key Vault Secret Provider to untrusted code
Once the App Key Vault Secret Provider codeunit has been initialized, it can be used to get secrets.
If you pass the codeunit to another method, then that method is also able use it.
If you pass the codeunit to a method in another extension, then the other extension can also use the secret
provider to get secrets.
These conditions may not be what you want, so be careful who you pass the secret provider to.
Enable publisher validation
For on-premises deployments, you can configure Business Central Server to run with or without publisher
validation of key vault secret providers. Publisher validation is controlled by the server's Enable Publisher
Validation (AzureKeyVaultAppSecretsPublisherValidationEnabled) configuration setting. The validation is a
runtime operation that ensures extensions use only key vaults that belong to their publishers. It essentially
blocks attempts in AL to read secrets from another publisher's key vault.
How it works
Publisher validation is done by comparing the key vault's Azure AD tenant ID with the extension publisher's
Azure AD tenant ID. It works this way:
1. When an extension is published by using the Publish-NAVApp cmdlet, the publisher can provide their
Azure AD tenant ID by setting the -PublisherAzureActiveDirectoryTenantId parameter:
NOTE
An error won't occur if -PublisherAzureActiveDirectoryTenantId isn't set. There is nothing preventing you
from publishing the extension at this point.
2. When the extension runs, it tries to initialize the App Key Vault Secret Provider codeunit.
3. The system compares the key vault's Azure AD tenant ID with the Azure AD tenant ID published with the
extension:
If they match, initialization succeeds.
If they don't match, an error occurs.
Turning off publisher validation
Publisher validation is turned on by default, which is the recommended setting. If it's turned off, the server
instance won't do any additional validation to ensure extensions have the right to read secrets from the key
vaults that they specify. This condition implies some risk of unauthorized access to key vaults that you should be
aware of. So, don't turn off publisher validation unless you trust the extensions that can be potentially installed.
For information about how to turn publisher validation on or off, see Configuring Business Central Server.
You're running an old version of Business Central Server. Upgrade to at least version 17.0.
Runtime
For runtime operations, there are two sources that you can use for gathering details:
Windows Event Log of the machine running the Business Central Server.
Application Insights.
These sources provide details about retrieving secrets from key vaults, for calls to the
TryInitializeFromCurrentApp and GetSecret methods from an extension.
Using Application Insights
You can set up extensions to emit telemetry to an Application Insights resource in Azure.
1. Create an Application Insights resource in Azure if you don't have one.
The Application Insights resource will be assigned an instrumentation key. Copy this key because you'll
need it to enable Application Insights in the Business Central administration center.
For more information, see Create an Application Insights resource.
2. In the app.json file of the extension, add the "applicationInsightsKey" :
"applicationInsightsKey":["<instrumenation key>"]
3. Now, you can run your extensions and view data in Application Insights.
For more information, see Viewing telemetry data in Application Insights and Analyzing App Key Vault
Secret Trace Telemetry.
See Also
Get Started with AL
Publishing and Installing Extensions
Configuring Business Central Server
Developing Printer Extensions in Business Central
2/6/2023 • 3 minutes to read • Edit Online
This article provides an overview about how to add code that enables Business Central reports to be sent from
the client directly to a web-connected printer, like an email printer or through a cloud printing service.
Without any customized code, there's no way to send a report directly to a printer for printing. The only way to
print a report from the client is to download it first (as a .pdf file), and then send it to a printer. But you can create
extensions that are designed to send reports to web-connected printers. For example, if you have an email
printer, you create an extension that sends print jobs directly to the printer's email address.
Overview
To accommodate printing, the system publishes two events that you can subscribe to: OnAfterSetupPrinters and
OnAfterDocumentPrintReady. The following figure illustrates the runtime execution of the events:
Throughout the print process, the system compiles the report into a PDF file and passes it in a stream object,
then finally sends the PDF file to the printer.
OnAfterSetupPrinters event
You subscribe to the OnAfterSetupPrinters event to set up different printers that users can use on reports, which
they select from the Printer Selections page. The OnAfterSetupPrinters event is a global integration event that
is published from codeunit 44 Repor t Managements . It has the following declaration:
[IntegrationEvent(false, false)]
local procedure OnAfterSetupPrinters(var Printers: Dictionary of [Text[250], JsonObject]);
The Printers parameter is a Dictionary of [Text, Text] type that includes a collection of key-value pairs that define
different printer setups. The key specifies a name for the printer. The value is a JSON object that specifies
settings supported by the printer. The settings include information like paper size, paper trays, default copies,
and more. The JSON object is referred to as the payload.
The OnAfterSetupPrinters event is raised when the following operations occur:
When you open a page that uses the virtual table Printer as its source.
From page 64 Printer Selections in the base application, when you access the Printer Name field for
selecting a printer for a report. This field has a lookup to the Printer table.
From a report request page, when you select the Print or Preview action for a report. But only if the report
is set up to use a specific printer from the Printer Selections page.
OnAfterDocumentPrintReady
You subscribe to the OnAfterDocumentPrintReady event to specify what happens when the user selects the
Print action on a report request page. You use OnAfterDocumentPrintReady event subscribers to provide
instructions on how and where to send to the report for printing. For example, with email printing, the
OnAfterDocumentPrintReady event subscriber would construct and send an email to a target printer.
The OnAfterDocumentPrintReady event is also a global integration event that is published from codeunit 44
Repor t Managements . It has the following declaration:
IntegrationEvent(false, false)]
local procedure OnAfterDocumentPrintReady(ObjectType: Option "Report","Page"; ObjectId: Integer;
ObjectPayload: JsonObject; DocumentStream: InStream; var Success: Boolean);
The event is raised when the use selects the Print action on the request page of a report. Two parameters of
interest are DocumentStream and ObjectPayload. DocumentStream is an Upstream object that contains the
report data to be printed. The ObjectPayload is a JsonObject type object that combines the printer payload and
report metadata. The report metadata includes information like the company name, MIME type, views, and
more. This combination is referred to as the report payload.
Development Overview
To develop a printer extension, you create codeunits that subscribe to the OnAfterSetupPrinters and
OnAfterDocumentPrintReady events. Plus, you would typically add other objects to support the printing. For
example, you could create a table that stores printer setups and a page that enables users to manage them.
For more information about using the OnAfterSetupPrinters and OnAfterDocumentPrintReady events to create
a printer extension, see Creating a Printer Extension.
See Also
Events in AL
Publishing Events
Raising Events
Subscribing to Events
Creating a Printer Extension
2/6/2023 • 6 minutes to read • Edit Online
This article describes how to use the OnAfterSetupPrinters and OnAfterDocumentPrintReady events to set up
different printers for reports.
Overview
This article uses a simplified printer extension example for sending reports to an email printer. The example
creates a printer extension that sets up a single email printer. Users can then assign the printer to reports from
the Printer Selections page in the client. In this article, you will:
Create two codeunits, one that subscribes to the OnAfterSetupPrinters event and another that subscribes to
the OnAfterDocumentPrintReady event.
Use the SMTP Mail and Mail Management codeunits that are part of the base application for sending the
report via email.
begin
end;
}
PaperTrayCustom.Add('papersourcekind', 'Custom');
PaperTrayCustom.Add('paperkind', 'Custom');
PaperTrayCustom.Add('width', 236);
PaperTrayCustom.Add('height', 322);
PaperTrayCustom.Add('units', 'mm');
5. At this point, you can compile your project, and publish/install the extension on the tenant to test the
payload.
Open the Printer Selections page in the client. You should see My Printer as an option in the Printer
Name field. If there are errors with payload, you'll get an error when you try to open the Printer Name
field. For more information, see Troubleshooting Printer Payload Errors.
About the printer payload
The event subscriber method has one parameter, which is a dictionary of printers. The key is a name of the
printer. The value is a JSON object that is referred to as the payload. The payload specifies information about a
specific printer. The payload includes several attributes in the following structure:
{
"version": 1,
"description":[default=""],
"duplex":[default=false],
"color":[default=false],
"defaultcopies":[default=1],
"papertrays":
[
{
"papersourcekind":'Upper' | 1,
"paperkind":'A4' | 9,
"units":[default='HI'],
"height":[default=0],
"width":[default=0],
"landscape":[default=false]
}
]
}
There are few required attributes, such as version and papertrays . The papertrays attribute must contain at
least one paper tray setup, which in turn must include the attributes papersourcekind and paperkind . For more
information about the attributes, see Printer Payload.
Using the ReadFrom method to create the payload
The following example illustrates how to create a payload by using the ReadFrom method.
As an alternative, if you're creating a new report, you can set a paper tray by specifying PaperSourceDefaultPage
property.
report 50103 MyReport
{
PaperSourceDefaultPage = Upper;
...
}
begin
end;
}
4. At this point, you can compile and publish/install the extension on a tenant to test.
First, make sure that SMTP email is set up on the tenant (see Set Up Email in the Application Help).
Then, on the Printer Selections page, set a report to use 'My Printer', and then run and print the report.
About the report payload
The event subscriber receives the printer payload and combines it with the report metadata, like the report's ID.
This combination is the report payload. The content of the report itself is received as a stream object. You add
code to define how and where to send the report payload for printing. In this example, it's sent as an email.
The report object payload is a JSON object that includes several parameters and values arranged in a specific
structure, as shown in the following example
{
"filterviews":
[
{"name":"Header","tableid":112,"view":"VERSION(1) SORTING(Field3) WHERE(Field3=1(103027))"},
{"name":"Line","tableid":113,"view":"VERSION(1) SORTING(Field3,Field4) WHERE(Field4=1(0..10000))"},
{"name":"ShipmentLine","tableid":7190,"view":"VERSION(1) SORTING(Field1,Field2,Field3)
WHERE(Field2=1(10000))"}
],
"version":1,
"objectname":"Standard Sales - Invoice",
"objectid":1306,
"documenttype":"application/pdf",
"invokedby":"00000000-0000-0000-0000-000000000001",
"invokeddatetime":"2020-01-17T15:33:52.48+01:00",
"companyname":"CRONUS International Ltd.",
"printername":"My Printer",
"duplex":false,
"color":false,
"defaultcopies":1,
"papertray":
{
"papersourcekind":257,
"paperkind":0,
"landscape":false,
"units":0,
"height":1268,
"width":929
}
}
The parameters can be read but not modified at runtime. For more information about the report payload, see
Report Payload.
See Also
Working With and Troubleshooting Payloads
Developing Printer Extensions Overview
Events in AL
Publishing Events
Raising Events
Subscribing to Events
Web Client URL
2/6/2023 • 10 minutes to read • Edit Online
There are several parameters that you can add to the Web client URL to manipulate what is displayed in the
client. For example, you can open a specific company, target a specific page, report, or table. The following URL
displays page 9305 Sales Order List for the CRONUS International Ltd. company:
https://businesscentral.dynamics.com/?company=CRONUS%20International%20Ltd.&page=9305
The following URL opens report 5 Receivables – Payables for the same company:
https://businesscentral.dynamics.com/?company=CRONUS%20International%20Ltd.&report=5
This article describes how you can construct URLs. A well-constructed URL can be useful for including in other
sources, such as emails or Word documents, or sending as hyperlinks to other users.
IMPORTANT
Certain data in the URL, such as filters, could be considered sensitive information. Use discretion if you distribute URLs
that contain filters, or if it's possible, exclude this information from the address.
URL Syntax
The Web client URL has the following syntax:
https://<hostname>[/<aadtenantid>][/<environmentname>]/?[company=<companyname>]&[page|query|report|table=
<ID>]&[tenant=<tenantID>]&[mode=<View|Edit|Create>]&[profile=<profileID>]&[customize]&[bookmark=<bookmark>]&
[captionhelpdisabled=<0|1>]&[showribbon=<0|1>]&[shownavigation=<0|1>]&[showuiparts=<0|1>]&[showheader=
<0|1>]&[isembedded=1]&[pagesize=<number of lines>]&[redirect<0|1>]&[extension=<extensionID>]
The URL consists of two parts; the hostname part and the query string. The hostname part includes the protocol
(https) and the hostname. The query string part includes everything after <hostname> . The query string
determines what content to target.
Syntax Key
The following table describes the notation that is used to indicate the syntax.
<> A placeholder for values that you must supply. Don't include
the brackets in the address.
https://businesscentral.dynamics.com/?company=CRONUS%20International%20Ltd.&page=9305&mode=View
https://businesscentral.dynamics.com/?page=9305&mode=View&company=CRONUS%20International%20Ltd.
URL Parameters
The following table describes the parameters of the URL for displaying a page.
PA RA M ET ER DESC RIP T IO N
company The name of the company in Dynamics 365 that you want
to target.
If you only have one company, then you can omit this
parameter.
- View
The page can only be viewed. The user can't change data on
the page. Note: Worksheet page types only display in the
edit mode, even if the value is set to View .
- Edit
The user can change data on the page. Note: To use the edit
mode, the Editable Property of the page in Page Designer
must be set to Yes . This mode isn't supported for pages of
the type List, RoleCenter, and CardPart. If you set the value
to Edit , pages of these types still display in the view mode.
For List type pages, the user can modify the list by choosing
Edit List on the page.
- Create
Opens a blank page that enables the user to create a new
item.
It's possible for two or more profiles have the same ID.
Profiles can have a scope of either system or tenant. Also,
tenant profiles can be either user-defined (added by using
the Profiles page in the client) or extension-based (added
by an extension). Among these different types, the IDs of
some profiles might be the same. If there's more than one
profile with the same ID as you provide, the profile is
selected as follows:
1. If there's a matching system profile, it's used.
2. If there's a matching user-defined tenant profile, it's
used.
3. If there's only one matching extension-based profile,
it's used.
4. If there are two or more extensions-based profiles
with the same ID, then the error message
More than one profile has the ID '<ID>'
within the Tenant scope.
appears. In this case, you can't use the profile
parameter for this profile.
If you want the Help look up from the field captions, either
omit this parameter or set its value to 0 , such as
captionhelpdisabled=0 .
If you don't want the Help lookup from field captions, set the
value to 1 , such as captionhelpdisabled=1 .
When you hide the action bar, it will remain hidden as you
move to different pages, until you refresh or reload the
browser or use showribbon=1 in the URL. Once you move
to another page, the parameter is no longer shown in the
URL, even though it's still in effect.
If you don't want to give users this option, set the value to
0 , such as redirect=0 .
&extension={72CC5E27-BD97-4271-AF55-F77E4471E493}
https://businesscentral.dynamics.com/?company=CRONUS%20International%20Ltd.&page=9305&filter='Sell-to
Customer No.' IS '10000' AND 'Location Code' IS 'BLUE'
Filter Syntax
The filter has the following syntax.
Include a space or %20 before and after the IS and AND operators. You can add the filter anywhere in the
address after /? .
Filter Parameters
The following table describes the filter parameters.
PA RA M ET ER DESC RIP T IO N
AND Use this parameter to specify more than one filter. It specifies
an "and" operator for adding additional filters. Place AND
between each additional filter.
See Also
Viewing Table Data
Linking to the Dynamics 365 Business Central App
2/6/2023 • 4 minutes to read • Edit Online
The protocol handler for the Business Central Mobile App lets you construct a URL for starting the app on a
device, such as a phone or tablet. You can then distribute this URL by e-mail or from a Web page to the users.
The Business Central Mobile App URL is based on the ms-businesscentral URI scheme, which is registered
automatically when the app is installed. Invoking a URL based on this scheme will start the app with the
provided parameters.
ms-businesscentral://[<hostname>][/<aadtenantid>][/sandbox]/[?<parameter>=<value>[&<parameter>=<value>]]
Parameters
The following table describes the parameters for the main part of the URL, which are the parameters up to and
including [/sandbox]/ .
The following table describes the optional parameters that are indicated by
[?<parameter>=<value>[&<parameter>=<value>]] in the syntax. These parameters are referred to as the query
parameters.
ms-
businesscentral://businesscentral.mysolution.com/?
page9305&filter='Sell-to-Customer-
No.'%20IS%20'10000'%20AND%20'Location-
Code'%20IS%20'BLUE'
The query parameters can be in any order. However, the first parameter must be preceded by the ? symbol,
and any additional parameters must be preceded by the & symbol.
See Also
Web Client URL
Introducing the Business Central Mobile App
Instrumenting an Application for Telemetry
2/6/2023 • 2 minutes to read • Edit Online
This article describes how you can implement custom telemetry signals in your application for emitting
telemetry data. This data can then be collected and visualized for analyzing the application against the desired
business goals, troubleshooting, and more.
Telemetry overview
One aspect of event logging is the data collection about the working and deployment infrastructure of an
application to diagnose conditions and troubleshoot problems that affect its operation and performance. For
example, this type of event logging includes Business Central Server events and trace events like SQL and AL
method (function) traces.
Another aspect of logging is telemetry, which is the collection of data about how your application works in
production. Telemetry can tell you about specific activities that users perform within the application in the
production environment. Telemetry also helps troubleshooting in those instances where you aren't able to
reproduce the conditions experienced by the user or have no access to the user's environment. Telemetry can be
divided into different categories, like: telemetry for engineering, telemetry about the business, telemetry for
customers.
Extension developers
can specify whether
the signal is only sent
to the extension
publisher or also to
the VAR partner
telemetry resource.
NOTE
Using Application Insights is recommended.
See Also
Monitoring and Analyzing Telemetry
Monitoring Business Central Server Events
Creating Custom Telemetry Traces for Application
Insights Monitoring
2/6/2023 • 6 minutes to read • Edit Online
This article explains how to develop extensions to send custom telemetry trace signals to Azure Application
Insights for viewing and analyzing.
You can add AL code in extensions to emit messages about activities or operations that users do within the
application. At runtime, the messages can be picked up by an Application Insights resource, which you set up
beforehand. In Application Insights, the custom telemetry events are stored in the traces table.
NOTE
Having Application Insights resources configured is not required to create custom signals in AL code.
NOTE
In Application Insights, the name of custom dimension will be prefixed with al . For example, if the dimension string you
define in code is result , then in the trace logged in Application Insights, the name appears as alresult .
D e fa u l t C u st o m D i m e n si o n s
The following table explains CustomDimensions that are automatically included in ALMessage traces that are
sent to Application Insights.
alObjectType Specifies the type of the object that called the LOGMESSAGE
method, like PageExtension for a page extension object.
Examples
The following code snippets create simple telemetry trace signals. They create a critical-level telemetry signal
that is scoped to the signal publisher. For a simple test of this code, add it to the OnRun trigger of a codeunit, and
then run the codeunit.
Using a dictionar y:
trigger OnRun();
var
CustDimension: Dictionary of [Text, Text];
begin
CustDimension.Add('result', 'failed');
CustDimension.Add('reason', 'critical error in code');
LogMessage('MyExt-0001', 'This is a critical error message', Verbosity::Normal,
DATACLASSIFICATION::SystemMetadata, TelemetryScope::ExtensionPublisher, CustDimension);
end;
Using an overload:
trigger OnRun();
begin
LogMessage('MyExt-0001', 'This is a critical error message', Verbosity::Critical,
DATACLASSIFICATION::SystemMetadata, TelemetryScope::ExtensionPublisher, 'result', 'failed', 'reason',
'critical error in code');
end;
Design considerations
For Business Central on-premises, the Diagnostic Trace Level setting on the Business Central Server
instance controls which signals are sent, based on their severity level.
If the Diagnostic Trace Level is set to Warning for example, then Normal and Verbose signals won't
be sent to Application Insights. For more information, see Configuring Business Central Server - General.
For privacy reasons, events that have a DataClassification other than SystemMetadata aren't sent to
Application Insight resources set up on the tenant. During development of your extension, it's good
practice to have a privacy review of the use of LOGMESSAGE calls to ensure that customer data isn't
mistakenly leaked into Application Insights resources.
See Also
Instrumenting an Application for Telemetry
LOGMESSAGE method
LOGMESSAGE method
Monitoring and Analyzing Telemetry
Sending App/Extension Telemetry to Azure
Application Insights
2/6/2023 • 2 minutes to read • Edit Online
This article describes how to set up an extension to send telemetry data to Azure Application Insights for
monitoring and analyzing. Business Central emits telemetry data for several operations that occur when
extension code is run. For an overview about the telemetry with Azure Application Insights, see Monitoring and
Analyzing Telemetry.
This feature targets publishers of per-tenant or appsource extensions to give them insight into issues in their
extensions before partners and customers report them.
"applicationInsightsConnectionString":"<connection string>"
Replace <connection string> with the string that you copied in the Azure Application Insights overview. For
more information about the format of the Azure Application Insights connection string, see Connection Strings.
When done, build the extension package, then publish and install it as usual. When the extension is run from
Business Central, Azure Application Insights gathers the telemetry data for viewing and analyzing.
Prior to runtime version 7.2
Up until runtime version 7.2 you cannot use the "applicationInsightsConnectionString" setting. Instead you
have to use the "applicationInsightsKey" setting which is added using only the instrumentation key from the
Azure Application Insights connection string as shown:
"applicationInsightsKey":"<instrumentation key>"
Where <instrumentation key> is replaced by the key denoted in the connection string as
InstrumentationKey=<instrumentation key>;<some other parameters> .
NOTE
Transition to using connection strings for data ingestion in Azure Application Insights by 31 March 2025 . On 31 March
2025, technical support for instrumentation key–based global ingestion in the Azure Application Insights feature of Azure
Monitor will end. After that date, your Azure Application Insights resources will continue to receive data, but Microsoft no
longer provide updates or customer support for instrumentation key–based global ingestion.
See Also
Get Started with AL
Publishing and Installing Extensions
JSON Files
Viewing telemetry data in Application Insights
LogMessage Method
Creating Custom Telemetry Events for Event Log
Monitoring
2/6/2023 • 3 minutes to read • Edit Online
NOTE
The SENDTRACETAG method is marked as obsolete in Business Central 2020 release wave 2 (v17). You can still use it, but
we recommend that you send traces to Application Insights using the LOGMESSAGE method instead. For more
information, see Creating Custom Telemetry Traces for Application Insights Monitoring.
You use the parameters to define the information about the telemetry trace event. This information is can be
consumed by event logging tools, and presented in different ways.
PA RA M ET ER DESC RIP T IO N
Message A text string that specifies the descriptive message for the
telemetry trace event.
PA RA M ET ER DESC RIP T IO N
For example, the following code creates simple telemetry trace events for the five different severity levels.
For a simple test of this code, add it to the OnRun trigger of a codeunit, and then run the codeunit. Of course,
you can also call the code from other objects, triggers or functions as well.
IMPORTANT
The Business Central Server instance includes a configuration setting called Diagnostic Trace Level ( TraceLevel in the
customsettings.config file) that enables you to specify the lowest severity level of telemetry events to be recorded in the
event log, or even turn off telemetry event logging altogether. If you do not see the expected events, then verify the
Business Central Server instance configuration with an administrator. For information, see Configuring Business Central
Server.
See Also
Instrumenting an Application for Telemetry
Monitoring and Analyzing Telemetry
Monitoring Business Central Server Events
Getting started with Microsoft .NET Interoperability
from AL
2/6/2023 • 3 minutes to read • Edit Online
You can call .NET type members, including methods, properties, and constructors, from AL code. In this article
we will guide you through the process of creating an extension that uses .NET types.
IMPORTANT
.NET Interoperability is only available on-premise. If you want to use this functionality, you must set the
"target": "OnPrem" in the app.json file. For more information, see JSON Files.
Alternatively you can use services such as Azure Functions to call into .NET dlls from AL, which will also work online. For
online training, see Use Azure Functions with Dynamics 365 Business Central.
dotnet
{
It is recommended to have only one package per extension that contains all the .NET types which you will be
using.
You continue by adding a declaration of the assembly that you will be referencing. For this example, we will use
the mscorlib assembly that contains the core .NET types. A dotnet package can contain an unlimited number
of assembly declarations. The name of the assembly must be the one defined in the assembly's manifest. See the
following example snippet.
dotnet
{
assembly(mscorlib)
{
}
}
By default, the compiler only knows about the location of the mscorlib assembly. You can reference any
compatible assembly by providing the compiler with a path to the assembly's containing folder. This can be
achieved by adding the path to assembly's containing folder to the "al.assemblyProbingPaths" setting. Open the
Command Palette Ctrl+Shift+P and choose either User Settings or Workspace Settings and specify the
al.assemblyProbingPaths setting. For example:
"al.assemblyProbingPaths": [
"./.netpackages",
"C:/Program Files/Assemblies"
]
NOTE
Any update to an assembly's code is not automatically detected by the compiler. If an assembly has changed, then you
must restart your development environment.
You continue by adding a reference to a type from the referenced assembly. In this example, we will use
System.DateTime from mscorlib and we will give it the alias MyDateTime . The type must be referenced using its
fully-qualified name. The alias is used for referencing the .NET type from code. If an alias is not provided, the
compiler will use the .NET type name. A .NET assembly declaration can contain any number of type declarations.
See the example below.
dotnet
{
assembly(mscorlib)
{
type(System.DateTime; MyDateTime){}
}
}
dotnet
{
assembly(mscorlib)
{
type(System.DateTime; MyDateTime){}
}
}
See Also
Get Started with AL
.NET Control Add-Ins
Subscribing to Events in a .NET Framework Type
Serializing .NET Framework Types
AL Language Extension Configuration
Migrating from .NET Framework to .NET Standard
2/6/2023 • 4 minutes to read • Edit Online
Starting in 2022 release wave 2 (v21), the Business Central Server supports .NET add-ins compiled to target the
.NET Standard runtime. This change currently doesn't affect your .NET add-ins. However, it might affect some
.NET add-ins in the next release (v22). Read this article to learn more.
What's the difference between .NET Framework, .NET Core, and .NET
Standard?
When first released, .NET Framework had one runtime for building and running Windows desktop and Web
applications. The .NET implementation has evolved over the years. Now, to supplement the .NET Framework, we
also have:
.NET Core
The latest .NET implementation, open source and available for multiple operating systems. With .NET Core,
you can build cross-platform console apps and ASP.NET Core Web applications and cloud services.
.NET Standard
The set of fundamental APIs, sometimes referred to as the .NET Base Class Library (BCL) that all .NET
implementations must implement. By targeting .NET Standard, you can build libraries that you can share
across all your .NET apps, no matter on which .NET implementation or operating system they run.
The various .NET implementations target specific versions of .NET Standard.
NOTE
The Visual Studio .NET Portability Analyzer extension is currently only available for Visual Studio 2019.
After the tool is installed, configure it to define the type of portability analysis needed, such as the target .NET
versions that you want to be compatible with. To do that, complete the following steps:
1. In Visual Studio, select Analyze and then Por tability Analyzer Settings .
2. In the General Settings window, select .NET Standard 2.0 under Target Platforms , and then choose OK .
3. Now, open the project file containing the code that needs to target .NET Standard, right-click the project, and
select Analyze Project Por tability .
This step opens up a Por tability Analysis Results page with and assessment of compatibility, and a list of
recommended changes.
When the command finished, you have a DGML file that can be opened in Visual Studio. Directed Graph Markup
Language (DGML) describes information used for visualization and complexity analysis. It's the format used to
persist code maps in Visual Studio.
See Also
Get Started with AL
.NET Control Add-Ins
Subscribing to Events in a .NET Framework Type
Serializing .NET Framework Types
AL Language Extension Configuration
.NET Control Add-Ins
2/6/2023 • 3 minutes to read • Edit Online
In Dynamics 365 Business Central on-premises you can use existing .NET and Javascript control add-ins from
the AL Language through .NET interoperability. It is recommended that you convert your existing .NET and
Javascript add-ins to native AL control add-ins that are supported both on-premises and in the cloud. For more
information about native AL control add-ins, see Control Add-In Object.
To declare the usage of a .NET or Javascript add-in in AL, you need three critical pieces of information about the
.NET type that represent the interface of the add-in. These are the name of the assembly containing the add-in,
the name of the control add-in, and the name of the class that implements the control add-in. We will show how
to retrieve this information for the Microsoft.Dynamics.Nav.Client.PingPong control add-in that ships with
Business Central.
The name of the assembly can be retrieved from the AssemblyName element in the .csproj file associated
with the .NET project that represents the control add-in. In this case the name of the assembly is
Microsoft.Dynamics.Nav.Client.PingPong .
NOTE
If you do not have access to the .csproj file , you can determine the name of the assembly by following the
instructions in How to: Determine an Assembly's Fully Qualified Name.
The following code sample contains the stub definition of the Microsoft.Dynamics.Nav.Client.PingPong .NET add-
in.
namespace Microsoft.Dynamics.Nav.Client.PingPong
{
/// <summary>
/// Add-in for pinging the server from the client. The client will respond with a pong.
/// </summary>
[ControlAddInExport("Microsoft.Dynamics.Nav.Client.PingPong")]
public class PingPongAddIn : WinFormsControlAddInBase
{
/// <summary>
/// Event will be fired when the AddIn is ready for communication through its API
/// </summary>
[ApplicationVisible]
public event MethodInvoker AddInReady;
/// <summary>
/// Event will be fired when the specified time by the ping has elapsed.
/// </summary>
[ApplicationVisible]
public event MethodInvoker Pong;
/// <summary>
/// Starts the ping process.
/// </summary>
/// <param name="milliseconds">Number of milliseconds before ponging.</param>
/// <remarks>If a milliseconds are less than the minimum then the MinimumValue is used.</remarks>
[ApplicationVisible]
public void Ping(int milliseconds)
{
...
}
}
The next needed piece of information is the namespace-qualified name of the type annotated with the
ControlAddInExport attribute. This is the type that provides the implementation of the control add-in and which
exposes members annotated with the ApplicationVisible attribute to the AL runtime. In this example this is
Microsoft.Dynamics.Nav.Client.PingPong.PingPongAddIn .
The ControlAddInExport attribute's constructor takes as an argument the name of the control add-in, as
represented in the runtime, and in existing C/AL code. In this example, the name of the control add-in is
Microsoft.Dynamics.Nav.Client.PingPong . This was the last component needed to construct a declaration for this
.NET control add-in in AL. The name of the assembly is used in creating the assembly construct, the namespace-
qualified name of the type is used as the first element in the type declaration, and the name of the control add-
in is used as the alias of the type. You complete the declaration by setting the IsControlAddIn property to true.
This property is used to tell the AL compiler to treat the given type declaration as a .NET control add-in
declaration.
Remember to add the setting "AL: Assembly Probing Paths" in the User Settings or Workspace Settings
specifying the path of the folder containing the assembly so that the compiler can access it. For more
information, see Getting started with Microsoft .NET Interoperability from AL.
dotnet
{
assembly("Microsoft.Dynamics.Nav.Client.PingPong")
{
type("Microsoft.Dynamics.Nav.Client.PingPong.PingPongAddIn"; PingPongAddIn)
{
IsControlAddIn = true;
}
}
}
You can now use the Microsoft.Dynamics.Nav.Client.PingPong from AL, just as you use a native control add-in.
trigger AddInReady()
begin
Message('Ready');
end;
}
}
}
}
Remarks
Only members of the .NET type implementing the control add-in that are annotated with the
ApplicationVisibleAttribute will be accessible from AL. Usages of .NET control add-ins in C/AL are
automatically converted to AL by the Txt2Al conversion tool, but the code will only compile, if you manually
insert the declaration of the control add-in, as outlined above.
If within the same project you have a native AL control add-in and a .NET add-in with the same name, the .NET
add-in will be the one used.
See Also
Migrating from .NET Framework to .NET Standard Get Started with AL
Control Add-In Object
Getting started with Microsoft .NET Interoperability from AL
Subscribing to Events in a .NET Framework Type
Serializing .NET Framework Types
How to: Determine an Assembly's Fully Qualified Name
AL Language Extension Configuration
Subscribing to Events in a .NET Framework Type
2/6/2023 • 2 minutes to read • Edit Online
With .NET Framework interoperability in Dynamics 365 Business Central objects, you can configure a DotNet
variable to subscribe to events that are published by a .NET Framework type. Events are handled by triggers in
the AL code of the Business Central object.
You start by declaring in AL the usage of two .NET types from the System assembly. The first type is
System.Timers.Timer and it will be used to generate .NET events. The second one is called
System.Timers.ElapsedEventArgs and it is required for creating a subscriber to the Elapsed event emitted by the
Timer type.
dotnet
{
assembly(System)
{
type(System.Timers.Timer; MyTimer) {}
type(System.Timers.ElapsedEventArgs; MyElapsedEventArgs) {}
}
}
You can only subscribe to events that are emitted by global variables of the .NET type marked with the
WithEvents attribute. For all the global variables that are marked with this attribute, the compiler will expose the
events available on the type as triggers on the variable. The syntax for declaring these triggers is
{VariableName}::{EventName}(...ParameterList) , but IntelliSense will offer suggestions for the event name and
autocomplete the parameter list.
trigger OnOpenPage()
begin
SetupTimer();
end;
procedure SetupTimer()
begin
timer := timer.Timer(2000);
timer.AutoReset := true;
timer.Enabled := true;
timer.Start();
end;
In Microsoft .NET Framework, serialization is the process of converting an object into a format that can be
transmitted across a network connection. Microsoft .NET Framework interoperability uses serialization for
communication between client-side .NET Framework objects and server-side .NET Framework objects. When
you configure DotNet variables in a Dynamics 365 Business Central object, you can specify .NET Framework
objects to target either the Business Central Windows client or Business Central Server. In some cases, a client-
side object and a server-side object must communicate and share data, such as return values and parameters.
The serialization occurs when the following conditions are true:
When a server-side object is assigned to a client-side object, and vice-versa.
When a server-side object is passed as a parameter in a method call from the server to a client-side
object, and vice-versa.
Serialization requires that the .NET Framework types that are used by the DotNet variables are serializable.
Many types in the Microsoft .NET Framework class library are already serializable. If you are using a .NET
Framework type that cannot be serialized, then you must modify the type to make it serializable.
IMPORTANT
For the Business Central Web client, you cannot implement Microsoft .NET Framework interoperability objects that target
the client.
[Serializable]
public class MyObject
{
code
}
This method requires that you have access to the source code of the .NET Framework assembly.
Basic Serialization of Date Fields
You can use basic serialization only if all data fields in the type are serializable. Fields that are calculated at
runtime cannot be serialized. If a field cannot be serialized, then at runtime, the serialization process will throw
an exception and the AL code execution will fail.
You can exclude fields from the serialization process by decorating the field with the
System.NonSerializedAttribute class.
Custom Serialization Using ISerializable Interface
With custom serialization, you can create an object that controls the serialization of types in another object. This
method is useful when you do not have access to the source code of the assembly that contains the .NET
Framework types that you are implementing with .NET Framework interoperability. The custom object specifies
which types will be serialized and how serialization will be done.
To implement custom serialization, you create a class that implements the ISerializable interface, and decorate
the class with SerializableAttribute. In most cases, you must also implement the
System.Runtime.Serialization.ISerializable.GetObjectData method and a special constructor that is used when
the source object is deserialized. You use the GetObjectData method to populate the SerializationInfo the data
that is required to serialize the source object at runtime.
The common language runtime calls the constructor during deserialization to construct a replica of the source
object. The constructor takes two parameters, a SerializationInfo type and a
System.Runtime.Serialization.StreamingContext type. The StreamingContext parameter describes the source
and destination of a given serialized stream.
Custom Serialization Example
The following code example demonstrates a custom serialization object that implements the basic functionality
that is required for compliance with the ISerializable interface. In the first procedure of this example, you
create a .NET Framework assembly that includes a serializable type. In the second procedure, in the Business
Central development environment, you create a codeunit that includes two DotNet variables for the serializable
type. You set one variable to target the Business Central Windows client and the other to target the Business
Central Server. In AL code, you add code that transfers the value for the DotNet variable on the Business Central
Server to the Business Central Windows client. You will also add code that verifies that the data transfer is
successful.
To c r e a t e t h e c u st o m se r i a l i z a t i o n o b j e c t
[Serializable]
public class SerializeWithInterface : ISerializable
{
// Defines a field that will not be serialized.
[NonSerialized]
private string notSerializedField;
// Defines two fields that will be serialized.
private int serializedIntField;
private string serializedStringField;
// Specifies literal field names.
private const string serializedIntFieldName = “serializedIntField”;
private const string serializedStringFieldName = “serializeStringField”;
// Defines a default constructor that initializes the object with default values.
public SerializeWithInterface()
{
this.serializedIntField = 1;
this.notSerializedField = string.Empty;
this.serializedStringField = string.Empty;
}
// Fills the SerializationInfo object with data that must to be sent to the replicated object.
// Data is stored in the dictionary using the AddValue method.
// The SerializationInfo object is a key/value dictionary.
// The name you use to store the value must match the name used in the constructor.
// For this reason, a string constant is used.
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(serializedStringFieldName, this.serializedStringField);
info.AddValue(serializedIntFieldName, this.serializedIntField);
}
dotnet
{
assembly(SerializationSample)
{
type(SerializationSample.SerializeWithInterface; SerializeWithInterface){}
}
}
begin
// Constructor that instantiates the ServerObject object on the server.
ServerObject := ServerObject.SerializeWithInterface();
// Constructor that instantiates the ClientObject object on the server.
ClientObject := ClientObject.SerializeWithInterface();
// Assign unique values to the data members in the two objects.
ServerObject.SerializedStringField := ‘ServerSide’;
ClientObject.SerializedStringField := ‘ClientSide’;
// Transfer the server object to the client object using serialization.
ClientObject := ServerObject;
// Test if the objects contain the same data.
If ClientObject.SerializedStringField <> ServerObject.SerializedStringField then
Error(‘Client object does not match the server object.’);
Message(‘Server data has been serialized to the client object.’);
end;
}
The line that contains assignment of the Ser verObject to the ClientObject causes the serialization process to
run. When completed, the message Ser ver data has been serialized to the client object appears, which
verifies that the server object has been transferred to the client object.
See Also
Get Started with AL
Getting started with Microsoft .NET Interoperability from AL Migrating from .NET Framework to .NET Standard
.NET Control Add-Ins
Subscribing to Events in a .NET Framework Type
Using Designer
AL Language Extension Configuration
The Microsoft_Application.app File
2/6/2023 • 3 minutes to read • Edit Online
The Microsoft_Application.app file is included with Business Central and is located in the
\Applications\Application\Source folder. The Microsoft_Application.app file logically encapsulates all of the
extensions making up a solution, for example, version 16.0.0.0 of the base and system application package
files, and it provides a convenient way to define and refer to this solution identity.
NOTE
In previous versions the references to base and system application were stated explicitly under dependencies in the
app.json file of the extension. Instead you must now use the Application version property in the app.json file. For
more information, see JSON Files.
The file name of the reference is Microsoft_Application.app and in the app.json file of the application package
file, the name is Application . For code-customized base applications that have their own app ID, the
Microsoft_Application.app file can be modified to reference the app ID of the code-customized base
applications instead. This allows any extensions that are dependent on the Application to resolve to the custom
app ID.
NOTE
The partner who redefines the application must ensure that extensions that are dependent on the Application compile
and work. This can be ensured, for example, by not introducing any breaking changes.
IMPORTANT
If you have modified the Microsoft_Application.app file, you can rename the file name, and change information about
the publisher , but it is important to keep "name": "Application" in the extension, which is what is being checked
for in terms of symbols references. It is also important to keep the propagateDependencies set to true . The version
must be set to the version of the Microsoft base application with which it is compatible. The id must be changed to
reference the app ID of the code-customized base application.
],
"platform": "15.0.0.0",
"showMyCode": true,
"brief": "Application (W1)"
}
If you have a code-customized base application, the file can be edited to reflect the dependency to this instead.
To do so, update the "dependencies": [] section and change the
"appId": "437dbf0e-84ff-417a-965d-ed2bb9650972" to the appId of your code-customized base application. You
can update the "name" and "publisher" information to match too.
...
"dependencies": [
{
"appId": "<appId of the code-customized base app>",
"name": "Customized Base Application",
"publisher": "PartnerSolutions",
"version": "15.3.0.0"
},
...
],
...
{
"id": "e5645aaf-74be-453a-ab50-2e34ec3ee53c",
"name": "Fabrikam Gadgets Management",
"publisher": "Fabrikam",
"version": "15.3.41056.29085",
"logo": "ExtensionLogo.png",
"privacyStatement": "https://go.microsoft.com/fwlink/?LinkId=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
"help": "https://go.microsoft.com/fwlink/?linkid=2104024",
"url": "https://go.microsoft.com/fwlink/?LinkId=724011",
"application": "15.3.0.0",
"dependencies": [
],
"screenshots": [
],
"platform": "15.0.0.0",
"showMyCode": true,
"brief": "Fabrikam Gadgets Mgt."
}
IMPORTANT
Soon up-taking the Application app will also be a mandatory requirement for AppSource apps, enforced by the
AppSource technical validation. Thus, it is highly recommended to change the existing AppSource apps at first
convenience, for example with your next planned app update, and adopt the "application" property for all new
AppSource apps. We also recommend up-taking the Application app for the customized Base Applications on-premise,
and per-tenant-extensions (PTEs) that you use in the Business Central online environments.
See Also
JSON Files
Install an Update
App Identity
Publishing a Code-Customized Base Application for
Business Central On-Prem
2/6/2023 • 4 minutes to read • Edit Online
This topic describes the steps and development environment configuration settings that are needed in order to
customize the Base Application code in Dynamics 365 Business Central on-premises and publish the code-
customized Base Application to the local server.
IMPORTANT
Instead of code-customizing the Base Application, it is strongly recommended to create extensions whenever possible.
NOTE
The steps in this topic are not validated against a Docker environment. If you are running the on-premises installation
and development from Docker, there can be dependencies and other steps that you need to take into consideration.
Prerequisites
Make sure to have the following prerequisites installed to be able to follow the steps in this topic.
Dynamics 365 Business Central on-premises with the AL Language Development Environment option
installed
Visual Studio Code
The AL Language extension
ToolTip = 'Specifies the customer''s name. This name will appear on all sales documents for the
customer.';
trigger OnValidate()
begin
CurrPage.SaveRecord;
end;
}
...
6. Use the Business Central Administration Console to ensure that the settings for developing for on-
premises are correctly set. On the Development tab these must be:
Allowed Extension Target Level is set to OnPrem .
Enable Developer Ser vice Endpoint checkbox is selected.
7. In the app.json file, in the dependencies section, make sure that version is set to the version of the
System Application found in the project under .alpackages . For example:
"dependencies": [
{
"appId": "63ca2fa4-4f03-4f2b-a480-172fef340d3f",
"publisher": "Microsoft",
"name": "System Application",
"version": "16.0.10037.0"
}
],
8. Configure User Settings or Workspace Settings to include the following paths for the
"al.assemblyProbingPaths" setting. For more information, see AL Language Extension Configuration.
"al.assemblyProbingPaths": [
"C:\\Program Files\\Microsoft Dynamics 365 Business Central\\170\\Service",
"C:\\Program Files (x86)\\Microsoft Dynamics 365 Business Central\\170",
"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8",
"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\WindowsPowerShell"
],
9. For improved performance when working with a large project like the Base Application, see the Optimize
Visual Studio Code Editing and Building Performance topic.
10. Next, you must uninstall all extensions from the command line. If you at this point try to just publish the
extension from Visual Studio Code you will get the following error:
The request for path /BC170/dev/apps?SchemaUpdateMode=synchronize&DependencyPublishingOption=ignore
failed with code 422. Reason: The extension could not be deployed because it is already deployed on
another tenant.
You get the error because the extensions are installed in the global scope. If you want to publish an
extension from Visual Studio Code, within the developer scope, you will have to first uninstall and then
unpublish the extensions from the command line.
Ideally, you should uninstall the application that you want to update and all its dependencies. To uninstall
the Base Application use the following cmdlet:
Uninstall-NavApp -Name "Base Application" -ServerInstance BC170 -Force
NOTE
Alternatively, uninstall everything using the following cmdlet.
Get-NAVAppInfo -ServerInstance BC170 | %{Uninstall-NAVApp -Name $_.Name -ServerInstance BC170 -
Force}
11. Having uninstalled, the next step is to unpublish the application and all of its dependencies. This needs to
happen before we can publish it. The following command can be used if there are no dependencies to the
Base Application:
Unpublish-NavApp -Name "Base Application" -ServerInstance BC170
But if there are dependencies on the Base Application this will give an error. To solve this, you must
unpublish all the applications with dependencies on the Base Application. This is easier to do using a
script that recursively removes the dependencies. Use Windows PowerShell ISE to create a new script
with the following lines of code:
NOTE
Use "dependencyPublishingOption": "Ignore" in the launch.json file to only publish this extension. For
more information, see JSON Files.
14. Import a license with rights to publish the extension. For example:
Import-NAVServerLicense -ServerInstance BC -LicenseFile "C:\Users\mylicense.BCLicense"
15. Press Ctrl+F5 to publish the modified Base Application as an extension from Visual Studio Code.
The Base Application is now published with the small customization of bolding the text in the Name field on the
Customer Card page.
See Also
Unpublishing and Uninstalling Extensions
Developing Extensions
Extending Application Areas
2/6/2023 • 5 minutes to read • Edit Online
Application areas represent a feature in the system that offers developers, administrators, and users the ability
to define differentiated user experiences.
Application areas are mapped to controls to show or hide them on page objects to enable more or fewer
business scenarios.
IMPORTANT
The code used in this example is still under active development and might be subject to change in the future.
The following example extends the Customer List page. The field ExampleField is added and it is followed by
a series of properties. The ApplicationArea property sets the application areas that apply to the control and in
this code, ExampleAppArea is assigned to it.
IMPORTANT
If your extension fails to use ApplicationArea in any controls or actions, they will not be visible when you use an
experience tier.
The OnOpenPage trigger will display the message only if ApplicationArea is enabled.
pageextension 50100 CustomerListExt extends "Customer List"
{
layout
{
addafter(Name)
{
field(ExampleField; "Name 2")
{
Caption = 'Example Field';
ApplicationArea = ExampleAppArea;
ToolTip = 'This is a field added by an example extension';
Importance = Promoted;
}
}
}
trigger OnOpenPage()
var
EnableExampleExtension : Codeunit "Enable Example Extension";
begin
if EnableExampleExtension.IsExampleApplicationAreaEnabled() then
Message('App published: Example Extension');
end;
}
The codeunit Install Example Extension is of the subtype Install and it enables the application area inside the
OnInstallAppPerCompany trigger.
codeunit 50101 "Install Example Extension"
{
Subtype = Install;
trigger OnInstallAppPerCompany()
var
EnableApplicationArea : Codeunit "Enable Example Extension";
begin
if(EnableApplicationArea.IsExampleApplicationAreaEnabled()) then
exit;
EnableApplicationArea.EnableExampleExtension();
The registration of the application area inside an experience tier is made inside the
OnGetEssentialExperienceAppArea . There are different versions of this event, one for each experience tier
and in this case, Essential is chosen. This will make the extension visible inside the Essential experience and the
event exposes an Application Area Setup temporary record; TempApplicationAreaSetup , to the
Application Area Setup table. At this point, to enable the application area, this must be set to true.
NOTE
This event is important because it is called every single time an experience tier is reset, which can happen because of
many reasons.
Another thing that is possible inside these methods is to modify the experience tier. You can also modify other
application areas, such as creating an extension that extends the Fixed Assets functionality. By subscribing to
OnValidateApplicationAreas , the application area inside an experience tier is validated.
OnValidateApplicationAreas is guaranteed to be executed after the events in the
OnGet...ExperienceAppArea family. The validation is necessary in the presence of extensions concurrently
manipulating the same application areas.
In case a needed application area is not enabled, the suggested action is to show an error and turn off the
extension to avoid unintended behavior. However, if the functionality controlled by this application area is of
secondary importance and its loss does not affect the rest of the extension, it is also appropriate to keep the
extension enabled.
codeunit 50100 "Enable Example Extension"
{
// Extend and modify Essential experience tier with "Example App Area"
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Application Area Mgmt.",
'OnGetEssentialExperienceAppAreas', '', false, false)]
local procedure RegisterExampleExtensionOnGetEssentialExperienceAppAreas(var TempApplicationAreaSetup:
Record "Application Area Setup" temporary)
begin
TempApplicationAreaSetup."Example App Area" := true;
// Modify other application areas here
end;
// Validate that application areas needed for the extension are enabled
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Application Area Mgmt.", 'OnValidateApplicationAreas',
'', false, false)]
local procedure VerifyApplicationAreasOnValidateApplicationAreas(ExperienceTierSetup: Record "Experience
Tier Setup"; TempApplicationAreaSetup: Record "Application Area Setup" temporary)
begin
if ExperienceTierSetup.Essential then
if not TempApplicationAreaSetup."Example App Area" then
Error('Example App Area should be part of Essential in order for the Example Extension to
work.');
end;
// Helpers ................................................................
procedure IsExampleApplicationAreaEnabled() : Boolean
var
ApplicationAreaSetup: Record "Application Area Setup";
ApplicationAreaMgmtFacade: Codeunit "Application Area Mgmt. Facade";
begin
if ApplicationAreaMgmtFacade.GetApplicationAreaSetupRecFromCompany(ApplicationAreaSetup,
CompanyName()) then
exit(ApplicationAreaSetup."Example App Area");
end;
procedure EnableExampleExtension()
var
ApplicationAreaMgmtFacade: Codeunit "Application Area Mgmt. Facade";
begin
ApplicationAreaMgmtFacade.RefreshExperienceTierCurrentCompany();
end;
}
IMPORTANT
Adding the application area Advanced to the experience will mean that you lose some of the simplification made to
pages. For example, you will see more actions duplicated on many pages, compared to Business Central where the
experience is intended to be simpler than in Dynamics NAV. You must also consider that we plan to re-tag the Advanced
actions/controls and add them to the Essentials and/or Premium experiences in a future release.
See Also
ApplicationArea Property
ApplicationArea Method
AccessByPermission Property
Properties
Extending Item Charge Distribution Methods
2/6/2023 • 5 minutes to read • Edit Online
To ensure correct valuation, your inventory items must carry any added costs, such as freight, physical handling,
insurance, and transportation that you incur when purchasing or selling the items.
Users can add these costs by adding a Charge (Item) line to the involved purchase or sales document. For more
information, see Use Item Charges to Account for Additional Trade Costs in application help.
Item charges are distributed over other item lines in the document according to a distribution method.
Dynamics 365 Business Central offers four distribution methods out of the box: Equally , By Amount , By
Weight , and By Volume . This article explains how to remove or add item charge distribution methods. The
article describes the method for purchases. The steps are similar for sales, except the events are located in
codeunit 5807, Item Charge Assgnt. (Sales) .
To enable extension of item charges distribution methods, two events can be found in codeunit 5805, Item
Charge Assgnt. (Purch.) . The work consists of the following two tasks:
1. In the OnBeforeShowSuggestItemChargeAssignStrMenu event, you manipulate the options that are
presented to users. You can remove, add, and change the order of the options.
Keep in mind that other extensions may also manipulate the options.
You should not assume that an option will exist, nor should you write code that may remove an option
added by another extension.
2. In the OnAssignItemCharges event, you distribute the item charge amount over the item lines
according to your new distribution method.
You must verify that the option selected by the user is your new option. If it is not, then exit without
taking action.
When you have distributed the amount over the lines, you must set the ItemChargesAssigned boolean
to true. If you do not set this boolean to true, an error will occur.
The following procedures show how to extend the item charges distribution methods:
1. Add a new option to the item charges distribution methods in the
OnBeforeShowSuggestItemChargeAssignStrMenu event.
2. Add a new distribution method for item charges.
3. Call the new distribution method in the OnAssignItemCharges event.
The procedures are based on an example where the By Fair y Dust option is added to the string menu
(STRMENU) and added to the CASE statement.
NOTE
To complete this example you will have to add a new field Fair y Dust to the Purchase Line table and other relevant
tables and pages.
if TempItemChargeAssgntPurch.Findset(true) then
repeat
// Calculate Fairy Dust to assign to the line
GetItemValues(TempItemChargeAssgntPurch, LineArray);
if TotalFairyDust <> 0 then
TempItemChargeAssgntPurch."Qty. to Assign" :=
(TotalQtyToAssign * LineArray[2] * LineArray[1]) / TotalFairyDust + QtyRemaining
else
TempItemChargeAssgntPurch."Qty. to Assign" := 0;
// Assign Fairy Dust to the line and calculate the remaining Fairy Dust to assign
ItemChargeAssignmentPurch.Get(
TempItemChargeAssgntPurch."Document Type",
TempItemChargeAssgntPurch."Document No.",
TempItemChargeAssgntPurch."Document Line No.",
TempItemChargeAssgntPurch."Line No.");
ItemChargeAssignmentPurch."Qty. to Assign" := Round(TempItemChargeAssgntPurch."Qty. to
Assign", 0.00001);
ItemChargeAssignmentPurch."Amount to Assign" :=
ItemChargeAssignmentPurch."Qty. to Assign" * ItemChargeAssignmentPurch."Unit Cost" +
AmountRemaining;
AmountRemaining := ItemChargeAssignmentPurch."Amount to Assign" -
Round(ItemChargeAssignmentPurch."Amount to Assign", Currency."Amount Rounding Precision");
QtyRemaining := TempItemChargeAssgntPurch."Qty. to Assign" - ItemChargeAssignmentPurch."Qty.
to Assign";
ItemChargeAssignmentPurch."Amount to Assign" :=
Round(ItemChargeAssignmentPurch."Amount to Assign", Currency."Amount Rounding Precision");
ItemChargeAssignmentPurch.Modify(false);
until TempItemChargeAssgntPurch.Next = 0;
TempItemChargeAssgntPurch.DeleteAll(false);
end;
See Also
Extending Application Areas
Extending Price Calculations
2/6/2023 • 24 minutes to read • Edit Online
If you offer special prices and line discounts for sales and purchases, Dynamics 365 Business Central can
automatically calculate prices on sales and purchase documents, and on job and item journal lines. The price is
the lowest permissible price with the highest permissible line discount on a given date. Dynamics 365 Business
Central automatically calculates the price when it inserts the unit price and the line discount percentage for
items on new document and journal lines. For more information, see Price Calculation.
This topic describes how price calculations are implemented in 2020 release wave 1 (referred to as "Business
Central Version 16" in the illustrations), and provides comparisons with 2019 release wave 2 (referred to as
Business Central Version 15 in the illustrations) to show what we have changed. It also provides some examples
of how you can extend price calculations in 2020 release wave 1 and later.
The Price Calculation Setup table has the Code field as its primary key. The value of the field is calculated by
combining the values in the Method, Type, Product Type, and Implementation fields. For example, it is [1-1-0]-
7003 for the setup line when the following fields contain the following values:
Method contains Lowest Price
Type contains Sale
Product Type contains All
Implementation contains Business Central (Version 15.0)
You can have multiple setups with the same combination of method, type, and product type. The
implementation should always be different though, because each implementation provides different
calculations. The default implementation is defined by the Default field. For example, in 2020 release wave 1
the following setups are available:
By default, all sales lines use the Business Central (Version 15.0) implementation to calculate prices, unless the
second line has a detailed setup that defines exceptions.
The Price Calculation method on the document line searches for a setup that that has a matching combination of
the method, the price type, and product type on the document line. The method then searches for detailed lines
that contain exceptions for the combination of a source group (Customer, Vendor, and Job) and an product (item,
resource, and so on) on the document line. If a matching setup is found its implementation is used to calculate a
price. If there is no matching setup exception, we use the default implementation.
For example, let's say we have a line on a sales order for Customer 20000 contains item 1000. The default
implementation for the sale of any asset is Business Central (Version 15.0), but the Business Central (Version
16.0) implementation contains a detailed setup line for Item 1000. That means that the Business Central (Version
16.0) implementation will calculate the price.
You can enter detailed setup records for non-default setup lines. The following image shows the relation
between a setup line and a detailed setup.
For a Business Central (Version 15.0) implementation, you can only edit the Default field. The records are
inserted by the codeunits that subscribe to the OnFindSupportedSetup() event in the Price Calculation Mgt.
codeunit. The two price calculation implementation codeunits add pairs of such records, one for the sale of
products and another for purchases.
Because the Price Calculation Setup table is extensible, you can add new fields to the key by subscribing to the
OnAfterDefineCode() event.
Each codeunit that implements the Price Calculation interface must subscribe to the OnFindSupportedSetup()
event of the Price Calculation Mgt codeunit to fill the price calculation setup table with new options.
Price Type
The Type field is an extensible Price Type enum that contains the following values:
Any (0)
Sale (1)
Purchase (2)
The values are part of the composite key in the Price Calculation Setup table. Sales and service lines use the Sale
type, purchase lines use the Purchase type, and job or item journal lines use both for calculating price and cost.
The Any value is the default value, and is used when a line contains both a price and a cost.
Product Type
The Product Type field is an extensible Price Asset Type enum that contains the following values:
All (0)
Item (10)
Item Discount Group (20)
Resource (30)
Resource Group (40)
Service Cost (50)
G/L Account (60)
The value in the Product Type field is part of the composite key in the Price Calculation Setup table. If the only
setup record contains Product Type - All , special price calculation implementations per product type are not
needed. The default implementation will be used regardless of the product type in the document line. If you
need different implementations, you must add a setup line with another product type. For example, the
following table shows a Resource Pricing implementation with a resource asset type.
Because only one record has the combination of Lowest Price, Sale, and Resource it will be the default. If a sales
line sells a resource, its price will be calculated by the Resource Pricing implementation. All other products will
use the Business Central (Version 15.0) implementation.
Price Calculation Method
The Method field is an extensible Price Calculation Method enum that contains the following values:
Not defined (0)
Lowest Price (1)
The method value is part of the composite key in the Price Calculation Setup table. A sales document line
inherits the method value from the sales header, which in turn inherits it from one of the following, depending
on where it's defined:
Customer
Customer price group
Sales & Receivable Setup table
The Sales & Receivable Setup table defines the default method, Lowest Price, for all sales prices. If you want to
use a different method, you can specify it on a customer price group or a customer. You cannot edit the method
on sales document headers or lines.
The Purchase & Payables Setup table also defines the default method for all purchase prices. You can redefine it
for a certain vendor. You cannot edit the method on purchase document headers or lines.
Now we'll extend the Price List Line table with the same field.
tableextension 50011 "Doc. No in Price List Line" extends "Price List Line"
{
fields
{
field(50000; "Document No."; Code[20])
{ }
}
}
Now we'll subscribe to the 'OnCopyFromSalesPrice' event to copy data from "Sales Price" to "Price List Line"
table.
Interface Objects
AL interface objects are important for extensibility. They define the capabilities that are available to an object,
and allow implementations to differ as long as they comply with the interface requirements. For more
information, see Interfaces in AL.
Price calculation uses the following AL interface objects:
Price Calculation
Line With Price
Price Source Group
Price Source
Price Calculation
The Price Calculation interface defines methods that calculate amounts and discount percentages on journal and
document lines.
In Business Central (Version 15.0) and earlier, the Price Calculation – V15 interface implementation calls the
Sales Price Calc. Mgt. and Purch. Price Calc. Mgt. codeunits to calculate prices. In Business Central (Version 15.0),
the implementation codeunit is Price Calculation – V16. This codeunit works the same as "Price Calculation –
V15" but is based on a different price line table and makes it easier to extend price calculations.
The Price Calculation - Undefined implementation is used when the setup line does not contain a match for the
document line. This implementation will display a message that states the combination that is missing.
You can add a new implementation codeunit or reuse one as a starting point and rewrite it as needed. For the
new codeunit, you must extend the Price Calculation Handler enum that implements Price Calculation interface
and is used in the Price Calculation Setup table.
Afterwards you can insert a record in the Price Calculation Setup table and set the new implementation as the
default.
The following code in codeunit 7001 "Price Calculation Mgt." returns a Price Calculation interface that initialized
with the instance of the Line With Price interface that depends on the setup record:
procedure GetHandler(
LineWithPrice: Interface "Line With Price";
var PriceCalculation: Interface "Price Calculation") Result: Boolean;
var
PriceCalculationSetup: Record "Price Calculation Setup";
begin
Result := FindSetup(LineWithPrice, PriceCalculationSetup);
PriceCalculation := PriceCalculationSetup.Implementation;
PriceCalculation.Init(LineWithPrice, PriceCalculationSetup);
end;
After the price calculation implementation is defined, the document line typically calls the methods in the
interface that calculate the price and discount. The following code is used in the Sales Line table:
var
Line: Variant;
begin
PriceCalculation.ApplyDiscount();
PriceCalculation.ApplyPrice(CalledByFieldNo);
PriceCalculation.GetLine(Line);
Rec := Line;
end;
The following example shows a typical use of the codeunits in the Sales Line table.
var
PriceCalculationMgt: codeunit "Price Calculation Mgt.";
PriceCalculation: Interface "Price Calculation";
SalesLinePrice: Codeunit "Sales Line - Price";
PriceType: Enum "Price Type";
begin
SalesLinePrice.SetLine(PriceType::Sale, SalesHeader, Rec);
PriceCalculationMgt.GetHandler(SalesLinePrice, PriceCalculation);
end;
The SalesLinePrice codeunit is declared directly in the context of the sales line. The instance is initialized by the
interface's SetLine() method, and then passed to the GetHandler() method for PriceCalculation initialization
because all Price Calculation implementation codeunits include an instance of the Line With Price interface,
which stores data about document and journal lines. The following example shows how to declare the interface
variable.
var
CurrLineWithPrice: Interface "Line With Price";
Price Source
The Price Source interface defines methods for price sources, such as vendors or customers. The list of
supported sources is defined by the Price Source Type enum. The interface is used in the Price Source table to
validate the primary key fields and look up respective tables, as shown in the following table.
Example
The Price Source enum implements the Price Source interface and defines Price Source - Customer as the
implementation for the value Customer.
enum 7003 "Price Source Type" implements "Price Source", "Price Source Group"
value(11; Customer)
{
Implementation = "Price Source" = "Price Source - Customer",
"Price Source Group" = "Price Source Group - Customer";
}
The Price Source table has a public method LookupNo() that opens a different page depending on the Source
Type value. The PriceSourceInterface variable gets the implementation value from the Source Type enum value
and then calls the interface's IsLookupOK(Rec) method.
Because the source type Customer implementation is the "Price Source - Customer" codeunit, the interface calls
its IsLookupOK() method and then opens the Customer List page.
codeunit 7032 "Price Source - Customer" implements "Price Source"
NOTE
The prices, names, and combinations in this example are completely fictional and intended only to support the scenario
described here. They do not reflect anything in the real-world.
We have the following licenses in our price list. If you buy 70061 or 70062 alone their prices do not change.
However, let's say that we want to offer discounts when one license is purchased along with another. For
example, we want to sell 70064 at a reduced monthly rate when it's purchased in combination with 70061 or
70062. Our list would then look like this.
M O N T H LY B A SE P RIC E P ER
A SSET N UM B ER NAME USER B UN DL E P RIC E
70065 Customer Service Pro $50 $20 and $21 when bundled
with 70061 or 70062.
The following image shows an example of a Sales Line page that is extended with the Attached to Line No. field.
Notice that the prices are changed based on the combinations of licenses.
Let's look at some sample extensions that will implement this logic for us.
The first table extension adds a new field named Attach to Line No. to the Sales Line table and recalculates
pricing when we make a change. This field will let us create the combinations that determine our discounts. It
also copies the GetPriceCalculationHandler() function from the Sales Line table.
The following page extension adds the Attach Line No. field to the Sales order page (subform).
The following table extension adds the Attach to Item No. field to the "Price Calculation Buffer" table.
The calculation that links these three new fields is based on the following events:
OnAfterSetFilters() – Sets the filter on the price list line when searching for the price.
OnAfterFillBuffer() – Copies the value from the sales line to the buffer.
FindItemToAttachToInLine() - Defines the value of the item number stored in the sales line that we attach to.
The new price calculation capabilities are not available in the user interface. When a page does become
available, either, from Microsoft or one that you develop yourself, you can use the following sample code to
extend the page with a new control.
The Price Asset Type enum implements the Price Asset interface. Add a Price Asset - Fixed Asset codeunit
that will implement this interface for the Fixed Asset value. Some of the interface's methods are not relevant for
fixed assets, so we will leave them empty but implement the methods from the codeunit. For an example, see
the Price Asset - G/L Account codeunit. The following example will enable the Fixed Asset product type in
price list lines.
- GetNo(),
- GetId(),
- IsLookupOk(),
- IsAssetNoRequired(),
- FilterPriceLines(),
- FillFromBuffer(),
- FillAdditionalFields()
procedure FilterPriceLines(PriceAsset: Record "Price Asset"; var PriceListLine: Record "Price List
Line") Result: Boolean;
begin
PriceListLine.SetRange("Asset Type", PriceAsset."Asset Type");
PriceListLine.SetRange("Asset No.", PriceAsset."Asset No.");
end;
local procedure UpdateUnitPriceByField(var SalesLine: Record "Sales Line"; xSalesLine: Record "Sales
Line"; CalledByFieldNo: Integer; CurrFieldNo: Integer)
var
SalesHeader: Record "Sales Header";
PriceCalculation: Interface "Price Calculation";
begin
SalesHeader.Get(SalesLine."Document Type", SalesLine."Document No.");
SalesLine.TestField("Qty. per Unit of Measure");
SalesLine.ClearFieldCausedPriceCalculation();
end;
}
Now we can test the price calculation. In Dynamics 365 Business Central, open the Sales Price List and add a
price line for the product with a minimum quantity of 0, and one with 5.
If we create a sales order with lines for the minimum quantities of the product, the unit prices are calculated
correctly.
enumextension 50003 "Location Sales Source Type" extends "Sales Price Source Type"
{
value(50001; Location)
{
Caption = 'Location';
}
}
The Price Source Type enum implements the Price Source and Price Source Group interfaces. We don't need
special source group handling here, and can reuse the existing implementation codeunit Price Source Group -
Customer . For the Price Source interface, we must add a new implementation codeunit Price Source -
Location . For examples, see the existing implementations of the Price Source interface.
The following example enables the new Applies-to Type on price lists.
codeunit 50003 "Price Source - Location" implements "Price Source"
{
var
Location: Record Location;
ParentErr: Label 'Parent Source No. must be blank for Location source type.';
Now lets ensure that price calculations include the new applies-to type.
To recalculate the price, we can subscribe to events that pass the sales line by reference. For example, the
OnValidateLocationCodeOnAfterSetOutboundWhseHandlingTime event. We'll call the
UpdateUnitPriceByLocationCode() method, which is a simplified version of the
UpdateUnitPriceByField() method that runs the price calculation on the Sales Line table.
To add the location in the source list for price calculations, we'll subscribe to the OnAfterAddSources event
of Codeunit "Sales Line - Price," and add the Location Code as a source of type Location .
The following example shows how.
Now we can test the price calculation. In this example, we have an East location where we keep item 1896-S,
and the item has prices for all customers.
We'll create a sales order and add four lines for our item. When we choose a location code, the value in the Unit
Price Excl. VAT changes.
Example: Add Hierarchical Price Calculations
This example adds a new price calculation method that changes the existing implementation to prioritize a
customer price over all other customer price, even if the price is higher. This requires a small adjustment to how
the price source list is generated, because the source list includes levels to implement hierarchical calculations.
The Price Calculation Method implements the price calculation methods. The following examples show how
to extend the enum with the new value.
Now we can set up a price calculation method and see how it works in a sales order. Let's create a new price
calculation method named Hierarchical with one implementation for the sales type, as shown in the following
images.
On the Customer Card page for customer 10000, in the Price Calculation Method field we'll choose
Hierarchical , and in the Customer Price Group field we'll choose PRICEGROUP .
In the price list, we'll create price lines for item 1900-S so that the lowest price is for All Customers and the
highest is for customer 10000, as shown in the following image.
Now we'll create a sales order for customer 10000, and add a line for item 1900-S. The highest price is
suggested for the line because it is specified for the customer. If we clear the Price Calculation Method field
on the customer card, the lowest price will be suggested for the line if we create another order.
See Also
Extending Application Areas
Extending Pages Previously Based on the Date
Virtual Table
2/6/2023 • 2 minutes to read • Edit Online
Pages that previously had the Date virtual table as their source table have been redesigned so that they are
based on buffer tables instead. This way, base application pages such as Item Availability Lines and Res.
Availability Lines can now be extended.
To perform extensions on such pages, you must first extend the underlying buffer table. Then you create a
method that calculates and updates the values of the extended fields and subscribe it to the OnAfterCalcLine
event of the page.
Example
The following example illustrates how to add two new fields, "Add. -Currency Debit Amount" and
"Add. -Currency Credit Amount" , to the G/L Account Balance Lines page, which used to be based on the Date
table.
The first step is to create a Table Extension object and add the two fields, "Add.-Currency Debit Amount" and
"Add.-Currency Credit Amount" , to the G/L Account Balance Buffer source table. Then you create a Page
Extension object to display the fields in the G/L Account Balance Lines page. This is shown in the following
code.
tableextension 50001 GLAccBalanceBufferExt extends "G/L Acc. Balance Buffer"
{
fields
{
field(50001; "Add.-Currency Debit Amount"; Decimal)
{
}
field(50002; "Add.-Currency Credit Amount"; Decimal)
{
}
}
}
// Calculate values
GLAccount.CalcFields("Add.-Currency Credit Amount", "Add.-Currency Debit Amount");
end;
}
See Also
Page Extension object
Page object
CalcFields Method
Extending the Data Archive Extension
2/6/2023 • 2 minutes to read • Edit Online
The Data Archive extension provides a basic framework for archiving and backing up data as part of date
compression. When you use date compression you specify a date range and all entries within the range are
consolidated into a single entry, and the originals are deleted. For more information, see Compress Data with
Date Compression. However, there might be value in keeping that data, so rather than deleting it, you can use
the Data Archive extension to archive it for later use.
This article provides an example of how you can use the objects in the Data Archive extension so that your
application can also archive data. You'll use the Data Archive codeunit, which is available in the System
Application.
The following patterns of use are supported:
Store individual records by calling the SaveRecord(Record) method.
Store a record set by calling the SaveRecords(RecordRef ) method.
Start recording deletions by calling the StartSubscriptionToDelete() method in the beginning of your code,
and StopSubscriptionToDelete() after records have been deleted. Note that this pattern records all deletions,
including those that happen in related tables and intermediate tables that might be used in the process
(though temporary records are not recorded).
NOTE
Recording deletions relies on the global database triggers, so for any deletions that have already been made on the
relevant records, and if the change log is not active for that table, you should consider using
StartSubscriptionToDelete(true ) to reset the session. Resetting the session will, however, also reset the state in the object,
so we recommend caution when you test or use it.
procedure CreateAndStartLoggingDeletions(Description: Creates a new archive entry, resets the session and starts
Text): Integer logging all new del
procedure Open(ID: Integer) Opens an existing archive entry so more can be added to it
procedure Save() Saves and closes the currently open archive entry.
procedure DiscardChanges() Discards any additions and closes the currently open archive
entry.
procedure SaveRecord(RecordVar: Variant) Saves the supplied record to the currently open archive
procedure SaveRecord(var RecRef: RecordRef) entry.
procedure SaveRecords(var RecRef: RecordRef) Saves all records within the filters to the currently open
archive entry.
procedure DataArchiveProviderExists(): Boolean Informs the consumer app whether there is a provider for
this interface.
See Also
The Data Archive Extension
The Microsoft_Application.app File
Extending Application Areas
Extending Document Sharing and OneDrive for
Business Integration
2/6/2023 • 6 minutes to read • Edit Online
Business Central developers can tap into Microsoft 365 native file viewers and file sharing capabilities. This
article explains the document sharing capability. You'll learn how it's used with OneDrive for Business, and how
you can extend it.
Overview
Standard functionality in Business Central makes it easy for users to store, manage, and share files with other
people through OneDrive for Business. On most pages where files are available for downloading, users will find
an Open in OneDrive and Share action. They'll see this action, for example, on reports in the Repor t Inbox
or on files attached to records. For more information about the user experience, see Business Central and
OneDrive for Business Integration.
In the application code, the document sharing and OneDrive capabilities are divided between the system
application and the base application. The system application provides that platform working with document
sharing services—the base application makes it specific to OneDrive. As an AL developer, you can use the
system and base applications to extend the OneDrive capabilities. Or even target another document sharing
service.
NOTE
The Share action was introduced in Business Central 2022 release wave 1.
System application
The document sharing functionality is provided by the Document Sharing module. This module enables
document sharing flows through a valid document service, like OneDrive.
The method returns true if Document Sharing is enabled. Use this method as a quick test to, for example,
control visibility of a share action.
The OnRun() trigger and Share(var DocumentSharingRec: Record "Document Sharing") method raise two events
when run:
OnCanUploadDocument(var CanUpload: Boolean) for testing whether there are any document services that
can handle the upload.
OnUploadDocument(var DocumentSharing: Record "Document Sharing" temporary; var Handled: Boolean) for
uploading when the document to the service.
For more information about the API, see Document Sharing Module in the microsoft/ ALAppExtensions repo on
GitHub.
Base application
To support integration with OneDrive for Business, the base application uses the document sharing module of
the system application. Keep in mind that OneDrive itself is built on top of the SharePoint file platform.
Integration with OneDrive is made available through the SharePoint service on Microsoft Azure.
NOTE
With Business Central online the connection to the SharePoint service is done automatically. With on-premises, you have
to set it up manually. For more information, see Configuring Business Central On-premises for OneDrive Integration.
The core to the base application functionality for OneDrive integration is codeunit 9510 Document Ser vice
Management . This codeunit provides functions for storing documents to OneDrive through the SharePoint
service. Some points of interest are described below.
The base application is used to specify the URL of the document to be opened in OneDrive. The document
information is stored as record in the Document Sharing table. Documents can be stored and passed to
OneDrive as either BLOB or Media data types.
Codeunit 9510 Document Ser vice Management includes four procedures that run the Document Sharing
codeunit of the system application to start the document flow for either opening the document in OneDrive or
sharing the document with other in OneDrive:
M ET H O D DESC RIP T IO N
OpenInOneDrive(FileName: Text; FileExtension: Text; For copying documents stored as BLOBs to OneDrive and
InStream: InStream) opening the documents.
ShareWithOneDrive(FileName: Text; FileExtension: For copying documents stored as BLOBs to OneDrive and
Text; InStream: InStream) sharing the documents with other people.
NOTE
With Business Central 2022 release wave 2, the way that you promote actions on pages or page extensions has changed.
Promoting actions is defined in a specific section of the page definition and contains a reference to the action. For more
information, see Promoted Actions.
trigger OnAction()
var
TempBlob: Codeunit "Temp Blob";
DocumentServiceManagement: Codeunit "Document Service Management";
InStr: InStream;
begin
GetInvoice(TempBlob);
TempBlob.CreateInStream(InStr);
action(ShareInOneDrive)
{
// The properties provide a look and feel that's consistent with the OneDrive experience in
other places of the base application.
ApplicationArea = Basic, Suite;
Caption = 'Share';
ToolTip = 'Copy the file to your Business Central folder in OneDrive and share it with other
people.', Comment = 'OneDrive should not be translated';
Image = Share;
Promoted = true;
PromotedCategory = Category6;
PromotedOnly = true;
trigger OnAction()
var
TempBlob: Codeunit "Temp Blob";
DocumentServiceManagement: Codeunit "Document Service Management";
InStr: InStream;
begin
GetInvoice(TempBlob);
TempBlob.CreateInStream(InStr);
var
ShareOptionsEnabled: Boolean;
SalesInvoiceName: Label 'Sales Invoice %1';
trigger OnOpenPage();
var
DocumentSharing: Codeunit "Document Sharing";
begin
ShareOptionsEnabled := DocumentSharing.ShareEnabled();
end;
FAQ
Do I have to use the base application?
No. You can just use the system application. In this case, you'll have to create a codeunit, similar 9510
Document Ser vice Management , that handles the storage of documents and passing them to the online
service. The codeunit should subscribe to the events raised by codeunit 9560 Document Sharing .
Can I move files to OneDrive in the background?
No, this feature is designed for user interaction.
Can I specify filename and folder?
Yes, when you set record on the Document Sharing temporary table. But we'll provide better support for this
scenario in a later release.
See Also
Business Central and OneDrive for Business Integration
Overview of the System Application
Extending Application Areas
Extending Customer, Vendor, and Item Templates
2/6/2023 • 3 minutes to read • Edit Online
You can extend customer, vendor, and item templates, or create your own template and use it for primary tables.
The following sections provide examples.
keys
{
key(Key1; Code)
{
Clustered = true;
}
}
}
The following card and list pages for the new template allow you to edit the template, or select it when you
create a new resource.
page 50104 "Resource Template Card"
{
PageType = Card;
SourceTable = "Resource Template";
layout
{
area(Content)
{
group(General)
{
Caption = 'General';
field(Code; Code)
{
ApplicationArea = All;
}
field("Template Description"; "Template Description")
{
ApplicationArea = All;
}
}
group(Details)
{
Caption = 'Details';
layout
{
area(Content)
{
repeater(Templates)
{
field(Code; Code)
{
ApplicationArea = All;
}
field("Template Description"; "Template Description")
{
ApplicationArea = All;
}
}
}
}
}
The following management codeunit runs the template list page for selecting templates when you create a new
resource. It also transfers data from the Extension Field and Resource Group No. fields from the template to
the Resource record.
trigger OnRun()
begin
end;
var
ResourceNewMode: Boolean;
ResourceNewMode := false;
SrcResource.Init();
SrcResource.Insert(true);
Resource.Copy(SrcResource);
end;
exit(false);
end;
See Also
Extending Application Areas
Extend Email Capabilities
2/6/2023 • 7 minutes to read • Edit Online
Business Central offers built-in email capabilities that cover the needs of most businesses. You can share
documents and information by email directly from Business Central.
However, you might have a bright idea for something extra that would benefit your, or your customers',
business. For example, you might want to use an email scenario that we don't provide. This article describes how
you can extend the key components of our standard email capabilities.
C O M P O N EN T DESC RIP T IO N
Email scenarios Define the business processes for which an email account will
be used by default.
Email address book lookup Sets how you find email addresses for specific entities.
Email view policies Determine who has access to which email messages.
Email accounts and connectors Specify the email providers and accounts that are connected
to Business Central.
Email Outbox and Sent Email pages Contain messages that haven't been sent, or have been sent,
respectively.
We'll explore each of these components in more depth, and provide an example of how to extend their
capabilities.
Email scenarios
Email scenarios are processes that involve sending a document. For example, a sales or purchase order or a
notification that gives an external accountant access to your Business Central. You can use specific email
accounts for specific scenarios. The following are a few examples:
All users always send sales documents from account A.
All users always send purchase documents from account B.
All users always send warehouse or production documents from account C.
The following diagram shows the relationship between the objects for email scenarios.
The following code example shows how to extend the Email Scenario enum by adding a new scenario named
BC LE Scenario . After you extend the enum, the new BC LE option is available in the Email Scenario field. You
can assign the scenario to accounts on the Email Scenarios page, or by using the
EmailScenario.SetEmailAccount() method.
{
value(999888; BCLEScenario)
{
Caption = 'BC LE Scenario';
}
}
The following code example shows how to extend the Email Address Entity enum by adding a BCLE Entity
option. The BCLE entity has an email address that we want to be able to access.
{
value(50110; "BCLE Entity")
{
Caption = 'BCLE Entity';
}
}
After you extend the Email Address Entity enum, subscribe to the OnGetSuggestedAddresses and
OnLookupAddressFromEntity events. These events do the following:
OnGetSuggestedAddresses gets email addresses from the records in the table that are related to an email that
you are composing and displays them in the address book.
OnLookupAddressFromEntity opens a modal dialog where you can choose the email addresses to add to the
address book.
The following examples show how to implement the events.
[IntegrationEvent(false, false)]
internal procedure OnGetSuggestedAddresses(TableId: Integer; SystemId: Guid; var Address: Record "Email
Address Lookup")
[IntegrationEvent(false, false)]
internal procedure OnLookupAddressFromEntity(Entity: Enum "Email Address Entity"; var Address: Record "Email
Address Lookup"; var IsHandled: Boolean)
var
NoRecordsFoundMsg: Label 'No %1 found with an email address.', Comment = '%1 Entity type';
NoRecordsFoundMsg: Label 'No %1 found with an email address.', Comment = '%1 Entity type';
BCLEEntityList.SetTableView(BCLEEntity);
BCLEEntityList.LookupMode := true;
BCLEEntityList.SetSelectionFilter(BCLEEntity);
if BCLEEntity.FindSet() then
repeat
if StrLen(BCLEEntity.Email) > 0 then begin
Address.Name := BCLEEntity."Speaker Name";
Address."E-Mail Address" := BCLEEntity.Email;
Address."Source Table Number" := Database::"BCLE Entity";
Address."Source System Id" := BCLEEntity.SystemId;
Address."Entity type" := Enum::"Email Address Entity"::"BCLE Entity";
Address.Insert();
IsHandled := true;
end;
until BCLEEntity.Next() = 0;
end;
local procedure InsertAddressFromBCLEEntity(var BCLEEntity: Record "BCLE Entity"; var Address: Record "Email
Address Lookup")
begin
if ((BCLEEntity.Email <> '') and not Address.Get(BCLEEntity.Email, BCLEEntity."Speaker Name",
Enum::"Email Address Entity"::"BCLE Entity")) then begin
Address.Name := BCLEEntity."Speaker Name";
Address."E-Mail Address" := BCLEEntity.Email;
Address."Source Table Number" := Database::"BCLE Entity";
Address."Source Table Number" := Database::"BCLE Entity";
Address."Source System Id" := BCLEEntity.SystemId;
Address."Entity type" := Enum::"Email Address Entity"::"BCLE Entity";
Address.Insert();
end;
end;
{
procedure GetSentEmails(var SentEmails: Record "Sent Email" temporary);
procedure GetOutboxEmails(var OutboxEmails: Record "Email Outbox" temporary);
procedure GetSentEmails(SourceTableId: Integer; var SentEmails: Record "Sent Email" temporary);
procedure GetOutboxEmails(SourceTableId: Integer; var OutboxEmails: Record "Email Outbox" temporary);
procedure GetSentEmails(SourceTableId: Integer; SourceSystemId: Guid; var SentEmails: Record "Sent
Email" temporary);
procedure GetOutboxEmails(SourceTableId: Integer; SourceSystemId: Guid; var OutboxEmails: Record "Email
Outbox" temporary);
procedure HasAccess(SentEmail: Record "Sent Email"): Boolean;
procedure HasAccess(OutboxEmail: Record "Email Outbox"): Boolean;
}
Next, we'll extend the Email View Policy enum by adding a BE LE View Policy option.
enumextension 50108 "BC LE View Policy" extends "Email View Policy"
{
value(50108; "BC LE View Policy")
{
Caption = 'BC LE View Policy';
Implementation = "Email View Policy" = BCLEViewPolicy;
}
}
The last step is to assign the email view policies to users. For more information, see Set Up View Policies.
C O N N EC TO R DESC RIP T IO N
Microsoft 365 Connector Everyone sends email from a shared mailbox in Exchange
Online.
Current User Connector Everyone sends email from the account they used to sign in
to Business Central.
NOTE
The Microsoft 365 Connector and Current User Connector require that the user has a mailbox on the tenant.
All email accounts use a connector, and the accounts contain the information needed to send email messages.
The following diagram shows the relationship between the objects for email accounts and connectors.
The first step is to implement the Email Connector interface.
{
procedure Send(EmailMessage: Codeunit "Email Message"; AccountId: Guid);
procedure GetAccounts(var Accounts: Record "Email Account");
procedure ShowAccountInformation(AccountId: Guid);
procedure RegisterAccount(var EmailAccount: Record "Email Account"): Boolean
procedure DeleteAccount(AccountId: Guid): Boolean
procedure GetLogoAsBase64(): Text;
procedure GetDescription(): Text[250];
}
Next, we'll extend the Email Connector enum by adding an SMTP option.
{
value(2147483647; SMTP)
{
Caption = 'SMTP';
Implementation = "Email Connector" = "SMTP Connector Impl.";
}
}
The last step is to create a page where we can view or create an email account. For more information, see Pages
Overview.
TIP
If you want more details, there are several examples available on the AlAppExtensions repository. For example, the SMTP
Connector is a good implementation to explore.
Email Importance Enum
value(0; Normal)
{
Caption = 'Normal';
}
value(1; Important)
{
Caption = 'Important';
}
Page extensions on the Email Editor and Email Viewer that allow the Importance field to be viewed and changed.
Page extensions for the Email Outbox and Sent Emails to display the Importance field.
See Also
Overview of the System Application
Set Up Email
Extending G/L Entry Aggregations When Posting
Invoices
2/6/2023 • 3 minutes to read • Edit Online
IMPORTANT
This feature is currently available only for sandbox environments. Do not use it in production environments.
This article provides an example of how to customize the way that G/L entries are aggregated when you post
sales, purchase, and service documents.
Extend the posting process for sales, purchase, and service documents by changing the way the posting
algorithm aggregates G/L entries. For example, for specific document lines, posting groups, or the tax setup
required by local legislation. Replace customizations to G/L invoice posting by using the Invoice Posting
interface, resolve issues for the legacy Invoice Post. Buffer table, and use your own implementation of G/L
invoice posting.
NOTE
The Invoice Post. Buffer table has been an important part of localizations and customizations for businesses that must
aggregate lines on sales, purchase, and service document lines in a specific way when they post the documents in order
to comply with local, industry, or customer requirements. Historically, this design wasn't extensible because we couldn't
change the primary key in the Invoice Post. Buffer table without introducing a breaking change in third-party solutions
and localizations.
We've removed the dependencies from the Invoice Posting Buffer table in the Base Application and built an Invoice
Posting object with an interface and an extensible enum for the implementation setup. For more information, see The
Objects to Use
NOTE
The legacy implementation is still available in posting codeunits, but are tagged as obsolete .
The Sales Invoice Posting . Purchase Invoice Posting , and Ser vice Invoice Posting enums are
extensible and define the current implementation.
The following is an example of an implementation that uses the Sales Invoice Posting enum.
enum815"SalesInvoicePosting"implements"InvoicePosting"
{
Extensible=true;
value(0;"InvoicePosting(Default)")
{
Caption='InvoicePosting(Default)';
Implementation="InvoicePosting"="UndefinedPostInvoice";
}
value(815;"InvoicePosting(v.19)")
{
Caption='InvoicePosting(v.19)';
Implementation="InvoicePosting"="SalesPostInvoice";
}
}
The temporary Invoice Posting Buffer table uses the generic key, Group ID: Text[1000] . You can use the
BuildPrimaryKey() method to compose the key from table fields. The OnAfterBuildPrimaryKey event can be
used to compose the primary key in a different way.
The Invoice Posting Setup field on the purchase and service setup tables lets you define the
implementation for the (Sales) Invoice Posting codeunit. If you define the value Invoice Posting (v.19) , the
Base Application will run codeunit 815 Sales Invoice Posting from the Sales-Post codeunit for your
customized posting process.
Typically, you'll only need to add fields to the Invoice Posting Buffer table.
tableextension50000"InvoicePostingBufferExt."extends"InvoicePostingBuffer"
{
fields
{
field(50000;"ProductLineCode";Code[10])
{
Caption='ProductLineCode';
}
}
}
2. After you have a Product Line Code field on sales lines, add subscribers as shown in the following code
sample.
codeunit50000"ProductLineSubscribers"
{
[EventSubscriber(ObjectType::Codeunit,Codeunit::"SalesPostInvoice",'OnPrepareLineOnAfterFillInvoicePo
stingBuffer','',false,false)]
localprocedureOnPrepareLineOnAfterFillInvoicePostingBuffer(varInvoicePostingBuffer:Record"InvoicePost
ingBuffer";SalesLine:Record"SalesLine")
begin
InvoicePostingBuffer."ProductLineCode":=SalesLine."ProductLineCode";
end;
[EventSubscriber(ObjectType::Table,Database::"InvoicePostingBuffer",'OnAfterBuildPrimaryKey','',false
,false)]
localprocedureInvoicePostingBufferOnAfterBuildPrimaryKey(varInvoicePostingBuffer:Record"InvoicePostin
gBuffer")
begin
//ProductLineCodevalueaddedasfirstfieldtotheexistingprimarykeyasexample
//althoughHroupIDfieldcanbecomposedinanyalternativewaytosupportanothersortingand
//aggregationofG/Lentriesforposting
InvoicePostingBuffer."GroupID":=
InvoicePostingBuffer.PadField(InvoicePostingBuffer."ProductLineCode",MaxStrLen(InvoicePostingBuffer."
ProductLineCode"))+
InvoicePostingBuffer."GroupID";
end;
}
3. Use your extension to set the Invoice Posting (v.19) value in the Invoice Posting Setup field on the
Sales & Receivables Setup table. The Invoice Posting Setup field is not available on the Sales &
Receivables Setup page to prevent the Invoice Posting interface from being misconfigured.
Advanced Scenarios
In more advanced scenarios, you can create your own implementation codeunit and use it instead of codeunit
815 Sales Post Invoice, implement interface methods, and add your values to the Sales Invoice Posting enum.
You can then use any methods for aggregation of G/L entries.
See Also
The Microsoft_Application.app File
Publishing a Code-Customized Base Application for Business Central On-Prem
Extending Application Areas
Event Types
2/6/2023 • 8 minutes to read • Edit Online
Dynamics 365 Business Central supports different types of events for different purposes.
Business events
A business event is a custom event that is raised by AL code. It defines a formal contract that carries an implicit
promise not to change in future releases. It is the expectation that business events are published by solution
ISVs, including Microsoft.
Business events can be compared with publicly released APIs on which 3rd party solution providers develop
integrations and additions. Therefore, the downstream cost of making changes to a business event
implementation can be considerable for those who use the event in their applications. There may be some cases
where changes are required; however, you should keep these to an absolute minimum.
Development considerations
A typical business event reflects changes in “state” with regards to a process. This makes them very well suited
for workflow. An example of a business event could be when a sales order has been posted. It is important to
note that business events should not be tied to the implementation-details, such as the tables or fields in which
the data is stored. Preferably, the event publisher developer should be free to change the implementation, while
still keeping the business event intact. To learn about the syntax and example on how to use the BusinessEvent
type, see BusinessEvent Attribute.
Business events should be documented with the solution, including the before-state and after-state of the
events.
Integration events
An integration event is also a custom event that is raised by AL code, like a business event, except that it does
not carry the same promise of not changing, nor does it have the restriction not to expose implementation
details.
The main purpose of integration events is to enable the integration of other solutions with Dynamics 365
Business Central without having to perform traditional code modifications.
Development considerations
An integration event can be changed to a business event later. At which time, it must adhere to the same implied
contract and commitment as any business event. It can also simply be designed-in hook points for external add-
ons. To learn about the syntax and example on how to use the IntegrationEvent type, see IntegrationEvent
Attribute.
Development considerations
To learn about the syntax and example on how to use the InternalEvent type, see InternalEvent Attribute.
Global events
Global events are predefined system events that are automatically raised by various base application codeunits.
For example, codeunit 40 LoginManagement includes several global method triggers, such as CompanyOpen,
CompanyClose, and GetSystemIndicator. For most of these global method triggers, there are one or two global
events: a before and after event. For example, there is an OnBeforeCompanyOpen event and an
OnAfterCompanyOpen event. The global events are defined as integration event publishers by local methods in
the following codeunits.
OnAfterLogInEnd
OnBeforeLogInStart
OnBeforeCompanyOpen
OnAfterCompanyOpen
OnBeforeCompanyClose
OnAfterCompanyClose
42 TextManagement OnBeforeMakeTextFilter
OnAfterMakeDateTimeFilter
OnAfterMakeDateFilter
OnAfterMakeTextFilter
OnAfterMakeTimeFilter
OnResolveCaptionClass
44 ReportManagement OnAfterGetPrinterName
OnAfterDocumentPrintReady
OnAfterGetPaperTrayForReport
OnAfterGetPrinterName
OnAfterHasCustomLayout
OnAfterDocumentReady
OnAfterDocumentDownload
OnAfterSetupPrinters
OnCustomDocumentMergerex
OnAfterSubstituteReport
C O DEUN IT ID C O DEUN IT N A M E EVEN T
45 AutoFormatManagement OnAfterAutoFormatTranslate
49 GlobalTriggerManagement OnAfterGetGlobalTableTriggerMask
OnAfterOnGlobalInsert
OnAfterOnGlobalModify
OnAfterOnGlobalDelete
OnAfterOnGlobalRename
OnAfterGetDatabaseTableTriggerSetup
OnAfterOnDatabaseInsert
OnAfterOnDatabaseModify
OnAfterOnDatabaseDelete
OnAfterOnDatabaseRename
OnBeforeOnDatabaseInsert
OnBeforeOnDatabaseModify
OnBeforeOnDatabaseDelete
OnBeforeOnDatabaseRename
Trigger events
Unlike business and integration events which must be programmed, trigger events are predefined events.
Trigger events are published by the runtime and they cannot be raised programmatically. There are two types of
trigger events: database trigger events and page trigger events.
NOTE
Trigger events do not appear as methods in AL for a table or page object.
O RDER IT EM EXA M P L E
See Also
Events in AL
Publishing Events
Raising Events
Subscribing to Events
Isolated Events
Publishing Events
2/6/2023 • 3 minutes to read • Edit Online
The first phase of implementing an event is publishing the event. Publishing an event exposes it in the
application. It provides hook up points for subscribers to register to the event, and eventually handle the event if
it's raised. An event is published by adding an AL method that is set up as an event publisher.
Business and integration events require that you manually create an event publisher method for each
event that you want to publish. An event publisher method declares the event in the application and
makes it available for subscription. However, it doesn't raise the event. After an event is published, you
can raise it in your application from where event subscribers can react and handle the event.
Trigger events don't require that you create publisher methods. Trigger events are predefined event
publisher methods that are called automatically at runtime. So trigger events are readily available to
subscribers by default.
IMPORTANT
If you include the event publisher method in a page object, the page must have a source table. Otherwise, you
can't successfully create an event subscriber method to subscribe to the event.
or
[BusinessEvent(IncludeSender : Boolean)]
TIP
Use the teventint snippet for an integration event or the teventbus snippet for a business event to get
started.
For more information about integration and business events, see Event Types.
4. Add parameters to the method as needed.
You can include as many parameters of any type as necessary.
Make sure to expose enough information. Parameters enable subscriber methods to add value to the
application. However, don't expose unnecessary parameters that may constrain you from changing or
extending methodically in the future.
You can now add code to the application that raises the event by calling the event publisher method. You can
also create subscriber methods that handle the event when it's raised.
Example
This example creates the codeunit 50100 MyPublishers to publish an integration event. The event is published
by adding the global method called OnAddressLineChanged . The event takes a single text data type parameter.
NOTE
This example is part of a larger, simple scenario where when users change the address of a customer on the page 21
Customer Card , you want to check that the address doesn't include a plus sign (+). If it does, you want to display a
message. To accomplish this, you will publish an event that is raised when the Address field on Customer Card is
changed, and add an event subscriber method to that includes logic that checks the address value and returns a message
to the user if it contains a plus sign. For a complete description of this scenario and all the code involved, see Event
Example.
The next step is to raise this event in the application. To see an example for how this event is raised, go to Raising
Event Example.
See Also
Raising Events
Subscribing to Events
Events Dynamics 365
Raising Events
2/6/2023 • 2 minutes to read • Edit Online
After an event has been published by an event publisher method, you can modify the application to raise the
event where it is needed. Subscribers of an event will not react on the event until it is raised in the application.
To raise an event, you add logic in AL code of the application to call the event publisher method that declares the
event. The procedure for calling the event publisher method is the same as calling any other method in AL.
When the code that calls the event publisher method is run, all event subscriber methods that subscribe to the
event are run. If there are multiple subscribers, the subscriber methods are run one at a time in no particular
order. You cannot specify the order in which the subscriber methods are called.
If there are no subscribers to the published event, then the line of code that calls the event publisher method is
ignored and not executed.
Snippet support
Typing the shortcut teventsub will create the basic event subscriber syntax when using the AL Language
extension in Visual Studio Code.
TIP
Typing the keyboard shortcut Ctrl+Space displays IntelliSense to help you fill in the attribute arguments and to discover
which events are available to use.
Example
This example uses a page extension object 50100 MyCustomerExt to modify the page 21 Customer Card so
that an event is raised when a user changes the Address field. This example assumes that the event has already
been published by the event publisher method OnAddressLineChanged in a separate codeunit called 50100
MyPublishers .
NOTE
This example is part of a larger, simple scenario where when users change the address of a customer on the page 21
Customer Card , you want to check that the address does not include a plus sign (+). If it does, you want to return a
message to the user. For a description of this scenario and all the code involved, see Event Example.
In the code that follows, the page extension object modifies the OnBeforeValidate trigger of the Customer
Card page to raise the event OnAddressLineChanged which includes the new value of the Address field.
pageextension 50100 MyCustomerExt extends "Customer Card"
{
layout
{
modify(Address)
{
trigger OnBeforeValidate();
var
Publisher: Codeunit MyPublishers;
begin
Publisher.OnAddressLineChanged(Rec.Address);
end;
}
}
}
To learn about how the event used in this example is published, see Publishing Events Example.
The next step would be to subscribe to the event to handle to condition. To see an example of how to subscribe
to this event, see Subscribing to Events Example.
See Also
Publishing Events
Subscribing to Events
Events in AL
Subscribing to Events
2/6/2023 • 5 minutes to read • Edit Online
To handle events, you design event subscribers. Event subscribers determine what actions to take in response to
an event that has been raised. An event subscriber is a method that listens for a specific event that is raised by
an event publisher. The event subscriber includes code that defines the business logic to handle the event. When
the published event is raised, the event subscriber is called and its code is run.
Subscribing to an event tells the runtime that the subscriber method must be called whenever the publisher
method is run, either by code (as with business and integration events) or by the system (as with trigger events).
The runtime establishes the link between an event raised by the publisher and its subscribers, by looking for
event subscriber methods.
There can be multiple subscribers to the same event from various locations in the application code. When an
event is raised, the subscriber methods are run one at a time in no particular order. You can't specify the order in
which the subscriber methods are called.
Set the arguments according to the following table. For optional arguments, if you don't want to set a
value, use an empty value ( '' ). In this case, the default value, if any, is used.
<Published Event Element Name> Specifies the table field that the no
trigger event pertains to. This
argument only requires a value for
database trigger events, that is,
when the
<Event Publisher Object Type>
is set to Table and the
<Published Event Name>
argument is a validate trigger event,
such as OnAfterValidateEvent .
TIP
There are a couple of things that can make defining an event subscriber method easier. You can use the
teventsub snippet to get started. Then, typing the keyboard shortcut Ctrl+Space displays IntelliSense to help
you fill the attribute arguments and discover which events are available. Or, use the Shift+Alt+E keyboard
shortcut to look up the event you want to subscribe to and insert the code.
5. Optionally, set the codeunit's EventSubscriberInstance property to specify how the event subscriber
method will be bound to the instance of this codeunit.
For more information, see EventSubscriberInstance Property.
Example 1
This example creates the codeunit 50101 MySubscribers to subscribe to an event that has been published by
the event publisher method called OnAddressLineChanged in the codeunit 50100 MyPublishers . The event is
raised by a change to the Address field on page 21 Customer Card . This example assumes:
The codeunit 50100 MyPublishers with the event publisher method OnAddressLineChanged already exists.
For an example, see Publishing Event Example.
The code for raising the OnAddressLineChanged event has been added to the Customer Card page. For an
example, see Raising Event Example.
The following code creates a codeunit called 50101 MySubscribers that includes an event subscriber method,
called CheckAddressLineOnAddressLineChanged . The method includes code for handling the published event.
NOTE
This example is part of a larger, simple scenario where when users change the address of a customer on the page 21
Customer Card , you want to check that the address does not include a plus sign (+). If it does, you want to return a
message to the user. For a description of this scenario and all the code involved, see Event Example.
Example 2
This example achieves the same as example 1, except it subscribes to the page trigger event
OnBeforeValidateEvent on the Address field instead. By using the page trigger, you avoid creating an event
publisher and adding code to raise the event. The event is raised automatically by the system.
codeunit 50101 MySubscribers
{
EventSubscriberInstance = StaticAutomatic;
See Also
Publishing Events
Raising Events
Event Types
Events in AL
EventSubscriberInstance Property
EventSubscriber Attribute
Isolated Events in AL
2/6/2023 • 2 minutes to read • Edit Online
You can define a business, integration, or internal event to be an isolated event. An isolated event ensures the
event publisher continues its code execution after calling an event. If an event subscriber's code causes an error,
its transaction and associated table changes will be rolled back. The execution continues to the next event
subscriber, or it will be handed back to the event's caller.
When an event is raised, the platform gets the first event subscriber. When the event is isolated, an isolated
transaction starts, then the event subscriber is invoked. If an error occurs, the transaction is rolled back, and the
flow is repeated for the next event subscriber. Otherwise, the transaction is committed and the flow is repeated
for the next event subscriber.
NOTE
Read-only transactions are allowed to call isolated events directly, but write transactions should explicitly be
committed before invoking an isolated event. Other wise, the isolated event will be invoked like an
normal event, that is, errors inside an event subscriber will cause the entire operation to fail.
Rollback
Only changes done via Modify/Delete/Insert calls on records of type TableType: Normal will be automatically
rolled back. Other state changes, like HTTP calls, variable alterations, changes to single instance codeunit's
members, won't be rolled back.
For example, if an integer variable that's passed by VAR is modified by a failing event subscriber, its changes will
persist.
Extension installation and upgrade
When the operation is installing, uninstalling, or upgrading extensions, isolated events aren't run isolated. The
events run normally instead.
The reason for this behavior is that these operations require that all operations within them are done in one
transaction. So explicit Commit calls can't be made during the operations.
To define an isolated event, set the Isolated argument, which is to true , for example:
[InternalEvent(true, true)]
Example
codeunit 50145 IsolatedEventsSample
{
trigger OnRun()
var
Counter: Integer;
cust : Record Customer;
begin
// Precondition: Customer table isn't empty.
if (cust.IsEmpty) then
Error('Customer table is empty.');
MyIsolatedEvent(Counter);
// Code only reaches this point because the above event is isolated and error thrown in
FailingEventSubscriber is caught.
if (Counter <> 2) then
Error('Both event subscribers should have incremented the counter.');
[InternalEvent(false, true)]
local procedure MyIsolatedEvent(var Counter: Integer)
begin
end;
Error('Fail!');
See Also
Publishing Events
Raising Events
Subscribing to Events
Developing Extensions Using the New Development Environment
Discoverability of Events
2/6/2023 • 2 minutes to read • Edit Online
You subscribe to events to extend application and interact with the base application and other extensions. This
topic describes how to discover events that you can subscribe to without writing the code manually. Using the
Event Recorder , you can record the events that are published and raised while performing the actions of your
scenario. For example, record the events raised when you post a purchase order and identify the events that you
need for your extension. You can retrieve the events in the form of AL snippet code and use them in Visual
Studio Code directly.
NOTE
The event recorder captures all events that are raised in the same session. If the actions performed by the user are in
another session, then the event recorder will not capture them.
NOTE
The recorded events are not saved. When you refresh the page, the recorded events disappear.
Recorded Events
All the recorded events display in the order they were called. The Event Recorder page provides information on
the events that were raised including the details whether the raised events were trigger events or custom events.
The custom events are either Business Events or Integration Events. For more information, see Event Types.
You can identify the Event types, additionally, you can discover which object types and methods raised the
events with the details like calling methods, object types, and object names. For more information about Events,
see Events in AL.
See Also
Events in AL
Publishing Events
Raising Events
Subscribing to Events
Debugging in AL
Developing Extensions
Event Example
2/6/2023 • 2 minutes to read • Edit Online
This article includes a simple code example to explain how to use Business Central events. The example uses an
event to verify a customer's address. When a user changes the address of a customer on the page 21
Customer Card , an event is used to check that the address doesn't include a plus sign (+). If it does, a message
is displayed in the client. In this example, you'll add code that:
Publishes an event that is raised when the Address field on Customer Card is changed.
Raises the event from the Customer Card page
Subscribes to the event to check the address value and return a message to the user if it contains a plus sign.
// The following code creates codeunit that publishes the `OnAddressLineChanged` event.
// The following code extends the Customer Card page to raise the `OnAddressLineChanged` event
// when the Address field is changed.
pageextension 50100 MyCustomerExt extends "Customer Card"
{
layout
{
modify(Address)
{
trigger OnBeforeValidate();
var
Publisher: Codeunit MyPublishers;
begin
Publisher.OnAddressLineChanged(Rec.Address);
end;
}
}
}
See Also
Publishing Events
Raising Events
Subscribing to Events
Events Dynamics 365
Walkthrough: Implementing New Workflow Events
and Responses
2/6/2023 • 12 minutes to read • Edit Online
If a business scenario requires a workflow event or a workflow response that is not supported in a Business
Central solution, you must implement it by extending the application code.
In the Workflow page, the workflow administrator creates a workflow by listing the involved steps on the lines.
Each step consists of a workflow event, moderated by event conditions, and a workflow response, customized by
response options. You define workflow steps by filling fields on workflow lines from fixed lists of event and
response values representing scenarios that are supported by the application code. For more information, see
Set Up Workflows in the business functionality content.
The following procedure describes how to add a new workflow event and a new workflow response and then
register the involved object relations, so that the new elements can be used in workflows. You can then share
your code as an app or a per-tenant extension, for example. The workflow administrator can then select the new
workflow event and response from the Workflow page to incorporate them in new or existing workflow steps.
IMPORTANT
To ensure that custom workflow records are upgraded correctly, you must add new workflow events, workflow responses,
and workflow table relations to dedicated extension points, as described in this procedure. During an upgrade to the next
version, the libraries of workflow events, responses, and table relations are removed and then recreated with the latest
content from Microsoft. By adding your custom workflow records using subscriptions to the Microsoft-provided extension
points, you ensure that your custom record library gets recreated after an upgrade.
NOTE
This topic refers to two types of events:
Workflow event: An occurrence in the application that users in the client can select from the Workflow page to define
workflow steps. For more information, see Workflows in Dynamics 365 Business Central in the business functionality
content.
Event: The declaration of the occurrence or change in the application. Workflow events typically subscribe to events.
For more information, see Events in AL.
The development work involved in creating a new workflow event and a related workflow response consists of
the following tasks, as a minimum:
1. Create a workflow event
a. Create a workflow event code that identifies the workflow event
b. Add the workflow event code to the Workflow Event table
c. Create and publish an event that the workflow event subscribes to
d. Raise the event
e. Subscribe to the event and implement the workflow event
2. Create a workflow response
a. Create a workflow response code that identifies the workflow response
b. Add the workflow response code to the Workflow Response table
c. Implement the workflow response
d. Enable that the workflow response can be executed
e. Add a new workflow response option
3. Register workflow event/response combinations needed for the new workflow response
4. Register workflow event hierarchies needed for the new workflow event
5. Creating table relations between entities used when the new workflow event and response are used
NOTE
Data and code samples in this procedure refer loosely to a workflow step of sending a notification when a purchase
header is posted. However, the procedure alone does not result in a complete solution. The purpose of the walkthrough is
simply to illustrate the process.
Workflow event
In this section, we'll create a code to identify the workflow event, add the workflow event to the library, create an
event that the workflow event subscribes to, raise the event, and then subscribe to the event and implement the
workflow event.
Each subsection takes you through the discrete steps.
To create a workflow event code that identifies the workflow event
1. Create a new .al file, such as MyWorkflowEvents.codeunit.al, and add a codeunit that will be used for new
workflow events. Name it to reflect that it is used to identify the new workflow event, such as
MyWorkflowEvents .
2. Add a method in the codeunit. Optionally, use the shortcut tprocedure . Name the method to reflect that
it is used to identify the workflow event, such as MyWorkflowEventCode , and make it take 128 characters of
code as a parameter.
TIP
The terminology can be a bit confusing here. This method is not an AL event. It's a method that declares the workflow
event, and it will subscribe to an AL event that, when triggered, will trigger the workflow event.
Select the event type that is relevant for the workflow event, such as Integration. For more information,
see Event Types.
To raise the event
1. Create an object or an extension object to add the code that will raise the event that triggers the workflow
event, such as the Purch.-Post codeunit.
The following code raises the event by extending the Purchase Order page object in a new file,
MyPurchOrder.PageExt.al .
The following code illustrates the new workflow event that subscribes to your previously created event:
Another task that you can perform at this point is to specify which filter fields appear in the Workflow Event
Conditions page.
For more information, see Subscribing to Events.
You have now created a new workflow event. Next, we'll create a new workflow response that relates to the
workflow event.
Workflow response
Create a new .al file, such as MyWorkflowResponses.codeunit.al, with code to identify the workflow response,
add the workflow response code to the library, implement the workflow response, and then enable that the
workflow response can be executed.
To create a workflow response code that identifies the workflow response
1. Add a new codeunit that will be used for the new workflow responses. Name it to reflect that it handles
your new responses, such MyWorkflowResponses .
2. Add a method in the codeunit. Name the method to reflect that it is used to identify the workflow
response, such as MyWorkflowResponseCode with a return value of code (128).
To add the workflow response code to the Workflow Response table
1. Add another method in the codeunit that will be the event subscriber. Name it to reflect that it is used to
add the workflow response to the library, such as AddMyWorkflowResponsesToLibrary and set it to subscribe
to the OnAddWorkflowResponsesToLibrary method in the Workflow Response Handling` codeunit.
[...]
var
WorkflowResponseHandling: Codeunit "Workflow Response Handling";
3. In the method, write code that registers the response, so that you end up with something like the
following code.
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Workflow Response Handling",
'OnAddWorkflowResponsesToLibrary', '', true, true)]
local procedure AddMyWorkflowResponsesToLibrary()
var
WorkflowEventHandling: codeunit "Workflow Event Handling";
begin
WorkflowResponseHandling.AddResponseToLibrary(MyWorkflowResponseCode, Database::"Purchase
Header", 'Send a notification.', 'GROUP 0');
End
end;
NOTE
In the To add a new workflow response option section, you will change the GROUP value to 50100. This way, you'll be
able to see the workflow in action.
3. Create a page extension object that extends page 1523, Workflow Response Options , such as
MyworkflowStepArgument.PageExt.al.
4. Add a group and a control for the new field.
Here, the Visibility property of the group is set to "Response Option Group" = 'GROUP 50100' , but you can
set it to another value.
5. Go back to MyWorkflowResponses.codeunit.al and the ´AddMyWorkflowResponsesToLibrary` method.
6. In the method code, change 'GROUP 0' to 'GROUP 50100' .
7. To use the new option in the MyWorkflowResponse method, proceed to add a local parameter and a local
variable and show a message as the response.
You have now created the actual workflow event and response. Proceed to perform various tasks that
enable them to be used in workflows.
In the method, write code that registers event/response combinations that you want to support in your
application, using a CASE statement, such as the code in the example above.
You can also do this work from the user interface on page 1507 Workflow-Event-Response-
Combinations .
In the method, write code that registers event hierarchies that you want to support in your application,
using a CASE statement, such as the code in the example above.
You can also do this work from the user interface on page 1506 Workflow-Event-Hierarchies .
In the method, write code that registers table relations that you want to support in your application, such
as the example above.
You can also do this work from the user interface on page 1509 Workflow Table-Relations .
You have now enabled a new workflow scenario by implementing the required workflow event and response in
the application code. The workflow administrator can now select the workflow event and workflow response
from the Workflow page to define new or edit existing workflows. For more information, see Set Up Workflows
in the business functionality content.
See Also
Workflows in Dynamics 365 Business Central
Set Up Workflows
Event Example
Events in AL
Page Extension Object
Table Extension Object
Codeunit Object
Table Object
Get Started with AL
Development and Administration for Dynamics 365 Business Central
Notifications
2/6/2023 • 5 minutes to read • Edit Online
Notifications provide a programmatic way to send non-intrusive information to the User Interface (UI) in the
Web client. Notifications differ from messages initiated by the Message method. Messages are modal, which
means users are typically required to address the message and take some form of corrective action before they
continue working. On the other hand, notifications are non-modal. Their purpose is to give users information
about a current situation, but do not require any immediate action or block users from continuing with their
current task. For example, you could have a notification that a customer's credit limit is exceeded.
Notifications in the UI
In the UI, notifications appear in the Notification bar (similar to validation errors) at the top of the page on
which a user is currently working. The user can then choose to dismiss the notification, which clears it. Or, if
actions are defined on notification, the user can choose one of the actions.
There can be multiple notifications. The notifications appear in chronological order from top to bottom.
Notifications remain for the duration of the page instance or until the user dismisses them or takes action on
them.
Notifications that are defined on sub-pages, for example in parts and FactBoxes, appear in the same
Notification bar.
Validation errors on the page will be shown first.
M ET H O D DESC RIP T IO N
The Send method call should be the last statement in the notification code, after any AddAction or SetData
method calls for the notification instance.
NOTE
GlobalScope is currently not supported. This will be implemented in a future release.
DataValue := MyNotification.GetData('Created');
DataValue := MyNotification.GetData('ID');
Example
This simple example illustrates how notifications work and provides some insight into how you can use them.
This example extends page 42 Sales Order of the CRONUS International Ltd. demonstration database
according to the following:
The code compares a customer's balance with their credit limit. If the balance exceeds the credit limit, a
notification is sent to the client.
The notification includes an action, which has the caption Change credit limit , that opens page 21
Customer Card . This enables the user to increase the credit limit.
To complete the example, follow these steps:
1. Create a page extension object that extends page 42 Sales Order , and add the notification code on the
OnOpenPage trigger.
pageextension 50100 CreditBalanceNotification extends "Sales Order"
{
trigger OnOpenPage()
var
Customer: Record Customer;
CreditBalanceNotification: Notification;
OpenCustomer: Text;
Text003: Label 'The current balance exceeds the credit limit.';
Text004: Label 'Change credit limit';
begin
Customer.Get("Sell-to Customer No.");
if Customer."Balance (LCY)" > Customer."Credit Limit (LCY)" then begin
//Create the notification
CreditBalanceNotification.Message(Text003);
CreditBalanceNotification.Scope := NotificationScope::LocalScope;
//Add a data property for the customer number
CreditBalanceNotification.SetData('CustNumber', Customer."No.");
//Add an action that calls the ActionHandler codeunit, which you define in the next step.
CreditBalanceNotification.AddAction(Text004, Codeunit::"ActionHandler", 'OpenCustomer');
//Send the notification to the client.
CreditBalanceNotification.Send();
end;
end;
}
2. Create a codeunit called ActionHandler for handling the notification action. Add a global method called
OpenCustomer that has a Notification data type parameter called CreditBalanceNotification for
receiving the Notification object, and include the following code on the method:
end;
See Also
Notification Data Type
Developing Extensions
Get Started with AL
Control Add-in Style Guide
2/6/2023 • 5 minutes to read • Edit Online
This article offers a variety of stylistic definitions that are used throughout Dynamics 365, which you can apply
to your control add-ins to create an experience that complements Dynamics 365.
Introduction
Control add-ins for Dynamics 365 extend a business solution by surfacing contextual functionality alongside
business data. Control add-ins empower users to get more done without costly context switching, no matter
which device they access Dynamics 365 from. Typical uses of control add-ins include unique data visualizations,
surfacing controls from a third party service, or displaying related content from another data source.
Apart from the functionality, an important aspect of creating a control add-in is making sure the control add-in
looks good and blends seamlessly into Dynamics 365. To achieve this, you should follow these basic principles:
Apply similar patterns for command, navigation and presentation of data.
Favor content over chrome
Design for all platforms and input methods.
Make it accessible to all users.
Make it enjoyable and keep users in control.
Dynamics 365 uses a set of specific colors and fonts. You can employ these colors and fonts in your control add-
ins to give it a style that matches the rest of client's user interface.
Colors
Choosing the right color gives the interface visual continuity. Color can be used to convey information to users,
indicate interactivity, give feedback, and more. The following sections describe the colors used in Dynamics 365.
The colors can be used on all aspects of a UI element, such background, border, text, and more.
Main colors
The following colors represent the Dynamics 365 theme main palette.
C O LO R NAME USE H EX VA L UE
Style colors
The following colors are used to express or accent conditions or user activity in the UI. For example, these colors
are used as sentiments, or color indication, on Cues.
C O LO R DESC RIP T IO N H EX VA L UE
Standard #212121
Accent #00B7C3
Strong #212121
Favorable #35AB22
Ambiguous #9F9700
Unfavorable #EB6965
Attention #EB6965
Subordinate #A7ADB6
C O LO R DESC RIP T IO N H EX VA L UE
Yellow #C9C472
Green #88CE81
C O LO R DESC RIP T IO N H EX VA L UE
Red #E97768
Blue #75B5E7
Sky 75D8E7
Egg EEEA86
Orange #E89E63
Violet #DBBDEB
Teal #39B294
Grass #73BA5A
Scarlet #E65E6D
Chart colors
The following table describes the colors used in charts.
C O LO R DESC RIP T IO N H EX VA L UE
- #505C6D
- #008089
Yellow #C9C472
Red #E97768
Blue #75B5E7
Sky 75D8E7
Egg EEEA86
Violet #DBBDEB
Teal #39B294
Grass #73BA5A
Applying colors
To apply a color scheme to the control add-in, you specify CSS rule-sets that use the following properties:
For example, to change the background of a part of your UI to use the Secondary (#505C6D) color, write the
following CSS:
.my-ui-part {
background-color: #505C6D;
}
If you want to change the text color of a caption to the Primary (#00B7C3) color, use the following CSS:
.my-caption {
color: #00B7C3;
}
Typography
The main goal of typography is to provide clean and readable text in the user interface. Similar to colors,
typography can also be used to convey or communicate conditions to the user.
Font Families
Dynamics 365 uses the following font families to specify the typeface and weight for text elements, such as
headings, captions, messages, and so on:
EXA M P L E NAME VA L UE
EXA M P L E NAME VA L UE
largest-plus-font-size 37.5pt
largest-font-size 30pt
large-plus-font-size 22.5pt
large-font-size 18pt
medium-plus-font-size 15pt
medium-font-size 13.5pt
small-plus-font-size 12pt
small-font-size 10.5pt
smallest-font-size 9pt
IMPORTANT
To ensure that the correct fonts are used on devices, do not omit fonts or change the order of the fonts.
Example
This examples illustrates how to use CSS to style a simple HTML UI part of a control add-in. The example
includes three UI controls, as shown in the following HTML code:
<div class="addin">
<div class="control">
<div class="caption">Name:</div>
<div class="value">
<input type="text" name="name">
</div>
</div>
<div class="control">
<div class="caption">Surname:</div>
<div class="value">
<input type="text" name="name">
</div>
</div>
<div class="control">
<div class="submit">Submit</div>
</div>
</div>
The following is CSS code for styling the controls, including padding, background colors, and fonts:
.addin {
padding: 1em;
background-color: #505C6D; /* Sets the background color to "Secondary" */
}
.addin .control {
border-color: #00B7C3; /* Sets the border color to "Primary" */
}
See Also
Control Add-in Best Practices
Control Add-In Performance Best Practices
2/6/2023 • 2 minutes to read • Edit Online
When developing control add-ins it's important to provide the best possible experience, as well as performance
so that users can maintain their productivity without interruption. With version 20.0 of Business Central the
client, if it detects a slow, or unhealthy control add-in, will present the user with a warning equivalent to the
following.
The dialog can be closed by the user, but will appear again if the control add-in continues to run slowly. To
ensure that the client is responsive and fast, the non-responsive or non-performant control add-in will result in
continuous warnings, and if the problem persists the control add-in communication is throttled depending on
the volume of communication with the Business Central service. If the volume of requests to Business Central
does not decrease, the service actively rejects incoming calls, resulting in some or all of the control add-in not
functioning.
Code examples
Bad code example
The following example illustrates code that is problematic and might cause performance issues because the
trigger is invoked no matter if the previous calls are completed.
function invokeALTriggerTheWrongWay() {
// Invoke the trigger every 10 seconds, ignoring
// whether the previous call has completed
window.setTimeout(() => {
Microsoft.Dynamics.NAV.InvokeExtensibilityMethod(
"MyTrigger",
arguments,
false);
invokeALTriggerTheWrongWay();
},
10000);
}
See also
Control Add-In Resiliency
InvokeExtensibilityMethod Method
GetEnvironment Method
Add Power BI Report Parts to Pages
2/6/2023 • 7 minutes to read • Edit Online
APPLIES TO: Business Central 2022 release wave (v21) and later. For earliers versions, see Adding Power BI
Report Parts to Pages (Legacy).
Business Central integrates with Microsoft Power BI, enabling users to create Power BI reports based on
Business Central data. Users can view the reports from their Power BI workspaces, but also from the Business
Central client. For an overview about Power BI integration, see Business Central and Power BI.
Displaying a Power BI report in a Business Central page requires the page includes a Power BI Repor t part.
This part makes the connection to the Power BI Service, and lets users choose which report to display. Business
Central comes equipped with several pages that already include the Power BI Repor t part. For a list of these
pages, see Power BI FAQ.
For example, the following code adds a Power BI Report part to the Team Member Role Center page by using
a page extension.
pageextension 50101 TeamMemberRCPwrBiExt extends "Team Member Role Center"
{
layout
{
addfirst(rolecenter)
{
// Add the Power BI Report part on the role center page
part(PowerBIReportPart"; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports';
}
}
}
}
The following code adds a Power BI Report part to the Sales Invoices List page by using a page extension.
The InputSelection variant specifies the table field that uniquely identifies records in the list page. This field
should resolve to the primary key of the source table.
Example 1
This example extends the Sales Invoices page to include a Power BI Report part and uses the
SetCurrentListSelection method to use the update data in the report based on the primary key No. of the
Sales Invoice table.
pageextension 50100 SalesInvoicesListPwrBiExt extends "Sales Invoice List"
{
layout
{
addfirst(factboxes)
{
part("Power BI Report FactBox"; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports';
}
}
}
trigger OnAfterGetCurrRecord()
begin
// Gets data from Power BI to display data for the selected record in the list
// based on the primary key, in this case the "No." field.
CurrPage."Power BI Report FactBox".PAGE.SetCurrentListSelection(Rec."No.");
end;
}
For example, suppose you wanted to add two Power BI Report parts to the Team Member Role Center page.
In this case, you could use the following code:
pageextension 50101 TeamMemberRCPwrBiExt extends "Team Member Role Center"
{
layout
{
addfirst(rolecenter)
{
part(PowerBIReportPart; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports';
SubPageView = where(Context = const('TeamMemberReportsPart1'));
}
part(PowerBIReportPart2; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports';
SubPageView = where(Context = const('TeamMemberReportsPart2'));
}
}
}
}
You can do the same for FactBoxes on list and card type page. For example, suppose you wanted to add two
Power BI Report parts in the FactBox of the Sales Invoices List . In this case, you could use the following code:
}
part("Power BI Report FactBox 2"; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports 2';
SubPageView = where(Context = const('DetailedSalesInvoiceReports2'));
}
}
}
trigger OnAfterGetCurrRecord()
begin
CurrPage."Power BI Report FactBox 1".PAGE.SetCurrentListSelection(Rec."No.");
CurrPage."Power BI Report FactBox 2".PAGE.SetCurrentListSelection(Rec."No.");
end;
}
By calling SetPageContext , you can get the same results as you do with the SubPageView property. For example:
pageextension 50100 SalesInvoicesListPwrBiExt extends "Sales Invoice List"
{
layout
{
addfirst(factboxes)
{
part("Power BI Report FactBox 1"; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports 1';
}
part("Power BI Report FactBox 2"; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports 2';
}
}
}
trigger OnOpenPage()
begin
CurrPage."Power BI Report FactBox 1".PAGE.SetPageContext('DetailedSalesInvoiceReports1');
CurrPage."Power BI Report FactBox 2".PAGE.SetPageContext('DetailedSalesInvoiceReports2');
trigger OnAfterGetCurrRecord()
begin
CurrPage."Power BI Report FactBox 1".PAGE.SetCurrentListSelection(Rec."No.");
CurrPage."Power BI Report FactBox 2".PAGE.SetCurrentListSelection(Rec."No.");
end;
}
Example 2
Suppose you want to display the same reports on the Sales Invoices page and Sales Orders page. In this
case, you could use the following line of code in both the Sales Invoices and Sales Orders pages, where
Sales is the common context identifier:
pageextension 50100 SalesInvoicesListPwrBiExt extends "Sales Invoice List"
{
layout
{
addfirst(factboxes)
{
part("Power BI Report FactBox"; "Power BI Embedded Report Part")
{
ApplicationArea = Basic, Suite;
Caption = 'Power BI Reports';
SubPageView = where(Context = const('sales'));
}
}
}
trigger OnAfterGetCurrRecord()
begin
CurrPage."Power BI Report FactBox".PAGE.SetCurrentListSelection(Rec."No.");
end;
}
trigger OnAfterGetCurrRecord()
begin
CurrPage."Power BI Report FactBox".PAGE.SetCurrentListSelection(Rec."No.");
end;
}
See Also
Get Started with AL
Adding a FactBox to a Page
Pages Overview
Publishing and Installing an Extension
Rules and Guidelines for AL Code
2/6/2023 • 4 minutes to read • Edit Online
This page defines the rules and guidelines to follow when writing AL code in an extension package for Dynamics
365 Business Central. The rules and guidelines are grouped according to two importance levels: critical errors
that must be resolved, and important errors that should be resolved. Errors that are not resolved must include
an explanation and justification for the error.
Critical errors
Code uses encryption key functions such as IMPORTENCRYPTIONKEY, EXPORTENCRYPTIONKEY,
CREATEENCRYPTIONKEY, and DELETEENCRYPTIONKEY. (It is fine to use the ENCRYPT and DECRYPT
methods.)
Code uses ASSERTERROR.
External data connections do not properly handle sensitive data.
It does not encrypt sensitive table data. (i.e. credit card info, passwords, etc.).
Important errors
Temporary files are not cleaned up after use.
Code uses codeunits that require printers to be selected.
Code uses a specific time zone or locale.
Common pitfalls
To help you save time, we're sharing a list of the top 15 common pitfalls that regularly lead to app validation
failures.
1. Prefix/Suffix missing
One of the app requirements is for you to reserve a prefix/suffix for your app. This is needed to ensure a
healthy app ecosystem by avoiding collision amongst apps. This common failure occurs due to not
setting your prefix/suffix in some or all required places. For more information, see Benefits and
Guidelines for using a Prefix or Suffix.
2. DataClassification missing or set incorrectly
Due to GDPR requirements, fields of field class Normal must use the DataClassification property, and its
value must be different from ToBeClassified. This applies to fields in tables and table extensions. Use the
AppSourceCop tool for detecting this.
3. Required translation files missing
There are many countries today that where Dynamics 365 Business Central is available, and that you can
support as well with your app. For specifying additional languages, we no longer support Caption ML.
You must use xliff translation files instead. For more information, see Working with Translation Files.
Microsoft provides a free translation tool that you can access from https://lcs.dynamics.com. To support a
specific country, you must include a translation file per for each language code. For example, to support
Switzerland, you must provide fr-CH, de-CH, and it-CH.
4. Missing permission sets
Your app must provide one or more permission sets so that users can use your app's functionality. Your
app must never require the SUPER permission set.
5. Permission errors
For your app to be a good citizen in Dynamics 365 Business Central, permission errors must not appear
unless it is a necessary reason for showing the error.
It is acceptable to throw an error to a user that does not have your permission set marked and tries to
access your page object. It is not acceptable to throw an error to that same user trying to access Business
Central pages in the base application, or to throw an error to a user who is not trying to access your app's
functionality.
6. Missing application area tagging
Tag in which part your app participates. Pages, controls, actions, and fields will not appear in Dynamics
365 Business Central if the Application Area property has not been set.
7. Usage Category not set
You enable a page or report to be available through search in Dynamics 365 Business Central by using
the UsageCategory property. For more information, see Using Tell Me to Find Features and Information.
8. OnCompany procedure
Due to their performance impact, OnBeforeCompanyOpen and OnAfterCompanyOpen cannot be used.
For more information, see Replacing OnBeforeCompanyOpen and OnAfterCompanyOpen.
9. Upgrade procedures
Make sure that your app can be upgraded properly. For more information, see Upgrading extensions.
10. Profiles
Do not insert into the Profile table. Use the Profile object instead.
11. App file not properly code signed
Your app file must be digitally signed with a certificate from a third-party certification authority trusted
by Windows.
12. You tested your app on an obsolete Dynamics 365 Business Central version (or never even tested it)
Make sure that your app is properly tested on the correct version. For more information, see Current
Build - Developing for Dynamics 365 Business Central on the Collaborate site.
13. You tested using SUPER permissions
You tested your app, but your user had SUPER permissions. This can hide critical errors. You must test
with a user that doesn't have the SUPER permissions. The user must have the ESSENTIAL license. For
more information, see Testing your Extension.
14. User scenario document unclear
Our validation team is testing your app functionality manually, so we need to be able to understand the
core functionality of your app. If your user scenario document is missing important details that are
needed for us to properly walk through your app's setup and usage scenarios, we cannot validate your
app successfully. For more information, see User Scenario Documentation.
15. The .json file is incorrect
There are many values in the app.json file that may not be mandatory to compile your app, but are
mandatory for your app to be in AppSource. For example, your app cannot be published to a production
tenant if the target value is set to OnPrem. It must be set to Cloud. For information, see JSON Files.
See Also
Best Practices for AL Code
Checklist for Submitting Your App
Best Practices for Deprecation of AL Code
2/6/2023 • 2 minutes to read • Edit Online
This article provides guidelines that describe how code in the Base App is obsoleted. The article describes some
best practices that Microsoft is using for obsoleting code, and is meant as a non-enforced guidance and best
practice. You can use this article as an inspiration on how to set up a best practice for your own code. For
obsoleting code, preprocessor statements in AL can be used. For more information, see Directives in AL.
Obsoleting Code
When we obsolete code, we:
Add the preprocessor statements #if , #else , and #endif surrounding the code to be obsoleted.
Use one of the following preprocessor symbols, where the pattern is CLEAN<Version> , such as CLEAN15 ,
CLEAN16 , CLEAN17 , and CLEAN18 .
NOTE
These symbols are not shipped with the product.
The version to use in the symbol matches the <major> of the ObsoleteTag . For example:
If a method is to be removed, then we're using #if not
If a table or table field is to be removed, then we'll use #if #else #endif
table 1808 "Aggregated Assisted Setup"
{
Access = Internal;
Caption = 'Aggregated Assisted Setup';
#if CLEAN16
ObsoleteState = Removed;
ObsoleteTag = '17.0';
#else
ObsoleteState = Pending;
ObsoleteTag = '16.0';
#endif
ObsoleteReason = 'Data available in Assisted Setup already- extensions also register in
the same table.';
In order to have the compiler take the new ‘clean’ code path, the symbols must be defined. The symbols are
defined in the app.json file with the following setting. For more information, see JSON Files.
IMPORTANT
A best practice is to change this locally to make sure everything compiles, run tests locally, and submit test jobs.
See Also
AL Development Environment
Directives in AL
Microsoft Timeline for Deprecating Code in Business Central
ObsoleteTag Property
ObsoleteState Property
ObsoleteReason Property
Obsolete Attribute
Benefits and Guidelines for using a Prefix or Suffix
2/6/2023 • 4 minutes to read • Edit Online
In your extension, the name of each new application object (table, page, codeunit), must contain a prefix or suffix.
This rule applies to all objects. You can use the Caption values for what you decide to display to the user. When
you modify a core Dynamics 365 object using a table extension or a page extension, the prefix/suffix must be
defined at the control/field/action/group level.
Benefits
The use of affixes reduces name collisions with objects defined in other extensions.
Environments that have extensions with name collisions can experience issues when deploying new extensions,
when upgrading the environment, or when creating a sandbox as a copy of the current environment (for
production environments).
General rules
The prefix/suffix must be at least 3 characters
The object/field name must start or end with the prefix/suffix
If a conflict arises, the one who registered the prefix/suffix always wins
For your own objects, you must set the prefix/suffix at the top object level
For pages/tables/enums/reports/permissionsets in the base application or other apps that you extend, you
must set the prefix/suffix at the top object level and also at the
control/field/action/procedure/values/dataitem/column level
Use the AppSourceCop tool to find all missing prefixes and/or suffixes. Configuration options for this tool
can be found here. The Rules section explains the different checks that the analyzer will do. For prefix/suffix
detection, refer to the Configuration section. It explains how to set your affixes in the AppSourceCop.json file.
IMPORTANT
The use of affixes for object names is required for AppSource submissions as part of the Technical Validation Checklist.
In order to meet the requirements for the AppSource technical validation, you must have a 3 letters affix
registered for your extension publisher and you must use the affix in your extension.
If you do not have any affixes registered yet, contact us at d365val@microsoft.com and provide us with the
following information to reserve the prefix/suffix of your choosing:
Your MPN ID,
The publisher name that you will use in your extensions (in the app.json file),
You must provide at least 5 affix suggestions. Each affix must be exactly 3 characters.
NOTE
Affixes are not case-sensitive, which means that for example "ABC", "abc", and "AbC" are treated as the same affix.
Providing both "ABC" and "abc" counts as only one of your suggestions.
Note, that you are not required to change any already registered affixes; you can continue using these affixes.
The guidelines above only apply to new registrations.
For per-tenant extensions
Per-tenant extensions are not required to use a prefix or suffix, but we strongly recommend that you do so. You
can use pte as prefix or suffix to avoid conflicts with AppSource apps or base objects.
NOTE
If your per-tenant extension causes a conflict with a new object in the base application or an updated AppSource app,
then the per-tenant extension will be required to make the change.
Page
actions
{
addafter(ApprovalEntries)
{
action(VacationMySuffix)
{
Caption = 'Vacation';
}
}
}
Codeunit
pte-myext-salespersoncode salespersoncode-myext-pte
pte_myext_salespersoncode salespersoncode_myext_pte
pteMyExtSalesPersonCode SalesPersonCodeMyExtPte
fab-salespersoncode salespersoncode-fab
fab_salespersoncode salespersoncode_fab
FabSalesPersonCode SalesPersonCodefab
At Fabrikam, another team is building another app, so you request a special affix for your app so that the two
Fabrikam apps can be kept apart. In this scenario, you do not have to register anything with Microsoft, as long as
you do this with your company affix. Here are some examples:
fab-rentals-salespersoncode salespersoncode-rentals-fab
fab_rentals_salespersoncode salespersoncode_rentals_fab
FabRentalsSalesPersonCode SalesPersonCodeRentalsfab
In this scenario, your AppSourceCop.json configuration will specify fab-rentals and rentals-fab as values for
mandatoryaffixes , even though only fab was registered with Microsoft.
See Also
Checklist for Submitting Your App
Rules and Guidelines for AL Code
Instrumenting an Application for Telemetry
2/6/2023 • 2 minutes to read • Edit Online
This article describes how you can implement custom telemetry signals in your application for emitting
telemetry data. This data can then be collected and visualized for analyzing the application against the desired
business goals, troubleshooting, and more.
Telemetry overview
One aspect of event logging is the data collection about the working and deployment infrastructure of an
application to diagnose conditions and troubleshoot problems that affect its operation and performance. For
example, this type of event logging includes Business Central Server events and trace events like SQL and AL
method (function) traces.
Another aspect of logging is telemetry, which is the collection of data about how your application works in
production. Telemetry can tell you about specific activities that users perform within the application in the
production environment. Telemetry also helps troubleshooting in those instances where you aren't able to
reproduce the conditions experienced by the user or have no access to the user's environment. Telemetry can be
divided into different categories, like: telemetry for engineering, telemetry about the business, telemetry for
customers.
Extension developers
can specify whether
the signal is only sent
to the extension
publisher or also to
the VAR partner
telemetry resource.
NOTE
Using Application Insights is recommended.
See Also
Monitoring and Analyzing Telemetry
Monitoring Business Central Server Events
Testing your Extension
2/6/2023 • 4 minutes to read • Edit Online
Several key things lead to your Dynamics 365 Business Central extension passing the Microsoft validation
process. However, one of the most important checks you can do is to take the time and test your extension
before submitting it for validation. This allows you to catch some of the basic errors that could lead to validation
failures. The following list calls out key points, and the sections below provide more context.
Always test in a Dynamics 365 Business Central online environment. If you test in an on-premises
deployment, you might miss errors that would be seen online.
Ensure that your extension can be published without code signing errors. You must not use the
-skipverification flag.
The extension should be able to be installed without errors.
If you are using the Assisted Setup , ensure that you can use your wizard to completion without errors.
Walk through the setup and usage of your extension to verify it works as expected (remember to test as a
user that does not have SUPER permissions ).
Check that you can uninstall and unpublish your extension without any errors.
Make sure you can republish and reinstall your extension without any errors.
See Also
Checklist for Submitting Your App
Rules and Guidelines for AL Code
User Scenario Documentation
2/6/2023 • 3 minutes to read • Edit Online
One of the keys to a successful extension validation is a document that guides the tester through the setup and
usage of the extension. You must include a document that helps Microsoft test some of the key scenarios of your
extension. We want to ensure that we are validating the functionality in the correct manner. Following are some
key points to keep in mind when writing the user scenario document.
Be as detailed as possible. No detail is too small. If a field needs a specific value, include that value in your
document.
Keep the inexperienced user in mind. You know your app well, but other users do not.
Use screenshots as much as possible. They provide a good picture of what you want the user to
accomplish.
Provide all prerequisite and setup steps required for successful test scenario completion.
If your app requires setup of its own, include those details.
If any setup is extensive, consider using the import of Rapid Start packages.
If your app has a dependency on non-standard settings in the core default version of Business Central,
include those details. The Microsoft-provided demo data might not have everything that your app
needs to work properly.
Include the most important functionality scenarios of your extension. We are not looking to test your
entire extension, but we do want to ensure we are validating the most used aspects of your app.
Do not give a summary as to what these scenarios do. List step by step details instead. Again, the
tester doing the validation might not have the same product knowledge as you do.
It should be possible for the inexperienced tester to complete the user scenario test in less than
20 minutes (after installation and startup).
NOTE
This is not the same as the requirement to include Help for your functionality. For more information about getting started
with extending and customizing the Business Central user assistance, see User assistance model.
5. Choose Next
6. Choose Next
7. New Name = TestReport1
8. Data Source Type = Page
9. Data Source Id = 22
10. Data Source Name = Customer List
11. Choose Next
See Also
Checklist for Submitting Your App
Rules and Guidelines for AL Code
User assistance model
Restrictions on UI for Objects Exposed as Web
Services
2/6/2023 • 2 minutes to read • Edit Online
Pages and code units that are designed to be exposed as Web services must not generate any UI that would
cause an exception in the calling code.
SUMMARY AND INTENT : When writing code for Web services, you must not use end-user confirmation
dialog boxes, message boxes, or any other page constructs in the code. Because a Web service runs
independently of a user interface, running this type of code causes the code to throw an exception. The
exception can be caught and handled, but the Web service will not complete.
RESO