忍者ブログ
VBAによる実用アプリケーションの構築、およびGAS(Google Apps Script)やOffice Scriptへのモダンな移行パスを検証・解説するテックブログ。現場で即戦力となるコードモジュールや再利用可能な実用部品を継続的に提供します。

【Excel VBA】試し割り法で高速素因数分解!入力値バリデーション付き堅牢関数の作り方

Excel VBAでちょっとした数値計算やアルゴリズムを実装したいとき、整数の「素因数分解」をパッと行えたら便利ですよね。

この記事では、VBAで素因数分解を効率的かつ安全に行うためのアルゴリズム(試し割り法)の解説と、そのまま標準モジュールに貼り付けて使える実践的なVBAコード・テスト結果をご紹介します。

1. 試し割り法(Trial Division)のアルゴリズム

今回は、素因数分解の最も基本的で直感的なアルゴリズムである試し割り法を使用しています。

  • 2で割れるだけ割る:最小の素数である 2 で割れるだけ繰り返し割り、割れた数を素因数として記録しながら元の数 N を小さくしていきます。
  • 奇数のみ試す:2 で割れなくなったら、次は 3, 5, 7... と奇数(2 ずつ加算)のみで割っていきます(2 以外の偶数値で割り切れることはないため、計算量を半減できます)。
  • 判定の範囲:割る数 d について、d * d <= N(d が N の平方根以下)の範囲まで調べれば十分です。ループ終了時に N が 1 より大きければ、その残った N 自体が最後の素因数となります。

2. VBAコード(標準モジュールに記述)

不正な入力(文字列、小数、1以下の数値など)に対するバリデーション(入力値チェック)もしっかり組み込んだ堅牢なコードです。

Option Explicit

' 素因数分解を行う関数
Public Function Factorize(ByVal inputVal As Variant) As String
    ' 1. 引数のバリデーション
    If Not IsNumeric(inputVal) Then
        Factorize = "エラー: 数値を入力してください。"
        Exit Function
    End If
    
    Dim n As Double
    n = CDbl(inputVal)
    
    If n <> Fix(n) Then
        Factorize = "エラー: 整数を入力してください。"
        Exit Function
    End If
    
    If n < 2 Then
        Factorize = "エラー: 2以上の正の整数を入力してください。"
        Exit Function
    End If
    
    ' 2. 試し割り法による計算
    Dim result As String
    Dim divisor As Double
    divisor = 2
    
    Do While divisor * divisor <= n
        ' Double型での余り判定
        If n - Fix(n / divisor) * divisor = 0 Then
            If result <> "" Then result = result & " * "
            result = result & CStr(divisor)
            n = n / divisor
        Else
            If divisor = 2 Then
                divisor = 3
            Else
                divisor = divisor + 2 ' 奇数のみ進める
            End If
        End If
    Loop
    
    ' 最後に残った数が1より大きければ素因数として追加
    If n > 1 Then
        If result <> "" Then result = result & " * "
        result = result & CStr(n)
    End If
    
    Factorize = result
End Function

' テスト実行用プロシージャ (イミディエイトウィンドウに出力)
Public Sub Test_Factorize()
    Debug.Print "=== 正常系のテスト ==="
    Debug.Print "12         -> " & Factorize(12)         ' 2 * 2 * 3
    Debug.Print "84         -> " & Factorize(84)         ' 2 * 2 * 3 * 7
    Debug.Print "97         -> " & Factorize(97)         ' 97 (素数)
    Debug.Print "360        -> " & Factorize(360)        ' 2 * 2 * 2 * 3 * 3 * 5
    Debug.Print "999999     -> " & Factorize(999999)     ' 3 * 3 * 3 * 7 * 11 * 13 * 37
    Debug.Print "8589934592 -> " & Factorize(8589934592#) ' 2が33個
    
    Debug.Print vbCrLf & "=== 異常系(エラーチェック)のテスト ==="
    Debug.Print "1          -> " & Factorize(1)          ' エラー
    Debug.Print "0          -> " & Factorize(0)          ' エラー
    Debug.Print "-10        -> " & Factorize(-10)         ' エラー
    Debug.Print "3.14       -> " & Factorize(3.14)        ' エラー
    Debug.Print "abc        -> " & Factorize("abc")      ' エラー
End Sub

3. 実行結果(イミディエイトウィンドウ)

上記の Test_Factorize を実行すると、正常系・異常系ともに意図した通りに出力されます。

=== 正常系のテスト ===
12         -> 2 * 2 * 3
84         -> 2 * 2 * 3 * 7
97         -> 97
360        -> 2 * 2 * 2 * 3 * 3 * 5
999999     -> 3 * 3 * 3 * 7 * 11 * 13 * 37
8589934592 -> 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2

=== 異常系(エラーチェック)のテスト ===
1          -> エラー: 2以上の正の整数を入力してください。
0          -> エラー: 2以上の正の整数を入力してください。
-10        -> エラー: 2以上の正の整数を入力してください。
3.14       -> エラー: 整数を入力してください。
abc        -> エラー: 数値を入力してください。

VBAでちょっとした数学的処理を行いたいときや、アルゴリズムの基礎を実装する際の参考にしてみてください!



PR