【入門編】【中級者向け】添付ファイル名に特定のキーワードが含まれる場合のみ保存する正規表現活用術 – Outlook VBA解析バイブル

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

【脱・マクロ記録】Outlook VBAを極める:正規表現で添付ファイルを「狙い撃ち」して保存する技術

こんにちは。業務自動化の世界へようこそ。

「マクロの記録」ボタンを押して、なんとか自動化の第一歩を踏み出したあなた。素晴らしい一歩です。でも、実際に動かしてみると、こんな壁にぶつかりませんでしたか?

*「メールに付いているロゴ画像や署名のアイコンまで、全部保存されてしまう……」*
*「ファイル名が『請求書_20231001.pdf』だったり『20231001_見積書.pdf』だったりして、条件分岐が複雑すぎてコードがスパゲッティ状態だ……」*

これらは、あなたが「記録」から「設計」のフェーズへ進むための、いわば卒業試験のようなものです。

今日は、そんな悩みを一撃で解決する「正規表現(Regular Expression)」という強力な武器を、Outlook VBAの中でどう使いこなすか。その極意を伝授します。ここをクリアすれば、あなたの自動化スキルは「単なる作業の代行」から「知的なエージェントの構築」へと進化しますよ。

なぜ「単純な比較」では足りないのか?

通常、ファイル名を判定するとき、多くの人は `If fileName = “請求書.pdf” Then` のような書き方や、`InStr` 関数を使った部分一致を試みます。

しかし、実務のファイル名は、エンジニアの思い通りには動いてくれません。

  • `20231025_請求書_株式会社A.pdf`
  • `【重要】見積書(案).xlsx`
  • `invoice_12345.pdf`

これらすべてに対応しようとすると、`If` 文が延々と続く、読みづらくメンテナンス性の低いコードになってしまいます。

ここで登場するのが正規表現です。正規表現とは、文字列の「パターン」を記述する特殊な言語のこと。これを使えば、「『請求書』か『見積書』という言葉が、ファイル名のどこかに含まれていればOK」というルールを、わずか一行のパターンで表現できるのです。

武器の準備:VBScript.RegExp とは

VBAで正規表現を使うには、Windowsが標準で持っている `VBScript.RegExp` というオブジェクトを利用します。

このオブジェクトには、主に3つの重要なプロパティがあります。

1. Pattern: 「どんな文字列を探すか」というルール(例:`請求書|見積書`)
2. Global: 文書全体を探すかどうか(今回は単一の判定なので `False` でOK)
3. IgnoreCase: 大文字・小文字を区別するかどうか(英語が含まれる場合に重要)

これらを使いこなすことで、ファイル名という「不規則なデータ」を、正確に「狙い撃ち」できるようになります。

実践:添付ファイル・スナイパーの実装

それでは、実際に動くコードを見てみましょう。
このコードは、受信トレイのメールをスキャンし、ファイル名に「請求書」または「見積書」が含まれる添付ファイルだけを、指定したフォルダへ保存するものです。

Option Explicit

''' <summary>
''' 特定のキーワードを含む添付ファイルのみを抽出して保存する
''' </summary>
Sub SaveSpecificAttachments()
    ' --- 設定エリア ---
    Dim savePath As String
    Dim patternString As String
    ' 保存先フォルダ(末尾に必ず \ をつけること)
    savePath = "C:\Users\YourName\Documents\SavedAttachments\"
    ' 正規表現パターン: 「請求書」 または 「見積書」 を含む
    ' | は「または(OR)」を意味する記号です
    patternString = "請求書|見積書"
    ' ------------------

    Dim outlookApp As Outlook.Application
    Dim ns As Outlook.NameSpace
    Dim inbox As Outlook.Folder
    Dim mailItem As Object
    Dim attachment As Outlook.Attachment
    
    ' 正規表現オブジェクト(Late Binding: 参照設定なしで動くように実装)
    Dim regExp As Object
    Set regExp = CreateObject("VBScript.RegExp")
    
    With regExp
        .Pattern = patternString
        .IgnoreCase = True ' 大文字小文字を区別しない
        .Global = False    ' 最初に見つかった時点で判定終了
    End With

    ' Outlookオブジェクトのセットアップ
    Set outlookApp = New Outlook.Application
    Set ns = outlookApp.GetNamespace("MAPI")
    Set inbox = ns.GetDefaultFolder(olFolderInbox)

    ' フォルダが存在するか、書き込み可能かのチェック(実務では必須!)
    If Dir(savePath, vbDirectory) = "" Then
        MsgBox "保存先フォルダが見つかりません: " & savePath, vbCritical
        Exit Sub
    End If

    Debug.Print "--- 処理開始: " & Now & " ---"

    ' 受信トレイのアイテムをループ
    ' ※大量のメールがある場合は、処理時間を考慮して範囲を絞るのがプロの技
    For Each mailItem In inbox.Items
        ' メールアイテム(MailItem)である場合のみ処理
        If TypeOf mailItem Is Outlook.MailItem Then
            
            ' 添付ファイルのループ
            For Each attachment In mailItem.Attachments
                
                ' 【ここが心臓部】正規表現でファイル名を判定
                If regExp.Test(attachment.FileName) Then
                    
                    ' 条件に一致した場合のみ保存
                    Dim fullPath As String
                    fullPath = savePath & attachment.FileName
                    
                    ' 同名ファイルによるエラーを防ぐための処理
                    If Dir(fullPath) <> "" Then
                        fullPath = savePath & Format(Now, "yyyymmddhhmmss_") & attachment.FileName
                    End If
                    
                    attachment.SaveAsFile fullPath
                    Debug.Print "保存成功: " & attachment.FileName
                Else
                    ' 条件に合わないものは無視
                    Debug.Print "スキップ: " & attachment.FileName
                End If
                
            Next attachment
        End If
    Next mailItem

    Debug.Print "--- 処理完了 ---"
    MsgBox "添付ファイルの抽出処理が完了しました。", vbInformation

    ' オブジェクトの解放(メモリリークを防ぐための大切な作法)
    Set regExp = Nothing
    Set ns = Nothing
    Set outlookApp = Nothing
End Sub

コードの解剖図:プロの視点

このコードには、単なる「動くコード」以上の、実務で耐えうるための工夫がいくつか散りばめられています。

1. Late Binding(遅延結合)の採用

`CreateObject(“VBScript.RegExp”)` を使っていますね。これは「参照設定」をあらかじめ行わなくても動く書き方です。他の人にこのツールを配る際、相手の環境で「参照不可エラー」が出るのを防ぐための、配慮の行き届いた設計です。

2. `regExp.Test` メソッドの威力

`If regExp.Test(attachment.FileName) Then`
この一行が、これまでの複雑な `If` 文をすべて飲み込みます。`Test` メソッドは、パターンに一致すれば `True` を、しなければ `False` を返す非常に高速な判定メソッドです。

3. ファイル名の衝突回避

実務では、同じ名前のファイル(例:`請求書.pdf`)が何度も届きます。そのまま `SaveAsFile` すると、上書きされるかエラーになります。
ここでは、既にファイルが存在する場合に、ファイル名の先頭にタイムスタンプ(`yyyymmddhhmmss_`)を付与する処理を入れています。これこそが、「壊れないツール」を作るための思考です。

陥りやすい罠:設計者が気をつけるべき3つのポイント

ここをクリアすれば、あなたも立派な自動化エンジニアです。

1. オブジェクトのライフサイクルを意識せよ
VBAは強力ですが、メモリ管理はあなたの責任です。使い終わった `regExp` や `outlookApp` は、必ず `Set … = Nothing` で解放する癖をつけましょう。大規模なループ処理でこれを怠ると、Outlookが突然落ちる原因になります。

2. 正規表現のパターンは「欲張りすぎない」
パターンを `.*`(何でもあり)のように書きすぎると、意図しないファイルまで拾ってしまいます。「何を含むか」だけでなく、「何を含まないか」を意識することも重要です。

3. エラーハンドリングを忘れない
ネットワークドライブに保存しようとして接続が切れたとき、あるいはファイルが他のプログラムで開かれているとき……。実務では、コードが止まることは「想定内」です。`On Error GoTo …` を使って、エラーが起きてもログを残して次に進む設計を心がけましょう。

おわりに

いかがでしたか?
正規表現をマスターすることは、単にコードを短くすることではありません。「不規則な現実世界を、論理的なルールでコントロールする力」を手に入れることなのです。

最初はパターンを考えるのが難しく感じるかもしれません。でも、一歩ずつ、試行錯誤しながら進んでいけば大丈夫。もし迷ったら、またここに戻ってきてください。

さあ、次はどんな業務を、あなたの魔法(コード)で自動化しましょうか?応援していますよ!

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