【ExcelVBA・マクロ】Slackへ自動通知する方法|Incoming WebhookでVBAからメッセージを送信する【コピペOK】

ExcelVBA

Excelでの集計作業やバッチ処理が終わったタイミングで、離席していても結果をすぐに知りたいことはありませんか。この記事では、ExcelVBAとSlackの「Incoming Webhook」を組み合わせて、マクロの処理結果をSlackへ自動通知する方法を解説します。WinHTTPを使ったJSON送信の書き方から、実務で使えるエラー通知の実装例まで、コピペで動かせるコードを紹介します。

スポンサーリンク
スポンサーリンク

Slack Incoming Webhookを準備する

まず、SlackのメッセージをVBAから送信するために「Incoming Webhook」というURLを発行します。これはSlack側が用意しているシンプルなAPIで、決められたURLにJSON形式のデータをPOSTするだけでメッセージが投稿される仕組みです。

  1. Slackの管理画面から「App管理」を開き、「Incoming Webhooks」を検索してワークスペースに追加する
  2. 通知を送信したいチャンネルを選択する
  3. 発行された「Webhook URL」(https://hooks.slack.com/services/~から始まるURL)をコピーする

このURLは一種のパスワードのような役割を持つため、VBAコードに直接書き込む場合はブックの配布範囲に注意してください。共有ブックで使う場合は、URLをレジストリや別ファイルから読み込む形にするとより安全です。

VBAからSlackへメッセージを送信する基本コード

Slackへの通知には、Excel VBAから外部サイトへHTTPリクエストを送れるWinHttp.WinHttpRequestオブジェクトを使います。以下が最もシンプルな送信コードです。

Sub SendSlackMessage()

    Dim webhookUrl As String
    Dim jsonBody As String
    Dim http As Object

    webhookUrl = "https://hooks.slack.com/services/XXXX/XXXX/XXXXXXXXXXXX"

    jsonBody = "{""text"":""Notification from Excel VBA""}"

    Set http = CreateObject("WinHttp.WinHttpRequest.5.1")

    With http
        .Open "POST", webhookUrl, False
        .SetRequestHeader "Content-Type", "application/json"
        .Send jsonBody
    End With

    If http.Status = 200 Then
        MsgBox "Slackへの通知に成功しました。"
    Else
        MsgBox "送信に失敗しました。ステータスコード:" & http.Status
    End If

    Set http = Nothing

End Sub

jsonBodyには送信するメッセージ本文をJSON形式で組み立てます。ダブルクォートを""と二重にしているのは、VBAの文字列リテラル内でダブルクォートをエスケープするための書き方です。送信後、http.Statusが200であれば送信成功と判定できます。ただし、このコードのように.Sendに文字列をそのまま渡すと、日本語部分がシステムの既定の文字コードで送信されてしまい、Slack側では文字化けします。日本語を送る場合は次の章の方法でUTF-8に変換する必要があります。

日本語や改行を含むメッセージを送る

Slack通知では、日本語メッセージや複数行のメッセージを送りたい場面が多くあります。改行はJSON内では\nで表現する必要があり、さらに日本語を文字化けさせずに送るには、送信データをUTF-8のバイト列に変換してから送信する必要があります。VBAのStrConv関数はシステムの既定の文字コード(日本語Windowsでは通常Shift-JIS)に変換するため、UTF-8への変換には使えません。そこで、ADODB.Streamを使ってUTF-8のバイト列に変換する関数を用意します。

Sub SendSlackReportMessage(processName As String, rowCount As Long, isSuccess As Boolean)

    Dim webhookUrl As String
    Dim jsonBody As String
    Dim messageText As String
    Dim statusText As String
    Dim http As Object

    webhookUrl = "https://hooks.slack.com/services/XXXX/XXXX/XXXXXXXXXXXX"

    If isSuccess Then
        statusText = "✅ 正常終了"
    Else
        statusText = "❌ エラー終了"
    End If

    messageText = statusText & vbLf & _
                  "処理名:" & processName & vbLf & _
                  "処理件数:" & rowCount & "件" & vbLf & _
                  "実行日時:" & Format(Now, "yyyy/mm/dd hh:nn:ss")

    ' JSON内の改行は\nに、ダブルクォートは\"に置換する
    jsonBody = Replace(messageText, vbLf, "\n")
    jsonBody = "{""text"":""" & jsonBody & """}"

    Set http = CreateObject("WinHttp.WinHttpRequest.5.1")

    With http
        .Open "POST", webhookUrl, False
        .SetRequestHeader "Content-Type", "application/json; charset=utf-8"
        .Send ToUTF8Bytes(jsonBody)
    End With

    Set http = Nothing

End Sub

Private Function ToUTF8Bytes(text As String) As Byte()

    Dim stream As Object
    Set stream = CreateObject("ADODB.Stream")

    stream.Type = 2 ' adTypeText
    stream.Charset = "UTF-8"
    stream.Open
    stream.WriteText text
    stream.Position = 0
    stream.Type = 1 ' adTypeBinary
    stream.Position = 3 ' 先頭のBOM(3バイト)を読み飛ばす
    ToUTF8Bytes = stream.Read
    stream.Close

    Set stream = Nothing

End Function

ToUTF8Bytes関数では、ADODB.Streamオブジェクトの文字コードをUTF-8に指定してテキストを書き込み、バイナリとして読み直すことでUTF-8のバイト列を取得しています。先頭の3バイトはUTF-8のBOM(バイト順マーク)なので、Position = 3で読み飛ばしている点がポイントです。この関数を経由して送信することで、日本語を含むメッセージでも文字化けを防げます。呼び出す側はCall SendSlackReportMessage("月次集計処理", 128, True)のように、処理名・件数・成否を渡すだけで通知文が自動的に組み立てられます。

長時間のマクロにエラー通知を組み込む

大量データを処理するマクロほど、エラーで途中停止しても気づきにくいものです。On Errorと組み合わせて、エラー発生時に自動でSlackへ通知する仕組みを作っておくと安心です。

Sub RunLongProcessWithNotification()

    On Error GoTo ErrHandler

    Dim i As Long
    For i = 2 To 10000
        Cells(i, 1).Value = Cells(i, 1).Value * 1.1
    Next i

    Call SendSlackReportMessage("単価一括更新処理", 9999, True)
    Exit Sub

ErrHandler:
    Call SendSlackReportMessage("単価一括更新処理", i, False)
    MsgBox "エラーが発生したため処理を中断しました:" & Err.Description

End Sub

これにより、正常終了時だけでなくエラーで処理が止まった場合にも、担当者がExcelを開いていなくてもSlackで異常を把握できます。

まとめ

Slack Incoming Webhookを使えば、ExcelVBAに数行のコードを追加するだけで、処理結果や異常終了をリアルタイムに通知できます。特に夜間バッチや定期実行マクロでは、処理が終わったかどうかをExcelを開いて確認する手間がなくなり、業務効率が大きく向上します。まずはシンプルなテキスト送信から試し、慣れてきたら処理件数やエラー内容を含めたレポート通知へと発展させてみてください。

スポンサーリンク
スポンサーリンク
ExcelVBA
シェアする
いがぴをフォローする

コメント

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