A question I receive a lot from customers and partners is if there’s a way to implement the PlaceInBottom effect on a report in RDLC.
As you might already know, in the Classic Client, which I should now call the Development Environment, in the report object, there’s a property called PlaceInBottom. It determines whether a footer section should be printed at the bottom of the (physical) page.
In NAV 2009 and beyond, the property isn’t supported in RDLC and there’s no counterpart in the properties of the layout in Visual Studio. So basically, if you want to implement the Place In Bottom effect, you either have to keep using the Classic Layout or find a workaround in the RDLC layout.
Finding a solution in the RDLC layout is not that easy. I have been scratching my head for a long time and still haven’t found a good one. So what I will present here is a workaround, until a better solution is available.
The problem is determining in the RDLC layout what is the physical end of a page.
First, let’ s have a look at what we want.
At design time:
At run time:
Now le’ts see what we get in RDLC.
At design time:
At run time:
As you can see, in the RDLC the text is not at the bottom of the page and there’s no property on the textbox, or rectangle for this either.
Hey, what if I would use the Page Footer in RDLC and put the rectangle/textbox in there?
Well, that would fix the problem, BUT, in most cases, the text that needs to be at the bottom of the page is in a data region, like a table, matrix or chart, and a data region can not be moved to a Page Footer.
So the real question is, how do we simulate a Place In Bottom Of Body?
Well, the magic trick in my case, is to generate linefeeds, and for that I’m going to use an expression and a function:
Public Function GenerateVbCrLf(ByVal Count as integer) dim Value as String dim i as integer For i = 1 To Count Step 1 Value = Value & " " & VbCrLf Next i Return Value End Function
And in the table, I will add a table footer row in which I will call this function:
=Code.GenerateVbCrLf(42 - cint(CountRows("Table1")))
This will generate a number of line feeds (“CarriageReturn LineFeed” to be exact) depending on the number of rows in the table: Table1.
Why 42 you might think, well because 42 is the answerto the Ultimate Question of Life, the Universe, and Everything… (see The Hitchhiker’s Guide to the Galaxy) 🙂 🙂
No, 42 is found via trial and error and will depend in the size of your table, the other ‘stuff’ in your report, the margins, … You can find it by running the report and changing the number untill your PlaceInBottom text falls of the page. The number before that is your answer to the ultimate question 😉 And in this case, for report 111, the magical number happens to be 42.
This is, as I said, just a workaround. It’s imho not a solution.
It requires trial and error for every report you implement it on and if you ever update the report layout, you will have to do the trial & error all over again. And remember to test it in Print Layout, not Print Preview. And also, export to pdf and/or print it on paper to see if that”s also ok.
Anyway, it’s better then nothing, no?
The solution can also be automated. For example by creating a Report Layout Setup table, in which you store, for every report you need it on, the magical number. Then, via C/AL code you can fetch this number and pass it on to the RDLC layout.
Using a Report Layout Setup table can also be a good idea to store colors. For example if you want to standardize the company look & feel and have the same colors in table headers, table details, table footers, … But I will come back to this in a later blog post…
To download the demo report: