MESCIUS SPREAD for Windows Forms 17.0J サンプルコード集
独自の数式を設定する(既存クラスの継承)

SPREADからは数多くの組み込み関数が提供されているため、通常はこれらの利用によってほとんどの機能を実現できます。

しかしながら、提供されている関数以外の処理を実装したい場合にはFunctionInfoクラス(FarPoint.CalcEngine名前空間)を継承したサブクラスを作成することで、独自のカスタム関数を作成することも可能です。(カスタム関数の引数としてセル範囲を渡した場合は、Evaluateメソッドの引数args()にもセル範囲が渡されます)

本サンプルでは、独自に作成したカスタム関数(MySumFunction)にセル範囲を指定することで、範囲内の全ての値を足し込んだ結果を返す例を紹介します。

【実行例】

カスタム関数

  • 既存クラスの継承は.NETアプリケーション開発における一般的な手法です。継承方法の詳細についてはMSDNライブラリをご参照ください。
  • 本サンプルは基本的な継承例です。実際にはプロジェクトの仕様に基づいた各カスタマイズが必要となります。
  • SPREAD for Windows Formsにおける各コレクションインデックスの下限は必ず「0」から始まりますが、数式の作成では「1」から始まる参照番号を使用します。つまり、先頭の列および行を表す番号は「0」ではなく常に「1」となります。 (例:Cells(0,0) ⇒ "A1")
  • ActiveX版で使用された「A#+B#」のような数式はサポートされません。

    SPREAD for Windows Formsでは、例えばA列とB列の値を加算してC列に設定する場合は、相対セル参照をRC[-2]+RC[-1]のようにします。現在の位置(C列内)と演算対象のセルの相対位置を指定することで、ActiveX版のワイルドカードと同様の操作を行うことができます。
         FpSpread1.Sheets(0).ReferenceStyle = FarPoint.Win.Spread.Model.ReferenceStyle.R1C1
                 FpSpread1.Sheets(0).Columns(2).Formula = "SUM(RC[-2]:RC[-1])"
    

 private void Form1_Load(object sender, System.EventArgs e)
 {

   fpSpread1.ActiveSheet.RowCount = 4;
   fpSpread1.ActiveSheet.ColumnCount = 4;
   fpSpread1.ActiveSheet.DefaultStyle.CellType = new FarPoint.Win.Spread.CellType.NumberCellType();
   fpSpread1.ActiveSheet.HorizontalGridLine = new FarPoint.Win.Spread.GridLine(FarPoint.Win.Spread.GridLineType.None);
   fpSpread1.ActiveSheet.VerticalGridLine = new FarPoint.Win.Spread.GridLine(FarPoint.Win.Spread.GridLineType.None);
   fpSpread1.ActiveSheet.Cells[0, 0, 2, 2].BackColor = Color.LightPink;
   fpSpread1.ActiveSheet.Cells[3, 3].BackColor = Color.LemonChiffon;
   fpSpread1.ActiveSheet.Cells[3, 3].Border = new FarPoint.Win.LineBorder(Color.Blue, 2);

   fpSpread1.ActiveSheet.SetValue(0, 0, 10);
   fpSpread1.ActiveSheet.SetValue(1, 0, 20);
   fpSpread1.ActiveSheet.SetValue(2, 0, 30);
   fpSpread1.ActiveSheet.SetValue(0, 1, 40);
   fpSpread1.ActiveSheet.SetValue(1, 1, 50);
   fpSpread1.ActiveSheet.SetValue(2, 1, 60);
   fpSpread1.ActiveSheet.SetValue(0, 2, 70);
   fpSpread1.ActiveSheet.SetValue(1, 2, 80);
   fpSpread1.ActiveSheet.SetValue(2, 2, 90);

   FarPoint.Win.Spread.Model.ICustomFunctionSupport fs = (FarPoint.Win.Spread.Model.ICustomFunctionSupport)fpSpread1.ActiveSheet.Models.Data;
   FarPoint.CalcEngine.FunctionInfo f = fs.GetCustomFunction("MySumFunction");

   if (f == null)
   {
      //作成したカスタム関数を追加します
      fs.AddCustomFunction(new MySumFunction());
   }
   else
   {
      fs.RemoveCustomFunction("MySumFunction");
   }

   //セルに関数を設定します
   fpSpread1.ActiveSheet.SetFormula(3, 3, "MySumFunction(A1:C3)");

 }
 Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load

   FpSpread1.ActiveSheet.RowCount = 4
   FpSpread1.ActiveSheet.ColumnCount = 4
   FpSpread1.ActiveSheet.DefaultStyle.CellType = New FarPoint.Win.Spread.CellType.NumberCellType
   FpSpread1.ActiveSheet.HorizontalGridLine = New FarPoint.Win.Spread.GridLine(FarPoint.Win.Spread.GridLineType.None)
   FpSpread1.ActiveSheet.VerticalGridLine = New FarPoint.Win.Spread.GridLine(FarPoint.Win.Spread.GridLineType.None)
   FpSpread1.ActiveSheet.Cells(0, 0, 2, 2).BackColor = Color.LightPink
   FpSpread1.ActiveSheet.Cells(3, 3).BackColor = Color.LemonChiffon
   FpSpread1.ActiveSheet.Cells(3, 3).Border = New FarPoint.Win.LineBorder(Color.Blue, 2)

   FpSpread1.ActiveSheet.SetValue(0, 0, 10)
   FpSpread1.ActiveSheet.SetValue(1, 0, 20)
   FpSpread1.ActiveSheet.SetValue(2, 0, 30)
   FpSpread1.ActiveSheet.SetValue(0, 1, 40)
   FpSpread1.ActiveSheet.SetValue(1, 1, 50)
   FpSpread1.ActiveSheet.SetValue(2, 1, 60)
   FpSpread1.ActiveSheet.SetValue(0, 2, 70)
   FpSpread1.ActiveSheet.SetValue(1, 2, 80)
   FpSpread1.ActiveSheet.SetValue(2, 2, 90)

   Dim fs As FarPoint.Win.Spread.Model.ICustomFunctionSupport = FpSpread1.ActiveSheet.Models.Data
   Dim f As FarPoint.CalcEngine.FunctionInfo = fs.GetCustomFunction("MySumFunction")

   If f Is Nothing Then
      '作成したカスタム関数を追加します
      fs.AddCustomFunction(New MySumFunction)
   Else
      fs.RemoveCustomFunction("MySumFunction")
   End If

   'セルに関数を設定します
   FpSpread1.ActiveSheet.SetFormula(3, 3, "MySumFunction(A1:C3)")

 End Sub

カスタム関数クラス

 [Serializable()] public class MySumFunction : FarPoint.CalcEngine.FunctionInfo //FunctionInfoクラスを継承したサブクラスを作成します
 {

   public override object Evaluate(object[] args)
   {
      FarPoint.CalcEngine.CalcReference cr;
      double total = 0;

      if (args[0] is FarPoint.CalcEngine.CalcReference)
      {

         //引数args[0]より範囲を取得します
         cr = (FarPoint.CalcEngine.CalcReference)args[0];
         for (int r = cr.Row; r < (cr.Row + cr.RowCount); r++)
         {
            for (int c = cr.Column; c < (cr.Column + cr.ColumnCount); c++)
            {
               //範囲内の値を足し込みます
               total += FarPoint.CalcEngine.CalcConvert.ToDouble(cr.GetValue(r, c));
            }
         }

         //算出結果を返します
         return total;

      }
      else
      {
         return FarPoint.CalcEngine.CalcError.Value;
      }

   }

   public override int MaxArgs { get { return 1; } }

   public override int MinArgs { get { return 1; } }

   public override string Name { get { return "MySumFunction"; } }

   public override bool AcceptsReference (int i) { return true; }

 }
 <Serializable()> Public Class MySumFunction

   'FunctionInfoクラスを継承したサブクラスを作成します
   Inherits FarPoint.CalcEngine.FunctionInfo

   Public Overrides Function Evaluate(ByVal args() As Object) As Object

      Dim cr As FarPoint.CalcEngine.CalcReference
      Dim total As Double = 0

      If TypeOf args(0) Is FarPoint.CalcEngine.CalcReference Then

         '引数args(0)より範囲を取得します
         cr = CType(args(0), FarPoint.CalcEngine.CalcReference)
         For r As Integer = cr.Row To cr.Row + cr.RowCount - 1
            For c As Integer = cr.Column To cr.Column + cr.ColumnCount - 1
               '範囲内の値を足し込みます
               total += FarPoint.CalcEngine.CalcConvert.ToDouble(cr.GetValue(r, c))
            Next
         Next

         '算出結果を返します
         Return total

      Else
         Return FarPoint.CalcEngine.CalcError.Value
      End If

   End Function

   Public Overrides ReadOnly Property MaxArgs() As Integer
      Get
         Return 1
      End Get
   End Property

   Public Overrides ReadOnly Property MinArgs() As Integer
      Get
         Return 1
      End Get
   End Property

   Public Overrides ReadOnly Property Name() As String
      Get
         Return "MySumFunction"
      End Get
   End Property

   Public Overrides Function AcceptsReference(ByVal i As Integer) As Boolean
      Return True
   End Function

 End Class

 

 


© MESCIUS inc. All rights reserved.