There is a report for that
Jan 22 2010
I spend a great deal of programming time writing reports. On the surface that does not sound very challenging. With all that is required, it is extremely challenging, but that is another blog entry.
Having dozens of datasets to collect from different sources, and that the date criteria is different from day to day and report to report, poses a unique problem. This makes knowing what to pass to each function a little confusing. The functions know what data they want, but the calling page does not.
This posed a rather unique coding challenge. Keep the page neat and easy to read, yet pass the proper data to each function. After the page grew to a thousand lines of code, it became really hard to deal with. There needed to be a simple way.
Each of the function names is stored in a table along with other data needed to collect the proper data. All that was needed is a way to dynamically use that data. That proved to be very simple and at the same time solved another problem.
A structure with everything every function could ever need was created.
2<cfset z.component = "" />
3<cfset z.method = "" />
4<cfset z.returnVariable = "r" />
5<cfset z.statDate = theDate />
6<cfset z.startDate = startDate />
7<cfset z.endDate = endDate />
8<cfset z.firstSaturday = firstSaturday />
9<cfset z.lastFriday = lastFriday />
Then a call to the table with the data to be collected and a loop of that query, change the structure data as needed and dynamically call each function. This made the code easier to maintain and reduced the page file size considerably.
By using attributeCollection, every variable can be passed in the function will use only what it needs. This also makes it easier for others to turn on or off reports as needed.
Here is the code.
2 SELECT
3 *
4 FROM
5 a_report_collect
6 WHERE
7 reportType = 'eod'
8 ORDER BY
9 collectID
10</cfquery>
11<cftry>
12 <cfloop query = "q">
13 <cfset z.component = "#application.reportEODCollectData#" />
14 <cfset z.method = "#q.readComponent#" />
15 <cfinvoke attributeCollection = "#z#" />
16 <cfoutput>
17 #r#<br />
18 </cfoutput>
19 </cfloop>
20 <cfcatch type="any">
21 <cfoutput>
22 <br />
23 <br />
24 Error!!<br />
25 #cfcatch.Message#
26 <br />
27 <br />
28 </cfoutput>
29 <cfdump var="#cfcatch.TagContext#" /><br />
30 <cfset myError = True />
31 </cfcatch>
32</cftry>










#1 by Kevin Pepperman on 3/31/10 - 12:09 AM
If you combined OpenBd's Render() function with this method you could even store component methods and inject them into your report services. Or if you are using ACF9/Railo's RAM drive you could write the entire .cfc to the drive and create them temporarily.