【VBAリファレンス】Excel VBAでツイッターの数式解答を解析する:関数名と使用回数を配列で抽出する高度なテクニック

スポンサーリンク

概要:SNS上の数式パズルを自動解析する意義

Excelにおける「数式」は単なる計算ツールではなく、一種の言語です。特にSNS(旧Twitter)上で頻繁に投稿される「この数式の答えは?」といったパズル形式の投稿に対し、回答者がどのような関数を、何回使用して解を導き出したのかを分析することは、VBAのスキル向上において非常に優れた練習題材となります。

本記事では、文字列として入力された数式から、使用されている関数名を抽出し、それらの「関数名」と「使用回数」を二次元配列として取得するプロフェッショナルなVBA手法を解説します。単なる文字列操作を超え、正規表現を用いた高度な解析ロジックを実装することで、データ分析の幅を劇的に広げることが可能です。

詳細解説:正規表現を用いた関数パターンの抽出ロジック

数式の中から関数名を特定するには、単純な文字検索では不十分です。「SUM」と「SUMIF」のように、関数名の一部が他の関数と重複している場合があるためです。ここで強力な武器となるのが「正規表現(Regular Expressions)」です。

ロジックの要点は以下の3ステップです。
1. 正規表現エンジンを用いて、アルファベットの連続かつ直後に「(」が続くパターンを抽出する。
2. 抽出した関数名を「連想配列(Scripting.Dictionary)」に格納し、キーとして関数名、アイテムとして出現回数をカウントする。
3. 連想配列のデータを最終的に二次元配列に変換して出力する。

このアプローチにより、数式の構造がどれほど複雑であっても、一貫して高速に処理を行うことが可能となります。特に、ネストされた関数についても、正規表現のパターンマッチングを繰り返すことで正確に捕捉できます。

サンプルコード:関数抽出エンジンの実装

以下のコードは、セル内の文字列から関数名とその回数を抽出し、結果を配列として返す関数です。Microsoft VBScript Regular Expressions 5.5を参照設定するか、あるいは実行時にオブジェクト生成して利用してください。


Function ExtractFunctionUsage(ByVal formulaStr As String) As Variant
    ' 正規表現オブジェクトの生成
    Dim regEx As Object
    Set regEx = CreateObject("VBScript.RegExp")
    
    ' 関数名のパターン: アルファベット大文字または数字が続き、直後に括弧が来るもの
    ' [A-Z0-9.]+ 
    regEx.Pattern = "([A-Z0-9\.]+)\("
    regEx.Global = True
    regEx.IgnoreCase = True
    
    Dim matches As Object
    Set matches = regEx.Execute(formulaStr)
    
    ' 連想配列でカウント
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")
    
    Dim match As Object
    Dim funcName As String
    For Each match In matches
        ' マッチした文字列の末尾の"("を除去
        funcName = Left(match.Value, Len(match.Value) - 1)
        funcName = UCase(funcName)
        
        If dict.Exists(funcName) Then
            dict(funcName) = dict(funcName) + 1
        Else
            dict.Add funcName, 1
        End If
    Next
    
    ' 結果を二次元配列に変換
    Dim resultArr() As Variant
    ReDim resultArr(0 To dict.Count - 1, 0 To 1)
    
    Dim i As Long
    Dim key As Variant
    i = 0
    For Each key In dict.Keys
        resultArr(i, 0) = key
        resultArr(i, 1) = dict(key)
        i = i + 1
    Next
    
    ExtractFunctionUsage = resultArr
End Function

' 実行用プロシージャ
Sub TestExtraction()
    Dim formula As String
    formula = "=SUM(A1:A10)+IF(B1>0,AVERAGE(B1:B10),COUNT(C1:C10))"
    
    Dim results As Variant
    results = ExtractFunctionUsage(formula)
    
    Dim i As Long
    For i = LBound(results, 1) To UBound(results, 1)
        Debug.Print "関数名: " & results(i, 0) & " / 回数: " & results(i, 1)
    Next
End Sub

実務アドバイス:メンテナンス性を高めるための設計

実務でこのコードを使用する際、以下のポイントを意識してください。

1. **例外処理の追加**: 数式が正しくない場合や、関数を含まない文字列が渡された場合のエラーハンドリングを強化してください。例えば、`matches.Count`が0の場合の条件分岐を明示的に記述することが重要です。
2. **パフォーマンスの最適化**: 大量の数式を一度に解析する場合、連想配列への書き込みがボトルネックになることがあります。数万行単位の処理を行う場合は、配列のサイズを予め予測して確保するなどの工夫が必要です。
3. **ユーザー定義関数との区別**: Excelにはユーザーが作成した関数(UDF)も存在します。これらと標準関数を区別したい場合、別途「標準関数リスト」を保持した配列を用意し、`Exists`メソッドで比較を行うことで、使用している標準関数の内訳だけを抽出することも可能です。
4. **大文字小文字の正規化**: Excelの関数は基本的に大文字小文字を区別しませんが、抽出したデータは分析のために`UCase`関数で統一して格納するのが定石です。

まとめ:VBAによるデータ解析力の向上

数式を解析するということは、その数式を書いた人間の「思考プロセス」を読み解く作業に他なりません。今回紹介した正規表現と連想配列を組み合わせた手法は、単なる関数抽出にとどまらず、テキストマイニングの基礎となる強力な技術です。

VBAは古臭い言語だという誤解がありますが、このように正規表現エンジンを呼び出し、メモリ上で効率的にデータを処理するロジックを組むことで、現代のデータサイエンスにも通ずる高度な自動化を実現できます。

ぜひ、日々の業務やSNSでの数式パズル解析において、このコードをベースに独自の分析ツールを作り上げてみてください。プログラムが意図した通りに数式を分解し、関数名と回数を正確に吐き出した瞬間、あなたはExcel VBAの新たな地平に到達しているはずです。継続的な学習こそが、プログラミングスキルを磨く唯一の近道です。

タイトルとURLをコピーしました