1

何度も呼び出されるレポートを持っていますが、順番を毎回変えたいです。

変数に応じて「順序」を変更するにはどうすればよいですか。

例えば

report print_label()

   If is_reprint
   then
       order by rpt.item_code, rpt.description
   else
       order by rpt.description, rpt.item_code
   end if

レポートを呼び出すときに変数を渡そうとしました:

let scratch = "rpt.item_code, rpt.description"
start print_label(scratch)

そして、私がしたレポートで:

order by scratch

しかし、それはうまくいきませんでした......他の提案はありますか?? ありがとうございました!

4

4 に答える 4

2

私がそのタイプの問題に使用した手法は、次のようなものです。

REPORT report_name(x)
DEFINE x RECORD
    param1,param2, ..., paramN ...,
    sort_method ...,
    data ...
END RECORD

ORDER [EXTERNAL] BY x.param1, x.param2, ..., x.paramN

BEFORE GROUP OF x.param1
    CASE 
        WHEN x.sort_method ...
            PRINT ...
        WHEN x.sort_method ...
            PRINT ...
    END CASE

BEFORE GROUP OF x.param2
    # similar technique as above

...

BEFORE GROUP OF x.paramN
    # similar technique as above

ON EVERY ROW
    PRINT ...

AFTER GROUP OF x.paramN
   # similar technique as above
...

AFTER GROUP OF x.param2
    # similar technique as above

AFTER GROUP OF x.param1
    # similar technique as above

...次に、REPORT を呼び出す 4gl で、x.param1、x.param2、...、x.paramN に、並べ替えに使用する必要なパラメーターを設定します。

CASE x.sort_method 
    WHEN "product,branch"
        LET x.param1 = x.data.product_code
        LET x.param2 = x.data.branch_code
    WHEN "branch,product"
        LET x.param1 = x.data.branch_code
        LET x.param2 = x.data.product_code
END CASE
OUTPUT TO REPORT report_name(x.*)

私の例によると、これは私が見て、株式レポートなどに使用した手法です。倉庫/支店/店舗マネージャーは、倉庫/支店/店舗、次に製品/SKU/アイテム別に注文されたものを確認したいのに対し、製品マネージャーは製品/SKU/アイテム、次に倉庫/支店/アイテム別に注文されたものを確認したいと考えています。お店。同じ手法を使用して、より多くの潜在的なパラメーターを含むより多くの分析レポートを作成できます。私が見たレコードは 6 だと思います。したがって、その場合、考えられる注文の組み合わせごとに個別のレポートを作成するよりも、6!=720 の可能な組み合わせすべてをカバーする 1 つのレポートの方がはるかに優れています。

したがって、おそらくジョナサンのオプション 1 に似ていますが、複雑さについて同じ留保はありません。コードレビューで、後輩の開発者がひどく間違っているのを見つけた覚えはありません。実際、レポートが十分に一般的である場合は、あまり頻繁に触れる必要がないことがわかります。

于 2016-09-08T21:41:13.220 に答える
1

簡潔な答え

I4GL REPORT 関数の ORDER BY 句は、レポートを実装するコードの生成方法に重大な影響を与えます。生成されたコードを実行時にそのように再配線することは、まったく現実的ではありません。

したがって、目的の結果を直接達成することはできません。

ノート

ORDER EXTERNAL BYおそらくではなくを使用する必要があることに注意してくださいORDER BY— 違いは、 を使用するとEXTERNAL、レポートはデータが正しい順序で表示されていると想定できますが、使用しないと、レポートはすべてのデータを (データベースの一時テーブルに) 保存する必要があります。をクリックし、必要な並べ替え順序でテーブルからデータを選択して、2 パス レポートを作成します。

勇気があり、I4GL C コード コンパイラをお持ちの場合は、レポート用に生成されたコードを確認してください。それは、あなたが自分で使うとは夢にも思わないあらゆる種類のトリックを使用します。

回避策 — 概要

わかった; 直接できるので。あなたの選択肢は何ですか?私の見解では、次の 2 つのオプションがあります。

  1. 特に順序付けを選択するために 2 つのパラメーターを使用し、次にEXTERNALそれらを常に固定順序でリストする ORDER BY (なし) 句を使用します。ただし、レポートを使用するときは、引数の順序を選択してください。

  2. レポート名と ORDER EXTERNAL BY 句のみが異なる 2 つのレポートを作成します。必要な順序に応じて、正しいレポートを呼び出すように手配します。

これらのうち、オプション 2 はメンテナンスの問題を除けば、はるかに簡単です。ほとんどの場合、単一のコピーからコードを生成するように手配します。つまりREPORT print_label_code_desc、1 つのファイルに保存してから、それを編集して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 コードを書いてからしばらく経ちました。

重要な点は、順序付けされた値がレポートに特別に渡され、その編成を制御するためだけに使用されることです。2 つの列の BGO (BEFORE GROUP OF の省略形、AFTER GROUP OF の AGO) セクションに異なる詳細を出力できる必要がある場合があります。これは通常、(gasp) グローバル変数によって処理されます — これは I4GL であり、ビジネスを行う通常の方法です。実際には、レポート ドライバー コード (START REPORT、OUTPUT TO REPORT、および FINISH REPORT を呼び出すコード) がレポート自体と同じファイルにある場合、それらはグローバル変数ではなくモジュール変数である必要があります。これが必要になるのは、一般に、グループ レベル (BGO および AGO ブロック内) でのレポートには、説明の前にコードを並べ替えるか、その逆かによって、異なるタイトルまたはラベルが必要になるためです。

すべてのレポートが必ずしもこのような並べ替えに適しているわけではないことに注意してください。BGO ブロックと AGO ブロックを異なる順序で実行するだけでは、レポート出力を適切に表示するには不十分です。その場合、オプション 2 またはオプション 2A にフォールバックします。これは、ORDER BY 句の並べ替えだけではない 2 つの別々のレポートを作成することです。 ORDER BY 句。

ご覧のとおり、これには注意が必要です。別の方法 (オプション 2) よりもかなり注意が必要です。動的 SQL を使用して SELECT ステートメントを作成する場合は、適切な ORDER BY 句を文字列に配置して、カーソルが正しい順序でデータを取得できるように準備できます。つまり、ORDER EXTERNAL BY を使用できるようになります。 .

概要

あなたが I4GL の初心者である場合は、オプション 2 を使用してください。あなたのチームが I4GL の経験が豊富でない場合は、オプション 2 を使用してください。あまり好きではありませんが、簡単に処理できる方法であり、あなた自身、あなたの現在の同僚、そしてこれから先の同僚たちも容易に理解できます。

あなたが I4GL にある程度慣れていて、チームが I4GL の経験が豊富で、レポート レイアウトが動的に再編成するのに適している場合は、オプション 1 を検討してください。 .

于 2016-09-07T20:43:38.603 に答える
0

次のように、order by 句内に case ステートメントを含めることができます。

order by 
       case 
         when 1 = 1 then 
            rpt.item_code, rpt.description
         else
            rpt.description, rpt.item_code
       end
于 2016-09-07T19:18:27.317 に答える