無料LLMとエクセル関数で取引データの経費仕訳を自動化する方法!ネット未接続でOK!

無料LLMとエクセル関数で取引データの経費仕訳を自動化する方法!ネット未接続でOK!

取引データの経費仕訳を効率化したい…
そんなときはないでしょうか。

けど、そんな中で悩むことは、

・取引内容に対して適切な勘定科目が分からないので自動判定したいが方法がわからない
・毎回手動で勘定科目を入力するのが面倒で自動化したいが方法がわからない

ですよね。

今回はそんなお悩みを解決する

・ローカルLLMとエクセルVBAを使った勘定科目の自動判定の方法

についてまとめます!

タカヒロ
タカヒロ
確定申告に向けた帳簿の勘定科目の仕分けが非常に面倒でしたのと、今興味があるローカルLLMを活用したいと思い、ちょっと作ってみました。

自動で勘定科目を判定する自動仕分け関数の完成イメージ

自動で勘定科目を判定する自動仕分け関数の完成イメージについて説明します。

例えば、

POINT
「東京ガスガスリヨウキン2024/01」と「支払」という記載から「水道光熱費」と自動で判定される

などの操作が可能です。

自動仕分け関数を入れると、

勘定科目が自動で入ります!

 

タカヒロ
タカヒロ
「収支」列に応じて、無料のローカルLLM(例:LM Studioで動かすGemmaモデル)と通信し、
適切な勘定科目(交通費・通信費・売上など)を自動で返してくれる仕組みです。
ちょっと難しそうですけど、実装はとても簡単ですので説明していきますね!

ローカルLLMとは?

次に無料で利用できるLLMのローカルLLMについて説明をします。

LLM「大規模言語モデル(LLM)」はChatGPTなどが有名ですが、動いている環境はインターネットの先につながっているクラウド上となり、国内のデータセンタもあれば海外もあります。
一方でローカルLLMはその名の通り、自分のパソコンや社内サーバーなどの手元の環境で動作させるLLMのことを指します。

メリットとしては、
インターネット接続が不要なので、外部に情報を送信せずにプライバシーを保護できるほか、
通信遅延が少なく、高速に応答を得やすいです。

ただデメリットもあります。
大きな計算資源(CPUやGPU)やメモリを必要とするモデルが多く、
動作環境の構築や管理がやや難しく、初期投資コストが高くなります。

ローカル環境でLLMを運用することで、業務で使う機密データの取り扱いがよりセキュア(情報漏洩リスク軽減)となり、
またインターネットサービスに依存せずに機器を占有して利用したいケースなどで
大きな利点があるかと思います。

タカヒロ
タカヒロ
取引データや会計情報などの機密情報をインターネット上のLLM(大規模言語モデル)サービスで分析することは、サービス提供元にログとして記録される可能性があるため、セキュリティの観点から避けるべきだと考えています。一方で、AIを活用して分析やアドバイスを受ける流れは今後ますます進んでいくと見込まれているので、そのような場面ではローカル環境で動作するLLMが最適な選択かなと思っています。

エクセルVBAで自動仕訳の関数を作成

まず、エク短オリジナルの自動仕分け関数 ext_keihikoumokuhantei について解説します。

関数名と構文

関数名と構文は以下の通りです。
自動仕分け関数は、取引内容の文字列(例:「〇〇電力」など)と収支(支出、収入)の文字列をもとに、
ローカルで動くLLM(例:Gemma-3-4b-it)にリクエストを送り、返された最適な「勘定科目名」を返します。

関数名

ext_keihikoumokuhantei

構文
ext_keihikoumokuhantei(<取引内容の文字列と収支を指定>)

入力例
例えば以下のように関数を入力すると、

=ext_keihikoumokuhantei(B2 & D2)

取引名と収支の情報を組み合わせて、勘定科目が表示されます。

この関数をつくるためのVBAコードを実装していきます。

以下はコードとなります、

VBAコード

Function ext_keihikoumokuhantei(inputText As String) As String
    Dim objhttp As Object
    Dim strRequestBody As String
    Dim strResponse As String
    Dim apiUrl As String
    Dim jsonResponse As Object
    Dim prompt As String
    Dim categoryList As String
    Dim strMessages As String
    Dim modelName As String
    Dim content As String
    Dim startPos As Long
    Dim endPos As Long

    modelName = "gemma-3-4b-it"

    ' カテゴリ判定
    If InStr(inputText, "支出") > 0 Then
        categoryList = Join(Array("租税公課", "水道光熱費", "交通費", "通信費", "広告宣伝費", _
                                  "接待交際費", "損害保険料", "消耗品費", "福利厚生費", "外注費", _
                                  "利子割引料", "地代家賃", "賃借料", "修繕費", "雑費"), "、")
        prompt = "次の文に基づいて、以下の経費項目の中から最も適切なものを一つ選び、必ず **項目名** を**で囲んで返答してください。書籍支出は「雑費」にしてください。自動車保険は「損害保険料」、食費や文房具購入など不明なものは「雑費」でまとめてください。高速料金/ガソリン/自動車道路料金は「交通費」にしてください。" & vbCrLf & _
                 inputText & vbCrLf & "候補:" & categoryList
    ElseIf InStr(inputText, "収入") > 0 Then
        categoryList = Join(Array("売上", "雑収入"), "、")
        prompt = "次の文に基づいて、以下の収入項目の中から最も適切なものを一つ選び、必ず **項目名** を**で囲んで返答してください。" & vbCrLf & _
                 inputText & vbCrLf & "候補:" & categoryList
    Else
        ext_keihikoumokuhantei = "対象外"
        Exit Function
    End If

    ' エスケープ
    prompt = Replace(prompt, """", "\""")
    prompt = Replace(prompt, vbCrLf, "\n")
    strMessages = "[{""role"": ""user"", ""content"":""" & prompt & """}]"

    apiUrl = "http://127.0.0.1:1234/v1/chat/completions"

    Set objhttp = CreateObject("MSXML2.XMLHTTP")
    With objhttp
        .Open "POST", apiUrl, False
        .setRequestHeader "Content-Type", "application/json"
        strRequestBody = "{""model"":""" & modelName & """, ""messages"":" & strMessages & "," & _
                         """temperature"": 0.7, ""max_tokens"": -1, ""stream"": false}"
        .Send strRequestBody

        If .Status = 200 Then
            strResponse = .responseText
        Else
            ext_keihikoumokuhantei = "HTTPエラー: " & .Status
            Exit Function
        End If
    End With

    content = strResponse

    ' **文字** の中身だけ取り出す
    startPos = InStr(content, "**")
    If startPos > 0 Then
        endPos = InStr(startPos + 2, content, "**")
        If endPos > startPos Then
            ext_keihikoumokuhantei = Mid(content, startPos + 2, endPos - startPos - 2)
        Else
            ext_keihikoumokuhantei = content ' fallback
        End If
    Else
        ext_keihikoumokuhantei = content ' fallback
    End If
End Function

VBAの説明

modelName = "gemma-3-4b-it"
apiUrl = "http://127.0.0.1:1234/v1/chat/completions"

ここで、LM Studio上で起動したローカルLLMとHTTP通信を行っています。
応答は以下のような形式で返り、その中から **水道光熱費** のように囲まれた文字だけを抽出します。

今回Gemma 3 モデルはGoogle の Gemma シリーズの2025年3月時点の最新版となり、 4億のパラメータとなります。
画像を認識するマルチモーダル対応で、多言語の大量のテキスト(128k)解析OKです。またコーディングもすることができる、万能、高性能なモデルとなっています。
また、業務用PCなどGPUがない環境でも、そこそこ動くモデルでもあるので、今ある環境でとりあえず利用してみるには最適かなとおもいます。

ほかのLLMも試してみたいという場合は、
"gemma-3-4b-it"
を別のLLM名にすればOKです。

経費項目の設定(支出の場合)

categoryList = Join(Array("租税公課", "水道光熱費", "交通費", "通信費", "広告宣伝費", _
"接待交際費", "損害保険料", "消耗品費", "福利厚生費", "外注費", _
"利子割引料", "地代家賃", "賃借料", "修繕費", "雑費"), "、")

経費として分類される 15個の勘定科目をカンマ区切りの文字列にして categoryList に格納しています。
これは後ほど LLM に「候補一覧」として提示するために使われます。
もし追加、変更したい場合はこちらを編集してください。

収入項目の設定(収入の場合)

ElseIf InStr(inputText, "収入") > 0 Then
categoryList = Join(Array("売上", "雑収入"), "、")

「収入」という単語が含まれている場合、支出ではなく収入分類だと判定します。
この場合の選択肢は「売上」と「雑収入」の2つのどちらかを選択します。こちらも支出用と同様に追加変更したい場合は、プロンプトを編集してください。

 

VBAの実装手順

実装手順は以下の通りです。

Excel側にVBAを実装していきます。

①Excelを新規に開き、「開発」タブをクリックし、「VisualBasic」をクリックします。
もしくはショートカットキー「Alt」+「F11」でもOKです。

②標準モジュールを追加します。
左ペインのVBAProjectを右クリックし、「挿入」、「標準モジュール」を選択します。

③右ペインのウインドウに上記のVBAを入力します。

こちらで完了です。

ローカルLLMを動かすプラットフォームを実装

ローカルLLMを動かすプラットフォームは
LMStudio
を使用します。

インストール方法など導入手順については以下の記事を参照の上、実装してください。

使用するローカルLLMのモデルは
"gemma-3-4b-it"
となりますので、LMStudioインストール後に、ダウンロードするようお願いします。

使用するサンプルデータ

使用するサンプルデータは以下の通りです。通帳に記載された取引データを想定しています。
これを収支ごとに勘定科目の仕分けをおこないます。

日付 通帳記載名 金額 収支 勘定科目
2024/01/26 東京ガスリヨウキン2024/01 -5884 支出
2024/01/21 ミライヤショテン -3960 支出
2024/01/18 東京電力 -21415 支出
2024/01/14 エネオス-ガソリン -5920 支出
2024/01/12 ETC 首都高速 特別割引 銀座外 東関東道接 -860 支出
2024/01/08 ミツイダイレクトソンガイホケン -33950 支出
2024/01/22 エーカンパニー 36164 収入
2024/01/19 振込 コウコク(カ 270 収入
2024/01/04 アマアマジヤパン(ト 5475 収入

以下のような感じで、エクセルにコピペします。

自動仕分け関数の使い方

では早速実装した自動仕分け関数を使ってみましょう。

  1. ローカルでLMStudioを起動し、モデル gemma-3-4b-it を立ち上げます
  2. APIエンドポイントは http://127.0.0.1:1234 に設定し、APIサーバを有効にしてください
  3. ExcelのVBAに上記関数を貼り付けてあることを確認します。
  4. エクセルの「勘定科目」列に以下のような数式を入力します:
    =ext_keihikoumokuhantei(B2 & D2)

    これは「通帳記載名(B列)」と「収支(D列)」を組み合わせて関数に渡しています。

  5. Enterを押すと、関数がローカルLLMと通信し、最も適切な勘定科目が自動で返ってきます!

1件ができたら、複数行もチャレンジしてみましょう。

関数を下の行にドラッグすると、

はい、複数行まとめて勘定科目が自動で入りました!!

タカヒロ
タカヒロ
若干誤判定しているところがありますが、まあこちらはプロンプトに条件を追加するなりチューニングをしていく必要があります。次に説明していきますね。

自動仕分け関数のチューニング

誤判定しているところを修正するため、プロンプトのチューニングをしてみます。

間違っている仕分け項目を具体的に指定します。

ミライヤショテンは「雑費」
ミツイダイレクトソンガイホケンは「損害保険料」

プロンプト全体は以下の通りです。

        categoryList = Join(Array("租税公課", "水道光熱費", "交通費", "通信費", "広告宣伝費", _
                                  "接待交際費", "損害保険料", "消耗品費", "福利厚生費", "外注費", _
                                  "利子割引料", "地代家賃", "賃借料", "修繕費", "雑費"), "、")
        prompt = "次の文に基づいて、以下の経費項目の中から最も適切なものを一つ選び、必ず **項目名** を**で囲んで返答してください。書籍支出は「雑費」にしてください。ミライヤショテンは「雑費」にしてください。ミツイダイレクトソンガイホケンは「損害保険料」、自動車保険は「損害保険料」、食費や文房具購入など不明なものは「雑費」でまとめてください。高速料金/ガソリン/自動車道路料金は「交通費」にしてください。" & vbCrLf & _
                 inputText & vbCrLf & "候補:" & categoryList

では自動仕分け関数を再度入力してみましょう。

はい、修正されていますね!

さいごに

いかがでしょうか。

今回は、

・ローカルLLMとエクセルVBAを使った勘定科目の自動判定の方法

についてまとめました。

自動仕分け関数により、毎日の仕訳作業を格段に効率化し、
人的ミスも防ぎながら、勘定科目を一貫して扱えるようになります。

ぜひ、LM Studioと組み合わせたこの自動仕訳機能を、
エクセル帳簿に取り入れてみてください!



この記事の関連キーワード

こちらの記事の関連キーワード一覧です。クリックするとキーワードに関連する記事一覧が閲覧できます。







コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA ImageChange Image