ExcelでAI活用【VBA×ローカルLLMの実践ガイド】
ExcelとAIを組み合わせれば、データ処理がさらに効率化できます。
この記事では、VBAからローカルLLMを呼び出してExcel作業を自動化する方法を解説します。
1. Excel×AIでできること
活用シーン
| 用途 | 内容 |
|---|---|
| データ分類 | テキストを自動でカテゴリ分け |
| 要約生成 | 長文コメントを要約 |
| 翻訳 | 多言語データの翻訳 |
| データクレンジング | 表記ゆれの統一 |
| レポート生成 | データから文章を生成 |
ローカルLLMのメリット
メリット
- 機密データも安心(外部送信なし)
- オフライン環境でも利用可能
- API費用がかからない
- 処理速度が安定
2. 環境構築
必要なもの
1. Ollama(ローカルLLM実行環境) 2. Excel(VBA対応版) 3. 適切なスペックのPC
Ollamaのインストール
1. ollama.com からダウンロード 2. インストーラーを実行 3. コマンドプロンプトで確認 ollama --version
モデルのダウンロード
bash
# 日本語に強いQwenをダウンロード
ollama pull qwen2.5
# 軽量モデル(低スペックPC向け)
ollama pull phi3:mini
VBAの参照設定
VBAエディタ → ツール → 参照設定 → Microsoft XML, v6.0 にチェック
3. VBAからOllamaを呼び出す
基本的なAPI呼び出し
VBA
Function CallOllama(prompt As String, Optional model As String = "qwen2.5") As String
Dim http As Object
Dim url As String
Dim requestBody As String
Dim response As String
' HTTPオブジェクトを作成
Set http = CreateObject("MSXML2.XMLHTTP")
' OllamaのAPIエンドポイント
url = "http://localhost:11434/api/generate"
' リクエストボディを作成
requestBody = "{""model"":""" & model & """,""prompt"":""" & EscapeJson(prompt) & """,""stream"":false}"
' リクエストを送信
http.Open "POST", url, False
http.setRequestHeader "Content-Type", "application/json"
http.send requestBody
' レスポンスを解析
response = http.responseText
CallOllama = ExtractResponse(response)
Set http = Nothing
End Function
' JSON文字列をエスケープ
Function EscapeJson(text As String) As String
Dim result As String
result = Replace(text, "\", "\\")
result = Replace(result, """", "\""")
result = Replace(result, vbCrLf, "\n")
result = Replace(result, vbCr, "\n")
result = Replace(result, vbLf, "\n")
result = Replace(result, vbTab, "\t")
EscapeJson = result
End Function
' レスポンスからテキストを抽出
Function ExtractResponse(jsonResponse As String) As String
Dim startPos As Long
Dim endPos As Long
startPos = InStr(jsonResponse, """response"":""") + 12
endPos = InStr(startPos, jsonResponse, """,""done""")
If startPos > 12 And endPos > startPos Then
ExtractResponse = Mid(jsonResponse, startPos, endPos - startPos)
ExtractResponse = Replace(ExtractResponse, "\n", vbCrLf)
ExtractResponse = Replace(ExtractResponse, "\""", """")
Else
ExtractResponse = "エラー: レスポンスの解析に失敗"
End If
End Function
ワークシート関数として使用
VBA
' カスタムワークシート関数
Function AI_PROCESS(text As String, instruction As String) As String
Dim prompt As String
prompt = instruction & vbCrLf & vbCrLf & text
AI_PROCESS = CallOllama(prompt)
End Function
' 要約関数
Function AI_SUMMARIZE(text As String) As String
Dim prompt As String
prompt = "以下の文章を50文字以内で要約してください:" & vbCrLf & text
AI_SUMMARIZE = CallOllama(prompt)
End Function
' 分類関数
Function AI_CLASSIFY(text As String, categories As String) As String
Dim prompt As String
prompt = "以下のテキストを分類してください。" & vbCrLf & _
"カテゴリ:" & categories & vbCrLf & _
"1つだけ回答してください。" & vbCrLf & vbCrLf & _
"テキスト:" & text
AI_CLASSIFY = CallOllama(prompt)
End Function
4. 実践的な活用例
一括分類処理
VBA
Sub ClassifyAllData()
Dim ws As Worksheet
Dim lastRow As Long
Dim i As Long
Dim text As String
Dim category As String
Set ws = ThisWorkbook.Sheets("データ")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Application.ScreenUpdating = False
For i = 2 To lastRow
text = ws.Cells(i, 1).Value ' A列:テキスト
If Len(text) > 0 And Len(ws.Cells(i, 2).Value) = 0 Then
category = AI_CLASSIFY(text, "問い合わせ,クレーム,要望,その他")
ws.Cells(i, 2).Value = category ' B列:カテゴリ
' 進捗表示
Application.StatusBar = "処理中... " & i & "/" & lastRow
DoEvents
End If
Next i
Application.StatusBar = False
Application.ScreenUpdating = True
MsgBox "分類が完了しました"
End Sub
コメントの要約
VBA
Sub SummarizeComments()
Dim ws As Worksheet
Dim lastRow As Long
Dim i As Long
Dim comment As String
Dim summary As String
Set ws = ThisWorkbook.Sheets("コメント一覧")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
For i = 2 To lastRow
comment = ws.Cells(i, 1).Value
If Len(comment) > 100 Then ' 100文字以上のコメントのみ
summary = AI_SUMMARIZE(comment)
ws.Cells(i, 2).Value = summary
End If
Next i
End Sub
表記ゆれの統一
VBA
Sub NormalizeText()
Dim ws As Worksheet
Dim lastRow As Long
Dim i As Long
Dim original As String
Dim normalized As String
Dim prompt As String
Set ws = ThisWorkbook.Sheets("住所データ")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
For i = 2 To lastRow
original = ws.Cells(i, 1).Value
prompt = "以下の住所を正規化してください。" & vbCrLf & _
"・全角数字は半角に" & vbCrLf & _
"・都道府県から記載" & vbCrLf & _
"・ハイフンは「-」に統一" & vbCrLf & vbCrLf & _
original
normalized = CallOllama(prompt)
ws.Cells(i, 2).Value = normalized
Next i
End Sub
感情分析
VBA
Function AI_SENTIMENT(text As String) As String
Dim prompt As String
prompt = "以下のテキストの感情を分析してください。" & vbCrLf & _
"ポジティブ、ネガティブ、ニュートラルの3つから1つだけ回答:" & vbCrLf & vbCrLf & _
text
AI_SENTIMENT = CallOllama(prompt)
End Function
Sub AnalyzeSentiment()
Dim ws As Worksheet
Dim lastRow As Long
Dim i As Long
Set ws = ThisWorkbook.Sheets("レビュー")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
For i = 2 To lastRow
ws.Cells(i, 2).Value = AI_SENTIMENT(ws.Cells(i, 1).Value)
Next i
End Sub
5. データ分析への活用
データの傾向分析
VBA
Sub AnalyzeDataTrend()
Dim ws As Worksheet
Dim dataRange As Range
Dim dataText As String
Dim analysis As String
Dim prompt As String
Set ws = ThisWorkbook.Sheets("売上データ")
Set dataRange = ws.Range("A1:D10")
' データをテキスト化
dataText = RangeToText(dataRange)
prompt = "以下のデータを分析し、傾向と改善点を3点挙げてください:" & vbCrLf & vbCrLf & dataText
analysis = CallOllama(prompt)
' 結果を別シートに出力
ThisWorkbook.Sheets("分析結果").Range("A1").Value = analysis
End Sub
Function RangeToText(rng As Range) As String
Dim cell As Range
Dim result As String
Dim row As Range
For Each row In rng.Rows
For Each cell In row.Cells
result = result & cell.Value & vbTab
Next cell
result = result & vbCrLf
Next row
RangeToText = result
End Function
レポート文章の生成
VBA
Sub GenerateReport()
Dim ws As Worksheet
Dim reportWs As Worksheet
Dim dataText As String
Dim report As String
Dim prompt As String
Set ws = ThisWorkbook.Sheets("月次データ")
Set reportWs = ThisWorkbook.Sheets("レポート")
dataText = RangeToText(ws.Range("A1:E20"))
prompt = "以下のデータから月次報告書を作成してください。" & vbCrLf & _
"形式:" & vbCrLf & _
"1. サマリー(3行)" & vbCrLf & _
"2. 主要指標" & vbCrLf & _
"3. 考察" & vbCrLf & vbCrLf & _
dataText
report = CallOllama(prompt)
reportWs.Range("A1").Value = report
End Sub
6. パフォーマンス最適化
バッチ処理
VBA
Sub BatchProcess()
Dim ws As Worksheet
Dim lastRow As Long
Dim i As Long
Dim batchSize As Long
Dim startTime As Double
batchSize = 10 ' 10件ずつ処理
Set ws = ThisWorkbook.Sheets("データ")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
startTime = Timer
Application.ScreenUpdating = False
For i = 2 To lastRow Step batchSize
' バッチ処理
ProcessBatch ws, i, WorksheetFunction.Min(i + batchSize - 1, lastRow)
' 進捗表示
Application.StatusBar = "処理中... " & i & "/" & lastRow & _
" (" & Format((i / lastRow) * 100, "0") & "%)"
DoEvents
Next i
Application.ScreenUpdating = True
Application.StatusBar = False
MsgBox "完了しました。処理時間: " & Format(Timer - startTime, "0.0") & "秒"
End Sub
Sub ProcessBatch(ws As Worksheet, startRow As Long, endRow As Long)
Dim i As Long
For i = startRow To endRow
If Len(ws.Cells(i, 1).Value) > 0 And Len(ws.Cells(i, 2).Value) = 0 Then
ws.Cells(i, 2).Value = AI_SUMMARIZE(ws.Cells(i, 1).Value)
End If
Next i
End Sub
キャッシュの活用
VBA
' 結果をキャッシュするDictionary
Dim CacheDict As Object
Sub InitCache()
Set CacheDict = CreateObject("Scripting.Dictionary")
End Sub
Function CallOllamaWithCache(prompt As String) As String
Dim cacheKey As String
If CacheDict Is Nothing Then InitCache
' プロンプトをキーとしてキャッシュ
cacheKey = Left(prompt, 100) ' 先頭100文字をキーに
If CacheDict.Exists(cacheKey) Then
CallOllamaWithCache = CacheDict(cacheKey)
Else
Dim result As String
result = CallOllama(prompt)
CacheDict.Add cacheKey, result
CallOllamaWithCache = result
End If
End Function
7. エラーハンドリング
堅牢なAPI呼び出し
VBA
Function CallOllamaSafe(prompt As String) As String
On Error GoTo ErrorHandler
Dim http As Object
Dim url As String
Dim requestBody As String
Dim response As String
Dim retryCount As Integer
retryCount = 0
RetryPoint:
Set http = CreateObject("MSXML2.XMLHTTP")
url = "http://localhost:11434/api/generate"
requestBody = "{""model"":""qwen2.5"",""prompt"":""" & EscapeJson(prompt) & """,""stream"":false}"
http.Open "POST", url, False
http.setRequestHeader "Content-Type", "application/json"
http.send requestBody
If http.Status = 200 Then
response = http.responseText
CallOllamaSafe = ExtractResponse(response)
Else
Err.Raise vbObjectError + 1, , "HTTP Error: " & http.Status
End If
Set http = Nothing
Exit Function
ErrorHandler:
retryCount = retryCount + 1
If retryCount <= 3 Then
Application.Wait Now + TimeSerial(0, 0, 2) ' 2秒待機
Resume RetryPoint
Else
CallOllamaSafe = "エラー: " & Err.Description
Set http = Nothing
End If
End Function
接続チェック
VBA
Function IsOllamaRunning() As Boolean
On Error GoTo NotRunning
Dim http As Object
Set http = CreateObject("MSXML2.XMLHTTP")
http.Open "GET", "http://localhost:11434/api/tags", False
http.send
IsOllamaRunning = (http.Status = 200)
Set http = Nothing
Exit Function
NotRunning:
IsOllamaRunning = False
End Function
Sub CheckAndProcess()
If Not IsOllamaRunning() Then
MsgBox "Ollamaが起動していません。" & vbCrLf & _
"コマンドプロンプトで 'ollama serve' を実行してください。", _
vbExclamation
Exit Sub
End If
' 処理を実行
ClassifyAllData
End Sub
8. まとめ
Excel×AIの活用パターン
活用パターン
- テキスト分類
- 要約生成
- 表記ゆれ統一
- 感情分析
- レポート生成
実装のポイント
1. Ollamaをインストール 2. VBAからHTTPリクエスト 3. エラーハンドリング 4. バッチ処理で効率化
注意点
注意点
- 大量データは分割処理
- キャッシュを活用
- エラーハンドリング必須
- 結果は必ず確認
関連記事
