Lab Notes #4
One of the main concepts in Business Central that sets it apart from accounting systems like Dynamics GP is the way you classify accounts. Now I’m not an accountant, but there are some interesting challenges in handling Dimensions, and I would like to cover one of them.
Quick primer for lay people like me:
Segment-Based Accounting
A chart‑of‑accounts–driven method where each “segment” is physically embedded in the GL account number.
Example: 4000‑10‑200
- 4000 = Revenue
- 10 = Department
- 200 = Region
Key traits:
- Hard‑coded structure: Every combination becomes its own GL account.
- Rigid: Changing structure requires redesigning the chart.
- Explodes the COA: You end up with hundreds or thousands of accounts.
- Reporting is simple because the segments are baked into the account number.
- Common in legacy ERPs (e.g., older Oracle, SAP, QuickBooks workarounds).
Dimensions
A metadata‑driven method where you keep the GL account clean and attach attributes (“dimensions”) to transactions.
Example: GL Account: 4000 – Revenue Dimensions:
- Department = Sales
- Region = East
- Project = P‑102
Key traits:
- Flexible: Add or remove dimensions without touching the COA.
- Cleaner chart of accounts: One revenue account, many dimension combinations.
- Powerful reporting: Analysis Views, account schedules, Power BI, etc.
- Rules-based: Dimension combinations, defaults, and blocking prevent errors.
- Modern ERP standard.
There are 2 Global Dimensions, these are available on just about everything and have a user interface shortcut as Shortcut Dimension 1 and Shortcut Dimension 2. The issue is after those 2 you can have unlimited dimensions!
Because dimensions are dynamic, there isn’t going to be a field for each one on the records. So, we need to store the record to dimension relationship in another table. There is a challenge here, dimension combinations will naturally group and become repetitive. Not EVERY combination of dimension value makes sense, and we end up with a lot of duplicate data. The Business Central team decided to handle this with the Dimension Set.
The Dimension Set is means to reduce the amount of data storage needed. Every time you assign a series of dimensions to a record the Dimension Set table is checked to see if that unique combination exists. If it is new, it creates a new Dimension Set record and returns the Id. If it finds a match, then the matching Id is returned. You assign this Id to the Dimension Set Id field, and everything is done.
When working on the front-end of BC, all this is automatic. However, when creating integrations or other automation, we need to handle the dimension set id from AL code. Let’s look at what it takes from the backend.
Every dimension has 2 components, a Code and a Value. Looking at the example from above:
| Code | Value |
|---|---|
| Department | Sales |
| Region | East |
| Project | P-102 |
I’m going to create a procedure that accepts these three values and gets returns the Dimension Set Id.
procedure GetDimensionSetId(Department: Code[20]; Region: Code[20]; Project: Code[20]): Integer
var
TempDimensionSetentry: Record "Dimension Set Entry" temporary;
DimSetMgr: Codeunit "DimensionManagement";
begin
TempDimensionSetentry.Init();
TempDimensionSetentry.validate("Dimension Code", 'Department');
TempDimensionSetentry.validate("Dimension Value Code", Department);
TempDimensionSetentry.Insert(true);
TempDimensionSetentry.Init();
TempDimensionSetentry.validate("Dimension Code", 'Region');
TempDimensionSetentry.validate("Dimension Value Code", Region);
TempDimensionSetentry.Insert(true);
TempDimensionSetentry.Init();
TempDimensionSetentry.validate("Dimension Code", 'Project');
TempDimensionSetentry.validate("Dimension Value Code", Project);
TempDimensionSetentry.Insert(true);
exit(DimSetMgr.GetDimensionSetID(TempDimensionSetentry));
end;
This example is a little simple, I could have gone with some Key Value pairs or something else, but the concept is the same.
The first thing to note is that on line 3 the Dimension Set Entry record is Temporary. We don’t want this record writing data to the database; we just want to temporarily store data for the code unit.
We add our Codes and Values to the Dimension Set Entry records. We then pass the temporary table records to the DimensionManager code unit. This code unit will review the records sent in and if they are unique create the actual records to store, create a dimension set entry record and return the id. If they are not found to be unique, it will return the dimension set id of matching record.
There you have it, this is how to handle a Dimension Set Id from the backend of Business Central. Let me know if you have any questions in the comment section.





Leave a comment