6 返信 最新の回答 日時: Mar 12, 2017 11:11 PM ユーザー:user19752

    自動入力でリレーション先を集計する計算式を再計算する方法はないでしょうか

    macchaka

      リレーション先をsum関数で自動計算した数値タイプフィールドがあります。

      集計目的なので、リレーション先は常にデータが変わります。

       

      例えば、リレーション元は顧客マスタ。リレーション先は入金履歴トランのようなものです。

      毎日顧客単位で入金累計とそれを使った計算フィールドを、データ書き出ししなければならないと想定します。

      (例えですので、この点は要件と仮定します)

       

      計算フィールドで行いたいところですが、集計は計算値の保存ができませんので、それを使った計算フィールドも保存が出来ず、結果として処理が遅くなる原因になります。

      そこで、処理速度を高めるために入金累計は数値フィールドで格納しておきたいと考えます。そうすれば、計算フィールドは同じテーブル内の計算で済み、かつ計算結果を保存しておくことができるからです。

       

      他の回答では「同じ計算式で全置換すればいい」というものもあったのですが、それではそもそも「自動計算」を設定する意味が半減し、今回の例では、(自動計算の設定を使わず)フィールドの全置換だけで済ませばいいということになります。

       

      ある外部サイトでは、フィールド内容の再ルックアップを実行すればいいというものもあったのですが、「ルックアップ」ではないので、「ルックアップするフィールドが見つかりません」というエラーで実行できません。

       

      レコードが作成されたときには自動計算し、(リレーション先の変更が検知できず自動再計算できないという点は理解しているので)、リレーション先の更新時にトリガーを引けば再計算されるということをしたいのですが、本当にFileMakerにその機能はない(フィールド置換で処理するしかない)のでしょうか。

       

      繰り返しになりますが、トリガーが引かれたときにフィールドの全置換を実行すればよい…というのは、実効性では理解しますが、自動計算の定義がされているのに、その再計算がリレーションキーの書き換えでもしないとできず、同じ式を使って全く別の機能で補うというのは、OAOO原則の観点で納得できないのが、質問の趣旨です。もし計算式が変わると、フィールド定義とスクリプトの2箇所修正しないといけないわけなので。

       

      されども、できないのならそれがソフトウェアの仕様ですから、納得します。

       

      ちなみに、バージョン依存はないと思いますが、今回の質問にあたり確認環境としたのはFM14です。

        • 1. Re: 自動入力でリレーション先を集計する計算式を再計算する方法はないでしょうか
          shin

          集計先のレコード数は,全体で,または 顧客毎に何レコードくらいになりますか。

          どの方法を取ったとしても、ライブで数値を取りたいのでしたら計算フィールドにする以外無いでしょうし,その際には少なくとも1顧客分の計算は必須です。

          対象レコード数が膨大ならば集計させた方が若干早いと思いますが,集計値は,GetSummary() を使うと他のテーブルからでも取り出せます。

          • 2. Re: 自動入力でリレーション先を集計する計算式を再計算する方法はないでしょうか
            macchaka

            > 集計先のレコード数は,全体で,または 顧客毎に何レコードくらいになりますか。

            実際には請求データと入金データ(それぞれ別テーブル)の差分を得ますので、それぞれ8万レコードと14万レコードです。顧客は2万レコードです。

             

            > どの方法を取ったとしても、ライブで数値を取りたいのでしたら計算フィールドにする以外無いでしょうし,その際には少なくとも1顧客分の計算は必須です。
            はい。表示上は1件ずつなので計算フィールドで処理しています。

            問題は全顧客分のデータを出力しなければならず、この処理時間を短縮する必要があることです。

             

            > 対象レコード数が膨大ならば集計させた方が若干早いと思いますが,集計値は,GetSummary() を使うと他のテーブルからでも取り出せます。

            こちらの回答も参考にさせて頂いています。

            こちらでは、「GetSummary() 関数は、非常に多くの評価が必要ですので、通常は使わないほうがいい」というご回答があり、ファイルメーカーのリファレンスでも、「自己連結リレーションシップと統計関数を使用して、同様の結果を得ることができます。」とあるのですが、今回は、GetSummaryを使う方がよいのでしょうか。

             

            いずれにしても、再計算という機能はないということなんでしょうね。

            • 3. Re: 自動入力でリレーション先を集計する計算式を再計算する方法はないでしょうか
              shin

              運用がわからないのですが、請求データは、請求残金があれば必ず作成、それとも、実請求が出たときのみに作成でしょうか。

              入金については、分割入金があるのですか。

               

              時間短縮のためには、請求データを入金データを同じテーブルに置いておくのが良いと思います。入力上は、基本データ(顧客データと期間データ)以外は別フィールドで処理していくと、問題は出ないでしょう。

              この構造ですと、期間データで絞り込んで顧客データをキーに集計すると、請求金額はそのソート時間+αくらいで求められ、それをそのままエクスポートすれば良いのでは、と思いますが。

               

              今の構造のままでしたら、顧客データから請求データ、入金データへリレーションを張り、Sum() で求めていくしか無いでしょうね。

              ただ、手元のかなりプアな環境で同様の規模のテーブルを作ってみましたが、全顧客の請求と入金金額を求めるのは、ほんの数秒です。(FM12, MacOS10.6, MacBook pro C2D2.1G)そこから差分を出しのもほとんど時間は同じなのですが。何か別の要素があるのでは、と思います。例えば、請求金額が他のテーブルからの計算値であるとか。

              • 4. Re: 自動入力でリレーション先を集計する計算式を再計算する方法はないでしょうか
                macchaka

                > 入金については、分割入金があるのですか。

                 

                あります。

                請求データと入金データを同じテーブルにできない理由は、分割入金の他に、いつどの口座に入金されたかなど細かなログを記録することが求められているためです。

                 

                > ただ、手元のかなりプアな環境で同様の規模のテーブルを作ってみましたが、全顧客の請求と入金金額を求めるのは、ほんの数秒です。
                (snip)

                > 何か別の要素があるのでは、と思います。例えば、請求金額が他のテーブルからの計算値であるとか。

                 

                はい。それはあると思います。一つ一つチューニングを施しているところです。

                色々出力が遅いのは、これに限らず発生しており、こちらのサイトも参照して、なるべくリレーションで引っ張ってくるフィールドを保存できる計算フィールドかスタティックなものにしようとしているところです。

                元々業界でも名の通った開発会社に作ってもらったもので、既に処理が重いので、要件とファイルメーカーの特性があってない側面もあるのだろうと思っています。

                 

                閑話休題

                 

                元々の質問は、再計算をすることができないのかどうか、でしたので、これについてはその機能がないと理解しました。

                 

                レコードを作成したときしか計算できない(初期値)というのならまだしも、リレーションのキーを書き換えれば再計算されるのに、それ以外にトリガーを引く方法がないというのは、片手落ちの気がします。

                • 5. Re: 自動入力でリレーション先を集計する計算式を再計算する方法はないでしょうか
                  shin

                  再計算ですが、そのフィールドの索引が常に必要ならば、その索引を再作成させないためには、そのフィールドの再評価は出来ないですね。そのために、索引を常に作っておくオプションは、計算結果を保存しておくというオプションが連動します。

                  逆に、その値を常に最新の状態で求めておく必要が有る場合も有るでしょう。その場合には、その計算結果を保存せずに必要時に計算する、というオプションがオンになります。

                   

                  お困りなのは、その前者の場合だと思いますが、敢えて計算させる様な仕組みを組み込んでおく計算式が作れます。例えば、

                  Evaluate ( "Sum ( フィールド )" ; 対象フィールド )

                  という式にしておきます。対象フィールドが変更されると、そのテキスト部分が再評価され値を返します。

                  • 6. Re: 自動入力でリレーション先を集計する計算式を再計算する方法はないでしょうか
                    user19752
                    リレーションのキーを書き換えれば再計算される

                    なら、それをトリガにすればいいんでは。現在の値で全置換すれば一度に複数レコードできます。

                     

                    他には

                    Let(

                    dummy = トリガフィールド ;

                    計算式

                    )

                    のようにすると、トリガフィールドの変更で再計算されます。