{"id":128,"date":"2008-07-07T04:01:00","date_gmt":"2008-07-07T04:01:00","guid":{"rendered":"\/lisa\/post\/2008\/07\/07\/The-scoop-on-scoping-FRX-variables-and-the-first-officially-recorded-instance-of-the-Duke-Principle.aspx"},"modified":"2021-08-30T13:38:47","modified_gmt":"2021-08-30T20:38:47","slug":"the-scoop-on-scoping-frx-variables-and-the-first-officially-recorded-instance-of-the-duke-principle","status":"publish","type":"post","link":"https:\/\/spacefold.com\/lisa\/2008\/07\/07\/the-scoop-on-scoping-frx-variables-and-the-first-officially-recorded-instance-of-the-duke-principle\/","title":{"rendered":"The scoop on scoping FRX variables, and the first officially-recorded instance of the Duke Principle"},"content":{"rendered":"<p><a title=\"Cesar's charting site\" href=\"http:\/\/weblogs.foxite.com\/vfpimaging\/\" target=\"_blank\" rel=\"noopener\">Cesar<\/a>\u00a0responded to my <a title=\"blog post on charting\" href=\"\/lisa\/2008\/06\/22\/Walkthrough-A-bar-chart-trick-examined-and-a-charting-alternative-offered\/\">recent walkthrough on barcharting<\/a>\u00a0with some VFPReport-specific questions.\u00a0 Here is his first one:<\/p>\n<blockquote><p>At this moment, I&#8217;m doing something like this:<\/p>\n<p><span class=\"codesample\">SET REPORTBEHAVIOR 90<br \/>\nPRIVATE oFoxChart <span style=\"color: green;\">&amp;&amp; needed by report<\/span><br \/>\noxFoxChart = ThisForm.Foxcharts1.ChartCanvas <span style=\"color: green;\">&amp;&amp; image control<\/span><br \/>\nREPORT FORM FoxChartsView PREVIEW<br \/>\n<\/span><br \/>\nIn my report, in the &#8220;ControlSource&#8221; I&#8217;m passing the &#8220;oFoxChart&#8221; reference, and it gets printed.<\/p>\n<p>Is that the best way to do that?<\/p><\/blockquote>\n<p>In my opinion, probably not.<\/p>\n<p>It&#8217;s really hard to tell, because (as I told Cesar) I don&#8217;t have a lot of time to investigate his use of the image control. I don&#8217;t really understand why this chart-handling object should be scoped to a form, for example.<\/p>\n<p>My first question to Cesar was: why aren&#8217;t you putting this object in the GFX collection?<\/p>\n<p>Cesar\u00a0answered, &#8220;Oh, sorry, I didn&#8217;t get what you meant here.\u00a0 Could you recommend me somewhere to do some researches regarding this?&#8221;<\/p>\n<p>Sure.<\/p>\n<p>Start with the <a title=\"FXAbstract docoid\" href=\"\/articles\/tmm\/tmm-fxabstract\/\" target=\"_blank\" rel=\"noopener\">TMM docoid on FXand GFX Inteface Implementations<\/a>.\u00a0 It takes only one method implementation to become part of the appropriate collection.\u00a0Read the <a title=\"FXListener docoid\" href=\"\/articles\/tmm\/tmm-fxlistener\/\" target=\"_blank\" rel=\"noopener\">TMM docoid covering the ReportListener Decorator Foundation Class<\/a>, which hosts the FX and GFX collections.\u00a0 Read the <a title=\"DataViz article\" href=\"\/articles\/datavizreports\/\" target=\"_blank\" rel=\"noopener\">Data Visualization in Reports with VFP 9.0 SP2 article<\/a>, in which Colin and I thoroughly worked through a GFX scenario.<\/p>\n<p>Check out the <a title=\"GFXOutputClip docoid\" href=\"\/articles\/tmm\/tmm-gfxoutputclip\/\" target=\"_blank\" rel=\"noopener\">TMM docoid on GFX Page Region Export<\/a>, while you&#8217;re at it.\u00a0 The sample code section\u00a0states that it is an excerpt from code in &#8220;a custom graphing object&#8221;, which should give Cesar some idea that this approach actually works for what Cesar has in mind.<\/p>\n<p>In point of fact, the example code in that topic has nothing to do with graphing, it is just illustrating one of two ways for a graphing object to\u00a0interact with and leverage\u00a0an Output Clip (or &#8220;Page Region Export&#8221;) object, so he might not be interested, but there are other types of synergy between the code for this gfx object and his work, so, hey, check it out.\u00a0 Maybe I&#8217;ll use gfxOutputClip to\u00a0illustrate some other ideas in a followup post, in which I&#8217;ll try to address some of Cesar&#8217;s other questions.<\/p>\n<p>The\u00a0trouble is, I&#8217;m kind of embarrassed to be having to suggest this stuff. It&#8217;s not like we hid our recommendations; we first\u00a0published these suggestions in the helpfile that shipped with RTM.\u00a0 In SP2,\u00a0we implemented production-quality examples of our recommendations and shipped them with the product.<\/p>\n<p>Hence the application of the Duke Principle; more about that below.\u00a0 For now, let&#8217;s just get some work done.<\/p>\n<h4>Let&#8217;s roll up our sleeves<\/h4>\n<p>Let&#8217;s assume that Cesar has really good reasons to tightly couple his charting object to a form or form class.\u00a0 For example, let&#8217;s suppose the data required by the chart isn&#8217;t actually available during the run of the FRX, only to the form.<\/p>\n<p>This problem &#8212; how do you scope variables for a report &#8212; has more general application than Cesar&#8217;s question. That gives me an excuse to explore it in a bit of depth. There are a number of different interesting things to be learned from playing with this question, so, using the image control scenario as context,\u00a0I am going to build up an answer in &#8220;layers&#8221;.<\/p>\n<p>The basic principles we&#8217;re going to explore include:<\/p>\n<ul>\n<li>some specific-to-FRX capabilities you can use<\/li>\n<li>some ways that you should treat FRXs more like full-fledged citizens of your application, even though they are &#8220;object-assisted&#8221; rather than &#8220;object-oriented&#8221; elements of the application<\/li>\n<li>some concerns about <em>where and how code should be bound<\/em>, including how to avoid these runtime requirements getting in your face while working on report design<\/li>\n<\/ul>\n<h4>A specifics-free report for testing<\/h4>\n<p>Being extremely lazy, I use a report that doesn&#8217;t require any specific data set for testing like this.\u00a0The report expressions are simply FIELD(1) in the header and EVAL(FIELD(1)) in the detail line.\u00a0 For\u00a0this scenario, I&#8217;ll just add an image control into the detail band.<\/p>\n<p>All\u00a0the reports in <a title=\"FRXVariables source zip\" href=\"\/wp-content\/downloads\/FRXVariables.zip\">the sample code for this post<\/a> have this same setup.\u00a0 If you have a table open and SELECTed,\u00a0they will use it, and if you don&#8217;t they will do the equivalent of a USE ? when you run the REPORT FORM command.\u00a0 Any table\u00a0will do.\u00a0 (You&#8217;ll see that I&#8217;m using an old table from the Europa beta test in these screen shots.)<\/p>\n<div style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" style=\"width: 360px; height: 380px;\" title=\"Context-free test report\" src=\"\/lisa\/wp-non\/migrated\/FRXWithVarsDesign1.png\" alt=\"Context-free test report\" width=\"360\" height=\"380\" \/><\/div>\n<p>The next step is to have some mechanism that emulates Cesar&#8217;s requirement in a context-free way way.\u00a0 While (again) this isn&#8217;t the way I normally do things, Cesar is using an image-based object reference as the expression-type control source\u00a0of the image layout control in the FRX.<\/p>\n<p>To emulate the dynamic nature of Cesar&#8217;s charting class in this test report, I&#8217;ll create\u00a0a simple alternation of two images, chosen randomly (by you) at the beginning of the report run.\u00a0 It works like this:<\/p>\n<ul>\n<li>\n<div>Each report has two report variables, MyImage1 and MyImage2.<\/div>\n<\/li>\n<li>\n<div>Both variables are released at the end of the report run.<\/div>\n<\/li>\n<li>\n<div>Both variables request the name of a file from you during report initialization (to ensure different images, one variable asks for a JPG and the other asks for a GIF).<\/div>\n<\/li>\n<li>\n<div>\n<p>Both variables store their own names to themselves after initialization.\u00a0 This is a trick I often use for a variable I want to use but the report engine doesn&#8217;t &#8220;understand&#8221; or adjust directly.<img loading=\"lazy\" decoding=\"async\" style=\"width: 479px; height: 236px;\" title=\"Image variables for test\" src=\"\/lisa\/wp-non\/migrated\/FRXWithVarsDesign3.png\" alt=\"Image variables for test\" width=\"479\" height=\"236\" \/><\/p>\n<\/div>\n<\/li>\n<li>\n<div>So now we just have to tell the the report to alternate images for each detail line to show some dynamic behavior as a proxy for Cesar&#8217;s real object.<br \/>\nWe&#8217;ll do that very simply by adding some code into the FRX event that runs before the detail band.<br \/>\nRemember I have no idea what triggers Cesar&#8217;s chart to start calculating and when to close up shop, this is just an emulation; it doesn&#8217;t really matter <em>what<\/em> images show, or how they get there, as long as we can demonstrate that they get there during the report run.<img loading=\"lazy\" decoding=\"async\" style=\"width: 490px; height: 391px;\" title=\"Image variables for test\" src=\"\/lisa\/wp-non\/migrated\/FRXWithVarsDesign4.png\" alt=\"Image variables for test\" width=\"490\" height=\"391\" \/><\/div>\n<\/li>\n<\/ul>\n<p>OK so far?<\/p>\n<p class=\"NB\">Are you perplexed at the use of EXECSCRIPT() in the On Entry code?<\/p>\n<p>Why didn&#8217;t I just\u00a0make the assignment: \u00a0<strong>MyVarName.PictureVal = IIF(RECNO() % 2 = 0, MyImage1,MyImage2)<\/strong> ?<\/p>\n<p>There&#8217;s a really good reason: the assignment would be &#8220;read&#8221; by the On Entry code as an evaluation, a simple .T. or .F. result. The actual contents of the .PictureVal property would not change.<\/p>\n<p>I could have used a UDF, of course, I&#8217;m just binding code that belong to the report directly to the report to save confusion when this report is moved around.\u00a0You can easily place\u00a0the code\u00a0elsewhere in your environment.<\/p>\n<p>All\u00a0the reports in\u00a0<a title=\"FRXVariables source zip\" href=\"\/wp-content\/downloads\/FRXVariables.zip\">the sample code for this post<\/a> have this same code. They only differ in how they assign the image control variable, which is the only part of the reports that is actually germaine to Cesar&#8217;s question.<\/p>\n<h4>Step 1: Hey, I know: let&#8217;s use a report variable!<\/h4>\n<p>Report variables are durned useful things.\u00a0 You should be able to see that, even if you don&#8217;t customarily use them, by my use of MyImage1 and MyImage2 in the generic setup code you&#8217;ve seen in these reports so far.<\/p>\n<p>To serve as the container for the image-based object reference for the image layout control in the report, you can use another one.\u00a0I&#8217;ve created one,\u00a0initialized similarly to MyImage1 and MyImage2, to set up a simple base-class image object as proof-of-concept, in FRXwithVars.FRX.<\/p>\n<p align=\"center\"><img loading=\"lazy\" decoding=\"async\" style=\"width: 398px; height: 205px;\" title=\"Initializing an image object in a report variable\" src=\"\/lisa\/wp-non\/migrated\/FRXWithVarsDesign2.png\" alt=\"Initializing an image object in a report variable\" width=\"398\" height=\"205\" \/><\/p>\n<p>The control source for this first report is, of course, the simple expression <strong>MyVarName<\/strong>.<\/p>\n<p>I then adapted\u00a0this simple approach to handle Cesar&#8217;s FoxChart custom object instead of a baseclass image control,\u00a0in FRXwithVars1.FRX. I create a FoxChart proxy object in a PRG called CreateFoxChart.PRG, as you can see in the NEWOBJECT call in this report. Then I address MyVarName.ChartCanvas instead of MyVarName in the On Entry code and the image control source:<\/p>\n<p align=\"center\"><img loading=\"lazy\" decoding=\"async\" style=\"width: 396px; height: 577px;\" title=\"Initializing a FoxChart object in a report variable\" src=\"\/lisa\/wp-non\/migrated\/FRXWithVarsDesign5.png\" alt=\"Initializing a FoxChart object in a report variable\" width=\"396\" height=\"577\" \/><\/p>\n<p>This is a really nice approach if the data and logic for FoxChart is\u00a0completely available to the class during the run of the report.\u00a0 You&#8217;ve bound in the requirements for the report directly to the report. There is no need for the report to &#8220;touch&#8221;\u00a0anything, such as a private variable, that is not directly visible to the person creating or maintaining this FRX.<\/p>\n<p>As a result, you can run both FRXWithVars.FRX and FRXWithVars1.FRX from a simple REPORT FORM command, no wrapper code, and they run fine if you choose to preview from the Report Designer.<\/p>\n<p align=\"center\"><img loading=\"lazy\" decoding=\"async\" style=\"width: 443px; height: 562px;\" title=\"Running the WithVars reports directly\" src=\"\/lisa\/wp-non\/migrated\/FRXWithVarsResult.png\" alt=\"Running the WithVars reports directly\" width=\"443\" height=\"562\" \/><\/p>\n<p class=\"NB\">You can\u00a0even run them with SET(&#8220;REPORTB&#8221;) = 80 or 90, for quick Designer previewing, if you want.\u00a0\u00a0The image control source\u00a0works when you preview. But the image object control\u00a0source\u00a0stuff is only guaranteed to render properly to the printer when you work in object-assisted mode.\u00a0 You knew that, didn&#8217;t you?<\/p>\n<h4>Step 2: Attaching to a form with a little help from the forms stack<\/h4>\n<p>The approach in FRXwithVars and FRXwithVars1 works great if your FoxChart (or similar) object isn&#8217;t tightly coupled to your form or form class.\u00a0 Never mind that I don&#8217;t know why it would be or should be &#8212; suppose it is?<\/p>\n<p>Suppose\u00a0Cesar has\u00a0some really good reason to initialize the FoxChart object in\u00a0the outlying\u00a0form, and give it special instructions, before running the report?\u00a0 How does your report code &#8220;grab&#8221; the object reference?<\/p>\n<p>Well, my friend,\u00a0your report\u00a0can do this quite easily and reliably by\u00a0accessing form stack.<\/p>\n<p>At the time the report engine generates output, the form that invoked the report will either be the active form (WONTOP(), in OldSpeak) or the next form down in the stack.\u00a0 The difference is simply whether a Fox form has been used to show report status during the run.\u00a0\u00a0If SET(&#8220;REPORTBEHAVIOR&#8221;) = 90 and you&#8217;ve invoked one of the FFC ReportListeners without setting QuietMode = .T., and without using\u00a0the NODIALOG keyword on the REPORT FORM command, the first form in the stack is the &#8220;therm&#8221; or progress window.<\/p>\n<p>To illustrate this, I&#8217;ve included the not-very-interesting CreateForm.PRG and two more report forms: FRXWithForm80.FRX and FRXWithForm90.FRX.<\/p>\n<p>These two reports still have the report variables MyImage1 and MyImage2, which are just part of the test setup.\u00a0 They no longer\u00a0need the report variable MyVarName holding the image object reference, since they address the forms collection directly.<\/p>\n<p>The only difference in these two reports is whether they address _Screen.Forms(1).FoxCharts1.ChartCanvas or _Screen.Forms(2).FoxCharts1.ChartCanvas in their code.<\/p>\n<p>As CreateForm.PRG points out in its comments, you could make the appropriate index value a public member of\u00a0your application object, add a property to screen, or perform similar tricks to avoid having two separate reports for these scenarios.\u00a0 I&#8217;m just illustrating different ways to reference a form and its potential FoxChart object member here, not providing a recommendation on best practice.<\/p>\n<p>Why not?\u00a0 Because I don&#8217;t really care.\u00a0 You should have a method for sharing information in your application environment.\u00a0 I don&#8217;t care what it is. You might have a private data session with a cursor holding this type of value, for all I know.\u00a0 The point is your report code should be able to use it, just as your other application components use it.\u00a0 Don&#8217;t assume reports are a special case.<\/p>\n<p>One thing I really don&#8217;t like about the code\u00a0you see in CreateForm.PRG and its reports, besides its\u00a0obvious clumsiness,\u00a0is that\u00a0the two reports won&#8217;t run easily during report design.<\/p>\n<p>How do you suppose we can take care of that?<\/p>\n<h4>Step 3: Hey, I know &#8212; why not use a report variable?<\/h4>\n<p>You can put the two approaches you&#8217;ve seen so far together. You can fit an FRX into your general application approach, <em>and<\/em> you can solve design time issues, if you put a report variable, a little code, and the forms stack together.<\/p>\n<p>In my example for you, I&#8217;ve demonstrating using an application object attached to _SCREEN.\u00a0 But once again, I don&#8217;t care how you manage your application scope, or forms collection, etc, in your work. Whatever you normally use is fine and you can adapt this approach to suit.<\/p>\n<p>Consider FRXWithVars2.FRX.\u00a0 This time, I&#8217;ve put the report variable MyVarName back into the report.\u00a0 The control source for the image in this report is, once again, the simple expression MyVarName, as it was in FRXWithVars.FRX (the first one), nothing more exciting.\u00a0 The Detail band On Entry code is also back to the simplest version, the one we used in FRXWithVars.FRX.\u00a0 Nice and simple.<\/p>\n<p>In FRXWithVars2.FRX, initialization of the MyVarName report variable changes.\u00a0 If we can find an application object, we&#8217;ll ask\u00a0it to hand us a the ChartCanvas belonging to the FoxChart instance\u00a0it deems appropriate.\u00a0 If it can&#8217;t find an appropriate FoxChart instance &#8212; never mind what its rules are &#8212; it will return a base image object. And\u00a0if\u00a0we can&#8217;t find an application object at all,\u00a0we&#8217;ll stub in any old image control:<\/p>\n<p class=\"codesample\">IIF(<span style=\"color: #0000ff;\">TYPE<\/span>(&#8220;_SCREEN.MyApplicationObject&#8221;) = &#8220;O&#8221;,<br \/>\n<span style=\"color: #0000ff;\">_SCREEN<\/span>.MyApplicationObject.GetFoxChart(),<br \/>\n<span style=\"color: #0000ff;\">CREATEOBJECT<\/span>(&#8220;image&#8221;))<\/p>\n<p>As you can probably tell, this report will run fine in design mode, whether\u00a0there happens to be an application object\u00a0defined or not.\u00a0 It just won&#8217;t show any interesting behavior that is specific to FoxChart.<\/p>\n<p>I&#8217;ve defined MyApplicationObject in CreateForm2.PRG.\u00a0 When this object is available, its GetFoxChart() method works out the correct form from which to derive the FoxChart object, using the\u00a0forms stack or whatever method you prefer, defaulting to a base class image for testing purposes if nothing else turns up:<\/p>\n<p><span style=\"color: #0000ff;\">DEFINE CLASS<\/span> MyApplicationObject <span style=\"color: #0000ff;\">As Custom <\/span><\/p>\n<p>FUNCTION GetFoxChart<br \/>\n<span style=\"color: #0000ff;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LOCAL\u00a0<\/span>oCanvas, iForm<br \/>\n<span style=\"color: #0000ff;\"><br \/>\nFOR <\/span>iForm = 1 <span style=\"color: #0000ff;\">TO _SCREEN<\/span>.<span style=\"color: #0000ff;\">FormCount<\/span><br \/>\n<span style=\"color: green;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 * you can use a more sophisticated<br \/>\n<span style=\"color: green;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>* method to figure out whether you<br \/>\n<span style=\"color: green;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>* have an object of the appropriate<br \/>\n<span style=\"color: green;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>* type, such as checking the<br \/>\n<span style=\"color: green;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>* class and asking it for the reference;<br \/>\n<span style=\"color: green;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>* the point is to approach<br \/>\n<span style=\"color: green;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>* the stack in the correct order<br \/>\n* or do whatever you feel appropriate<br \/>\n* in your environment<br \/>\n<\/span><span style=\"color: #0000ff;\"><span style=\"color: green;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>IF PEMSTATUS<\/span>(<span style=\"color: #0000ff;\">_SCREEN<\/span>.<span style=\"color: #0000ff;\">Forms<\/span>(iForm),&#8221;FoxCharts1&#8243;,5)<br \/>\n<span style=\"color: #0000ff;\"><span style=\"color: green;\">\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>WAIT WINDOW TIMEOUT <\/span>2 &#8220;Found!&#8221;<br \/>\n<span style=\"color: green;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>oCanvas = <span style=\"color: #0000ff;\">_SCREEN<\/span>.<span style=\"color: #0000ff;\">Forms<\/span>(iForm).FoxCharts1.ChartCanvas<br \/>\n<span style=\"color: #0000ff;\"><span style=\"color: green;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>ENDIF<br \/>\nNEXT <\/span><\/p>\n<p>IF VARTYPE(oCanvas) # &#8220;O&#8221;<br \/>\n<span style=\"color: green;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>oCanvas = <span style=\"color: #0000ff;\">CREATEOBJECT<\/span>(&#8220;Image&#8221;)<br \/>\n<span style=\"color: #0000ff;\">\u00a0\u00a0\u00a0\u00a0\u00a0 ENDIF <\/span><\/p>\n<p>RETURN oCanvas<\/p>\n<p><span style=\"color: #0000ff;\">\u00a0\u00a0 ENDFUNC <\/span><\/p>\n<p>ENDDEFINE<\/p>\n<p>So now we have something that runs well in design time, or from a bare REPORT FORM &#8230; command,\u00a0no matter what your current environment,\u00a0and is also integrated with your standard app development practices, whatever they are.<\/p>\n<h4>Where does the\u00a0GFX collection fit into this scenario?<\/h4>\n<p>The GetFoxChart code in your application environment could just as easily be checking to see if a GFX FoxChart member was available and put one in, if not.\u00a0 It could be setting up this member for the current form&#8217;s requirements, if necessary.\u00a0 You could, in fact, be calling it from the form before the REPORT FORM command, so that the form could communicate directly with the application manager object, passing a reference to itself, and avoiding the need for the manager to go through the form stack.<\/p>\n<p>You&#8217;re going to ask: how does that help you scope your image control reference?\u00a0 There are a lot of ways to do it, once your charting object\u00a0is swimming &#8220;inside&#8221; the FRX sea.\u00a0 For one thing, you don&#8217;t actually need the image control at all, you can draw directly to the surface of the page.\u00a0 For another, if you really like that image control, you can simply use a bare image object with a report variable and CREATEOBJECT() or NEWOBJECT(), as we&#8217;ve done in previous examples, have your gfx object interrogate the FRX details to figure out what it&#8217;s supposed to write to, store a reference to that object in its ChartCanvas member.<\/p>\n<p>You can bind additional report instructions to the image layout element using MemberData &#8212; now that I think about it, you could probably even swap out that image reference stubbed in by the report variable for a more specialized one, on the fly, during BeforeReport.<\/p>\n<p>Support your charting object is supposed to take care of drawing to images on forms as well as to reports? That&#8217;s no problem. All you need to do is add one method that is report-event-specialized, and that invokes your &#8220;standard&#8221; methods appropriately during the run.<\/p>\n<h4>What else can we add about scoping code and variables for report use?<\/h4>\n<p>One thing I used to do a lot was to leverage the Data Environment object to &#8220;hang&#8221; code and member objects on.\u00a0 As you may or may not be aware, you can use the NAME clause on a REPORT FORM command, just as you can on a DO FORM command, to give yourself a handy object reference.\u00a0 Because (here we go) reports are object-assisted, not object-based or object-oriented, the reference you get is a reference to the associated\u00a0Data Environment object for the report.\u00a0 This reference exists even if you put nothing in your DE for the report, don&#8217;t use a private data session, etc.\u00a0 It&#8217;s always there.<\/p>\n<p>You can (for example) use the Init code code of the DE to look through the forms collection for a FoxChart type object, or a form of appropriate class.\u00a0 You can AddProperty to the DE to give yourself information about whether you had to initialize some objects (and whether you want to release them later, accordingly, or whether they existed before the report began.<\/p>\n<p>You can refer to these elements in report variable and report expressions, by using the NAME you provided to the REPORT FORM command.\u00a0 To make everything nice and tidy, you can even use DE initialization code to STORE THIS.Name TO a report variable, so that the current NAME is known, no matter what the REPORT FORM command happened to use.<\/p>\n<p>The DE was the first object to &#8220;assist&#8221; report runs, a long time before VFP 9.\u00a0 It used to be a lot of fun to use it. In my first experiences with image control sources I did in fact &#8220;hang&#8221; these references off the DE.<\/p>\n<p>I don&#8217;t do this so much any more, for two reasons:<\/p>\n<ul>\n<li>There&#8217;s some instability in memory handling when you&#8217;re designing a report (and, often, making code errors) that can corrupt DE code. It&#8217;s okay once you&#8217;re done, but if you crash while working on a report and adding these fancy features, and if you forget to take frequent backups, the results can be&#8230; most annoying.<\/li>\n<li>It really goes against the grain to treat reports as a special case within the application, and to use the primitive DE object, when we have so many better ways to attach object syntax to reports now.\u00a0 Let&#8217;s use what we have to drag and drop reports, if not into a class library, at least into the modern era.That&#8217;s why we have report listeners.\u00a0 That&#8217;s why we have extended syntax in the FX and GFX collections.\u00a0 That&#8217;s why the <a title=\"FXMemberDataScript docoid\" href=\"\/articles\/tmm\/fxmemberdatascript\/\" target=\"_blank\" rel=\"noopener\">FX MemberData Script Implementation<\/a> lets you attach any script you want, to any element of a report, in any event, and that&#8217;s why Reporting Member Data lets you attach any custom attributes to any element of a report.Which brings me to&#8230;<\/li>\n<\/ul>\n<h4>The Duke Principle<\/h4>\n<p>A long time ago, C and I worked with a truly delightful guy named Duke.<\/p>\n<p class=\"NB\">His name wasn&#8217;t really Duke, but I&#8217;m going to call him Duke because it is the name everybody (including his mother) calls him.\u00a0 And, before you ask, he&#8217;s not a Fox programmer and he is highly unlikely to read this blog.\u00a0 However, in case he does, he should know that we think of him fondly and often.<\/p>\n<p>Anyway, the three of us were staying at a hotel at some point, and we were sitting in the little hotel restaurant, having some drinks and thinking about what to do with our evening.\u00a0 Duke\u00a0motioned to the waiter, who hurried over, menus in hand. And Duke asked him &#8220;Excuse me, do you have any idea where we could get some good food around here?&#8221;<\/p>\n<p>The waiter looked at him, completely non-plussed, and tried to decide what he could possibly say.\u00a0 He finally just walked away, I think.<\/p>\n<p>Now, Duke was not\u00a0usually an insensitive person in the slightest.\u00a0 But we were <em>sitting in a restaurant.<\/em> I&#8217;m going to leave you to imagine how the waiter felt being asked that question.<\/p>\n<p>I&#8217;m also going to leave you to figure out what that might have to do with this post.<\/p>\n<h4>Whew.<\/h4>\n<p>This\u00a0has been\u00a0a long post, and that&#8217;s enough for now.\u00a0 I&#8217;ll\u00a0get to Cesar&#8217;s other questions in\u00a0some followup post.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Cesar\u00a0responded to my recent walkthrough on barcharting\u00a0with some VFPReport-specific questions.\u00a0 Here is his first one: At this moment, I&#8217;m doing something like this: SET REPORTBEHAVIOR 90 PRIVATE oFoxChart &amp;&amp; needed by report oxFoxChart = ThisForm.Foxcharts1.ChartCanvas &amp;&amp; image control REPORT FORM FoxChartsView PREVIEW In my report, in the &#8220;ControlSource&#8221; I&#8217;m passing the &#8220;oFoxChart&#8221; reference, and it<a class=\"more-link\" href=\"https:\/\/spacefold.com\/lisa\/2008\/07\/07\/the-scoop-on-scoping-frx-variables-and-the-first-officially-recorded-instance-of-the-duke-principle\/\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,8,9],"tags":[],"class_list":["post-128","post","type-post","status-publish","format-standard","hentry","category-reporting","category-vfp-tmm","category-visual-foxpro"],"_links":{"self":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/posts\/128","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/comments?post=128"}],"version-history":[{"count":4,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/posts\/128\/revisions"}],"predecessor-version":[{"id":396,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/posts\/128\/revisions\/396"}],"wp:attachment":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/media?parent=128"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/categories?post=128"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/tags?post=128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}