マクロの記録を卒業しよう。本文から「特定の文字」を抜き出し、件名を自動書き換えする極限の第一歩
こんにちは。自動化の世界へようこそ。
「マクロの記録」機能を使って、ボタン一つで定型文を入力したり、フォルダを移動したりできるようになると、少しだけ魔法使いになったような気分になりますよね。でも、もしあなたが「もっとスマートに、メールの内容を読み取って、自動で仕分けたい」と願うなら、そこには「記録」では決して到達できない領域があります。
それは、「データの中身を理解して、判断する」というステップです。
今日は、初学者が最初にぶつかる壁であり、かつ、ここをマスターすれば業務効率が劇的に変わる「文字列操作」をテーマに、受信メールから「受付番号」を抜き出し、件名を書き換えるテクニックを伝授します。
ここをクリアすれば、Outlook VBAの基本はバッチリですよ。一緒に一歩ずつ進んでいきましょう。
今回のミッション:受付番号を件名に刻印せよ
例えば、あなたの元に以下のようなメールが届くとします。
> 件名: お問い合わせ
> 本文:
> お世話になっております。
> お問い合わせ内容を以下の通り送付します。
> 受付番号:A-12345
> よろしくお願いいたします。
これを手動で「【A-12345】お問い合わせ」と書き換えて管理するのは、あまりにスマートではありません。VBAを使って、本文中の「受付番号:」の直後にある文字列を自動で取得し、件名の先頭に付与する仕組みを作りましょう。
武器となる2つの関数:InStr と Mid
文字列操作の世界には、強力な「コンパス」と「ハサミ」があります。
1. `InStr` 関数(コンパス)
「指定した文字が、何文字目にあるか?」を探し出す関数です。文字列という長い道の中から、目印(ターゲット)の場所を特定します。
2. `Mid` 関数(ハサミ)
「指定した位置から、指定した文字数分だけ切り取る」関数です。コンパスで見つけた場所から、必要な情報だけを綺麗に切り取ります。
この2つを組み合わせることで、「特定のキーワードを探し、その隣にあるデータを取り出す」という高度な動きが可能になります。
実装コード:スマートな件名書き換えマクロ
まずは、現在選択しているメールに対して処理を行う、安全で実践的なコードを見てみましょう。
Sub RewriteSubjectWithReceptionNumber()
Dim objSelection As Outlook.Selection
Dim objItem As Object
Dim mail As Outlook.MailItem
Dim bodyText As String
Dim targetKeyword As String
Dim startPos As Long
Dim receptionNo As String
' 探したいキーワードを設定
targetKeyword = "受付番号:"
' 現在選択されているアイテムを取得
Set objSelection = Application.ActiveExplorer.Selection
' 選択されているアイテムを一つずつ処理
For Each objItem In objSelection
' アイテムが「メール」である場合のみ処理(会議出席依頼などを除外)
If TypeOf objItem Is MailItem Then
Set mail = objItem
bodyText = mail.Body ' メールの本文を取得
' 1. コンパス(InStr)でキーワードの位置を探す
' InStr(検索対象, 検索文字列)
startPos = InStr(bodyText, targetKeyword)
' キーワードが見つかった場合のみ実行
If startPos > 0 Then
' 2. ハサミ(Mid)で番号を切り出す
' キーワードの長さ分だけ後ろにずらし、そこから10文字分を抜き出す
' ※番号の長さが可変の場合は、さらに工夫が必要ですが、まずは基本形から
receptionNo = Mid(bodyText, startPos + Len(targetKeyword), 7)
' 前後の余計な空白や改行を掃除(トリミング)
receptionNo = Trim(receptionNo)
' 3. 件名を書き換える
' 元の件名の先頭に【番号】を付与
mail.Subject = "[" & receptionNo & "] " & mail.Subject
' 【重要】変更を保存する
' これを忘れると、メモリ上では変わっても、実際のメールには反映されません
mail.Save
Debug.Print "成功: " & mail.Subject
Else
Debug.Print "スキップ: キーワードが見つかりませんでした。"
End If
End If
Next objItem
MsgBox "処理が完了しました!", vbInformation
End Sub
アーキテクトの視点:コードの「肝」を解剖する
このコードには、現場で通用するエンジニアの思考が詰まっています。重要なポイントを解説しますね。
1. なぜ `If TypeOf objItem Is MailItem` が必要なのか?
Outlookの選択範囲には、メールだけでなく「会議の出席依頼」や「タスク」が含まれていることがあります。これらに対して `.Body`(本文)を読み取ろうとすると、プログラムは「そんなプロパティはない!」と怒って止まってしまいます(これを実行時エラーと呼びます)。
「対象が本当にメールかどうか」を確認する。 これは、堅牢なシステムを作る上での鉄則です。
2. `InStr` の戻り値の罠
`InStr` は、キーワードが見つからないとき、`0` を返します。
もし `0` のまま `Mid` 関数に渡してしまうと、プログラムは迷子になりエラーを吐きます。だからこそ、`If startPos > 0 Then` という「条件分岐」で、見つかったときだけ動くようにガードを固めているのです。
3. `mail.Save` の重み
ここが最も大切です。VBAでオブジェクトのプロパティ(`.Subject` など)を書き換えただけでは、それはまだ「作業机の上にあるメモ」に過ぎません。
`.Save` を呼び出すことで、初めて「実物のメール」に書き込みが行われます。自動化エンジニアにとって、「変更を確定させる(Commit)」という意識は極めて重要です。
次のステップへ:さらに進化させるために
このコードは「受付番号が必ず7文字である」という前提で書いています。しかし、実際の業務では番号の長さはバラバラですよね。
もし、番号の後に「改行」が入っているような場合は、以下のような考え方で進化させることができます。
- 改行を探す: `InStr` で「受付番号:」の後ろにある「改行コード(`vbCrLf`)」の位置を探す。
- その間を抜く: 「キーワードの位置」から「改行の位置」までの文字数を計算して `Mid` で切り取る。
これができるようになると、あなたはもう「マクロの記録」を使っているユーザーではなく、「ロジックを組み立てるエンジニア」の仲間入りです。
おわりに
一見難しそうに見える文字列操作も、分解してみれば「探して、切り取る」という単純な作業の組み合わせです。
最初はエラーが出ても、慌てなくて大丈夫。エラーメッセージは、コンピュータがあなたに「ここを直してほしい」と教えてくれているラブレターのようなものです。
一歩ずつ、確実に。あなたの自動化の旅を応援しています!
