5 返信 最新の回答 日時: Mar 11, 2014 7:48 PM ユーザー:roryconsulting

    カスタム関数で、SumIf もどきを作ってみた

    roryconsulting

      繰り返しフィールドで、EXCELのSumIfのような動作をする計算フィールドが欲しくて、作ってみました。

      目的は果たしたのですが、前提条件等使い方にクセが強く、皆さんの知恵を借りてよりよい関数にできたら良いなと思い投稿しました。

       

      ------------------------------------

      // Usage : SumIf ( <集計するフィールド名> ; <比較するフィールド名> ; <一致条件> ; <繰り返し上限数> ; <変化検出用フィールド名1> ; <変化検出用フィールド名1> )

      // Parameters :

      // 1 SummeryField : 集計フィールド

      // 2 ConditionField : 条件判定フィールド

      // 3 MatchText : 一致条件 (条件判定フィールド[繰り返し位置]=指定文字列)

      // 4 MaxIndex : 最大繰り返し数

      // 5 Dummy1 : 計算させるために、ダミーのフィールドを指定させる

      // 6 Dummy2 : 計算させるために、ダミーのフィールドを指定させる

      // Return : 条件判定フィールド と、条件一致した繰り返し位置番号で、集計フィールドを集計します。

      If ( MaxIndex = 0 ; 0 ; SumIf ( SummeryField ; ConditionField ; MatchText ; MaxIndex -1 ; 0 ; 0 ) +

      If ( MatchText = GetField ( ConditionField & "[" & MaxIndex & "]" ) ; GetField ( SummeryField & "[" & MaxIndex & "]" ) ; 0 ) )

      ------------------------------------

      具体例: 計算フィールドに、以下の様に設定します。 変化の検出をさせることで 計算結果を保存しなくても動作するはず。

      SumIf (

      "Income::AllowancesAmount" ;

      "Income::IncomeExpansion" ;

      AllowanceType [ Get ( 計算式繰り返し位置番号 ) ] ;

      150 ;

      Extend ( Income::Amounts ) ;

      Extend ( Income::Expansions ) )

      ------------------------------------------------

      Income::Amounts と、Income::Expansions は、値の変化をリアルタイムに検出できる様に、繰り返しフィールドをつなげているフィールドです。

       

      目的は果たしたのですが、前提条件等使い方にクセが強く、皆さんの知恵を借りてよりよい関数にできたら良いなと思い投稿しました。

        • 1. Re: カスタム関数で、SumIf もどきを作ってみた
          sago350@未来Switch

          繰り返しフィールドに入っている値に対して集計かけることが少ないので、与える値は「改行区切りのテキスト」の方が嬉しいです。

          • 2. Re: カスタム関数で、SumIf もどきを作ってみた
            roryconsulting

            改行区切りで、タブ区切りという条件で、作ってみた。

            区切り文字はご自由に

            // Usage : SumIfValue ( <Numbers> ; <Match Text> ; ValueCount(<Numbers>) )

            // <Numbers> is tab separated text and numbers.

            Case (

            IsEmpty ( Match ) ; 0 ;

            Repetition = 0 ; 0 ;

            Let ( target = Substitute ( GetValue ( Numbers ; Repetition ) ; Char (9) ; ¶ );

            SumIfValue ( Numbers ; Match ; Repetition -1 ) +

            If ( Match = GetValue ( target ; 1 ) ;

            GetAsNumber ( GetValue ( target ; 2 ) )

            ; 0 ) ) )

            /* Sample : 使用例

            Let ( a =

            "Test1" & Char(9) & 1 & ¶ &

            "Test2" & Char(9) & 2 & ¶ &

            "Test3" & Char(9) & 3 & ¶ &

            "Test1" & Char(9) & 4 & ¶ &

            "Test2" & Char(9) & 5 ;

            SumIfValue ( a ; "Test1" ; ValueCount(a) )

            )

            */

            • 3. Re: カスタム関数で、SumIf もどきを作ってみた
              roryconsulting

              比較文字列と数値が別変数の場合

              // Usage : SumIfValue2 ( <Texts> ; <Numbers> ; <Match Text> ; ValueCount(<Numbers>) )

              Case (

              IsEmpty ( Match ) ; 0 ;

              Repetition = 0 ; 0 ;

              SumIfValue2 ( Texts ; Numbers ; Match ; Repetition -1 ) +

              If ( Match = GetValue ( Texts ; Repetition ) ;

              GetAsNumber ( GetValue ( Numbers ; Repetition ) )

              ; 0 ) )

              /* Sample

              Let ( [

              txt = "Test1¶Test2¶Test3¶Test1¶Test2";

              num = "1¶2¶3¶4¶5" ] ;

              SumIfValue2 ( txt ; num ; "Test2" ; ValueCount(txt) )

              )

              */

              • 4. Re: カスタム関数で、SumIf もどきを作ってみた
                roryconsulting

                使ってみたら、 SumIfValue2 の汎用性が高い。

                 

                繰り返しフィールドもList関数を使えば簡単に利用できた。

                 

                Let ( Expansion = List ( <比較文字列が入った繰り返しフィールド> ) ;

                SumIfValue2 ( Expansion  ; List ( <集計対象の数値が入った繰り返しフィールド> ) ; <一致文字列> ; ValueCount(Expansion) ) )

                 

                実行速度も、フィールドから値を取り出すより断然早く動作しました。

                • 5. Re: カスタム関数で、SumIf もどきを作ってみた
                  roryconsulting

                  関数名とか分かり易く整理 & インデントして読みやすくしました。

                  // Function Name : SumIf

                  // Parameters :

                  //   1 Texts        :

                  //   2 Numbers   :

                  //   3 Match       :

                  //   4 Repetition :

                  // Usage : SumIf ( <Texts> ; <Numbers> ; <Match Text> ; ValueCount(<Texts> or <Numbers>) )

                  Case (

                    IsEmpty ( Match ) ; 0 ;

                    Repetition = 0 ; 0 ;

                    SumIf ( Texts ; Numbers ; Match ; Repetition -1 ) +

                      If ( Match = GetValue ( Texts ; Repetition ) ;

                        GetAsNumber ( GetValue ( Numbers ; Repetition ) ) ;

                        0 )

                  )