[ESP] En el siguiente enlace puedes ver leer los cambios relacionados a la versión vigente:
[ENG] En el siguiente link, you can read the changes related to the current version:

14.3
Yaml-support in JsonObject
Support for YAML is add to the JsonObject. YAML can be read into a JsonObject and be manipulated using the JsonObject API.
Two new methods are added to read YAML into a JsonObject instance:
[Ok :=] ReadFromYaml(String)
[Ok :=] ReadFromYaml(InStream)
And two new methods are added to write a JsonObject instance as YAML:
[Ok :=] WriteToYaml(String)
[Ok :=] WriteToYaml(OutStream)
AppSourceCop
- It will now be possible to delete table extensions which depend on Microsoft tables which are obsoleted for removal if the app source submission targets releases newer or equal to 2024 release wave 1 (version 24).
14.2
Resources in extensions
Resource files can now be packaged as part of an extension. To add resources to your extension, the following property has to be set in your app.json:
"resourceFolders": [<list of folders that contain resources>]
The folders should be listed relative to the root of your project. For example:
"resourceFolders": ["Resources"]
This will include all files under the folder ‘resources’. The resource folders themselves can contain additional subfolders. For example, you could have the following folder structure:
MyApp
| - Resources/
| - Images/
| - MyImage.png
| - Configuration/
| - MyConfiguration.json
| - src/
| - MyCodeunit.codeunit.al
Access to these resources is done through the NavApp.GetResource("resource name": Text; var instream: Instream; [optional] encoding: TextEncoding) method. The name of a resource is its path from the root of its resource folder. So for the folder structure above, you can do:
procedure MyProc()
var
resultStream: Instream;
jsonText: Text;
begin
NavApp.GetResource("Images/MyImage.png", resultStream);
// Do stuff with the blob in the resultStream object
NavApp.GetResource("Configuration/MyConfiguration.json", resultStream, TextEncoding::UTF8);
jsonText := resultStream.Read(jsonText);
end
There are also the methods NavApp.GetResourceAsText("resource name": Text; [optional] encoding: TextEncoding): Text and NavApp.GetResourceAsJson("resource name": Text; [optional] encoding: TextEncoding): JsonObject that directly retrieves resources as Text or JsonObject types.
The method NavApp.ListResources([optional] filter: Text) is also provided to allow for iteration over resources. The filter value for the method can contain wildcards. If it does not contain wildcards, then any resources with the filter text within its name will be returned. For example:
/**
* For the following resource structure:
* Resources/
* Images/
* SampleImage1.png
* SampleImage2.png
* SampleImage3.jpg
* TemplateImage.jpg
* Snippet/
* SampleSnippet.txt
* TemplateSnippet.txt
*/
// This will return: ["Images/SampleImage1.png","Images/SampleImage2.png","Images/SampleImage3.jpg", "SampleSnippet.txt"]
NavApp.ListResources("Sample");
// This will return: ["Images/SampleImage1.png","Images/SampleImage2.png"]
NavApp.ListResources("Images/*.png")
Resources can only be accessed within the scope of the app that contains them. This means that there is no way to access the resources of another app.
AppSourceCop
- Addressed issues executing page breaking change validation rules AS0029, AS0035, and AS0040 on pages whose source tables jave been moved tables to another extension, for instance ‘No. Series’.
Miscellaneous
- Fixed an issue where race conditions would occur if a code action that is invoked on project or workspace scope tried to change large number of files.
- Fixed an issue that caused the runtime to fail, when calling methods from extended interfaces on an instance of the derived interface.
14.1
Miscellaneous
- Interfaces cannot contain methods whose signatures collide with the methods from the extended interfaces. It is also not possible to extend an interface with other interfaces whose methods collide.
14.0
Github Issues
- #7751 [Copilot] AW0005 should not be shown for PromptGuide actions
- #7644 Package cache doesn’t support subfolders with .app files.
- #7670 TableExtension BlankZero
- #6997 Intellisense doesn’t work with foreach statement
- #7672 Word Layout compilation bug
- #7697 Command «AL: Publish with Debugging» does not open browser when incognito Edge is explicitly specified in settings.json
- #7695 Issue with Loading Projects after Downloading Symbols in Erroneous Network
- #7689 Incorrect Symbol Info shown in VS Code for Enum Values
- #7492 BC22 error AL0196: The call is ambiguous between the method Dictionary
- #7704 al/createPackage fails due to invalid custom xml part
- #7691 Cannot suppress diagnostic AL1080 via ruleset.json file
- #5866 Duplicated entries in xlf file
- #7723 ALDoc Exception if app name contains illegal folder chars
- #7731 AA0181 rule warning for Codeunit.Find method
- #7764 Intellisense in Query- Objects
- #7722 Error: Specified argument was out of the range of valid values. (Parameter ‘index’)
- #7659 Namespaces causing issues while generating permission sets in vscode
- #7712 Unexpected warning AL0697 when an object is added to an entitlement through a permissionsetextension
- #7715 Symbol Error AL0443 – «Allow Data Analysis Mode.»
- #7800 Publish fails with usage of
askeyword - #7793 Diagnostic AL0780 not working as expected
- #7798 Spelling mistake: «ErrorBehavior::Collect» tooltip
- #7788 Error AS0036 raised when modifing a tooltip at table level
AppSourceCop
- Updated rule AS0031 to also allow removing groups from promoted area on pages that no longer supports promoted areas. See AL0788.
- Updated rule AS0031 to allow removing non-obsolete page actions whose name conflicts with a new action from the base page.
- Updated rule AS0032 to allow removing non-obsolete page controls whose name conflicts with a new control from the base page.
- Updated rule AS0033 to allow removing non-obsolete page views whose name conflicts with a new view from the base page.
- Updated rule AS0072 to support adding parameters to an obsoleted event without triggering a diagnostic.
- Updated the rules AS0072, AS0073, AS0074, AS0075, AS0076 to support the scenario of modularizing an object by using extensions in the same app.
- Updated rule AS0036 to allow modifying tooltip property on table fields.
- Updated rule AS0029 to allow removing pages and page extensions whose source table comes from a dependency and the table has been marked with ObsoleteState Removed.
- Updated rules AS0035 and AS0040 to allow changing the SourceTable property if the new version of the source table used of the baseline page comes from a dependency and the table has been marked with ObsoleteState Removed.
Miscellaneous
- Add ‘Tenant Entra Id’ to Excel layout template in the Report Request table. Map report metadata and request properties to defined names for easy use.
- Added a new commandline argument to alc.exe called
errorsonlyinconsole. If this argument is used, then only error diagnostics from the compilation are sent to the console output. This is useful for projects that have a large number of Warning and Info level diagnostics that fill the console output. - Fixed an issue where
CurrReport.Previewusage outside of a procedure would cause the extension to crash. - Fixed an issue where setting
compilationOptions.outFolderto a relative path would result in the package file not being found when publishing. - Added warning AL0845 when having matching
APIVersion,APIPublisher,APIGroup, andEntityNamesorEntitySetNameproperty values across API Pages. From runtime version 16.0, this will turn into the error AL0846. - Added IntelliSense for foreach statements.
- Added an indicator for obsoleted fields in the hover tooltip for records.
- Fixed an issue where IntelliSense would suggest namespaces from other publishers when declaring namespaces.
- Fixed an issue where the code action for converting explicit ‘with’ statements would carry over comments to the fully qualified statements.
- Allow downloading symbols using an Attach type launch configuration.
- Allow having a list of interfaces
- Fixed an issue where the compiler could not select the most specific overload based on interfaces being used as parameters. Now the most specific interface is selected.
- Updated DocumentFormat.OpenXml dependency to version 3.0.2.
- Option variables no longer get the captions when assigned from a table field.
- Fixed an issue where the code action for converting explicit ‘with’ statements would remove comments from the beginning of the statement when it is a block statement.
- Updated AA0194 and AA0218 to validate actions of
FileUploadActiontype. - Added an GetCallerCallstackModuleInfos API for getting app information for extensions that contain the currently running method in the callstack.
- Added code actions to fix all AL0604 warnings in the document, project, or workspace scope.
- Added error AL0852 when subparts in API pages contain circular references.
- Added support for modifying the properties InsertAllowed, ModifyAllowed, and DeleteAllowed from page extensions and page customizations.
- Added a new property «OptimizeForTextSearch» on table fields of textual type, which specify if the field is included in a text optimized search index for faster word based filtering. A property «IsOptimizedForTextSearch» has also been added on FieldRef to check if a field is included in text optimized index.
- Added support to use Copilot prompt actions on
Document,Card, andListPluspages. - Fixed issue where InStream/OutStream used in Dictionaries would cause a runtime failure by blocking them at compilation time with diagnostic AL408
- Fixed an issue where CodeCop rule AA0175 would report false positive warnings in
repeat,while, andforloops. - Fixed issue with having a list of interfaces as a global variable.
- Fixed issue with having a named return value of type List
- Added support for moving all tooltips from page controls within a document or project to their related table fields using a code action.
- Added ToolTip property to query columns.
- Added AI token count on session information.
- Fixed issue with name clash with runtime functionality
- Fixed an issue where permission set extensions in the same application would not be accounted for when validating if an object is added to entitlements
- The command for generating permission sets is now compatible with namespaces.
- Fixed an issue where code actions would insert additional unnecessary new lines.
- Fixed an issue where wrong code would be generated when invoking a method on an interface produced by casting with the
asoperator. - Statements in a block can now start with a parenthesized expression to support invoking methods on casted interface, for example:
(foo as IFoo).Method();. - Fixed an issue where the code action for converting explicit ‘with’ statements would remove comments from the body of the ‘with’ block if it does not contain statements.
- Added support for the ClientService option value in the BreakOnNext property within launch.config, aiding in debugging tests with BCContainerHelper’s Run-TestsInBcContainer; requires a compatible 2024 release wave 2 or newer platform.
- Added support for the Scope property on Enums and Interfaces
- Added AL method to HttpClient for PATCH Http requests.
- Added support for specifying a table in SelectLatestVersion to only disregard caching for a single table.
- Fixed an issue where nested parts with duplicate entity names would cause an error.
- Fixed an issue where members of object extensions would not be recommended when they were originating from other projects in the workspace.
- Fixed an issue where packages created via the pre-release would not be backwards compatible with previous compilers.
Defining a positive list of elements in page customizations
Profiles and page customizations can be used to tailor the interface for users of a specific role. Since page customizations can hide elements such as controls, actions, or views, they are suited for defining a negative list of elements. However, any visible element that is not referenced by the page customization would be shown on the page, including elements defined in other extensions.
It is now also possible to create a positive list of elements to be shown on the page using the properties ClearActions, ClearLayout, and ClearViews.
For instance, the following code reduces the Customer Card to only the customer’s Name and the promoted Email action.
pagecustomization MyCustomerCardCust customizes "Customer Card"
{
ClearActions = true; // Hide all actions on the page
ClearLayout = true; // Hide all layout elements on the page
layout
{
modify(Name) { Visible = true; } // Show the Name
}
actions
{
modify(Email_Promoted) { Visible = true; } // Show the Email action
}
}
Note that you can also control the availability of the Create, Edit, and Delete system actions using the properties InsertAllowed, ModifyAllowed, and DeleteAllowed.
Deprecate legacy report layout functions
The legacy report layout methods DefaultLayout, RdlcLayout, WordLayout, and ExcelLayout have been deprecated. Replace usage of these methods with layout selection and ‘Report Layout List’ lookup. See Upgrading reports for more information.
Support for profile extension objects
It is now possible to define profile extension objects. They can be used to modify the target profile’s caption, role center, or even include/remove it from the role explorer. Finally, it is also possible to add page customizations to a specified profile. For more information, see Profile Extension Object.
profileextension MyProfileExt extends "O365 SALES"
{
Caption = 'Profile Extension Caption';
ProfileDescription = 'Profile Extension Description';
Enabled = true;
Promoted = true;
RoleCenter = 9027;
Customizations = SalesOrderCustomization, SalesQuoteCustomization;
}
Introduced new type PageStyle
The type can be used to get the valid values for StyleExpr, found on page controls. Here is an example of how to use it:
layout
{
area(Content)
{
field(Name; rec.Name)
{
StyleExpr = nameStyle;
}
}
}
var nameStyle : Text;
local procedure ChangeNameStyle(newPageStyle : PageStyle)
begin
nameStyle := format(newPageStyle);
end;
New command – Package full dependency tree for active project
We have added a new command that packages the active project and its entire dependency tree. Its purpose is to assist local development by allowing a developer to forcefully rebuild all the packages required for a single project.
This keyword
We have added support for the this keyword for self-reference on all objects. The main benefits are
- Allow codeunits to pass a reference to
thisas an argument to another method. - Improve readability by signaling that a referenced symbol is a member on the object itself.
We have added a CodeCop rule AA0248 that is enabled by default with severity ‘hidden’. ‘Hidden’ means that it shows up as three dots in the editor, but not as a diagnostics in the Problem view or in pipelines. There is also a CodeFixer to add the this keyword.
Support for extending interfaces
It is now possible to extend one or more existing interfaces when you declare an interface. When implementing an interface that extends other interfaces the implementor must also implement all methods from all extended interfaces.
The syntax is
interface IFoo
{
procedure Foo();
}
interface IBar
{
procedure Bar();
}
interface IFooBar extends IFoo, IBar
{
procedure FooBar();
}
codeunit 10 TheImplementor implements IFooBar
{
// Must implement IFoo, IBar, IFooBar
}
In the example above the TheImplementor can be used as both IFoo, IBar, and IFooBar. The feature also works with the testing and casting operators.
The as operator
The as operator is used for casting an instance of an interface to a specific interface. If the source interface does not implement the target interface, it will throw an error at runtime. Here’s an example:
procedure CastInterface(intf: Interface IFoo): Interface IBar
begin
exit(intf as IBar); // Throws an error if 'intf' doesn't implement 'IBar'
end;
Similarly, the as keyword works with variants:
procedure CastInterface(v: Variant): Interface IBar
begin
exit(v as IBar); // Throws an error if 'v' doesn't implement 'IBar'
end;
The is operator
The is operator allows you to test whether an instance of an interface or the content of a variant supports a specific interface. Here’s the syntax for using the is keyword:
procedure TestInterface(intf: Interface IFoo)
begin
if intf is IBar then
Message('I also support IBar');
end;
You can also use the is operator with variants:
procedure TestVariant(v: Variant)
begin
if v is IBar then
Message('I support IBar');
end;
New Date/Time/DateTime methods
We have modernized the Date/Time/DateTime APIs for extracting sub-components of the types.
| Type | New method | Existing | Description |
|---|---|---|---|
| Date | MyDate.Day | Date2DMY(MyDate, 1) | Gets the day of month from MyDate |
| Date | MyDate.Month | Date2DMY(MyDate, 2) | Gets the month from MyDate |
| Date | MyDate.Year | Date2DMY(MyDate, 3) | Gets the year from MyDate |
| Date | MyDate.DayOfWeek | Date2DWY(MyDate, 1) | Gets the day of week from MyDate |
| Date | MyDate.Year | Date2DWY(MyDate, 2) | Gets the week number from MyDate |
| Time | MyTime.Hour | Evaluate(i, Format(Time, 2, '<HOURS24>')) | Gets the hours MyTime (0..23). |
| Time | MyTime.Minute | Evaluate(i, Format(Time, 2, '<MINUTES>')) | Gets the hours MyTime (0..59). |
| Time | MyTime.Second | Evaluate(i, Format(Time, 2, '<SECONDS>')) | Gets the hours MyTime (0..59). |
| Time | MyTime.Millisecond | Evaluate(i, Format(Time, 3, '<THOUSANDS>')) | Gets the hours MyTime (0..999). |
| DateTime | MyDateTime.Date | DT2Date(MyDateTime) | Gets the date part of MyDateTime |
| DateTime | MyDateTime.Time | DT2Time(MyDateTime) | Gets the time part of MyDateTime |
There are no changes to the existing APIs.
Wildcard search in AL Explorer
We have improved the search functionality in AL Explorer by supporting * and ? wildcards.
* means zero or more characters ? means any single character
Here are some examples
| Pattern | Description | Examples |
|---|---|---|
| Customer* | Starts with Customer | ‘Customer Card’, ‘Customer’ |
| *Card | Ends with Card | ‘Customer Card’, ‘Item Card’, ‘SomeCard’ |
| Customer*Card | Starts with Customer and ends with Card | ‘Customer Card’, ‘Customer Accounts Card’ |
| *Customer* | Customer anywhere | ‘Customer’, ‘Apply Customer Entries’ |
Ternary operator ?: in AL
We have added the ternary (conditional) operator to the AL language. The ternary operator ? : known from other programming languages streamlines conditional operations in code, enhances readability, and reduces verbosity. It’s particularly useful for simple conditions, promoting code clarity, and intent-focused programming.
The following examples show how the code in GetBooleanText() can be rewritten using the ternary operator to be less verbose and more succint.
Without the ternary operator
procedure GetBooleanText(b: Boolean): Text;
begin
if b then
exit('True')
else
exit('False');
end;
With the ternary operator
procedure GetBooleanString(b: Boolean): Text;
begin
exit(b ? 'True' : 'False');
end;
Support for SaveAsJson on the Query object
We have added support for SaveAsJson on the Query object. This functionality is now available alongside the existing SaveAsXml and SaveAsCsv methods.
procedure Test();
var
result : Boolean;
os: OutStream;
begin
result := Query.SaveAsJson(10, os);
end;
Pull extension source from Git when opening Visual Studio Code from the web client
This feature allows users to pull source code from a Git repository or a specific build using the source metadata in the extension’s manifest. This is particularly useful if access to extension code is blocked by IP resource exposure protection.
From the Extension Management list and Page Inspector (Extensions tab) pages, a new “Open Source in VS Code” option is available in the context menu for an extension. When selected, Visual Studio Code will open and prompt you to clone or open the Git repository for the extension and synchronize it with the commit version used to compile it, using the repo metadata included in the extension. It will also remember the local path where the repository is located for easier access. This feature empowers support, consultants, and developers to navigate code, hotfix builds, or sync to get the latest changes for investigation or development.
Más información / More information:



Deja un comentario