#author("2018-05-26T13:16:30+09:00","default:mat2umoto","mat2umoto")
#contents

*関数定義 [#c76b6113]
**Variant型引数の判別 [#j5e111aa]
TypeName()関数を使用することで、Variant型の引数に何が渡されたかを判別することができる。この仕組みを利用して、全ての引数をVariant型で受けて後で判別するように作るのが理想的。~
そうすることで、ある引数に対して''値もセルも指定可能な柔軟な関数''になる。~

**引数に設定できる値 [#c5a9afa2]
***数値/文字列 [#s7855817]
-概要~
数値は対応した組み込み型もしくはVariant型の引数で受け取る。~
セルが指定された場合は、そのセルの値が入力される。~

-使用例~
 =UDFRef(10.5)
 =UDFRef("abc")
 =UDFRef(B2)

-定義例~
#code(vb){{
' 値をそのまま表示
Public Function UDFRef(ByVal val As Variant) As Variant

    UDFRef = val

End Function
}}

***真偽値 [#e946845e]
-概要~
真偽値はboolean型もしくはVariant型の引数で受け取る。~
条件式をそのまま指定することができる。~

-使用例~
 =UDFIf(1=1, "true", "false")
 =UDFIf(C3>30, "true", "false")
 =UDFIf(FALSE, "true", "false")

-定義例~
#code(vb){{
' 条件分岐
Public Function UDFIf(ByVal bl As Boolean, ByVal tval As Variant, ByVal fval As Variant) As Variant

	Dim ret As Variant

	If bl Then
		ret = tval
	Else
		ret = fval
	End If

	UDFIf = ret

End Function
}}

***セル範囲[#i0cb4150]
-概要~
セル範囲はVariang型、Object型、Range型(Ranges型ではないことに注意)のいずれかの型の引数で受け取る。~
-使用例~
 =UDFSum($A1:$C$5)
 =UDFSum('Sheet2'!F2)

-定義例~
#code(vb){{
' セル範囲の合計値
Public Function UDFSum(ByRef rs As range) As Variant

	Dim ret As Variant
	Dim r As range

	ret = 0
	For Each r In rs
		ret = ret + r.Value
	Next

	UDFSum = ret

End Function
}}


**省略可能な引数 [#o8d1c069]
引数にOptionalキーワードを付与することで、省略可能な引数となる。~
ただし、それ以降の全ての引数にもOptionalキーワードを付与する必要がある。~

引数が省略されたかどうかは、引数がVariant型であればIsMissing()関数で判定できる。~
#code(vb){{
Function UDFArgState1(Optional ByVal arg As Variant) As String

    Dim ret As String

    If IsMissing(arg) Then
        ret = "省略"
    Else
        ret = CStr(arg)
    End If
    
    UDFArgState1 = ret

End Function
}}

引数がVariant型では無い場合は、デフォルト値を設定しておいて判定することになる。~
#code(vb){{
Function UDFArgState2(Optional ByVal arg As String = "") As String

    Dim ret As String

    If arg = "" Then
        ret = "省略"
    Else
        ret = CStr(arg)
    End If
    
    UDFArgState2 = ret

End Function
}}

#code(vb){{
Function UDFArgState3(Optional ByRef arg As Range = Nothing) As String

    Dim ret As String

    If arg Is Nothing Then
        ret = "省略"
    Else
        ret = arg.Value
    End If
    
    UDFArgState3 = ret

End Function
}}

**可変長引数 [#p8e4f885]
引数にParamArrayキーワードを付与することで、可変長引数となる。~
ただし、必ずVariant型の配列にする必要がある。~
また、ByVal、ByRef、Optionalキーワードと併用はできない。~

引数が省略されたかどうかは、引数配列の上限が下限よりも小さいかどうかで判定できる。~

#code(vb){{
Function UDFParamArray(ParamArray args() As Variant) As String

    Dim v As Variant
    Dim ret As Long
    
    If UBound(args) < LBound(args) Then
        UDFParamArray = "省略"
        Exit Function
    End If

    ret = 0
    For Each v In args
        ret = ret + CLng(v)
    Next
    
    UDFParamArray = CStr(ret)

End Function
}}

**自動計算対応 [#xac40a22]
自動計算 Application.Volatile~

**エラー表示 [#sabb2d77]
関数の引数入力中に、Ctrl+Aで出てくるダイアログ
**マクロの説明 [#q4dfbe30]
Application.MacroOptions~


**マクロのカテゴライズ [#tedbf0fe]

**引数の入力支援 [#n1a73177]
引数入力中にカーソル下に表示されるツールチップ
*補足事項 [#h2e05e9d]
**引数の変数型 [#v9209376]
引数や戻り値はObject型やVariant型で、実行時に型情報を調べるほうがいい?SUM関数のようにセルや数値のどちらも引数に渡す場合「TypeOf TypeName IsNumeric」で処理を分岐するなど。~

boolean型の引数で、IF関数のような条件式(厳密にはその真偽値)を受け取ることもできる。「A1=1」
**Functionをワークシートで使用不可にする [#l6925650]
下記の手段によってFunctionプロシージャを関数挿入ダイアログや、入力途中の関数一覧に表示させないことが可能。~
-Funtionを「Private」宣言する~
-モジュールの先頭で「Option Private Module」を記述しておく(そのモジュール全体に影響することに注意)~

ただし、直接関数名を入力すると使用することはできてしまうので注意。~

*制限事項 [#g5f5c43b]
-スプレッドシートでのセルの挿入、削除、または書式の設定
-別のセルの値の変更
-ブックでのシートの移動、名前の変更、削除、または追加
-計算方法や画面表示など、環境オプションの変更
-ブックへの名前の追加
-プロパティの設定およびほとんどのメソッドの実行~
→つまり、戻り値が自動で対象セルにセットされるということ以外のアウトプット系処理は全滅?~
→ワークシート関数での制限に反するコードは無視される。エラー表示などはされない。~
http://support.microsoft.com/kb/170787/ja~


トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS