ワークシート関数をFunctionプロシージャで自作してみる遊びです。
今回は【COUNTA関数】を自作してみました。
ソースコード
' COUNTA関数 和風スパ版 Function spCOUNTA(ParamArray 値()) As Double If IsMissing(値) Then spCOUNTA = 0: Exit Function ' 本家と違い引数なしを許す ' 各引数をループ Dim 各引数 As Variant For Each 各引数 In 値 ' Rangeの場合 If TypeName(各引数) = "Range" Then spCOUNTA = spCOUNTA + COUNTAセル範囲(各引数) ' 配列の場合 ElseIf IsArray(各引数) Then spCOUNTA = spCOUNTA + COUNTA配列(各引数) ' 値の場合 ElseIf IsEmpty(各引数) = False Then spCOUNTA = spCOUNTA + 1 End If Next End Function ' Rangeの合計値 Private Function COUNTAセル範囲(ByVal セル範囲 As Range) As Double Dim セル As Range For Each セル In セル範囲.Cells ' Emptyでないセルをカウント If IsEmpty(セル.Value) = False Then COUNTAセル範囲 = COUNTAセル範囲 + 1 End If Next End Function ' 配列の合計値 Private Function COUNTA配列(ByVal 配列) As Double Dim 要素 For Each 要素 In 配列 ' 本家と違いジャグ配列(配列の中に配列)にも対応 If IsArray(要素) Then COUNTA配列 = COUNTA配列 + COUNTA配列(要素) ' Emptyでない要素をカウント ElseIf IsEmpty(要素) = False Then COUNTA配列 = COUNTA配列 + 1 End If Next End Function
解説
愚直にFor Each文でEmptyでない要素をカウントしていくコードです。
本家のCOUNTA関数もセル、配列どちらを渡されても動くため、
内部で二つのプロシージャに分岐して実装しています。
本家と同様「空の文字列""」はしっかりカウントし、
真にEmptyのセルだけを除外して他はすべて数え上げています。
この判定は「=Empty」では行えず、(""がTrueになる)
「IsEmpty」による判定でしか行えないため注意してください。
ついでに、ほとんどそんな使い方はしないのですが、
本家同様「COUNTA("あ")」のようなリテラルもカウントします。
自作関数でも一応それも実装しました。
本関数を作る上で最大の注意点は、
IsArray関数がRangeに対してもTrueを返してしまう点です。
このため、配列かセル範囲かを判定するには、
先にTypeNameがRangeであるかを判定する必要があります。
詳しくはこちらの記事を参照ください。
本家との違い(改良点)
今回は本家に忠実に作成しているので意図的に変更はしていないのですが、
本家のCOUNTA関数が対応していない「ジャグ配列(配列の配列)」に対応しました。
ただ↓のコードを書くだけで実装できますからね。
If IsArray(要素) Then COUNTA配列 = COUNTA配列 + COUNTA配列(要素)
こんなに綺麗にFunction名が3つ並ぶとなんとなく気持ちいいです。
以上で自作COUNTA関数の解説を終わります。
実用的かというと全くそんなことはありませんが、
遊びながら楽しくVBAを学べるいい題材だと思います。
Functionの作り方や、ForEach文の書き方を練習したい人は、
是非とも挑戦してみてください。