Dynamically Change Captions with Caption Class
Ever wanted to dynamically change Captions of a field in Business Central? This is possible with the CaptionClass property but it can be very tricky to use, so here's your definitive Guide to using CaptionClass
Mkublbock
7/15/20244 min read
Hey there and welcome to my very first Blog post!
Today I want to talk about a very interesting property called "CaptionClass". This property allows you to dynamically change captions in the Business Central UI.
I remember a couple of years ago when we had a customer request a feature like that but none of us knew about CaptionClass and we weren't able to implement said feature. If only we knew.
CaptionClass allows users to configure captions without touching the code, making captions truly dynamic. CaptionClass uses "Caption Class" Codeunit 42 to translate the CaptionClass property into translations.
The syntax of CaptionClass is always in the format of <Caption Area>, <Caption Expression> where <Caption Area> can either be "1", "2", "3" which will be managed by Base App Code or any number you want to assign that is later managed by your code.
Here are the specific meanings of "1", "2", and "3":
1 is for using a Dimension as caption.
2 is for captions of fields that can include or not VAT. For example, if CaptionClass = '2,0,Invoice Amount'; the resulting caption in the UI will be Invoice Amount Excl. VAT. If CaptionClass = '2,1,Invoice Amount'; the resulting caption in the UI will be Invoice Amount Incl. VAT.
3 returns the <Caption Expression> string
Let's first look at a simple example when translating Dimensions:
For this I have created a Table called "Caption Class Dim" that has two fields:
"Global Dimension 1 Code" & "Global Dimension 2 Code"
Normally, what we would do is set the Caption to the same as the field name and then translate it into the correct Dimension Name. However, that obviously has some negative side-effects:
If people are using the system in english, they would see "Global Dimension 1 Code" as the caption but they would prefer to see the actual Dimension Name
You would have to manually translate Dimensions into every language that is used
Instead of using the Caption, we can now use CaptionClass to let the system handle the translations automatically for us:
And this will automatically translate the Dimension Captions:
Like explained above the Base Application uses Codeunit 42 "CaptionClass" to handle the translations. Let's look into this codeunit to get a better understanding
Codeunit 42 provides two IntegrationEvents:
OnResolveCaptionClass(CaptionArea: Text; CaptionExpr: Text; Language: Integer; var Caption: Text; var Resolved: Boolean)
OnAfterCaptionClassResolve(Language: Integer; CaptionExpression: Text; var Caption: Text[1024])
Let's subscribe to both of them to see what they do in this example
Let's start debugging!
The first EventSub that will trigger is the "OnResolveCaptionClass". In the local Variables we can already see that the CaptionArea and CaptionExpr has been split and that the Caption has already been resolved to "Department Code". If the Area is a custom one then the Caption would have not been resolved here and you can resolve it by your own custom code. In this example however, it has already been translated by Base Code. Let's see where the caption was resolved
When starting from the beginning in the Call Stack we will quickly come across the "Caption Class Impl." Codeunit that Resolves the Caption Class by calling the "OnResolveCaptionClass" procedure
The Base Code then has multiple EventSubscribers in different places to resolve the caption, but for this example we'll focus on the one in "Dimension CaptionClass Mgtm" Codeunit. As you can see this Codeunit also has an EventSubscriber on "ResolveCaptionClass" Event that checks if the CaptionArea is 1. As we already know we are using Dimensions and therefore the CaptionArea we provided in the CaptionClass property is 1. Then the Caption is resolved via the "DimCaptionClassTranslate" Procedure
This procedure contains a comment section that explains what CaptionExpression you need to provide to get to your desired translation
// DIMCAPTIONTYPE
// <DataType> := [SubString]
// <Length> <= 10
// <DataValue> := 1..6
// 1 to retrieve Code Caption of Global Dimension
// 2 to retrieve Code Caption of Shortcut Dimension
// 3 to retrieve Filter Caption of Global Dimension
// 4 to retrieve Filter Caption of Shortcut Dimension
// 5 to retrieve Code Caption of any kind of Dimensions
// 6 to retrieve Filter Caption of any kind of Dimensions
// 7 to retrieve Name Caption of Shortcut Dimension
In our example we provided a CaptionExpression of 1,1 which will be split into the CaptionType and CaptionRef. CaptionType 1 means that we want to translate the Code Caption of a Global Dimension and CaptionRef 1 refers to the Global Dimension 1 Code. That's why we provided 1,2 for Global Dimension 2 Code.
To finally translate the Caption the "Dimension Translations" table is used
Summary:
It is possible to dynamically change translations in Business Central without even touching the code. This can be achieved by using the CaptionClass property and a Base Application implementation by using CaptionArea 1, 2 or 3 or by using a customized approach with a customized CaptionArea and EventSubscriber on "OnResolveCaption" that is published by the "Caption Class" Codeunit.
























Matthias Küblböck
Microsoft Business Central Developer
©Mkublbock 2024. All rights reserved.