EXCEL VBAクラスモジュール>

Statisticsクラスモジュール

EXCEL関数には便利な統計を扱う関数が多数あります、一例を挙げると、平均を返すMean、分散を返すVariance、回帰直線の傾きと切片を返すLINESTなどです。
これら関数は非常に便利ですが、EXCEL関数(ワークシートで使える関数)とVBAマクロで使える関数とは名前空間が別個のものであり、VBAEXCEL関数を用いるには、WorksheetFunction.Meanなど、WorksheetFunction....と名前空間を指定する必要があります。
コード中2〜3個であれば特に問題ありませんが、頻繁にもちいて、かつWithステートメントも使いづらい場合、コードの見通しを悪くする原因ともなってしまいます。

なるべくなら、元データである標本と標本を分析する統計関数とはセットで考えたい・・・。
そうです、オブジェクト指向の登場です。

上記問題を解決する為のクラスStatisticsを紹介いたします。以下のコードはクラスモジュールのコードとして用いるものです。

Option Explicit
Private sample As Variant

Private Sub Class_Initialize()
    sample = Factories.classInitVar 'FactoriesモジュールにおいてclassInitVarという公開変数を定義し、
End Sub                             'それを初期変数として初期化を行っている

Public Property Get Size() '標本数
    Size = WorksheetFunction.Count(sample)
End Property

Public Property Get Mean() '標本平均
    Mean = WorksheetFunction.Average(sample)
End Property

Public Property Get Variance() '標本分散
    Variance = WorksheetFunction.var(sample)
End Property

Public Property Get StandardDeviation() '標準偏差
    StandardDeviation = WorksheetFunction.StDev(sample)
End Property

Public Property Get Min()
    Min = WorksheetFunction.Min(sample)
End Property

Public Property Get LowerQuartile()
    LowerQuartile = WorksheetFunction.Quartile(sample, 1)
End Property

Public Property Get Median()
    Median = WorksheetFunction.Median(sample)
End Property

Public Property Get UpperQuartile()
    UpperQuartile = WorksheetFunction.Quartile(sample, 3)
End Property

Public Property Get Max()
    Max = WorksheetFunction.Max(sample)
End Property

Public Function Percentile(ratio)
    Percentile = WorksheetFunction.Percentile(sample, ratio)
End Function

Public Property Get Standardized() '正規化
    Dim std() As Variant
    ReDim std(Size - 1)
    Dim e As Variant
    Dim index%: index = 0
    For Each e In sample
        std(index) = WorksheetFunction.Standardize(e, Mean, StandardDeviation)
        index = index + 1
    Next
    Standardized = std
End Property

インターフェースFactories.generateStatistics

StatisticsクラスはClass_Initializeを書き換える必要がありますが、基本的にNew Statisticsでインスタンスを生成することが可能です。しかし、生成時に引数として、標本のデータを指定できたほうが直感的にわかりやすいです。
不幸なことにVBAのクラスシステムは、クラスインスタンス生成時に引数を与えることができません。しかし、クラスモジュールとは別に、標準モジュールにおいて、ファクトリ関数を作り出すことで、この問題を解消することが出来ます。標準モジュールの名前をFactoriesとし、ファクトリ関数の名前をgenerateStatisticsとしましょう。

Public chassInitVar
Public Function generateStatistics(sample) As Statistics
    classInitVar = sample 'Range型 -> 配列型 or 配列型 -> 配列型
    Set generateStatistics = New Statistics
End Function

簡単に仕組みを説明すると、Factoriesモジュールにおいて定義される公開変数classInitVarを仲介として、初期化変数をクラスモジュールに渡しています。

使用方法

簡単に使い方を学ぶ為、VBエディタのイミディエントウィンドウで実際に試してみましょう。

set s = generateStatistics(Range("A1:A100"))
'アクティブシートの"A1〜A100"のデータが標本として取り入れられました。
?s.Mean
'平均が返ります
?s.LowerQuartile
'第一四分位点が返ります。

まとめ

もし、VBAで統計量を頻繁に使用する場合は、WorksheetFunction...などと、一々EXCEL関数を呼び出すのではなく、クラスに組み込みメソッドとして呼び出すと、コードが簡潔に書けて便利です。


他にも、クラスにすることで、便利になるEXCEL関数群を見つけたら、またご紹介します。

[追記]
コメント欄でご指摘のあったいくつかの誤りについて修正を行いました。