All about Microsoft Dynamics NAV and Business Central
Author: Ammolh Saallvi
I'm a Dynamics NAV/Navision developer and helps partners and end-users with their NAV implementations. I do everything from third-party management advisory, training to new NAV teams, project management, training, setup and development.
Do you want to hire me to help getting your project a success? Then contact me via dropping one email from linkedin
Expertise in end-to-end development of software products from requirement analysis to System Study, Documentation and Testing. Demonstrated abilities in analyzing information system needs, evaluating end-user requirements, custom designing solutions, troubleshooting for complex information systems management. Deft at carrying out risk analysis, impact analysis, project reviews and documentation. Strong Problem solving & Technical skills coupled with confident decision making for enabling effective solutions leading to high customer satisfaction as well as low operational costs.
Certifications:-
Microsoft Certified Technology Specialist -Dynamics
Microsoft Sure Step Certified Professional
Moderator at DUG Forum
Specialties: • ERP Implementation
• Client/Server Programming
• Coding, Testing, troubleshooting and documentation.
• Database Tuning and SQL
• Database Performance
• Debugging large programs
• Project Management and Resource Management.
With the release of Business Central 2025 Wave 1, BC continues to enhance administrative control and governance features. One of the most welcome additions for global organizations is the ability to limit the available language options per environment. This is a game-changer for companies seeking better localization control, user experience consistency, and governance.
🚀 What’s New?
Until now, Business Central environments would display all installed languages by default, allowing users to switch freely. While flexibility is good, it posed problems in certain scenarios:
Local subsidiaries wanting only their national language.
Confusion due to long lists of unused language options.
Incorrect UI labels or translations due to unintended language selection.
Wave 1 2025 introduces the ability to define which languages are allowed per environment. Admins can now limit language choices for users based on the business unit, geography, or internal policy.
🔧 How to Configure Allowed Languages
To define allowed languages for a specific environment, follow these steps:
Sign in to the Business Central
Navigate to the new section: “Allowed Languages”.
From the list of installed languages, check the boxes for only those you wish to allow.
Once applied, users in this environment will only see the allowed languages in their My Settings > Language dropdown.
This new feature may seem minor at first glance, but for global businesses and IT admins, it’s a powerful tool for consistency, control, and compliance. Whether you’re managing multiple countries, brands, or test environments, defining allowed languages per environment helps streamline operations and avoid confusion.
When working with filters and record ranges in AL , two handy functions often come into play: GETRANGEMIN() and GETRANGEMAX(). These functions help you programmatically access the lower and upper bounds of a filter applied to a field in a record. This can be especially useful for creating reports, processing data, or passing filters between records.
What are GETRANGEMIN() and GETRANGEMAX()?
These two functions are part of the Record data type and help retrieve the range boundaries for a specific field filter.
GETRANGEMIN(Field): Returns the lowest value in the filter range for the specified field.
GETRANGEMAX(Field): Returns the highest value in the filter range for the specified field.
If there is no filter set for the field, both functions return blank.
IF (SalesHeader.GETRANGEMIN("Posting Date") < AllowedStartDate) OR
(SalesHeader.GETRANGEMAX("Posting Date") > AllowedEndDate) THEN
ERROR('Filter range is outside allowed period.');
The GETRANGEMIN() and GETRANGEMAX() functions are powerful tools when working with dynamic filters in AL. They enable developers to write cleaner, more adaptable code by directly accessing the boundaries of filter conditions.
In today’s fast-paced business environments, performance optimization is not a luxury — it’s a necessity. Whether you’re building custom reports, extending pages, or writing integration APIs in Microsoft Dynamics 365 Business Central, slow operations can frustrate users and strain resources.
One simple but powerful technique to improve performance is using the SetAutoCalcFields method.
Why FlowFields Matter for Performance
In Business Central, FlowFields are virtual fields calculated on the fly, not stored physically in the database. Examples include:
Inventory on Item
Balance on Customer
When you retrieve a record, FlowFields are not calculated automatically unless you explicitly call CalcFields().
Manually calculating FlowFields for every record during loops, leading to multiple SQL queries — one for each record — causing heavy load and slower performance.
SetAutoCalcFields solves this by batch-calculating FlowFields along with the record fetch. Instead of running one query per record, it combines the calculation in a single optimized query.
Imagine fetching 1,000 customers and displaying their balances without SetAutoCalcfields:
CustomerRec.FindSet();
repeat
CustomerRec.CalcFields(CustomerRec.Balance); // Triggers a DB call every time!
DisplayBalance(CustomerRec."No.", CustomerRec.Balance);
until CustomerRec.Next() = 0;
Result:
1 SQL query to get Customers
+ 1,000 SQL queries for Balances
With SetAutoCalcFields:
CustomerRec.SetAutoCalcFields(CustomerRec.Balance);
CustomerRec.FindSet();
repeat
DisplayBalance(CustomerRec."No.", CustomerRec.Balance);
until CustomerRec.Next() = 0;
Result:
1 SQL query to get Customers and Balances together
Benefits of Using SetAutoCalcFields
Improved Page Load Times: By deferring calculations, pages with numerous records and calculated fields will load significantly faster.
Faster Report Generation: Reports that rely on calculated fields will be generated more quickly as the calculations are performed only when the field’s value is actually needed for display or processing.
Reduced Database Load: Fewer automatic calculations translate to fewer database queries, reducing the overall load on your Business Central database.
Enhanced User Experience: Snappier performance leads to a more responsive and enjoyable user experience.
Best Practices for Performance Gains
To maximize the benefits of SetAutoCalcFields:
Only specify necessary FlowFields: Don’t auto-calculate every FlowField — focus on what your process needs.
Use it before data retrieval: Call SetAutoCalcFields beforeFindSet(), FindFirst(), or FindLast()
Avoid unnecessary recalculations: Once FlowFields are set to auto-calculate, do not manually call CalcFields() again for the same fields.
Monitor heavy FlowFields: Some FlowFields (e.g., Inventory) involve complex sums across tables — only auto-calculate when really needed.
Profile your code: Use Performance Profiler to measure improvements.
Using SetAutoCalcFieldsproperly can lead to dramatic performance improvements in Business Central. By reducing SQL traffic, simplifying code, and batch-fetching FlowFields intelligently, you can create faster, cleaner, and more scalable applications.
A small change in your coding habits can create a big impact for your users.
With the release of Microsoft Dynamics 365 Business Central Wave 1 2025, it continues to refine the AL development experience — and one of the key improvements is the ability to obsolete report layouts cleanly and officially.
If you’re managing a growing list of custom layouts or updating reports across multiple extensions, this new feature will help you deprecate old layouts safely, keep your solution clean, and guide developers or users toward better alternatives.
Why Obsoleting Layouts Matters
In real-world implementations, layouts evolve:
Data fields change.
Users request better designs.
Old layouts become unsupported.
Without a proper way to deprecate these layouts, organizations risk:
Confusion about which layout to use
Broken printouts
Technical debt piling up over time
Now, with Wave 1 2025, you can mark layouts as obsolete similarly to how you obsolete fields, tables, or procedures.
ObsoleteState: Can be Pending (warning) or Removed (error).
ObsoleteReason: Brief explanation for developers/users.
ObsoleteTag: Identifies when/why it was marked obsolete (your own versioning or tag).
What Happens to Users When a Layout is Obsoleted?
ObsoleteState = Pending:
Users and developers get compiler warnings.
The layout is still selectable and usable.
ObsoleteState = Removed:
The system throws compiler errors if any report layout tries to use it.
Users can no longer select it at runtime.
The ability to obsolete report layouts in Business Central Wave 1 2025 is a small but powerful feature that can dramatically improve the quality, maintainability.
Whether you’re cleaning up old customer-specific layouts or modernizing your extensions, using Obsolete State strategically will help future-proof your solutions.
With the release of Business Central 2025 Wave 1, Business Central continues to simplify AL development by introducing intuitive and developer-friendly features. One such small yet powerful enhancement is the ToText method — designed to streamline how simple type values are converted to text.
In previous versions, we developers often relied on FORMAT() for converting simple types like integers, decimals, booleans, and option values into text. While FORMAT() has been effective, it comes with localization considerations and sometimes produces inconsistent results depending on the environment or the formatting settings.
✨ What’s New: ToText Method
The new ToText method is a type extension method introduced for simple AL types. It provides a clearer, more consistent way to convert values to string representations without the overhead of full formatting logic.
Supported Types
The ToText method supports the following simple types:
Integer
Decimal
Boolean
Char
Option
Date
Time
DateTime
GUID
Let’s look at some examples of how the ToText() method can simplify your code:
var
myInteger: Integer := 42;
myDecimal: Decimal := 2.71828;
myDate: Date := TODAY;
myTime: Time := TIME(10, 30, 0);
myBoolean: Boolean := true;
myOption: Option Alpha,Beta,Gamma := Option::Beta;
integerAsText: Text;
decimalAsText: Text;
dateAsText: Text;
timeAsText: Text;
booleanAsText: Text;
optionAsText: Text;
begin
integerAsText := myInteger.ToText(); // integerAsText will be '42'
decimalAsText := myDecimal.ToText(); // decimalAsText will be '2.71828' (or similar based on locale)
dateAsText := myDate.ToText(); // dateAsText will be the default short date format
timeAsText := myTime.ToText(); // timeAsText will be the default time format
booleanAsText := myBoolean.ToText(); // booleanAsText will be 'true'
optionAsText := myOption.ToText(); // optionAsText will be 'Beta'
Message('Integer: %1', integerAsText);
Message('Decimal: %1', decimalAsText);
Message('Date: %1', dateAsText);
Message('Time: %1', timeAsText);
Message('Boolean: %1', booleanAsText);
Message('Option: %1', optionAsText);
end;
Prefer ToText() when you want predictable results across environments (e.g., when storing values in logs or metadata).
Continue using FORMAT() when you need locale-aware output, such as in printed documents or user-facing formatted messages.
It simplifies the process of converting simple data types to their default text representations, leading to cleaner, more readable, and potentially more efficient code. While FORMAT() remains the go-to for advanced formatting needs, ToText() will undoubtedly become a frequently used tool in your Business Central development.
With the release of Business Central 2025 Wave 1, Business central continues to refine and empower AL developers with more flexibility when extending standard functionality. One of the subtle but significant features is the ability to change the CardPageId in a PageExtension, giving developers greater control over navigation behavior in the application.
Why Would You Want to Change CardPageID?
Consider these scenarios:
Simplified Views: You’ve created a simplified version of a standard card page with only the most relevant fields for a specific user role. Now, you can easily link the standard list page to this streamlined card page for those users.
Custom Workflows: Your custom solution requires a specialized card page with unique actions and fields for certain data. You can now seamlessly integrate this custom card page with the existing list of that data.
Context-Specific Information: Depending on how a user navigates to a list page, you might want them to land on a different, more contextually relevant card page.
Let’s say you’ve built a custom card page for customers that shows additional analytics or fields. You want to replace the default Customer Card when users open a customer from the list.
Now, your users will be directed to the Custom Customer Card page instead of the standard one.
The ability to change the CardPageID in page extensions in Business Central Wave 1 2025 is a significant step forward in providing developers with more control over the user interface. This seemingly small change unlocks a wealth of possibilities for creating more tailored, efficient, and user-friendly Business Central solutions.
With the release of Business Central 2025 Wave 1, Microsoft continues to empower developers with more control and insights into the performance and behavior of their extensions. Among the new additions is the method FieldRef.IsOptimizedForTextSearch(), designed to help developers make more performance-conscious decisions when implementing search functionalities.
💡 What is FieldRef.IsOptimizedForTextSearch()?
FieldRef.IsOptimizedForTextSearch() is a method that returns a Boolean value indicating whether a particular field in a table is optimized for text search.
It is a method on the FieldRef data type, which is used in AL code to dynamically refer to fields of records, especially in scenarios involving field iteration, metadata handling, or dynamic filters.
✅ Syntax:
Boolean := FieldRef.IsOptimizedForTextSearch();
⚙️ How to Optimize a Field for Text Search
While IsOptimizedForTextSearch()only checks if a field is optimized, setting it up is done via the table metadata or through the table schema in AL.
Setting OptimizeForTextSearch = true; enables text search optimization (depending on SQL backend settings as well for on-premise).
Lets see how we can utlize above method to check optimize search
var
MyRecordRef: RecordRef;
MyFieldRef: FieldRef;
IsOptimized: Boolean;
begin
MyRecordRef.Open(Database::Customer);
if MyRecordRef.FindSet() then begin
MyFieldRef := MyRecordRef.Field(Name); // Let's check the "Name" field
IsOptimized := MyFieldRef.IsOptimizedForTextSearch();
if IsOptimized then
Message('The "%1" field in the Customer table is optimized for text search.', MyFieldRef.Name())
else
Message('The "%1" field in the Customer table is NOT optimized for text search.', MyFieldRef.Name());
end;
MyRecordRef.Close();
end;
To be optimized for full-text search, a field typically needs:
A Text or Code data type.
An active index that supports full-text search (defined in the table metadata or via table extensions).
Proper settings in SQL Server or Azure SQL (if full-text search is enabled).
The FieldRef.IsOptimizedForTextSearch() method is a small but powerful tool in the AL developer’s toolkit. Whether you’re designing smarter search UIs or optimizing performance in large datasets, this method gives you the metadata visibility to make informed choices.
With the release of Business Central 2025 Wave 1, Microsoft continues enhancing the AL language to make development cleaner, more flexible, and maintainable. One of the updates includes improvements around the AutoFormatExpression property — a property that may seem minor but plays a crucial role in controlling how data is displayed, especially in reports and pages.
In essence, the AutoFormatExpressionproperty allows you to define a specific format for how numeric and date/time values are displayed in your Business Central application. This goes beyond the basic formatting options and provides granular control over aspects like decimal places, thousands separators, date and time patterns, and more.
What is the AutoFormatExpression Property?
The AutoFormatExpressionproperty in AL is used to specify a formatting expression that overrides the default formatting behavior of a control. It works in conjunction with the AutoFormatTypeproperty and is typically used in pages and reports to control how numeric or date values are displayed.
For example, you might want to display a date in DD-MM-YYYY format instead of the system default, or format a decimal with specific currency or precision rules.
How Does AutoFormatExpression Work?
The AutoFormatExpression property accepts a string that defines the desired format. The syntax of this string follows specific rules depending on whether you are formatting numeric or date/time data.
For Numeric Data:
The expression can include placeholders for:
Decimal Places: Use # for optional digits and 0 for mandatory digits after the decimal point.
Thousands Separator: Typically a comma (,), but this can be influenced by regional settings.
Currency Symbol: The currency symbol is usually determined by the AutoFormatType and AutoFormatSubType properties.
Example:
#,##0.00: Displays numbers with two decimal places and thousands separators (e.g., 1,234.56).
0.0: Displays numbers with one mandatory decimal place (e.g., 123.4).
For Date/Time Data:
The expression uses specific codes to represent different parts of the date and time:
Days:d (day of the month), dd (day of the month with leading zero), ddd (abbreviated day name), dddd (full day name).
Months:M (month number), MM (month number with leading zero), MMM (abbreviated month name), MMMM (full month name).
While AutoFormatExpression gives you precise control, be aware that regional settings can still influence aspects like decimal and thousands separators, as well as date and time formats if not explicitly defined.
The AutoFormatExpression property in Business Central Wave 1 2025 is a significant enhancement for developers looking to control the presentation of numeric and date/time data.
With the release of Microsoft Dynamics 365 Business Central 2025 Wave 1, Microsoft has continued to improve the AL language and reporting capabilities. One notable addition for developers working with reports is the new Report.TargetFormat() method. This small yet powerful enhancement gives developers more control and visibility over how reports are executed, especially in scenarios involving automation, scheduling, or integration.
The Report.TargetFormat() method allows you to set the target output format for a report at runtime. This is particularly useful in scenarios where the desired output format isn’t static or needs to be determined based on user preferences, system configurations, or specific business logic.
Imagine you have a page action that allows users to export a list of customers. Instead of having separate actions for different formats, you can use Report.TargetFormat() to dynamically generate the output in Excel.
In this example, before running the “Customer List” report, we set the TargetFormat property of a ReportSettings record to Excel. When the report is executed using Run(ReportSettings), it will automatically be generated as an Excel file.
Consider a scenario where you need to automatically generate and archive a sales order confirmation as a PDF after the order is posted. You can achieve this within a codeunit.
codeunit 50101 SalesOrderProcessing
{
procedure GenerateConfirmationPDF(SalesHeaderRec: Record "Sales Header")
var
SalesConfirmationReport: Report "Sales - Order Conf.";
ReportSettings: Record "Report Settings";
begin
ReportSettings.TargetFormat := Enum::"Report Format"::PDF;
SalesConfirmationReport.SetTableView(SalesHeaderRec);
SalesConfirmationReport.Run(ReportSettings);
// Code to archive the generated PDF can be added here
end;
}
Here, within the GenerateConfirmationPDF procedure, we explicitly set the TargetFormat to PDF for the “Sales – Order Conf.” report. When the report is run, it will be generated directly as a PDF document.
You can create a more user-friendly experience by presenting users with a choice of output formats before running a report.
The Report.TargetFormat() method is a subtle yet powerful addition to the AL reporting toolbox in Business Central 2025 Wave 1. It unlocks a new level of flexibility for report behavior and presentation, enabling developers to create more intelligent, format-aware reporting solutions.
With the 2025 Wave 1 release of Microsoft Dynamics 365 Business Central, developers get a significant productivity boost: the ability to generate a launch.json file directly from the Web Client! 🎉 This is a feature that eliminates the need to manually configure environment settings in Visual Studio Code (VS Code), especially useful when working across multiple environments or containers.
💡 What is launch.json?
In AL development for Business Central, the launch.json file defines how your AL project connects to your Business Central environment. It includes settings like:
You can now generate the launch.json configuration directly from the Web Client using just a few clicks. No more copying URLs, figuring out authentication types, or guessing server details.
🔧 Steps to Generate:
Log into your Business Central Web Client.
Navigate to the Help & Support page (? page=134).
Scroll down to the Troubleshooting section.
Look for the new Download launch.json button (or similar option).
Click it – a launch.json file will be downloaded, pre-filled with your current environment’s configuration.
Second option will be navigate Installed extensions and download launch.json
The introduction of the launch.json generation feature in the Business Central Wave 1 2025 web client is a welcome addition for AL developers. It promises to streamline the initial setup process, reduce configuration errors, and enhance overall development efficiency.