Title: TERMINATE REPORT in GRW Post by: Anderson P. on April 02, 2014, 06:47:02 pm When generating a report in GRW the normal workflow is to start the report, output the data in a foreach statement and then finish the report.
The problem is when the foreach doesn't output any data, in this case we can't use the "Finish Report" command, this will cause an "Expression error" because the report was expecting data and did't receive it, but if we don't finish the report we get the following error next time we try to generate a report: "Premature end of file Cause:XML document structures must start and end within the same entity". So i guess that when no data is outputted the correct procedure is to use the "Terminate report" instead of "Finish report". The "Terminate report" command really seems to cancel the report generation, but when we try to generate another report we still get the "Premature end of file" error when the function fgl_report_commitCurrentSettings() is called. My question is, what is the correct procedure to cancel a GRW report generation? Is there something that has to be done to stop the "XML document structures must start and end within the same entity" error? Title: Re: TERMINATE REPORT in GRW Post by: Alex G. on April 03, 2014, 02:43:43 pm Hi,
>The problem is when the foreach doesn't output any data, in this case we can't use the "Finish Report" command, this will cause an "Expression error" because the report was expecting data a You are getting the error because you are accessing look-ahead variables from a list (trigger) that is empty. That typically happens in report headers where you access for example the customer name that is shipped in the order details. If the report has no order details then the header references a variable that is not shipped and an error is raised. There are two patterns to avoid that as follows: Pattern 1: 1) Add a variable to your report and declare is as the first variable in your ORDER EXTERNAL. 2) Populate the variable with a constant value in OUTPUT TO REPORT. Example introducing the variable "k" in the report as described: START REPORT myreport TO XML HANDLER handler FOREACH ... OUTPUT TO REPORT myreport(1,rec.*) #Note that k is always 1 END FOREACH FINISH REPORT myreport REPORT myreport(k,rec) DEFINE k INTEGER, rec RECORD LIKE ... ORDER EXTERNAL BY k,rec.... END REPORT In the report designer you will have a trigger for "Group k" in which you place your entire report content including the page root(s). In the case the OUTPUT TO REPORT is never called, the trigger "k" will not be executed and the report will not produce any output at all and no errors will be raised. The pattern has the additional benefit that you can have a trigger "BEFORE GROUP OF k" that is the equivalent of "FIRST PAGE HEADER" but allows you to put a dynamic number of PRINT inside (That is not allowed in FIRST PAGE HEADER). This way you could for example have a dynamic list of items in the page header. Pattern 2 (Code not tested): Delay the output by always reading ahead one record as follows: Example code before the change: DEFINE orderline OrderType .. START REPORT report_all_orders TO XML HANDLER handler FOREACH c_order INTO orderline.* OUTPUT TO REPORT report_all_orders(orderline.*) END FOREACH FINISH REPORT report_all_orders Example code after the change: DEFINE orderline, nextRow OrderType, startedReport BOOLEAN .. LET startedReport=FALSE FOREACH c_order INTO nextRow.* IF NOT startedReport THEN LET startedReport=TRUE START REPORT report_all_orders TO XML HANDLER handler ELSE OUTPUT TO REPORT report_all_orders(orderline.*) END IF LET orderline.*=nextRow.* END FOREACH IF startedReport THEN OUTPUT TO REPORT report_all_orders(orderline.*) FINISH REPORT report_all_orders END IF Regards, Alex Title: Re: TERMINATE REPORT in GRW Post by: Anderson P. on April 03, 2014, 03:38:52 pm Hi Alex
Thanks for the replay! We was already using the Pattern 2 as a workaround for this error, but indeed the solution proposed in Pattern 1 is also very interesting as it is a nice trigger to detect if the report has been started. But reading de Genero Studio Help Documentation it seems to me that using the "Terminate Report" instruction instead of "Finish Report" is the most "correct" or "code friendly" solution in this case, as it deletes any intermediate files or temporary tables that were created in processing the report. Title: Re: TERMINATE REPORT in GRW Post by: Alex G. on April 03, 2014, 04:17:34 pm Hi,
>But reading de Genero Studio Help Documentation it seems to me that using the "Terminate Report" instruction instead of "Finish Report" is the most "correct" or "code friendly" solution in this case, as it deletes any intermediate files or temporary tables that were created in processing the report. Yes, absolutely. We need to suppress error messages like "Unexpected EOF" in case that a report is terminated by "TERMINATE REPORT" or "EXIT REPORT" (This is a known issue: "Bug 20411 - TERMINATE REPORT is not handled in GRE") Regards, Alex Title: Re: TERMINATE REPORT in GRW Post by: Anderson P. on April 03, 2014, 04:38:04 pm I think it's weird that the error only occurs if you try to start another report, when the function fgl_report_commitCurrentSettings() is called the error pops up...
Seems like there is some trash remaining, that's why i asked in the original thread if i had forgot something, i suppose the first time i call fgl_report_commitCurrentSettings() it start the XML, writing the header and stuff and when you use terminate command it don't delete this data, so the second time the function is called it gets confused and pops the error. But that's me just guessing, i suppose it's just better to wait for the fix. Title: Re: TERMINATE REPORT in GRW Post by: Alex G. on April 03, 2014, 06:06:09 pm Hi,
>I think it's weird that the error only occurs if you try to start another report, when the function fgl_report_commitCurrentSettings() is called the error pops up... it is a bit internal but if you want an explanation of the current behavior then here it is: TERMINATE REPORT or EXIT REPORT perform the documented cleanup but fail to notify and close the XML channel. It is only when we start a new XML report that the previous XML channel is closed and we detect the incomplete document. >But that's me just guessing, i suppose it's just better to wait for the fix. Yes, perhaps you could make the error "Unexpected EOF" appear immediately after TERMINATE REPORT by patching the libraries but I wouldn't advise it. Making the "Unexpected EOF" go away altogether requires changes to the DVM and GRE or the usage of the patterns described. Regards, Alex Title: Re: TERMINATE REPORT in GRW Post by: Anderson P. on April 03, 2014, 06:17:42 pm Ok, now i understand...
Thanks for the explanation Title: Re: TERMINATE REPORT in GRW Post by: Reuben B. on April 07, 2014, 11:43:13 pm I wonder if fgl_report_stopGraphicalCompatabilityMode()
https://4js.com/online_documentation/fjs-gst-manual-html/#c_grw_fgl_report_stopGraphicalCompatibilityMode.html is also possible as an interim solution (haven't tested to verify) Really wanted to comment on ... Quote You are getting the error because you are accessing look-ahead variables from a list (trigger) that is empty. That typically happens in report headers where you access for example the customer name that is shipped in the order details. If the report has no order details then the header references a variable that is not shipped and an error is raised. ... and suspect that if that is the case the 4gl should be ORDER EXTERNAL BY header.id, detail.id BEFORE GROUP OF header.id -- Information for Page Header PRINTX header.* ON EVERY ROW -- Information for Line Detail PRINTX detail.* rather than ON EVERY ROW PRINTX header.*, detail.* i.e normalise what is sent through. Title: Re: TERMINATE REPORT in GRW Post by: Anderson P. on April 08, 2014, 01:27:35 pm Hi Reuben
Thanks for the reply Quote I wonder if fgl_report_stopGraphicalCompatabilityMode() https://4js.com/online_documentation/fjs-gst-manual-html/#c_grw_fgl_report_stopGraphicalCompatibilityMode.html is also possible as an interim solution (haven't tested to verify) Have tested calling fgl_report_stopGraphicalCompatibilityMode() before and after Terminate Report with no success, still getting the reported message. Quote ... and suspect that if that is the case the 4gl should be ORDER EXTERNAL BY header.id, detail.id BEFORE GROUP OF header.id -- Information for Page Header PRINTX header.* ON EVERY ROW -- Information for Line Detail PRINTX detail.* rather than ON EVERY ROW PRINTX header.*, detail.* Actually, my 4gl is like REPORT print(header.*, detail.*) FORMAT FIRST PAGE HEADER PRINTX header.* ON EVERY ROW PRINTX detail.* END REPORT Title: Re: TERMINATE REPORT in GRW Post by: Alex G. on May 15, 2020, 09:28:21 am Seeing by chance that this topic is currently the one with the most views, I would like to point out that since version 3.10 one can use the FirstPageHeader trigger for this purpose.
|