Some of you might have run into scenarios that a report that runs for some (acceptable) time on classic client takes far longer time on RTC or simply even errors out with OutOfMemory kind of exception.
Some have also asked what the limitation to number of records sent to RTC is, when experiencing this. Well, my personal environment here shows that 250.000 records will transfer, but the report will be left running for a long, long time. Far longer then the classic equivalent, which finished in say 15 minutes. So how to deal with this?
Well while as sending 250.000 rows (which equivalents to about 11.000 output pages!!!) is quite an amount of data to print, and one might assume that not too many people would want to print this much in the first place, you might not be aware your'e sending this many records, as your output may come down to mere 2 pages. So this is a blog for that kind of reports, reports that will process many rows, but really do output realtively little (and by relatively little, i mean anything under couple of hundred of pages).
Lets start by looking into what is sent to RTC. We have sections that are data containers for RDLC reports, so all data contained there would naturally be sent to RTC. But not only that! To see what's sent to RTC, look at your report metadata (export the metadata blob and save it as an xml file to check this). What you might not be aware of is that all records within metadata are sent. And metadata is really your report structure.So if your report has 3 data items, all records processed within filtered selection, that belong to those data items, will be sent to RTC. Which is why you might find out that some reports run for a long time (after sending dusins and hundreds of thousand of rows), but output only few pages, or in any case far less then the amount of records processed. This mostly happens with reports that:
1 Use data items for calculation and not necessarilly output records from these in printout (data items not used in sections at all)
2 Use dataitems for footers and headers only (data items not used in body type of sections)
3 Have 'PrintDetails' option (data item IS used in body section) which again means that regardless of the fact your user hasn't opted to print details, that data item is in the report structure hence all those records are sent to RTC anyway.
So these are the things you want to watch out for if you are writing your reports for RTC
In case of 1 and 3 => All you need here to stop records being sent to RTC is add (IF NOT PrintDetails then) CurrReport.SKIP at the end of OnAfterGetRecord trigger of the dataitem. Add at the end so you make sure your calculation is still done, but currreport.skip will then stop the actual data being sent.
In case of 2. => Don't! Using data item will send all records within filtered selection, so if you only want to print footer of a group of value entries (and don't have a body section for that data item at all), you will end up sending all these value entries to RTC, which in most installations is a lot. Use an integer data item to output the footer once per group instead, handle the summarizing of values within the group, in the code instead (keep the current report structure if you will, add currreport.skip in the end of OnAfterGetRecord trigger of the detailed item, summarize footer values in code of that trigger instead and add an integer data item to output summarized footer values).
As a test, I've done it on couple of standard reports that process a lot and tested their running time after modifications. And as assumed, millions of records process and the few pages are printed in 15 minutes, even on RTC :-)
By the way what do you mean saying "in code"? In the report's code? Or in NAV storing calculation results in the interim tables?
So I have to add further details to my explanation here.
Take example of report 120 for scenarios 1 & 3.
Adding CurrReport.SKIP as the last line of OnAfterGetRecord trigger of Customer Ldger Entry data item will keep the calculation but prevent data from being sent to RTC. If you additionally add If NOT PrintDetails then CurrReport.skip in OnAfterGetRecord of the TempCustLedgEntryLoop, then you avoid sending detailed entries if your customer hasn't selected Print Details. So you preserve original data structure and layout, but you cut down on no. of rows being sent (unnecessarilly).
Excellent post very useful..