Starting from Dynamics NAV 2013, the dimension structure underwent a significant overhaul. This change introduced the concept of Dimension Set IDs, which replaced the traditional dimension handling approach. While this modernization brought performance improvements and better data integrity, it also created a common challenge for developers: how to programmatically insert or update dimensions without getting lost in complex calculations.

If you’ve ever struggled with dimension management in NAV 2013 or later versions, you’re not alone. Rather than rehashing the theoretical explanations found elsewhere, I’ll share a practical solution that has saved countless development hours: the SpecDimensionManagement codeunit.

The Problem with Traditional Approaches

Before diving into the solution, let’s acknowledge why dimension management became more complex:

  • Dimension Set Tables: Dimensions are now stored in separate tables with unique set identifiers
  • Complex Relationships: Multiple temporary tables and validation rules must be managed
  • Performance Considerations: Proper handling is crucial for maintaining system performance
  • Error-Prone Code: Manual dimension calculations often lead to bugs and inconsistencies

The SpecDimensionManagement Solution

This codeunit provides a clean, intuitive API that abstracts away the complexity of dimension management. Here’s how to use it:

WITH SpecDimensionManagement DO BEGIN
    // Initialize with current dimension set or create new one
    INIT(MyRecord);
    
    // Update dimension values with simple commands
    UPDATE('DEPARTMENT', 'SALES');
    UPDATE('PROJECT', 'P-001');
    UPDATE('COSTCENTER', 'CC-100');
    
    // Remove dimensions that are no longer needed
    DELETE('OLDPROJECT');
    DELETE('TEMPCODE');
    
    // Calculate the new Dimension Set ID
    MyRecord."Dimension Set ID" := GetDimSetID;
    
    // Retrieve current values if needed for validation
    GetCurrDimValues(DimCode, DimValueCode, MyRecord."Dimension Set ID");
END;

Core Functions Explained

The codeunit provides these essential functions:

  • INIT(Record): Initializes the dimension management with an existing record’s dimension set or creates a new empty set
  • UPDATE(DimensionCode, DimensionValue): Adds a new dimension or updates an existing one with the specified value
  • DELETE(DimensionCode): Removes a dimension from the current set
  • GetDimSetID(): Calculates and returns the new Dimension Set ID based on current modifications
  • GetCurrDimValues(VAR DimCode, VAR DimValueCode, DimSetID): Retrieves dimension values from a specific Dimension Set ID

Implementation Workflow

The typical workflow follows these steps:

  1. Initialize: Start with existing dimensions from a record or create a new dimension set
  2. Modify: Add, update, or delete dimension values as needed using simple function calls
  3. Calculate: Generate the new Dimension Set ID with all modifications applied
  4. Apply: Update your record with the calculated ID

Practical Examples

Here are common scenarios where this codeunit shines:

// Example 1: Updating a Sales Header with new dimensions
WITH SpecDimensionManagement DO BEGIN
    INIT(SalesHeader);
    UPDATE('DEPARTMENT', 'SALES');
    UPDATE('SALESPERSON', SalesHeader."Salesperson Code");
    SalesHeader.VALIDATE("Dimension Set ID", GetDimSetID);
    SalesHeader.MODIFY(TRUE);
END;

// Example 2: Creating dimensions for a new G/L Entry
WITH SpecDimensionManagement DO BEGIN
    INIT;  // Start with empty set
    UPDATE('COSTCENTER', GetCostCenterFromLocation(LocationCode));
    UPDATE('PROJECT', GetActiveProject(CustomerNo));
    GLEntry."Dimension Set ID" := GetDimSetID;
END;

Key Benefits

This solution offers several advantages over manual dimension handling:

  • Simplified API: Clean, intuitive functions eliminate the need to work directly with complex temporary dimension tables
  • Error Prevention: Handles all validation and calculation complexity automatically, reducing bugs
  • Universal Compatibility: Works with any record or scenario that involves dimensions
  • Development Efficiency: Significantly reduces code complexity and development time
  • Maintainable Code: Clear function names and consistent patterns make code easier to understand and maintain

Download and Implementation

The complete solution is available as a downloadable FOB file that includes:

  • Codeunit 92600 “SpecDimensionManagement”: The main codeunit with all dimension handling functions
  • Codeunit 92601 “SpecDimensionManagement Examples”: Practical examples and test cases to help you get started
  • Documentation: Comprehensive comments and usage guidelines

Download the FOB file here

Version Compatibility

The FOB was created from a NAV 2015 FR (Build 49000) database and has been tested across multiple versions:

  • NAV 2017: Fully compatible
  • NAV 2016: Tested and working
  • NAV 2015: Original development platform
  • NAV 2013/2013 R2: Should work (dimension structure introduced)

Note: While the codeunit should work on NAV 2013, I recommend testing thoroughly in your specific environment before production use.

For developers working with dimensions in NAV, you might also find these posts helpful:

Connect with me for more detailed discussions:

  • LinkedIn for professional networking and technical discussions
  • Twitter for quick questions and NAV community updates

Conclusion

Managing dimensions in Dynamics NAV 2013+ doesn’t have to be a complex, error-prone process. The SpecDimensionManagement codeunit provides a clean, reliable way to handle dimension calculations, allowing you to focus on building great business solutions rather than wrestling with technical complexities.