How to Stop Fighting AL and RDL(C): Rename Report Columns Like a Pro

How to Stop Fighting AL and RDL(C): Rename Report Columns Like a Pro

If you’ve ever worked with AL report files, you know the pain: You rename a column (variable) in your AL file, and then you have to hunt through the RDLC file to update all the references, Field Name and DataField. It’s an ennerving activity, even a monkey could do it and you really should not have to waiste your time with it.

But fear not! The latest update to AL Navigator brings a feature that makes variable renaming so smooth, you’ll wonder how you ever lived without it.

The Problem

Let’s face it: maintaining consistency between AL and RDL(C) files has been a manual, error-prone process. You rename a column (variable) in your AL report, and suddenly:

  • You’re combing through the RDLC file for Field Name and DataField entries.
  • You’re breaking report layouts because you missed a reference.
  • You’re wasting time that could be better spent sipping coffee and pretending the boss didn’t just assign another sprint.

No more. AL Navigator is here to save you.

The Solution: Automated Renaming Across AL and RDLC Files

With this new feature, renaming variables in dataitem columns in the dataset is as simple as it should have been all along. AL Navigator:

  • Updates the corresponding Field Name and DataField entries in your RDLC file.
  • Handles Format fields and Fields!<name>.Value references with the precision of a German engineer.

How It Works

Imagine you’re working on a sales report. You want to rename SalesLCY_Customer to SalesLCY (because shorter is better, right?). Here’s what you do:

  1. Open your AL file.
  2. Place your cursor on the column (variable) you want to rename.
  3. Trigger the rename:
    • Open the Command Palette (Ctrl+Shift+P) or F1.
    • Select  AL Navigator: Rename report dataitem column.
  4. Enter the new name when prompted.
  5. Sit back and marvel as AL Navigator updates both the AL file and the RDL(C) file.

The Magic Behind the Curtain

The feature scans your AL report to identify:

  • Variables defined in column blocks within dataitem sections.
  • Whether the variable exists in the RDL(C) dataset.

It then applies the changes, ensuring:

  • Field Name and DataField entries in the RDL(C) are updated.
  • No references in the RDLC file are left hanging (because broken reports are a developer’s worst nightmare).

Before and After

Let’s put this into context with an example.

Before Renaming

AL File

 report 50100 "Sales Report"
{
    Caption = 'Sales Report';
    UsageCategory = Administration;
    ApplicationArea = All;
    RDLCLayout = 'SalesReport.rdl';

    dataset
    {
        dataitem(Customer; Customer)
        {

            column(SalesLCY_Customer; "Sales (LCY)")
            {
            }
            column(ProfitLCY_Customer; "Profit (LCY)")
            {
            }
        }
    }
} 

RDL(C) File

 <?xml version="1.0" encoding="utf-8"?>
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
  <AutoRefresh>0</AutoRefresh>
  <DataSources>
    <DataSource Name="DataSource">
      <ConnectionProperties>
        <DataProvider>SQL</DataProvider>
        <ConnectString />
      </ConnectionProperties>
      <rd:SecurityType>None</rd:SecurityType>
      <rd:DataSourceID>742dec4e-3404-45ed-a027-14e010971f2a</rd:DataSourceID>
    </DataSource>
  </DataSources>
  <DataSets>
    <DataSet Name="DataSet_Result">
      <Query>
        <DataSourceName>DataSource</DataSourceName>
        <CommandText />
      </Query>
      <Fields>
        <Field Name="SalesLCY_Customer">
          <DataField>SalesLCY_Customer</DataField>
        </Field>
        <Field Name="SalesLCY_CustomerFormat">
          <DataField>SalesLCY_CustomerFormat</DataField>
        </Field>
        <Field Name="ProfitLCY_Customer">
          <DataField>ProfitLCY_Customer</DataField>
        </Field>
        <Field Name="ProfitLCY_CustomerFormat">
          <DataField>ProfitLCY_CustomerFormat</DataField>
        </Field>
      </Fields>
    </DataSet>
  </DataSets>
  <ReportSections>
    <ReportSection>
      <Body>
        <ReportItems>
          <Textbox Name="Textbox1">
            <CanGrow>true</CanGrow>
            <KeepTogether>true</KeepTogether>
            <Paragraphs>
              <Paragraph>
                <TextRuns>
                  <TextRun>
                    <Value>=First(Fields!SalesLCY_Customer.Value, "DataSet_Result")</Value>
                    <Style />
                  </TextRun>
                </TextRuns>
                <Style />
              </Paragraph>
            </Paragraphs>
            <rd:DefaultName>Textbox1</rd:DefaultName>
            <Top>0.89458in</Top>
            <Left>1.79042in</Left>
            <Height>0.25in</Height>
            <Width>1in</Width>
            <Style>
              <Border>
                <Style>None</Style>
              </Border>
              <PaddingLeft>2pt</PaddingLeft>
              <PaddingRight>2pt</PaddingRight>
              <PaddingTop>2pt</PaddingTop>
              <PaddingBottom>2pt</PaddingBottom>
            </Style>
          </Textbox>
        </ReportItems>
        <Height>2in</Height>
        <Style />
      </Body>
      <Width>6.5in</Width>
      <Page>
        <Style />
      </Page>
    </ReportSection>
  </ReportSections>
  <ReportParametersLayout>
    <GridLayoutDefinition>
      <NumberOfColumns>4</NumberOfColumns>
      <NumberOfRows>2</NumberOfRows>
    </GridLayoutDefinition>
  </ReportParametersLayout>
  <Code>Public Function BlankZero(ByVal Value As Decimal)
    if Value = 0 then
        Return ""
    end if
    Return Value
End Function

Public Function BlankPos(ByVal Value As Decimal)
    if Value > 0 then
        Return ""
    end if
    Return Value
End Function

Public Function BlankZeroAndPos(ByVal Value As Decimal)
    if Value >= 0 then
        Return ""
    end if
    Return Value
End Function

Public Function BlankNeg(ByVal Value As Decimal)
    if Value < 0 then
        Return ""
    end if
    Return Value
End Function

Public Function BlankNegAndZero(ByVal Value As Decimal)
    if Value <= 0 then
        Return ""
    end if
    Return Value
End Function
</Code>
  <Language>=User!Language</Language>
  <ConsumeContainerWhitespace>true</ConsumeContainerWhitespace>
  <rd:ReportUnitType>Inch</rd:ReportUnitType>
  <rd:ReportID>0eeb6585-38ae-40f1-885b-8d50088d51b4</rd:ReportID>
</Report> 

After Renaming SalesLCY_Customer to SalesLCY

AL File

 report 50100 "Sales Report"
{
    Caption = 'Sales Report';
    UsageCategory = Administration;
    ApplicationArea = All;
    RDLCLayout = 'SalesReport.rdl';

    dataset
    {
        dataitem(Customer; Customer)
        {

            column(SalesLCY; "Sales (LCY)")
            {
            }
            column(ProfitLCY_Customer; "Profit (LCY)")
            {
            }
        }
    }
} 

RDLC File

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
  <AutoRefresh>0</AutoRefresh>
  <DataSources>
    <DataSource Name="DataSource">
      <ConnectionProperties>
        <DataProvider>SQL</DataProvider>
        <ConnectString/>
      </ConnectionProperties>
      <rd:SecurityType>None</rd:SecurityType>
      <rd:DataSourceID>742dec4e-3404-45ed-a027-14e010971f2a</rd:DataSourceID>
    </DataSource>
  </DataSources>
  <DataSets>
    <DataSet Name="DataSet_Result">
      <Query>
        <DataSourceName>DataSource</DataSourceName>
        <CommandText/>
      </Query>
      <Fields>
        <Field Name="SalesLCY">
          <DataField>SalesLCY</DataField>
        </Field>
        <Field Name="SalesLCYFormat">
          <DataField>SalesLCYFormat</DataField>
        </Field>
        <Field Name="ProfitLCY_Customer">
          <DataField>ProfitLCY_Customer</DataField>
        </Field>
        <Field Name="ProfitLCY_CustomerFormat">
          <DataField>ProfitLCY_CustomerFormat</DataField>
        </Field>
      </Fields>
    </DataSet>
  </DataSets>
  <ReportSections>
    <ReportSection>
      <Body>
        <ReportItems>
          <Textbox Name="Textbox1">
            <CanGrow>true</CanGrow>
            <KeepTogether>true</KeepTogether>
            <Paragraphs>
              <Paragraph>
                <TextRuns>
                  <TextRun>
                    <Value>=First(Fields!SalesLCY.Value, "DataSet_Result")</Value>
                    <Style/>
                  </TextRun>
                </TextRuns>
                <Style/>
              </Paragraph>
            </Paragraphs>
            <rd:DefaultName>Textbox1</rd:DefaultName>
            <Top>0.89458in</Top>
            <Left>1.79042in</Left>
            <Height>0.25in</Height>
            <Width>1in</Width>
            <Style>
              <Border>
                <Style>None</Style>
              </Border>
              <PaddingLeft>2pt</PaddingLeft>
              <PaddingRight>2pt</PaddingRight>
              <PaddingTop>2pt</PaddingTop>
              <PaddingBottom>2pt</PaddingBottom>
            </Style>
          </Textbox>
        </ReportItems>
        <Height>2in</Height>
        <Style/>
      </Body>
      <Width>6.5in</Width>
      <Page>
        <Style/>
      </Page>
    </ReportSection>
  </ReportSections>
  <ReportParametersLayout>
    <GridLayoutDefinition>
      <NumberOfColumns>4</NumberOfColumns>
      <NumberOfRows>2</NumberOfRows>
    </GridLayoutDefinition>
  </ReportParametersLayout>
  <Code>Public Function BlankZero(ByVal Value As Decimal)
    if Value = 0 then
        Return ""
    end if
    Return Value
End Function

Public Function BlankPos(ByVal Value As Decimal)
    if Value > 0 then
        Return ""
    end if
    Return Value
End Function

Public Function BlankZeroAndPos(ByVal Value As Decimal)
    if Value >= 0 then
        Return ""
    end if
    Return Value
End Function

Public Function BlankNeg(ByVal Value As Decimal)
    if Value < 0 then
        Return ""
    end if
    Return Value
End Function

Public Function BlankNegAndZero(ByVal Value As Decimal)
    if Value <= 0 then
        Return ""
    end if
    Return Value
End Function
</Code>
  <Language>=User!Language</Language>
  <ConsumeContainerWhitespace>true</ConsumeContainerWhitespace>
  <rd:ReportUnitType>Inch</rd:ReportUnitType>
  <rd:ReportID>0eeb6585-38ae-40f1-885b-8d50088d51b4</rd:ReportID>
</Report> 

Now your variable is renamed everywhere it matters, and you didn’t even have to break a sweat.


Why This Matters

Aside from saving your sanity, this feature:

  • Reduces errors caused by manual updates.
  • Speeds up your workflow, so you can focus on what really matters: delivering reports your users won’t complain about.
  • Makes you look like a wizard in front of your team. Seriously, who doesn’t want to be the office wizard?

How to Get Started

  1. Make sure you’ve installed the latest version of AL Navigator.
  2. Open your AL file and place your cursor on a column variable inside a dataitem.
  3. Use the Command Palette (Ctrl+Shift+P) or F1 to trigger  AL Navigator: Rename report dataitem column. .
  4. Let AL Navigator handle the rest.

Closing Thoughts

Refactoring AL reports no longer has to feel like pulling teeth. With the new rename functionality, you can keep your AL and RDL(C) files in sync effortlessly. Try it out today, and let me know how many hours (and headaches) you’ve saved.

Stay efficient, stay professional, and maybe enjoy that coffee while AL Navigator does the heavy lifting.

Explore AL Navigator

Ever wondered how to remove unused report variables from the dataset in AL? This blog post might be a good read for you.

6 thoughts on “How to Stop Fighting AL and RDL(C): Rename Report Columns Like a Pro

Leave a Reply

Your email address will not be published. Required fields are marked *