Claude AI is surprisingly good at AL coding

Miklos_Hollender
Miklos_Hollender Member Posts: 1,627

I just tried the free version in a browser, not even registration is necessary. I have not tested it yet (don't have a working environment rn) but it looks about right. I can recommend it to consultants who are new to programming, even if it has bugs it seems to have the correct outline, and also for experience devs for saving typing time.

Prompt: "create a new table for microsoft dynamics business central, that has fields like date, transaction type, quantity 1, quantity 2, quantity 3, value 1 , value 2, value 3. also write a procedure that reads the business central calendar table, and tells me how many working days are in this current month, and also which workin day (first, second etc.) is today"

answer:

Custom Transaction Table (50100):

  • Entry No. (auto-increment primary key)
  • Transaction Date
  • Transaction Type (Option field with values: Purchase, Sale, Transfer, Adjustment)
  • Quantity 1, 2, and 3 (decimal fields with up to 5 decimal places)
  • Value 1, 2, and 3 (decimal fields with 2 decimal places for currency)

Calendar Management Codeunit (50100):

  • GetWorkingDaysInfo() - Returns the total working days in the current month and which working day today is
  • IsWorkingDayInCalendar() - Checks if a specific date is a working day by:
    • Excluding weekends (Saturday/Sunday)
    • Checking the Base Calendar Change table for specific non-working dates
    • Checking for recurring non-working days (holidays)
  • ShowWorkingDaysMessage() - Displays a user-friendly message with the results

To use this:

  1. Deploy the table and codeunit to your Business Central environment
  2. Update the Base Calendar Code in the IsWorkingDayInCalendar procedure if you're using a specific calendar
  3. Call ShowWorkingDaysMessage() from a page action or directly from code

The procedure accounts for weekends and company holidays defined in the Base Calendar Change table, giving you accurate working day counts.

// Custom Transaction Table
table 50100 "Custom Transaction"
{
DataClassification = CustomerContent;
Caption = 'Custom Transaction';

fields
{
field(1; "Entry No."; Integer)
{
DataClassification = CustomerContent;
Caption = 'Entry No.';
AutoIncrement = true;
}
field(10; "Transaction Date"; Date)
{
DataClassification = CustomerContent;
Caption = 'Transaction Date';
}
field(20; "Transaction Type"; Option)
{
DataClassification = CustomerContent;
Caption = 'Transaction Type';
OptionMembers = " ",Purchase,Sale,Transfer,Adjustment;
OptionCaption = ' ,Purchase,Sale,Transfer,Adjustment';
}
field(30; "Quantity 1"; Decimal)
{
DataClassification = CustomerContent;
Caption = 'Quantity 1';
DecimalPlaces = 0 : 5;
}
field(31; "Quantity 2"; Decimal)
{
DataClassification = CustomerContent;
Caption = 'Quantity 2';
DecimalPlaces = 0 : 5;
}
field(32; "Quantity 3"; Decimal)
{
DataClassification = CustomerContent;
Caption = 'Quantity 3';
DecimalPlaces = 0 : 5;
}
field(40; "Value 1"; Decimal)
{
DataClassification = CustomerContent;
Caption = 'Value 1';
DecimalPlaces = 2 : 2;
}
field(41; "Value 2"; Decimal)
{
DataClassification = CustomerContent;
Caption = 'Value 2';
DecimalPlaces = 2 : 2;
}
field(42; "Value 3"; Decimal)
{
DataClassification = CustomerContent;
Caption = 'Value 3';
DecimalPlaces = 2 : 2;
}
}

keys
{
key(PK; "Entry No.")
{
Clustered = true;
}
key(DateKey; "Transaction Date")
{
}
}

}

// Codeunit with Calendar Working Days Procedure
codeunit 50100 "Calendar Management"
{
procedure GetWorkingDaysInfo(var TotalWorkingDays: Integer; var CurrentWorkingDay: Integer)
var
BaseCalendarChange: Record "Base Calendar Change";
CalendarDate: Date;
StartDate: Date;
EndDate: Date;
IsWorkingDay: Boolean;
begin
// Initialize
TotalWorkingDays := 0;
CurrentWorkingDay := 0;

    // Get first and last day of current month
StartDate := CalcDate('<-CM>', Today);
EndDate := CalcDate('<CM>', Today);

// Loop through all days in the month
CalendarDate := StartDate;
while CalendarDate <= EndDate do begin
// Check if it's a working day
IsWorkingDay := IsWorkingDayInCalendar(CalendarDate);

if IsWorkingDay then begin
TotalWorkingDays += 1;

// Check if we've reached today
if CalendarDate <= Today then
CurrentWorkingDay += 1;
end;

CalendarDate := CalcDate('<+1D>', CalendarDate);
end;
end;

local procedure IsWorkingDayInCalendar(CheckDate: Date): Boolean
var
BaseCalendarChange: Record "Base Calendar Change";
DayOfWeek: Integer;
begin
// Get day of week (1=Monday, 7=Sunday)
DayOfWeek := Date2DWY(CheckDate, 1);

// Default: Monday-Friday are working days
if DayOfWeek in [6, 7] then // Saturday or Sunday
exit(false);

// Check if date is marked as non-working in Base Calendar Change
BaseCalendarChange.SetRange("Base Calendar Code", ''); // Use your calendar code
BaseCalendarChange.SetRange(Date, CheckDate);
BaseCalendarChange.SetRange(Nonworking, true);
if not BaseCalendarChange.IsEmpty then
exit(false);

// Check recurring non-working days
BaseCalendarChange.Reset();
BaseCalendarChange.SetRange("Base Calendar Code", '');
BaseCalendarChange.SetRange("Recurring System", BaseCalendarChange."Recurring System"::"Annual Recurring");
BaseCalendarChange.SetRange(Day, Date2DMY(CheckDate, 1));
BaseCalendarChange.SetRange(Month, Date2DMY(CheckDate, 2));
BaseCalendarChange.SetRange(Nonworking, true);
if not BaseCalendarChange.IsEmpty then
exit(false);

exit(true);
end;

procedure ShowWorkingDaysMessage()
var
TotalWorkingDays: Integer;
CurrentWorkingDay: Integer;
MessageText: Text;
begin
GetWorkingDaysInfo(TotalWorkingDays, CurrentWorkingDay);

MessageText := StrSubstNo('Total working days in %1: %2\Today is working day number: %3',
Format(Today, 0, '<Month Text> <Year4>'),
TotalWorkingDays,
CurrentWorkingDay);

Message(MessageText);
end;

}