A really annoying RDLC limitation

by Lisa Nicholls Mon, October 05 2009 18:05

C is visiting family and I'm supposed to be on vacation, but somehow work keeps getting in the way.  Also house improvement chores; if work ever gets terminally dispiriting, I think my contractor might take me on as a stucco apprentice.

Still, I have a long queue of questions from various people on reports that I was going to look into during this period.  I can't help everybody, no matter how much time I have, because some things just aren't... fixable ... and I'll talk about one of those next.  (Linda -- I promise to do yours too!)  

But Himanshu is first, because not only did this request pose a question and ask for help, but also it came with some valuable information that we should all share.   

Here's the original email (which came with the RDLC as an attachment):

I need your help to solve the problem related with Report (.rdlc), I am also facing the same problem which you discuss in one of the Thread in the ASP form, in my case i have multiple subreports on the main page and i need every sub report start from the new page. To seprate them i use rectangle inbetween and use the Insert Page Break After rectangle. I need to show the subreports on the basis of a report parameter. If parameter says don't show the report it work as i use the express to hide the report and it's fine but left the blank page but if i use the same condition for rectangle (to hide), page break don't work in normal condition and report start from the end of the previous page. I don't know why this is happening.

Big surprise, I had no idea either. After ascertaining that subreports weren't critical to the issue, I went about reproducing this with a report holding multiple tables and datasets, and bashed my brain on it for a while -- a little at a time, over a month. Nothing good happened.

Meanwhile, instead of lying back and expecting a miracle, Himanshu went about doing his own research. Next stop: Microsoft support.

Deus ex machina, not so much

I pinged Himanshu to say I hadn't forgotten about the problem, but had no resolution yet. Here's what I learned:

Thank you so much for keeping my hope alive. I didn’t found any solution from Microsoft as well. I am attaching a mail herewith which tells this is a bug in VS2005.

When I read the enclosed e-mail (from Chris Baldwin Himself!), I could see that from MS POV, it's not a bug, and is not really about VS2005 either:

Hello Himanshu, This is a limitation of RDLC in the VS 2008 controls that will be lifted in VS 2010. In RDLC for VS 2008, page breaks on conditionally hidden items are never honored even if they are visible at runtime. In VS 2010, the page break will occur if the item is visible at runtime.

[... later, in followup:]

Hi Himanshu, No I do not believe there is a solution for VS2005 or VS2008 controls in local mode. -Chris

Let's look at that again:

[CB] In RDLC for VS 2008, page breaks on conditionally hidden items are never honored even if they are visible at runtime.  

Well.   That's that, then.

Hmmm.

It's not entirely surprising that some things are "underimplemented" in local mode.  After all, this is the mode of ReportViewer that doesn't expect you to have an instance of Reporting Services available; the ReportViewer control does all the rendering and, presumably, doesn't have all the "smarts" of the server. (That's why not all export types are supported in local mode, too.) 

Let's face it: MS aren't getting a SQL Server license from you to use this control, it's pretty much a freeby for .NET developers.  Its engine is out of step with Reporting Services (as far as I know local mode doesn't support the 2008 RDL schema additions yet, right?) and it needs a separate development effort.

Let's look at the "underimplementation" in question here: Forced page breaks are ignored when items in a data region are conditionally hidden. 

It may sound silly, but actually this is a development compromise that makes a lot of sense.  Pagination is a PITA to start with; when you add the logic for "what if items stretch/flow" you complicate everything, and of course one has to add that. 

Then, adding "what if some items don't always show?", figuring out whether they will show before figuring out pagination, and how big they will be IF they will show and IF they stretch... it's huge.  The page collection is almost always figured out at a different time than the actual data, and -- as I've discussed elsewhere -- it looks like the sequence of evaluation may be slightly different in local mode than in the server engine -- meaning, we can't just "borrow" this code from one engine to the next.

So, MS left this particular feature out of the freebie local mode.  It's frustrating, but definitely understandable.

So that's reality. What can we do?

While the original requirement isn't "fixable", sometimes you can talk to users about it and come to a compromise resolution, given the tools at hand.

One thing I suggested to Himanshu, if the report was assembling a "book" (as is normally the case with subreports that start on their own page each), and  if the "booK' was rendered to a PDF,  was that each subreport could be programmatically rendered separately.  When you do this, obviously, the conditional rendition of some subreports is as simple as ... not rendering the ones you don't want.  IOW, this report is a case of "reports as document sections", something I've also discussed here before. The PDFs you do want can be "stitched together" using PDFTK (as discussed in that earlier post), or using the iText libraries that form the basis of PDFTK.

Yes, you can handle running page numbers. You have to provide an offset to each report in turn, to add to what it thinks the current page count is, as a parameter, based on the accumulated page count of the reports before it. (You can interrogate each PDF's pagecount using PDFTK or iText.  I think you can also get TotalPages from ReportViewer's LocalReport member, in one of three modes: Progressive, Actual, and Estimate, but I haven't tried this.)

Astute readers will immediately realize that what we have here is an alternate method of doing "Table of Contents reports". Gather the page numbers, as described above, "pour" them into a data source for the TOC report, run the TOC report last of all, but "stitch" it together first. My team is doing this for a client right now.

What should Himanshu do?

There's a good chance that Himanshu's report needs to be viewed interactively, not just in a PDF. I suggested that the right resolution for this report might be dynamic loading, rather than conditional hiding. 

In other words: you can load the report definition dynamically, don't ask a single report definition to be all things to all rendering instances.

At the risk of being ridiculously self-referential in this post, let me remind you that not every report should be resolved with tricks on the reporting engine.  In a "Quick Report" example, I created a dynamic report layout -- but also questioned the limits to which this technique should be stretched.  Sometimes, it's better to create a non-dynamic report on-the-spot, to do exactly what you want, without any tricks. 

It's a variation on "Doctor, doctor, my arm hurts when I do this. " "Well, don't do that."  If conditional hiding doesn't work for this report, don't use it. 

Himanshu asked me to be more explicit about this, so I will :-).

What is dynamic loading in ReportViewer? 

Check out http://gotreportviewer.com, if you haven't already.  You'll see a couple of items labelled "generate an RDLC" and another one labelled "load an RDL from a stream".

While the title of the latter says "an RDL", check out the code for the former (either sample).  You'll definitely see code that looks like this:

/* where m_rdl is a MemoryStream */
this.reportViewer1.LocalReport.LoadReportDefinition(m_rdl); 

How does Himanshu apply dynamic loading? 

Himanshu's not going to do anything as fancy as creating an entire RDL from scratch at runtime.  In this scenario, you take the original RDLC -- just removing the conditional visibility elements, leaving the page breaks where you want them -- and use it as a template, rather than as the literal RDLC to be loaded to the ReportViewer control.

Somewhere, somehow, Himanshu has a bunch of instructions from the user or from biz logic that say which subreports should be shown on the current run.  That logic has to be applied to the RDLC instead of within the RDLC, to create the actual RDLC that will be run.

Here's a quicky example of how you would remove the unwanted subreports.  Frankly I would rather do this with XSLT than loading into the DOM but people still seem to think it's an arcane skill, so here's all the code you really need:

Dim fn As String = [...]' your template RDLC here
Dim xx As System.Xml.XmlDocument = New System.Xml.XmlDocument()
Dim yy As System.Xml.XmlElement, zz As System.Xml.XmlElement
xx.Load(fn)
Dim sr As String ' name of the subreport to remove
sr = "subReportOnFinances"

' don't get too upset about this XPATH,
' I'm showing you all the qualifiers but
' in a second example below you'll see
' they're not really necessary:
yy = xx.SelectSingleNode( _
   "/*[local-name()='Report' and " & _
   "namespace-uri()='http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition']" & _
   "/*[local-name()='Body' and namespace-uri()=" & _
   "'http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition'][1]"
& _
   "/*[local-name()='ReportItems' and namespace-uri()=" & _
   "'http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition'][1]"
& _
   "/*[local-name()='Subreport' and " & _
   "namespace-uri()='" & _
   "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition'"
& _
   "and @Name='" & sr & "']")
' or if you prefer to remove subreports by sequence,
' in this example subReportOnFinances is the 2nd subreport in the series.
' I'll cut out some of the other xpath you really don't need here too:
yy = xx.SelectSingleNode("/*/*/*/*[local-name()='Subreport'][2]")

zz = yy.ParentNode
zz.RemoveChild(yy)
' repeat, removing all subreports not to be used in this
' run, from the document.

' Finally, for this example, I'll save to a temp RDLC,
' but again you can use streams or however you want to deal
' with the rest of the non-report-specific problem of
' temporary files:
xx.Save("c:\temp\x.rdlc")

In addition to removing the subreports you don't want, you can adjust the Top attributes for the subreports that remain, if you find that this is needed.  You'll find that each subreport element has a Top child element, you can work out how much space you want in between each subreport, etc.  If necessary, remove them manually from a copy of the template in the Report Designer, moving the remaining subreports until they suit you. Examine the results in the XML report definition, to figure out the right way to adjust them at runtime.

Better than nothing

... not too bad, actually.  And certainly more productive than wailing into the storm (assuming you're not Lauren Bacall), or poking little notes into the MS feature wish list. 

Tags:

Reporting

Comments (14) -

10/30/2009 1:47:18 AM #

adult reviews

I am a newbie when it comes to RDLC. The problem that Homanshu raised seems to be very difficult to answer. Himanshu hasn't gotten a positive response from Microsoft. Anyway, it's a great thing that you addressed the problem and shared some concepts and issues regarding it with us.

adult reviews United States

11/3/2009 12:10:23 PM #

Casio Pathfinder

The problem that Homanshu raised seems to be very difficult to answer

Casio Pathfinder United States

4/22/2010 11:56:25 AM #

Tim

I am trying to do almost the same thing with VS2008. I have multiple tables but we only want selective ones to show at runtime. Well, same as you've found out, it just doesn't work. I was surprised that such basic function was not fixed even though rdlc is considered as kind like a freebie.

If like MS said this is indeed fixed in VS2010, I would rather purchase a copy of VS2010 than spending time work around this.

Tim Canada

4/27/2010 6:45:44 AM #

Tim

The past few days I have been working on how to work around this issue. I noted that in the article you mentioned that in VS2010 the problem has been fixed so I went ahead downloaded ReportViewer V10 redistributable file from MS. Installed it, and then took awhile before I figured it out how to copy them out of the windows\assembly folder. Removed the version 9 reference in VS2008 and added the version 10 references. Run the Viewer, and just like promised by MS, the pagebreak problem is gone! However, now I have numerous new small or big problems. A major one would be the chart function. Somehow the charts dont plot lines anymore, all they show is a dot. Tried everything but still no luck.

Anyway, sorry about the long reply here. Just thought post this so anyone who's interested in this method would get a bit info from my experience so far. My next plan to work around the plotting issue is to seperate table and chart into two different reports, and also seperate projects. Set the table project referring version 10, and the chart project referring version 9. Hopefully somehow I can find a way to join the 2 report into one at runtime. If anyone has been working on this and have a solution, please let me know. Thanks guys!

Tim Canada

4/27/2010 9:54:30 AM #

>L<

Thanks for checking in, Tim.  I was going to answer your first post and say "sometimes too many other things change when you upgrade, and sometimes there is a corporate policy against it"... but you've already made my point <g>.

To join the two reports at runtime you can use the PDF solution that I provided somewhere on this blog... let me see...

PDFTK is mentioned in this post (ignore the fact that it starts by talking about VFP because for the purpose of this discussion there is no difference): http:// spacefold.com/lisa/post/2007/08/29/A-Tad-More-About-PDF-and-Reports-as-Document-Sections.aspx

... and to think about "reports as document sections" more conceptually you might want to reference the earlier blog post it links to, which talks briefly about both VFP and RS.

A second way to fix it is to fix the charting issues properly in 2010, I'd be interested in trying to help with that (but very little time so let me know if you are willing to return to this idea later and ping me in a couple of months!).

BTW don't apologize for the "long reply".  You took the time to help people.  I appreciate it.

>L<

>L< United States

4/30/2010 11:03:26 AM #

Tim

Hi Lisa,
Thanks for your reply. However, I don't think the first solution is suitable for my application. As for the second one, I've been trying everything the last couple of days but so far not getting anywhere. What's really strange is the "Fields!" works in the Table, it brings up all values from the Oracle database. But just doesn't work with charts.

I really just wondering if anyone has tried the same thing as I did, so at least I can confirm this is not some problem that solely happens to my case. It would really sucks if I have to purcahse VS2010 just for this one issue. Not to mention that upgrading a VS2008 project to VS2010 project may cause more uncertain problems.

Tim Canada

4/30/2010 11:17:03 AM #

&gt;L&lt;

Tim, I agree with you and I want to give the 2010 issue a shot to see if it's resolvable. Unfortunately, because I have enough trouble convincing clients to upgrade to SQL 2008 R2 (or even to 2008!), I'm behind the curve on testing with VS2010 because I have no incentive except my enjoyment of feedback, like yours, on this blog.

In fact, somebody else has just asked me for another 2005-specific resolution and I'm probably going to use my free time answering that one, rather than a 2010 question because (a) it seems still to be an issue for so many people and (b) if I don't answer it now, I'm not sure how much longer I'll have easy access to 2005 environment. <g>

Honestly I want to check out the charting in VS2010, though, and I would like to help you as quickly as I can.  Feel free to email me with specifics about the Fields! question.  Thanks again for checking back in.

>L< United States

4/30/2010 12:09:19 PM #

Tim

Hi Lisa,
I totally understand, and not long ago I was still using VS2005 as well. We only switched to VS2008 was because VS2005 had a DataSource issue with Oracle (not common, but that issue effected our project). It was very much like the problem I'm facing now, MS told everyone they wouldn't fix it in 2005 and ask everyone to switch to 2008 cause that's where they fixed it. Anyway, I think the Chart problem will happen to anyone who tries what I have done. The exact same rdlc works well under ReportViewer v9. After my last reply I went back and created a seperate project with a new rdlc file that has nothing but a chart. My question now is "how do you provide the Data Source to a report from Project A when calling it from Project B?". I'm not sure if you know what I mean.

Tim Canada

5/3/2010 6:50:28 PM #

LSN

Tim – I’ve configured a machine with VS 2010, FWIW if you want to tell me about the Fields! Thing I’m set up to look at it.   Details please, and I’ll give it a shot.

Regarding this question>>. My question now is "how do you provide the Data Source to a report from Project A when calling it from Project B?". I'm not sure if you know what I mean.
… I sort of know what you mean, but sort of don’t deal with that stuff.  I tend to add the data information dynamically at runtime (not using the wizard-tools and standard design time interfaces, because I think they’re limiting and hokey) anyway.

There are some posts already on the site describing this.  If they don’t suit you, and if you re-phrase your question, I’ll give it a shot.  Basically what I need is the problem you are trying to solve – which in my mind has nothing to do with the issue of Projects in Visual Studio because that’s not the business problem of what you’re implementing, it’s just a current implementation obstacle.

I’ll help if I can… but I still want to understand about the charting thing.  That’s of real interest to me.  So I’d rather look at both?

>L<

LSN United States

7/31/2010 4:41:14 AM #

Danny

I don't think the first solution is suitable for my application. As for the second one, I've been trying everything the last couple of days but so far not getting anywhere. What's really strange is the "Fields!" works in the Table, it brings up all values from the Oracle database. But just doesn't work with charts. <a href="http://www.checkhivsymptoms.com">hiv symptoms</a>

Danny United States

9/28/2010 3:56:52 AM #

darshan thacker

hi,

i have sub reporting concept for printing more then one invoices in pre printed paper using dot matrix printer. but i am not able to print report header in sub report any other way to do this ?
how to have header in sub report or parameter values. so that i can repeat header on each page.

please suggest/advice

darshan

darshan thacker India

9/28/2010 6:25:10 AM #

&gt;L&lt;

Hi Darshan,

You can send the parameters to the subreport and repeat the header in the subreport.  What you'll probably have to do to *place* it correctly, however, is to start the subreport on a new page.  If that doesn't work for your situation, sometimes it's a better idea not to use a subreport. Sometimes there's a different way to achieve the same effect.  Might this work for you?  Write to my contact email if you need further information.

>L< United States

10/6/2010 6:00:17 PM #

Joshua

Thanks for posting. I agree that the limitations on RDLC is stupid. They shouldn't put a limitation on RDLC.

Joshua United States

10/25/2010 2:14:22 AM #

darshan thacker

guys good news!

done with this complexity with help of my team. sub reporting concept has been removed and working has been done in one master report only by formatting table according to the pre printed report requirement.

i had firstly taken list and table inside that list and had grouping and shorting with ID column inside table for generating multiple invoices continuously.

but now facing problem with printing part as page size is 132 column (15X12inch appx) as second continuous page break is not appears at proper end and second page header is appearing inside first page footer as i have taken page size 15X11 to make it in portrait mode. any solutions regarding sizes.
please help.

write me if need more details.

Thank you guys! Smile

darshan thacker India