简答
I4GL REPORT 函数中的 ORDER BY 子句对如何生成实现报告的代码具有至关重要的影响。像在运行时那样重新连接生成的代码是不可行的。
因此,你不能直接达到你想要的结果。
注意事项
请注意,您可能应该使用ORDER EXTERNAL BY 而不是ORDER BY — 不同之处在于,使用EXTERNAL,报告可以假设数据以正确的顺序显示,但如果没有,报告必须保存所有数据(在数据库中的临时表中),然后从表中按要求的排序顺序选择数据,制成两遍报告。
如果您有勇气并拥有 I4GL c 代码编译器,您应该查看为报告生成的代码,但请注意,这是您很可能会在很长一段时间内遇到的最可怕的代码.它使用了你自己做梦也想不到的各种技巧。
解决方案——概述
好的;所以你可以直接做。你有什么选择?在我看来,你有两个选择:
使用两个参数专门用于选择排序,然后使用 ORDER BY(不带EXTERNAL)子句始终按固定顺序列出它们。但是,当需要使用报告时,请选择您希望参数使用的顺序。
编写两个仅报告名称和 ORDER EXTERNAL BY 子句不同的报告。根据您想要的顺序安排调用正确的报告。
其中,选项 2 更为简单——除了维护问题。最有可能的是,您会安排从单个副本生成代码。也就是说,您将REPORT print_label_code_desc 保存在一个文件中,然后安排将其编辑为REPORT print_label_desc_code(例如,使用sed)——并且编辑将反转ORDER BY 子句中名称的顺序。这在makefile 中并不难做到,尽管它需要一些小心。
实践中的选项 1
选项 1 在实践中是什么样的?
DECLARE c CURSOR FOR
SELECT * FROM SomeTable
START REPORT print_label -- optional specification of destination, etc.
FOREACH c INTO rpt.*
IF do_item_desc THEN
OUTPUT TO REPORT print_label(rpt.item_code, rpt.description, rpt.*)
ELSE
OUTPUT TO REPORT print_label(rpt.description, rpt.item_code, rpt.*)
END IF
END FOREACH
FINISH REPORT print_label
报告函数本身可能如下所示:
REPORT print_label(col1, col2, rpt)
DEFINE col1 CHAR(40)
DEFINE col2 CHAR(40)
DEFINE rpt RECORD LIKE SomeTable.*
ORDER BY col1, col2
FORMAT
FIRST PAGE HEADER
…
BEFORE GROUP OF col1
…
BEFORE GROUP OF col2
…
ON EVERY ROW
…
AFTER GROUP OF col1
…
AFTER GROUP OF col2
…
ON LAST ROW
…
END REPORT
对于大纲代码中的任何错误,我们深表歉意;距离我上次编写任何 I4GL 代码已经有一段时间了。
关键点是 order by 值是专门传递给报表的,并且仅用于控制其组织。你可能需要
能够在两列的 BGO(BEFORE GROUP OF 的简写;AGO 为 AFTER GROUP OF)部分打印不同的详细信息。这通常由(喘气的)全局变量处理——这是 I4GL,它们是做生意的正常方式。实际上,如果报告驱动程序代码(调用 START REPORT、OUTPUT TO REPORT 和 FINISH REPORT 的代码)与报告本身位于同一文件中,则它们应该是模块变量而不是全局变量。您需要这个,因为通常在组级别(在 BGO 和 AGO 块中)的报告将需要不同的标题或标签,具体取决于您是否在描述之前对代码进行排序,反之亦然。请注意,组聚合的含义会根据 ORDER BY 子句中的顺序而变化。
请注意,并非每份报告都必然适合这种重新排序。仅以不同的顺序运行 BGO 和 AGO 块不足以使报告输出看起来合理。在这种情况下,您将退回到选项 2 — 或选项 2A,即编写两个单独的报告,它们不会假装只是对 ORDER BY 子句的重新排序,因为数据的格式需要根据不同的ORDER BY 子句。
如您所见,这需要一些小心 — 比替代方案(选项 2)要更加小心。如果您使用动态 SQL 创建 SELECT 语句,您可以安排将正确的 ORDER BY 子句放入准备好的字符串中,以便游标以正确的顺序获取数据——毕竟允许您使用 ORDER EXTERNAL BY .
总结
如果您是 I4GL 的新手,请选择选项 2。如果您的团队在 I4GL 方面经验不足,请选择选项 2。我不太喜欢它,但这是可以处理的方式您自己、您当前的同事以及未来的同事都容易理解并且容易理解。
如果您对 I4GL 相当满意,并且您的团队对 I4GL 有相当的经验 - 并且报表布局确实适合动态重组 - 然后考虑选项 1。它比较棘手,但我在 I4GL 中做了更糟糕的事情在过去。