MESCIUS SPREAD for Windows Forms 17.0J
カスタム関数の作成

使用頻度の高い処理が、組み込み関数として存在しない場合、あるいは、複数の組み込み関数を組み合わせて1つの関数にしたい場合、カスタム関数を作成する方法があります。カスタム関数は、組み込み関数と同様に呼び出すことができます。

カスタム関数に、組み込み関数と同じ名前を付けることもできます。その場合、カスタム関数が組み込み関数よりも優先されます。カスタム関数は評価時に動的にリンクされます。カスタム関数が同じ名前を使用し、また数式が解析される前に追加される場合、アプリケーションは既存の組み込み関数を再定義できます。

数式が関数のMinArgsプロパティとMaxArgsプロパティで指定された範囲外のパラメータ数のカスタム関数を呼び出そうとすると、その関数のEvaluateメソッドはスキップされ、#VALUE!エラー値が結果として使用されます。

また、数式がエラー値(#NUM!、#VALUE!、#REF!など)のパラメータを使用したカスタム関数を呼び出して、IReadonlyPrimitiveValueインターフェースのGetErrorメソッドがそのパラメータに対してFalseを返した場合、FunctionクラスのEvaluateメソッドはスキップされ、エラー値が結果として使用されます。

Evaluateメソッドは指定された引数を基にカスタム関数を評価し、評価された値を結果に割り当てます。

設定方法

  1. カスタム関数を定義します。
  2. シートに関数を登録します。
  3. カスタム関数を使用します。

サンプルコード

最初はカスタム関数を作成します。この例では、税を評価し、スプレッドシート内の指定されたセルに数値を返すTaxValue関数を作成します。

次のコードはTaxValueカスタム関数を定義します。

C#
コードのコピー
using GrapeCity.CalcEngine;
public class TaxValueFunction : GrapeCity.CalcEngine.Function
    {
        public TaxValueFunction() : base("TAXVALUE", 1, 2, FunctionAttributes.SingleCell | FunctionAttributes.Number) { }
        protected override void Evaluate(IArguments arguments, IValue result)
        {
            IEvaluationContext context = arguments.EvaluationContext;
            double num = arguments[0].GetNumber(context);
            double taxrate = arguments.Count > 1 ? arguments[1].GetNumber() : 0.15;
            result.SetValue(null, num - (num * taxrate));
        }
    }

次のコードはカスタム関数を登録します。

C#
コードのコピー
fpSpread1.AddCustomFunction(new TaxValueFunction());

次のコードは数式内でカスタム関数を実装します。

C#
コードのコピー
fpSpread1.ActiveSheet.Cells[1,1].Formula = "TAXVALUE(A1)";

カスタム関数内のパラメータ

以下の2つの方法でカスタム関数で引数を指定できます。

デフォルトでは、パラメータは値により渡されます(単一のセルを使用している場合)。単一の空白セルはnull値(Visual BasicではNothing)として渡されます。空白ではない単一セルは、ボックス化されたプリミティブ(double、boolean、stringなど)として渡されます。

セル範囲を使用している場合、パラメータは参照により渡されます。

カスタム関数をパラメータ付きで動作させるには、派生クラス内から Functionクラスのメソッドとプロパティを使用します。

IReferenceSourceインターフェースのGetValueメソッドおよびIPrimitiveValueインターフェースのSetValueメソッドを使用して、参照先のセルに対して、値を取得または設定できます。GetValueメソッドおよびSetValueメソッドの行および列のインデックスは、参照範囲の行・列から開始します。

サンプルコード

次のサンプルコードでは、指定したセル範囲から、指定した値未満のセル数をカウントする関数を作成します。 

C#
コードのコピー
class CountIfLessThanFunction : GrapeCity.CalcEngine.Function
    {
        public CountIfLessThanFunction() :
          base("COUNTIFLESSTHAN", 2, 2, GrapeCity.CalcEngine.FunctionAttributes.Number)
        {
        }
        protected override void Evaluate(IArguments arguments, IValue result)
        {
            IValue range = arguments[0];
            if (range.ValueType != GrapeCity.CalcEngine.ValueType.Reference && range.ValueType != GrapeCity.CalcEngine.ValueType.AdjustableReference)
            {
                arguments.EvaluationContext.Error = CalcError.Value;
                result.SetValue(CalcError.Value);
            }
            else
            {
                IEvaluationContext evaluationContext = arguments.EvaluationContext;
                double criteria = arguments[1].GetNumber(evaluationContext);
                IReferenceSource referenceSource = range.GetReferenceSource(evaluationContext);
                RangeReference rangeRef = range.GetReference(evaluationContext, 0);
                int count = 0;
                for (int c = rangeRef.Column; c <= rangeRef.Column2; c++)
                {
                    for (int r = rangeRef.Row; r <= rangeRef.Row2; r++)
                    {
                        referenceSource.GetValue(evaluationContext, r, c, result);
                        double cellValue = result.GetNumber(evaluationContext);
                        if (cellValue < criteria)
                        {
                            count++;
                        }
                    }
                }
                result.SetValue(evaluationContext, count);
            }
        }
    }

次のコードでは、カスタム関数を登録し、その関数をセルに実装します。

C#
コードのコピー
// カスタム関数を登録し、数式内に実装します。
fpSpread1.AddCustomFunction(new CountIfLessThanFunction());                                                                                       
fpSpread1.ActiveSheet.Cells[0, 0].Formula = "COUNTIFLESSTHAN(A2:A4,100)";                                                                                       
                                                                                       
// 上記数式が参照している範囲に値を設定します。                                                                                       
fpSpread1.ActiveSheet.Cells[1, 0].Value = 110;                                                                                       
fpSpread1.ActiveSheet.Cells[2, 0].Value = 90;                                                                                       
fpSpread1.ActiveSheet.Cells[3, 0].Value = 200;                                                                                       
参照

 

 


© MESCIUS inc. All rights reserved.