Mohana's D365 Business Central & NAV Blog
Monday, 27 January 2025
Multi Level User Group Approval Workflows in Business Central
Monday, 16 December 2024
Business Central v25.1 Upgrade Challenge with Master Data Management app
Recently,
while upgrading version 25.1,
we encountered a critical error related to the Master Data Management
app by Microsoft. This error halted the upgrade process, presenting the
following message:
Error
Details:
Could not
upgrade the extension '_Exclude_Master_Data_Management' by 'Microsoft' from
version '22.0.54157.55195' to '25.1.25873.25900' for tenant 'default' and
company 'CRONUS USA, Inc.' due to the following error:
'Call to the
function 'MODIFY' is not allowed inside the call to 'OnUpgradePerCompany' when
it is used as a TryFunction.'
AL stack
trace:
"Master Data Mgt. Upgrade"(CodeUnit
7238).TryModify line 2 - _Exclude_Master_Data_Management by Microsoft
"Master Data Mgt. Upgrade"(CodeUnit
7238).UpgradeJobQueueEntryFrequencies line 33 - _Exclude_Master_Data_Management
by Microsoft
"Master Data Mgt. Upgrade"(CodeUnit
7238).OnUpgradePerCompany line 2 - _Exclude_Master_Data_Management by Microsoft
"Upgrade Triggers"(CodeUnit
2000000008).OnUpgradePerCompany(Event) line 2.
Root
Cause
The issue was
from the Master Data Management app attempting to use the MODIFY
function within a TryFunction during the OnUpgradePerCompany process.
A fix has been promised in the upcoming cumulative updates for Business Central. However, until the fix is officially released, users upgrading to version 25 may face this issue.
Temporary
Workaround
To bypass
the error and proceed with the upgrade, you can temporarily adjust the DisableWriteInsideTryFunctions
property in the server instance configuration.
Steps to
Apply the Workaround:
Import-Module
'C:\Program Files\Microsoft Dynamics 365 Business
Central\250\Service\NavAdminTool.ps1'
Set-NAVServerConfiguration
-ServerInstance BC250 -KeyName DisableWriteInsideTryFunctions -KeyValue false
Restart-NAVServerInstance
BC250
Important
Note:
Use this as
a temporary solution and revert the DisableWriteInsideTryFunctions property to true
once the upgrade is complete.
Monday, 2 December 2024
Why My Custom Table/Page Isn't Appearing in "Search Company Data" in Business Central – And How to Fix It?
If you've ever added a custom table/Page in Microsoft Dynamics 365 Business Central and found that it doesn't show up in the "Search Company Data" feature to enable, you're not alone. This post will explain why this happens and how to fix it with a simple solution.
The
Problem: Custom Table/Page Missing in "Search Company Data"
The
"Search Company Data" feature allows users to search across various
tables in Business Central. However, if your custom table or page isn’t
configured correctly, it won’t appear in the “Enable lists for searching”. This can be
frustrating.
Symptoms:
- Your custom table or page does
not appear in the “Enable lists for searching”.
- Other standard tables/pages show
up as expected.
- You can still manually navigate
to your custom table or page, but not through "Search Company
Data".
Root
Cause: Missing “LookupPageId” Property
In Business
Central, tables need to have a LookupPageId property defined to be searchable
through the "Search Company Data" feature.
If this
property is not set, the system cannot determine how to present the table’s
data in the search results, hence excluding it.
The
Solution: Setting the LookupPageId Property
To resolve this issue, you need to set the LookupPageId property in your custom table.
Conclusion
By simply
setting the LookupPageId property, you ensure your custom table/page is visible in the “Enable lists for searching” list.
Friday, 8 November 2024
Ensuring a Smooth Upgrade to Business Central 25 – SQL Server Full-Text Search Requirement
We encountered this error during a recent Business Central 25 upgrade.
Error: "Text optimized index cannot be
created/queried because the SQL Server Full-Text Search component is not
installed. Please install the SQL Server Full-Text Search component and try
again."
This error
message, which some may encounter during their upgrade process, indicates that
the SQL Server Full-Text Search component must now be installed for Business
Central 25.
Upgrading Unmodified C/AL Application to version 25 - Business Central | Microsoft Learn
Here’s how
to add the Full-Text Search component to your SQL Server for Business Central
25:
Steps to
Install SQL Server Full-Text Search Component
1.
Open SQL Server Installation Center.
If your installation media is accessible, launch the SQL Server Installation
Center.
2.
Navigate to Installation.
Click on Installation from the sidebar.
3.
Choose “Stand-Alone or Add Features Option.”
Select New SQL Server stand-alone installation or add features to an
existing installation
4. Add Features to an Existing Instance.
Click Next through the initial dialogs until you see the Installation
Type dialog. Here, choose Add features to an existing instance of SQL
Server.
5. Select Full-Text and Semantic Extractions for Search.
Under Database Engine Services, check Full-Text and Semantic
Extractions for Search to enable the Full-Text Search component.
6. Complete Installation.
Follow the remaining prompts to finalize the installation of this feature.
After
installation, you should be able to proceed with the Business Central 25
upgrade without encountering the Full-Text Search error.
Saturday, 31 August 2024
Streamlining Report Substitution in Business Central: A Dynamic Alternative to OnAfterSubstituteReport Code Changes
In Microsoft
Dynamics 365 Business Central, the OnAfterSubstituteReport event is commonly
used to substitute one report for another at runtime. While this event handler
is powerful, it can become cumbersome when you frequently update report
substitutions. For each report change, you must modify the code, which can be
time-consuming, and you must wait to move the changes to the production
environment.
It can grow
big like the example below:
[EventSubscriber(ObjectType::Codeunit, Codeunit::ReportManagement, 'OnAfterSubstituteReport',
'', false, false)]
local procedure OnAfterSubstituteReport(ReportId: Integer; RunMode: Option;
RequestPageXml: Text; RecordRef: RecordRef; var NewReportId: Integer);
begin
case ReportId of
1305:
NewReportId := 10075;
299:
NewReportId := 50107;
393:
NewReportId := 50108;
120:
NewReportId := 50140;
10040:
NewReportId := 50140;
108:
NewReportId := 50154;
10048:
NewReportId := 50141;
5802:
NewReportId := 50147;
10049:
NewReportId := 50142;
end;
end;
An
alternative approach to managing report substitutions dynamically involves
creating a custom table that stores the mappings between old report IDs and new
report IDs. By leveraging this table in conjunction with the OnAfterSubstituteReport
event, you can simplify the process of updating report substitutions without
modifying the underlying code each time.
Step 1:
Create a Custom Table and Page for Report Mappings
First,
create a custom table to store the mappings between old and new report IDs.
This table should have at least two fields: one for the old report ID and
another for the new report ID. Here’s an example:
table 88100 "MPA
Dynamic Rep. Subs. Mapping"
{
Caption = 'Dynamic Report Substitution Mapping';
DataClassification = CustomerContent;
fields
{
field(1; ReportId; Integer)
{
DataClassification = CustomerContent;
TableRelation = AllObjWithCaption."Object
ID" WHERE("Object Type" = CONST(Report));
trigger OnValidate()
begin
Calcfields("Report
Caption");
end;
}
field(2; NewReportId; Integer)
{
DataClassification = CustomerContent;
TableRelation = AllObjWithCaption."Object
ID" WHERE("Object Type" = CONST(Report));
trigger OnValidate()
begin
Calcfields("New Report
Caption");
end;
}
field(4; "Report Caption"; Text[250])
{
CalcFormula = lookup("Report
Metadata".Caption where(ID = field(ReportId)));
Caption = 'Report Name';
Editable = false;
FieldClass = Flowfield;
}
field(5; "New Report Caption"; Text[250])
{
CalcFormula = lookup("Report
Metadata".Caption where(ID = field(NewReportId)));
Caption = 'New Report Name';
Editable = false;
FieldClass = Flowfield;
}
}
keys
{
key(Key1; ReportId)
{
Clustered = true;
}
}
}
This page
will allow you to maintain a list of report substitutions that can be easily
updated through the UI, without needing to touch any code.
page 88100 "MPA
Dynamic Rep. Subs. Mapping"
{
Caption = 'Dynamic Report Substitution Mappings';
PageType = List;
UsageCategory = Lists;
ApplicationArea = All;
SourceTable = "MPA Dynamic Rep. Subs. Mapping";
layout
{
area(Content)
{
repeater(Group)
{
field(ReportId; Rec.ReportId)
{
ApplicationArea =
All;
}
field("Report
Caption"; Rec."Report Caption")
{
ApplicationArea =
All;
}
field(NewReportId; Rec.NewReportId)
{
ApplicationArea =
All;
}
field("New Report
Caption"; Rec."New Report Caption")
{
ApplicationArea =
All;
}
}
}
}
}
Step 2:
Populate the Table with Mappings
Once the
table is created, you can populate it with your report mappings. For example,
if you want to replace Report 100 with Report 200, simply add an entry with Old
Report ID = 100 and New Report ID = 200.
Step 3:
Modify the OnAfterSubstituteReport Event
Now, modify
the OnAfterSubstituteReport event to reference the custom table you created.
This will enable the event to dynamically substitute reports based on the
mappings stored in the table:
codeunit 88100
"MPA Report Management Subs"
{
[EventSubscriber(ObjectType::Codeunit, Codeunit::ReportManagement, 'OnAfterSubstituteReport',
'', false, false)]
local procedure OnAfterSubstituteReport(ReportId: Integer; RunMode: Option;
RequestPageXml: Text; RecordRef: RecordRef; var NewReportId: Integer);
var
SubstituteReports: Record "MPA Dynamic Rep. Subs.
Mapping";
begin
if SubstituteReports.Get(ReportId) then
NewReportId := SubstituteReports.NewReportId;
end;
}
This code
checks the custom table for a matching Old Report ID and, if found, assigns the
corresponding New Report ID to the NewReportID parameter. This substitution
happens without the need to hard-code any report IDs, making your solution much
more flexible and easier to maintain.
Step 4:
Manage Substitutions Dynamically
With this
setup, managing report substitutions becomes straightforward. Whenever you need
to substitute a report, simply update the mapping in the custom table—no code
changes are required. This approach allows for quick adjustments in a
production environment without the need for a new deployment.
Conclusion
Using a
custom table to manage report substitutions in Business Central is a powerful
alternative to hard-coding substitutions in the OnAfterSubstituteReport event.
By separating the logic from the code and storing it in a table, you gain
flexibility, reduce maintenance overhead, and simplify the process of updating
report mappings.
You can find
the code here
pmohanakrishna/DynamicReportSubstitutions
(github.com)
Wednesday, 29 May 2024
Resolving the DML Statement Error During the Business Central Upgrade
Upgrading to Business Central can sometimes throw unexpected errors, and one such error we recently encountered involved a DML statement issue with the 'Access Control' table. Here, we’ll walk you through the problem and how we resolved it.
The Error
During an upgrade attempt from BC14 to BC23,
the Event log reported the following error related to the 'Access Control'
table:
The
target table 'BC14PROD_UPG.dbo.Access Control’ of the DML statement cannot have
any enabled triggers if the statement contains an OUTPUT clause without INTO
clause.
Investigation
and Findings
Upon investigating the error, we discovered
that the 'Access Control' table had several triggers enabled. Triggers in SQL
Server are special types of stored procedures that automatically run when
specific actions occur in the database.
Resolution
The upgrade process failed because the DML
statement included an OUTPUT clause without an INTO clause, which conflicted
with the enabled triggers. To resolve this, we deleted the triggers on the
'Access Control' table.
Steps to
Resolve the Error
1. Identify Triggers: First, identify any triggers associated with the 'Access Control'
table.
2. Delete Triggers: Next, delete the identified triggers.
3. Re-run the Upgrade: After deleting the triggers, we re-ran the upgrade process, which completed successfully.
Conclusion
If you
encounter the DML statement error during your BC upgrade, check for
and remove any triggers on the associated table. This straightforward
solution allowed our upgrade to proceed without further issues.
We hope
this insight helps others facing similar upgrade challenges. If you have any
questions or need further assistance, feel free to reach out in the comments
below.
Happy
upgrading!