excel-vba
ユーザー定義関数(UDF)
サーチ…
構文
function functionName(argumentVariable dataTypeとして、argumentVariable2はdataTypeとして、オプションのargumentVariable3はdataTypeとして)functionReturnDataTypeとして
関数の基本宣言。すべての関数は名前を必要としますが、引数をとる必要はありません。引数は0個か、与えられた数の引数を取るかもしれません。引数をオプションとして宣言することもできます(関数を呼び出すときに引数を指定しても問題ありません)。各引数に可変型を指定し、同様に関数自体が返すデータ型を返すことをお勧めします。functionName = theVariableOrValueBeingReturned
他のプログラミング言語を使用している場合は、Return
キーワードに慣れている可能性があります。これはVBAでは使用されません。代わりに、関数名を使用します。変数の内容または直接提供される値に設定できます。ファンクションの戻り値のデータ型を設定した場合、今回指定した変数またはデータは、そのデータ型である必要があります。終了機能
必須。Function
コードブロックの終わりを示し、末尾にある必要があります。 VBEは通常、新しい関数を作成するときにこれを自動的に提供します。
備考
ユーザー定義関数(別名UDF)は、ユーザーが作成したタスク固有の関数を指します。ワークシート関数(ex: =SUM(...)
)として呼び出すことも、Subプロシージャ内の実行中のプロセスに値を返すこともできます。 UDFは、通常、1つ以上のパラメーターとして渡された情報から値を戻します。
これは次の方法で作成できます。
- VBAを使用します。
- Excel C APIを使用する - コンパイルされた関数をExcelにエクスポートするXLLを作成します。
- COMインターフェイスを使用します。
UDF - Hello World
- オープンExcel
- Visual Basic Editorを開きます(Visual Basic Editorを開くを参照してください)
- [挿入] - > [モジュール]をクリックして新しいモジュールを追加します。
- 次のコードを新しいモジュールにコピーして貼り付けます。
Public Function Hello() As String
'Note: the output of the function is simply the function's name
Hello = "Hello, World !"
End Function
取得するには:
- ワークブックに戻って、セルに "Hello"( "Hello")と入力すると、 "Hello World"が表示されます。
ペナルティなしで完全な列参照を許可する
完全な列参照をパラメーターとして渡すことができれば、ワークシートにUDFを実装する方が簡単です。しかし、コーディングの明示的性質のために、これらの範囲に関係するループは、何百ものセルが完全に空であることを処理している可能性があります。これにより、VBAプロジェクト(およびワークブック)がフリーズしてしまい、不要な値が処理されなくなります。
ワークシートのセルをループすることは、タスクを達成する最も遅い方法の1つですが、ときどきやむを得ないこともあります。実際に必要とされているものに実行された作業をカットすることは、完全に理にかなっています。
この問題を解決するには、 Intersectメソッドを使用してWorksheet.UsedRangeプロパティへの完全な列参照または完全行参照を切り捨てます。次のサンプルでは、ワークシートのネイティブSUMIF関数を緩やかに複製するため、 sum_rangeの各値にcriteria_rangeの値を指定する必要があるため、 criteria_rangeもsum_rangeに合うようにサイズが変更されます 。
ワークシート上で使用されるUDFのApplication.Callerは、それが存在するセルです。セルの.Parentプロパティはワークシートです。これは、.UsedRangeを定義するために使用されます。
モジュールコードシート:
Option Explicit
Function udfMySumIf(rngA As Range, rngB As Range, _
Optional crit As Variant = "yes")
Dim c As Long, ttl As Double
With Application.Caller.Parent
Set rngA = Intersect(rngA, .UsedRange)
Set rngB = rngB.Resize(rngA.Rows.Count, rngA.Columns.Count)
End With
For c = 1 To rngA.Cells.Count
If IsNumeric(rngA.Cells(c).Value2) Then
If LCase(rngB(c).Value2) = LCase(crit) Then
ttl = ttl + rngA.Cells(c).Value2
End If
End If
Next c
udfMySumIf = ttl
End Function
構文:
=udfMySumIf(*sum_range*, *criteria_range*, [*criteria*])
これは非常に単純な例ですが、完全な2列の参照(それぞれ1,048,576行)を渡しますが、データと基準の15行しか処理しないことを適切に示しています。
個々のメソッドとプロパティの正式なMSDNドキュメントをMicrosoft™の仲間とリンクしました。
範囲内のユニークな値をカウントする
Function countUnique(r As range) As Long
'Application.Volatile False ' optional
Set r = Intersect(r, r.Worksheet.UsedRange) ' optional if you pass entire rows or columns to the function
Dim c As New Collection, v
On Error Resume Next ' to ignore the Run-time error 457: "This key is already associated with an element of this collection".
For Each v In r.Value ' remove .Value for ranges with more than one Areas
c.Add 0, v & ""
Next
c.Remove "" ' optional to exclude blank values from the count
countUnique = c.Count
End Function