この記事は公開から2年以上経過しています。
.NET開発でPower Fxを利用する際、標準では提供されていない機能を自前で実装して関数として利用する方法を紹介します。
本例は.NET 6のコンソールアプリケーションですが、Power Fx自体はNET Framework(4.7.2以上)上のWinForms/WPFからでも利用可能です。
2022.9.9追記:
PowerFx 0.2.2-previewの変更に対応しました。
・アセンブリ名と外部I/F変更の変更。
・Randbetween組み込み関数追加に伴いサンプルの関数名をRandBetween
→RandBetween2
に変更。
サンプルソースコード(C#)
本例では指定された範囲内の整数の乱数を返すRandBetween2(minVal, maxVal)
関数を作成します。
カスタム関数の実装方法についてのサンプルのため、入力チェックやエラー処理は行なっていません。
2022.1.6時点ではVisual StudioのNuGetパッケージマネージャー経由でPower Fxを導入する場合、パッケージ検索テキストボックス右のプレリリースを含める
にチェックを入れておく必要があります。
PowerFx 0.2.1-preview
PowerFx220106.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.PowerFx.Core" Version="0.2.1-preview" />
<PackageReference Include="Microsoft.PowerFx.Interpreter" Version="0.2.1-preview" />
</ItemGroup>
</Project>
Program.cs
using System;
using System.Globalization;
using Microsoft.PowerFx;
using Microsoft.PowerFx.Core.Public.Types;
using Microsoft.PowerFx.Core.Public.Values;
static class PowerFxTest210106
{
public static void Main(string[] _)
{
// CurrentCultureがnullの場合の対策
CultureInfo.CurrentCulture = new CultureInfo("ja-JP");
// Power Fxエンジンの生成
var engine = new RecalcEngine();
// Randbetween関数を追加
engine.AddFunction(new RandBetween2());
// 追加したRandbetween関数を実行
for (var i = 0; i < 10; ++i)
{
var ret = engine.Eval(@"RandBetween2(1, 100)");
if (ret is NumberValue sb)
Console.WriteLine(sb.Value);
}
}
// RandBetween2(minVal, maxVal)
private sealed class RandBetween2 : ReflectionFunction
{
// 乱数初期化(シードなし)
private readonly Random _rand = new();
// 戻り値、パラメータ1、パラメータ2は数値として初期化
public RandBetween2() : base(nameof(RandBetween2), FormulaType.Number, FormulaType.Number, FormulaType.Number) { }
// 戻り値、パラメータ1、パラメータ2は数値
public NumberValue Execute(NumberValue numBegin, NumberValue numEnd)
{
return FormulaValue.New(_rand.Next((int)numBegin.Value, ((int)numEnd.Value) + 1));
}
}
}
PowerFx 0.2.2-preview以降
PowerFx220106.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.PowerFx.Core" Version="0.2.2-preview" />
<PackageReference Include="Microsoft.PowerFx.Interpreter" Version="0.2.2-preview" />
</ItemGroup>
</Project>
Program.cs
using System;
using System.Globalization;
using Microsoft.PowerFx;
using Microsoft.PowerFx.Types;
static class PowerFxTest220106
{
public static void Main(string[] _)
{
// CurrentCultureがnullの場合の対策
CultureInfo.CurrentCulture = new CultureInfo("ja-JP");
// Power Fxコンフィグ作成
var config = new PowerFxConfig();
// Randbetween関数を追加
config.AddFunction(new RandBetween2());
// Power Fxエンジンの生成
var engine = new RecalcEngine(config);
// 追加したRandbetween関数を実行
for (var i = 0; i < 10; ++i)
{
var ret = engine.Eval(@"RandBetween2(1, 100)");
if (ret is NumberValue sb)
Console.WriteLine(sb.Value);
}
}
// RandBetween2(minVal, maxVal)
private sealed class RandBetween2 : ReflectionFunction
{
// 乱数初期化(シードなし)
private readonly Random _rand = new();
// 戻り値、パラメータ1、パラメータ2は数値として初期化
public RandBetween2() : base(nameof(RandBetween2), FormulaType.Number, FormulaType.Number, FormulaType.Number) { }
// 戻り値、パラメータ1、パラメータ2は数値
public NumberValue Execute(NumberValue numBegin, NumberValue numEnd)
{
return FormulaValue.New(_rand.Next((int)numBegin.Value, ((int)numEnd.Value) + 1));
}
}
}
出力結果
プログラムを実行すると、今回作成したカスタム関数RandBetween2(1, 100)
をループで10
回評価することで、1〜100までの整数の乱数値を10個表示します。
40
63
93
66
55
68
5
70
93
91
参考ウェブサイトなど
- GitHub
microsoft/Power-Fx
以上です。