I think Friday is the perfect day to break Business Central! Very dangerous, do not repeat this on Production!
Let's start by breaking the server instance. After executing this code, the server instance will break for all users. Cloud Business Central will recover after some time, but I would not recommend using this on production. Yes, this code doesn't do anything useful, quite the opposite actually :)
page 81008 "DET Destroy Instance"
{
PageType = List;
ApplicationArea = All;
UsageCategory = Lists;
SourceTable = "DET Some Table";
SourceTableTemporary = true;
Caption = 'Destroy Instance';
layout
{
area(Content)
{
repeater(Repgroup)
{
field("Entry No."; Rec."Entry No.")
{
ToolTip = 'Specifies the value of the Entry No. field.';
}
field(Description; Rec.Description)
{
ToolTip = 'Specifies the value of the Description field.';
}
}
}
}
actions
{
area(Processing)
{
action("DET DestroyInstance")
{
ApplicationArea = All;
Caption = 'Destroy Instance';
ToolTip = 'Destroy Instance';
Image = DeleteExpiredComponents;
trigger OnAction()
begin
Execute();
end;
}
}
area(Promoted)
{
actionref("DET DestroyInstance_promoted"; "DET DestroyInstance")
{
}
}
}
procedure Execute()
var
SessionIndex, StartIndex, EndIndex : Integer;
ListOfParts: List of [Integer];
i: Integer;
ParallelSessionCount: Integer;
begin
ParallelSessionCount := 6;
StartIndex := 1;
ListOfParts.Add(111);
ListOfParts.Add(112);
ListOfParts.Add(113);
ListOfParts.Add(114);
ListOfParts.Add(115);
ListOfParts.Add(112);
Rec.Init();
Rec."Entry No." := 1;
Rec.Insert();
for i := 1 to ParallelSessionCount do begin
EndIndex := StartIndex + ListOfParts.Get(i) - 1;
Rec."Start Index" := StartIndex;
Rec."End Index" := EndIndex;
if i > 1 then
StartSession(SessionIndex, Codeunit::"DET Insert Record Range", CompanyName(), Rec);
StartIndex := EndIndex + 1;
end;
end;
}
codeunit 81002 "DET Insert Record Range"
{
TableNo = "DET Some Table";
trigger OnRun()
var
TempRecRef: RecordRef;
FieldRef: FieldRef;
StartIndex, EndIndex : Integer;
i, j : Integer;
begin
Sleep(500);
TempRecRef.GetTable(Rec);
StartIndex := Rec."Start Index";
EndIndex := Rec."End Index";
for i := StartIndex to EndIndex do begin
TempRecRef.Init();
for j := 1 to 2 do begin
FieldRef := TempRecRef.Field(j);
FieldRef.Value(i);
end;
TempRecRef.Insert();
end;
end;
}
table 81003 "DET Some Table"
{
DataClassification = CustomerContent;
fields
{
field(1; "Entry No."; Integer)
{
DataClassification = CustomerContent;
Caption = 'Entry No.';
}
field(2; Description; Text[100])
{
DataClassification = CustomerContent;
Caption = 'Description';
}
field(3; "Start Index"; Integer)
{
DataClassification = CustomerContent;
Caption = 'Start Index';
}
field(4; "End Index"; Integer)
{
DataClassification = CustomerContent;
Caption = 'End Index';
}
}
keys
{
key(PK; "Entry No.")
{
Clustered = true;
}
}
}
Let's fix this code to make it do something useful. We will use an array of Record to populate each instance of the variable with different ranges in current session. Just fill data into temporary table, nothing special.
procedure Execute()
var
TempSomeTable: array[6] of Record "DET Some Table" temporary;
StartIndex, EndIndex : Integer;
ListOfParts: List of [Integer];
i: Integer;
Parts: Integer;
ResultTxt: TextBuilder;
begin
Parts := 6;
StartIndex := 1;
ListOfParts.Add(100);
ListOfParts.Add(100);
ListOfParts.Add(100);
ListOfParts.Add(100);
ListOfParts.Add(100);
ListOfParts.Add(100);
for i := 1 to Parts do begin
EndIndex := StartIndex + ListOfParts.Get(i) - 1;
TempSomeTable[i]."Start Index" := StartIndex;
TempSomeTable[i]."End Index" := EndIndex;
Codeunit.Run(Codeunit::"DET Insert Record Range", TempSomeTable[i]);
StartIndex := EndIndex + 1;
ResultTxt.AppendLine(StrSubstNo('Count is %1 for table %2', TempSomeTable[i].Count(), i));
end;
Message('The numbers are going up?!%1', ResultTxt.ToText());
end;
But what happened? I expected to see 100 entries in each of TempSomeTable[i], but instead, I encountered a strange situation where each subsequent element of the TempSomeTable array includes the previous records. Strange, isn't it?
Natalie Karolak pointed out that this is a documented behavior. Therefore, it's not a bug, but a feature! Unfortunately, it's still unclear what problem this feature solves, but it is known for sure that it complicates working with the array of the temporary table.
What do you think will be the result of executing such code?
pageextension 81000 "DET Customer List" extends "Customer List"
{
trigger OnOpenPage()
var
Vendor: Record Vendor;
begin
Rec.Init();
Rec."No." := 'test';
Rec.Insert();
Vendor.Init();
Vendor."No." := 'test';
Vendor.Insert();
Error('Stop!');
end;
}
Guessed it? You will end up creating Customer and Vendor with the number 'test'! Errors do not roll back transactions on the OnOpenPage trigger. Pretty cool, right?
What happens if we assign such a ShortCutKey for an Action? Spoiler - it will be very bad -)
ShortcutKey = 'Shift+k';
I think it's enough breaking Business Central for today, time to get ready for the weekend!