概要: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の新たな地平に到達しているはずです。継続的な学習こそが、プログラミングスキルを磨く唯一の近道です。
