Outlook のセキュリティ更新プログラムがリリース

今月提供された月例セキュリティ更新プログラムに Outlook の修正がありました。対象となるバージョンは Outlook 2007/2003/2002 であり、いずれも ATL という技術を使った Outlook の ActiveX コントロールに関する修正です。バージョンごとのセキュリティ更新プログラムのダウンロード リンクは以下の通りです。なお、Outlook 2007 のセキュリティ更新プログラムは、8 月にリリースされた累積的な更新プログラムとファイルがまったく同じです。そのため、KB974489 の修正プログラムが適用済みであれば、このセキュリティ更新プログラムは適用する必要はありません。

また、これらのセキュリティ更新プログラムを適用した後、カスタム フォームに埋め込まれている Outlook View Control が正常に動作しなくなるという問題が発生します。これは、カスタム フォームの表示に使用される FM20.DLL が、更新された Outlook View Control を安全な ActiveX コントロールと認識しないためです。これを回避するには、FM20.DLL を更新する修正プログラムをインストールする必要があります。それぞれのバージョンごとの FM20.DLL の修正プログラムのダウンロード リンクは以下の通りです。

Outlook Express でメッセージのリンクをクリックした際の挙動について

Outlook Express でメッセージのリンクをクリックすると、以下のような挙動になります。

  • ブラウザを起動してから一度も Outlook Express でリンクをクリックしていない場合、新しいウィンドウでリンク先のページが表示されます。
  • Outlook Express で開いたウィンドウが存在する場合、メールのほかのリンクをクリックすると同じウィンドウでリンク先のページが表示されます。

このような挙動となるのは、 Outlook Express で表示した HTML メールのリンクのターゲットとして "_unspecifiedFrame" が指定されているためです。
リンクのターゲットとは、リンクをクリックした際に表示するウィンドウの名前を指定するもので、フレームを使った Web ページで任意のフレームにリンク先のページを表示させるために使用します。たとえば、ページの左側にインデックスのフレームがあり、真ん中に本文の表示を行うフレームがあるようなページでは、インデックスのページのリンクのターゲットとして、本文の表示を行うフレームの名前を指定します。

そして、リンクのターゲットが "_unspecifiedFrame" である場合、そのリンクをクリックすると以下のような動作となります。

  • "_unspecifiedFrame" という名前のウィンドウが存在しない場合、新たにウィンドウが開かれ、そのウィンドウでリンク先のページが表示されます。
  • "_unspecifiedFrame" という名前のウィンドウが存在する場合、そのウィンドウにリンク先のページが表示されます。

このような動作であるため、メールのリンクを最初にクリックしたときには新しいウィンドウで表示され、以降のリンクのクリックでは同じウィンドウで表示されるのです。

残念ながら、この動作を Outlook Express やブラウザの設定によって回避することはできません。また、Shift キーや Ctrl キーを押しながらリンクをクリックしたとしても、ターゲットの指定が変わることはないため、挙動も変わりません。

なお、以下のようにアドレスに入力すると、現在表示されているウィンドウの名前が確認できます。

  javascript:alert(window.name);

また、以下のようにアドレスに入力すると、そのウィンドウは Outlook Express では使われなくなります。

  javascript:window.name = "";

PDF の添付ファイルを直接開こうとすると Adobe Reader がハングアップする

メッセージにて以下のようなご質問をいただきました。


Outlook で受信した PDF のファイルを直接開くと、Adobe Reader がハングアップしてしまいます。
Outlook が添付ファイルを壊すようなことはあるのでしょうか?
送信者も受信者も Outlook を使っており、Adobe Reader のバージョンは 9.0 です。


これは私も経験したことがありますが、このような PDF ファイルも Adobe Reader を先に起動しておけば開けます。Process Monitor で調査を行なったところ、Adobe Reader が以下のファイルにアクセスしようとして、ファイルが存在しない場合に処理が停止していることがわかりました。

C:\Program Files\Adobe\Reader 9.0\Resource\TypeSupport\Unicode\Mappings\win\CP949.txt

そして、ためしに同じフォルダにある CP932.TXT を CP949.TXT としてコピーしたところ、現象が回避できるようになりました。

つまり、Outlook が原因で現象が発生しているということではないと考えられます。

なお、CP932.TXT の内容を確認したところ、http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT とほぼ同一ファイルなので、おそらく正式には http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT の先頭に以下の 1 行を追加したものが正しい CP949.TXT の内容になると思います。

##Adobe File Version: 1.000

自動仕分けのルールで転送するマクロ

コメントで以下のようなご要望をいただきました。


特定の人からメールを受信したら、そのメールを特定フォルダーに移し、カスタムアクションを使って別の人をTOに、もう一人の人をCCに入れ、本文内に"checked"と入力した上で転送する方法はどうやれば良いのでしょうか?


自動仕分けルールの [カスタム アクション] を実装するには C++ などで本格的なプログラミングを行う必要があり、ちょっと敷居が高いと言えます。また、もともとは Exchange クライアントのルールを拡張するためにある機能なので、いずれなくなるかもしれません。
[スクリプト] なら VBA マクロでの実装が可能ですので、マクロによりご要望の動作を実装してみましょう。

自動仕分けルールからスクリプトで呼び出せるようにするには、マクロで定義する Sub プロシージャの引数として MailItem または MeetingItem のいずれかの型の変数を一つだけ指定します。これ以外の型 (例えば Variant や Object) を指定した場合、そのプロシージャはスクリプトで指定することができません。

具体的なマクロのサンプルは後述しますが、その前にやらなければならないことがあります。それは最新の累積的な修正プログラムを適用するということです。Outlook 2007 には POP/IMAP のアカウントでルールにスクリプトを指定した場合にクラッシュするという不具合があり、その不具合は 2009 年 8 月 25 日リリースの Outlook 2007 の累積的な修正プログラムによって修正されています。したがって、POP/IMAP のアカウントでルールにスクリプトを指定する場合は必ずこの修正プログラムを適用してください。

マクロのサンプルは以下の通りです。このプロシージャを定義すると、仕分けルールのアクションで [スクリプト] を指定した場合、[スクリプトの選択] でこのプロシージャが選択できるようになります。

' ここをトリプルクリックでマクロ全体を選択できます。
Sub CustomForwardRule(objItem As MailItem)
    Const TO_ADDRESS = "forwardto@example.com" ' 転送するメッセージの To を指定します。
    Const CC_ADDRESS = "forwardcc@example.com" ' 転送するメッセージの Cc を指定します。
    Dim objFwdItem As MailItem
    Set objFwdItem = objItem.Forward
    objFwdItem.To = TO_ADDRESS
    objFwdItem.CC = CC_ADDRESS
    objFwdItem.Recipients.ResolveAll
    objFwdItem.Body = "checked" & vbCrLf & objFwdItem.Body
    ' 件名など他にも変更するプロパティがある場合は、ここで変更します。
    objFwdItem.Send
End Sub

マクロの登録方法やメニューへの追加について

– 参考リンク
KB306108 Outlook の自動仕訳ウィザードでスクリプトを作成する方法
KB973404 Outlook 2007 修正プログラム パッケージ (Outlook-x-none.msp): 2009 年 8 月 25 日

Outlook の個人用フォルダのサイズをチェックするスクリプト

Outlook の個人用フォルダのサイズがある程度大きくなってくると、Outlook のパフォーマンスに悪影響が発生します。Outlook には古いアイテムの自動整理機能があるため、こちらも使用しているのですが、突発的に大容量のメッセージを受信したような事態には対応ができません。
そのため、定期的にファイル サイズをチェックしているのですが、そのようなチェックを自動化したいと思ったため、スクリプトを作ってみました。

' ここをトリプルクリックでマクロ全体を選択できます。
Option Explicit
Const WARNING_SIZE = 1000000000 ' 警告するサイズを指定します。
Const HKEY_CURRENT_USER = &H80000001
Const MAPI_PROFILE_KEY = "Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles"
Const MAPI_SERVICES_KEY = "9207f3e0a3b11019908b08002b2a56c2"
'
Dim objReg
Dim objFSO
Dim strKey
Dim strDefaultProfile
Dim strProfileKey
Dim strServicesKey
Dim abyStoreUIDs
Dim abyAddrBookUIDs
Dim iCount
Dim i,j
Dim strServiceKey
Dim strPSTPath
Dim abyData
Dim objPSTFile
Dim strWarning
'
' レジストリにアクセスするための WMI の StdRegProv オブジェクトを取得します。
Set objReg = GetObject( "winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
' ファイル情報にアクセスするための FileSystemObject オブジェクトを取得します。
Set objFSO = CreateObject("Scripting.FileSystemObject")
' 既定の MAPI プロファイルの名前を取得します。
objReg.GetStringValue HKEY_CURRENT_USER, MAPI_PROFILE_KEY, "DefaultProfile", strDefaultProfile
' プロファイルの名前からキーの文字列を生成します。
strProfileKey = MAPI_PROFILE_KEY & "\" & strDefaultProfile & "\"
strServicesKey = strProfileKey & MAPI_SERVICES_KEY
' メッセージ ストア プロバイダの ID の一覧を取得します。
objReg.GetBinaryValue HKEY_CURRENT_USER, strServicesKey, "01023d00", abyStoreUIDs
' 警告メッセージを初期化します。
strWarning = ""
' メッセージ ストア プロバイダの ID ごとに処理します。
iCount = (UBound(abyStoreUIDs)+1)/16
For i=0 To iCount-1
    strServiceKey = ""
    ' 16 バイトのバイナリ データを文字列に変換します。
    For j=0 To 15
        strServiceKey = strServiceKey & Right("0" & Hex(abyStoreUIDs(i*16+j)), 2)
    Next
    ' Outlook 2002 の個人用フォルダのパスを取得します。
    objReg.GetStringValue HKEY_CURRENT_USER, strProfileKey & strServiceKey, "001e6700", strPSTPath
    If IsNull(strPSTPath) Then
        ' Outlook 2003 の個人用フォルダのパスを取得します。
        objReg.GetBinaryValue HKEY_CURRENT_USER, strProfileKey & strServiceKey, "001f6700", abyData
        If Not IsNull(abyData) Then
            ' 取得できた場合にはバイナリデータを文字列に変換します。
            strPSTPath = BinaryToUnicodeString( abyData )
        End If
    End If
    If Not IsNull(strPSTPath) Then
        ' ファイルのサイズをチェックします。
        Set objPSTFile = objFSO.GetFile(strPSTPath)
        If objPSTFile.Size > WARNING_SIZE Then
            strWarning = strWarning & objPSTFile.Name & ": " & objPSTFile.Size & " バイト" & vbCrLf
        End If
    End If
Next
'
If strWarning <> "" Then
    MsgBox "以下の個人用フォルダのサイズが大きくなっています。アイテムを削除または移動した後、今すぐ圧縮を実行してサイズを小さくしてください。" _
        & vbCrLf & strWarning, vbCritical, "PST ファイル サイズ チェック"
End If
'
'    バイナリ データを Unicode 文字列に変換する関数です。
'
Function BinaryToUnicodeString( abyData )
    Dim strUnicode
    Dim i
    strUnicode = ""
    ' 2 バイトごとに Unicode 文字に変換します。
    ' 最初のバイトが下位バイト、次のバイトが上位バイトになります。
    For i = 0 To UBound(abyData) Step 2
        strUnicode = strUnicode & ChrW( abyData(i) + abyData(i+1) * &h100 )
    Next
    ' 文字列の中に NULL がある場合は取り除きます。
    BinaryToUnicodeString = Replace( strUnicode, Chr(0), "" )
End Function

マクロの登録方法やメニューへの追加について

新着サポート技術情報を RSS 購読する

メッセージにて以下のようなご質問をいただきました。


Outlookの修正プログラムがリリースされたというような情報はどうやって入手しているのですか?
サポートページでどのように検索すればよいのか教えてください。


私はサポート ページの新着情報については Outlook 2007 の RSS 購読の機能で取得しています。

マイクロソフトのサポート技術情報のサイトでは RSS フィードによって新着情報が提供されているのですが、ホームページの RSS ディレクトリのサポートのカテゴリでは、どういうわけか Outlook 2007 のような最新のバージョンのフィードのリンクがありません。

ただし、実際には提供されており、以下のような手順で Outlook 2007 の RSS 購読に追加することが可能です。

  1. サポート ページの「サポート ライフサイクル – アルファベット順 製品一覧」ページで購読したい製品をクリックします。
  2. 製品のライフサイクルのページが表示されたら、URL の ?p1= や ?C2= の次の数字をメモします。例えば、Outlook 2007 なら 11335 となります。
  3. アドレス バーに以下の文字列を入力します。なお、xxxxx は 2. でメモした数字に置き換えます。

    feed://support.microsoft.com/common/rss.aspx?rssid=xxxxx&ln=ja

  4. Outlook 2007 の RSS 購読のダイアログで適切な設定を行ない、RSS を登録します。

なお、ln=ja を ln=en とすると、英語版の新着サポート技術情報を購読できます。

Outlook や Outlook Express から Hotmail にアクセスできなくなる問題について

これまで、Hotmail では DAV (HTTP) によるアクセスが可能だったのですが、9/1 から DAV によるアクセスができなくなり、Hotmail でのメッセージの送受信できなくなったという方が増えてきています。

DAV アクセスを使用している方にはお知らせのメッセージが送信されており、そのメッセージのリンク先のページの設定にしたがって POP 接続にすれば良いという話なのですが、どうやらそれでもうまくいかないということがあるようです。

今回は Hotmail にアクセスできるための以下の 4 つの方法をそれぞれ説明します。

  1. http://mail.live.com にアクセスする。
  2. Windows Live メールをインストールする。
  3. POP/SMTP サーバーの設定を行なう。(Outlook Express ユーザー向け)
  4. Outlook Connector をインストールする。(Outlook 2007/2003 ユーザー向け)

http://mail.live.com にアクセスする方法

Hotmail はもともと Web メールであるため、Web ブラウザでメッセージの送受信ができます。http://mail.live.com にアクセスすると、サインインの画面になりますので、Windows Live ID に Hotmail のメール アドレスとパスワードを入力してサインインします。もし、MSN のサービスなどで Hotmail とは異なる Windows Live ID を使っているのであれば、それらのサービスでいったんサインアウトしてください。
以降で説明する設定がうまくいかない場合などや、普段使っている PC が使えない場合など、一時的なトラブルにも使える方法です。


Windows Live メールをインストールする方法

マイクロソフトから無償で提供されている Windows Live メールを使うと、Hotmail のアカウントに Outlook Express と同様のアクセスができます。Outlook Express は通常サポートが終了している製品ですし、Windows Vista や Windows 7 では使えません。しかも、Windows 7 にはメールソフトが同梱されないため、一般的には Windows Live メールが今後の Windows 上のメールソフトの主流となる可能性があります。さらに、Windows Live メールには迷惑メール フィルタやカレンダー機能もあります。
したがって、今から Windows Live メールに慣れ親しんでおくというのもお勧めです。

Windows Live メールは以下の URL からダウンロード、インストールできます。Hotmail の設定はメールアドレスとパスワードを入れるだけです。

http://download.live.com/wlmail


POP/SMTP サーバーの設定を行なう方法

Outlook Express を使い続けたいという場合、POP/SMTP サーバーの設定を行なって Hotmail アカウントの送受信をすることもできます。設定手順は Windows Live ヘルプに記載されているのですが、図などがないため若干わかりにくいようです。

図入りの一般的な POP/SMTP サーバーの設定方法が下記のリンクにありますので、まずはこちらを参照してください。

http://support.microsoft.com/kb/880856/ja

その上で、ポイントとなる点を説明します。

  • 手順 3. の表示名にはご自身の名前もしくはニックネームを入力します。
  • 手順 4. の電子メールアドレスには Hotmail のメールアドレスを入力します。
  • 手順 5. の受信メール サーバーには pop3.live.com と入力し、送信メール サーバーには smtp.live.com と入力します。
  • 手順 6. のアカウント名には Hotmail のメールアドレスを入力し、パスワードは Hotmail にサインインするためのパスワードを入力します。また、[セキュリティで保護されたパスワード認証 (SPA) を使用する] がオフになっていることも確認します。

さらに、この設定が終わった後、追加で以下の手順により設定が必要になります。

  1. [インターネット アカウント] ウィンドウの [メール] タブで、上記で追加した Hotmail アカウントをクリックして、[プロパティ] をクリックします。
  2. [詳細設定] タブの [サーバーのポート番号] の下で以下の情報を入力し、[OK] をクリックします。
  • [送信メール (SMTP)] と [受信メール (POP3)] の下にある [このサーバーはセキュリティで保護された接続 (SSL) が必要] チェック ボックスをそれぞれオンにします。
  • [受信メール (POP3)] ボックスに「995」と入力します。
  • [送信メール (SMTP)] ボックスに「587」と入力します。
  • Web 上、携帯電話、または別の電子メール プログラムで Hotmail を使用するときに過去の受信メールを参照できるようにしたい場合は、[配信] の下にある [サーバーにメッセージのコピーを置く] チェック ボックスをオンにします。既定では、Outlook Express でメッセージをコンピューターにダウンロードすると、そのメッセージは Hotmail のサーバーから削除されます。

設定が終わると、[詳細設定] タブの内容は以下のようになります。

hotmail

なお、この方法を使う場合は、以下の点のご注意ください。

  • 前述の通り、[サーバーにメッセージのコピーを置く] をオンにしていない場合、Outlook Express でメッセージをダウンロードすると Hotmail のサーバーから削除されます。
  • [サーバーにメッセージのコピーを置く] をオンにしていたとしても、未読・既読の情報はサーバーとクライアントで同期されません。例えば、Web で読んだメッセージであっても、Outlook Express では未読となります。
  • Hotmail のサーバー上のフォルダにメッセージの振り分けをしている場合、受信トレイ以外のフォルダに振り分けられたメッセージはダウンロードされません。したがって、誤って迷惑メールに振り分けられたメッセージがないかどうかを定期的に Web ページで確認する必要があります。

Outlook Connector をインストールする方法

Outlook 2007 または Outlook 2003 を使っている場合は、Outlook Connector をインストールすることで Hotmail のメッセージにアクセスできます。また、Hotmail の連絡先や Windows Live カレンダーにもアクセスが可能となります。

Outlook Connector は以下の URL からダウンロードできます。

http://www.microsoft.com/downloads/details.aspx?FamilyID=9a2279b1-df0a-46e1-aa93-7d4870871ecf&displaylang=ja

インストール方法などについては、以下の URL に図入りで説明があります。

http://office.microsoft.com/ja-jp/outlook/HA102218231041.aspx?pid=CH100622151041

配信確認通知メッセージなどの差出人の情報を取得するマクロ

コメントで以下のような質問をいただきました。


Outlook2003で開封確認メッセージをありにしてメール送信し、返信された開封確認メールを次のVBAで受け取って内容をファイルに保存したいのですが、
Set myMsg = Application.Session.GetItemFromID(i)
の行で「型が不一致」になってしまいます。通常の受信メールはうまく受け取れます。

…略…

Dim myMsg As Object
に変更するとこの行は通りますが、myMsg.SenderNameやmyMsg.SenderEmailAddressが存在しないプロパティとなってしまいます。この方法では開封確認メールは受け取れないのでしょうか?


開封確認通知や配信確認通知のようなメッセージは、MailItem ではなく ReportItem というクラスのオブジェクトになります。これは、Outlook がこれらのメッセージについては通常のメッセージと異なる処理をが行うためです。

そして、ReportItem に関しては SenderName や SenderEmailAddress というプロパティがないため、このままでは差出人の情報は取得できません。しかし、メッセージのデータとしては存在します。Outlook 2007 では PropertyAccessor によりこれらの情報を取得することが可能なのですが、Outlook 2003 の Outlook Object Model では MAPI プロパティに直接アクセスする方法がないため、ちょっとした工夫が必要となります。

それは、MessageClass を “IPM.Note” にするというものです。MessageClass というプロパティはそのアイテムの種類をあらわすもので、通常のメッセージは “IPM.Note”、開封確認通知は “REPORT.IPM.Note.IPNRN”、配信確認通知は “REPORT.IPM.Note.DR” となっています。そして、このプロパティを変更することにより、アイテムの種類を変更することが可能です。したがって、配信確認通知だった場合には MessageClass を “IPM.Note” に変更することで、差出人の情報を取得することができるようになります。ただし、MessageClass を変更しても、ReportItem のオブジェクトが直ちに MailItem になるわけではないため、改めて EntryID を指定してメッセージのオブジェクトを取得する必要があります。
また、ReportItem の Body プロパティは実際の通知メッセージの本文ではなく、通知メッセージに含まれるプロパティなどによって動的に作成されるものであるため、通常のメッセージにしてしまうと Body が空になってしまいます。そこで、Body については “IPM.Note” を設定する前にあらかじめ取得しておき、”IPM.Note” に変更後に改めて Body に設定しなおす必要があります。
さらに、MessageClass を変更後、そのままにしてしまうと、Outlook が行なうはずの確認通知メッセージに対する処理が実行されなくなり、送信済みアイテムの [確認] タブで通知状態が追跡できなくなってしまいます。そのため、必要なプロパティの取得が終わったら、元の MessageClass に戻すという処理も必要です。

これらを踏まえて、コメントでいただいたソースコードを修正したものが以下の通りになります。

' ここをトリプルクリックでマクロ全体を選択できます。
'
Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
    Dim myMsg As Object
    Dim i As Integer
    Dim arrEntryId As Variant
    Dim bDelete As Boolean
    Dim fdes As Integer
    Dim strOrgMsgClass As String
    Dim strBody As String
    '
    arrEntryId = Split(EntryIDCollection, ",")
    For i = 0 To UBound(arrEntryId)
        Set myMsg = Session.GetItemFromID(arrEntryId(i))
        ' アイテムが通知メッセージだったら
        If TypeName(myMsg) = "ReportItem" Then
            ' 元のメッセージ クラスを退避
            strOrgMsgClass = myMsg.MessageClass
            ' 元の本文を退避
            strBody = myMsg.Body
            ' メッセージ クラスを "IPM.Note" に変更
            myMsg.MessageClass = "IPM.Note"
            myMsg.Save
            ' メッセージ クラスを変更したアイテムを取得しなおし
            Set myMsg = Session.GetItemFromID(myMsg.EntryID)
            ' 退避した本文を取得したアイテムに設定
            myMsg.Body = strBody
        Else
            strOrgMsgClass = ""
        End If
        fdes = FreeFile()
        Open "c:\temp\受信メール_" & Format(Now, "YYYYMMDD_HHNNSS") & ".txt" For Output As #fdes
        Write #fdes, myMsg.Subject
        Write #fdes, myMsg.CreationTime
        Write #fdes, myMsg.SenderName
        Write #fdes, myMsg.SenderEmailAddress
        Write #fdes, myMsg.Body
        Close #fdes
        If strOrgMsgClass <> "" Then
            ' 退避されたメッセージ クラスの文字列があるなら、メッセージ クラスを元に戻す
            myMsg.MessageClass = strOrgMsgClass
            myMsg.Save
        End If
    Next
End Sub

 

マクロの登録方法やメニューへの追加について

Outlook 2007 の累積的な修正プログラムがリリース

8/26 (米国時間 8/25) に Office 2007 製品の累積的な修正プログラム (以下、CU) がリリースされました。
以下は Outlook 2007 に関連する製品のそれぞれの CU の KB へのリンクです。

973404 Outlook 2007 修正プログラム パッケージ (Outlook-x-none.msp): 2009 年 8 月 25 日
20 弱の不具合が修正されています。

973935 予定表印刷アシスタントの Outlook 2007 修正プログラム パッケージ (none.msp-Cpao-x) の説明: 2009 年 8 月 25 日
ユーザー名に / を含む場合に、/ が 「in」となる不具合が修正されています。日本語版では 「in」ではなく「内に」になりますね。

973401 Word 2007 修正プログラム パッケージ (Word-x-none.msp、none.msp-Wordconv-x): 2009 年 8 月 25 日
Word 2007 の修正ですが、カスタム フォームで署名が追加されない、 右から左に文字が流れるメッセージが正しく表示されないといった Outlook 関連の不具合が修正されています。

なお、その他の Office 2007 製品の今月リリースの累積的な修正プログラムへのリンクは以下の KB で公開されています。

974982 Office 2007 2009年 8 月用の累積的な更新プログラム

件名に含まれるキーワードにより送信警告の表示を制御するマクロ

コメントで以下のようなご要望をいただきました。


会社の環境はOutlook2007なのですが、以前ご紹介いただいた、「メールの宛先を送信前に確認するマクロ」をもう少し進化させる事が出来ないかと思案しております。
このマクロでは、外部ドメインが宛先、CCフィールドに入っているとアラートが出るわけですがこれを、
1) メールタイトルに記載されたキーワードを取り込み
2) このキーワードに対応するメールドメインとは異なる外部ドメインが宛先、CCフィールドに入っている場合にアラートが出る
ようにしたいと思います。
例えば、タイトルに、”【***社様】”と入っている場合には、***社に対応するメールドメイン(@***.co.jp)を事前に指定する事で、@***.co.jp以外の社外ドメインが含まれる場合にアラートを出させたいと思います。
当然、タイトルで検索させる社名分のドメインリストを事前に作って、マクロに貼り付ける必要があるのですが、「どうしても誤送信をしては困る宛先」を数社に絞れば実用可能だと思います。
例えば、前作と組み合わせる事で、
1) ドメインリストに記載がある社名に送信する場合で、異なるドメインが宛先に入っている場合には、大きめのアラートを表示させ
2) タイトルに、【***社】のように指定がない場合には、前作のような外部ドメインが宛先に入っているかどうかだけをチェックさせる
と出来ると思うのですが・・・


このご要望について、以下のような実装を考えました。

  1. メールボックス直下の「DomainList」というフォルダにキーワードと送信可能なアドレスを設定しておき、その設定に基づいてチェックを行なう。
  2. 連絡先の分類項目にキーワードを設定しておき、その設定に基づいてチェックを行なう。

マクロ サンプルは記事の最後に紹介しますが、これを使用するために必要な設定について説明します。

A. ドメイン リストの設定

この設定は、ご要望どおり特定のキーワードを含む件名のメッセージについて、指定されたドメインとは異なるドメインが含まれている場合にダイアログを表示するためのものです。
手順としては、まず、メールボックスの直下に DomainList という名前のフォルダを作成します。
次に、キーワードと送信可能なアドレスをそれぞれ件名と本文に記載した投稿アイテムを DomainList フォルダに保存します。例えば、「Microsoft」というキーワードが含まれる件名のメッセージで「@microsoft.co.jp」および「@microsoft.com」以外のドメインで警告を表示する場合は、以下のような投稿アイテムを DomainList に投稿します。


件名: Microsoft
本文:
*@microsoft.co.jp
*@microsoft.com


ドメインの前に * がついていますが、これはメール アドレスをワイルドカードを使ってあらわすようにしたためです。これなら、あるドメインの特定のユーザーのみ警告を表示しないというような設定も可能です。
なお、ドメインが複数ある場合には改行で区切ります。

このようなアイテムをキーワードごとに投稿します。

B. 連絡先の分類項目の設定

私としては、Outlook の連絡先も活用したかったので、送信の際に受信者が連絡先に登録されている場合は、その連絡先の分類項目の文字列が件名に含まれているかどうかをチェックし、含まれている場合は警告しないという機能も加えました。

連絡先のアイテムを開き、[分類]-[すべての分類項目] で任意の文字列を追加します。こうすることで、指定した文字列を件名に含むメッセージの場合、その連絡先への送信は警告ダイアログが表示されないようになります。

なお、上記のチェックは社外のアドレスに対してのみ行なわれます。

以下は、サンプルコードです。

' ここをトリプルクリックでマクロ全体を選択できます。
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
    Cancel = CheckRecipients(Item)
End Sub
'
Private Function CheckRecipients(Item As Object) As Boolean
    Const MyDomain = "@example.com" ' 社内扱いするドメインを指定します。
    ' SMTP アドレスを格納する MAPI プロパティの TAG です。URL ではありません。
    Const PR_SMTP_ADDRESS = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E"
    Dim i As Integer
    Dim j As Integer
    Dim strAddress As String
    Dim strExtAddr As String
    If Item.MessageClass Like "IPM.TaskRequest*" Then
        Set Item = Item.GetAssociatedTask(False)
    End If
    ' Phase 1 - 社外のアドレスのみを抽出
    strExtAddr = ""
    For i = 1 To Item.Recipients.Count
        With Item.Recipients.Item(i)
            strAddress = .Address
            If LCase(strAddress) Like "/o=*" Then
                ' アドレスが Exchange アドレスなら、SMTP アドレスを取得
                strAddress = .PropertyAccessor.GetProperty(PR_SMTP_ADDRESS)
            End If
            If Not strAddress Like "*" & MyDomain Then
                strExtAddr = strExtAddr & strAddress & ";"
            End If
        End With
    Next
    ' 社外アドレスが存在する場合のみの処理
    If strExtAddr <> "" Then
        Dim arrAddress
        Dim arrPattern
        Dim fldDomainList 'As Folder
        Dim itmDomain 'As PostItem
        Dim strPrompt As String
        Dim objContacts 'As Folder
        Dim objContact 'As ContactItem
        ' アドレスが ' でくくられていたら削除
        If strExtAddr Like "'*'" Then
            strExtAddr = Mid(strExtAddr, 2, Len(strExtAddr)-2)
        End If
        ' 社外アドレスを配列に格納
        arrAddress = Split(strExtAddr, ";")
        strExtAddr = ";" & strExtAddr
        ' Phase 2 - ドメイン リストのチェック
    ' DomainList フォルダを取得
        Set fldDomainList = Session.GetDefaultFolder(olFolderInbox).Parent.Folders("DomainList")
        For Each itmDomain In fldDomainList.Items
            ' DomainList のアイテムの件名がメッセージの件名に含まれていた場合
            If InStr(Item.Subject, itmDomain.Subject) > 0 Then
                ' アイテムの本文を改行で分割し、アドレス パターンを取得
                itmDomain.BodyFormat = olFormatPlain
                arrPattern = Split(itmDomain.Body, vbCrLf)
                ' 受信者のアドレスとアドレス パターンの照合
                For i = 0 To UBound(arrAddress) - 1
                    For j = 0 To UBound(arrPattern)
                        ' アドレス パターンと一致するアドレスは社外アドレスから除外
                        If arrAddress(i) Like arrPattern(j) Then
                            strExtAddr = Replace(strExtAddr, ";" & arrAddress(i) & ";", ";")
                            Exit For
                        End If
                    Next
                Next
                ' アドレス パターンに一致しないアドレスが存在した場合
                If strExtAddr <> ";;" Then
                    strPrompt = String(54, "*") & vbLf & "このメッセージの件名には「" & itmDomain.Subject _
                        & "」が含まれていますが、このキーワードでは以下のアドレスは許可されていません。[OK] をクリックすると送信します。" _
                        & Replace(strExtAddr, ";", vbLf) & String(54, "*")
                    If MsgBox(strPrompt, vbOKCancel + vbExclamation) = vbCancel Then
                        CheckRecipients = True ' 送信しない
                    Else
                        CheckRecipients = False ' 送信する
                    End If
                Else
                    CheckRecipients = False ' 送信する
                End If
                ' ドメイン リストが合致したら以降の処理は行なわない
                Exit Function
            End If
        Next
        ' Phase 3 - 受信者ごとの分類項目チェック
        ' 連絡先フォルダを取得
        Set objContacts = Session.GetDefaultFolder(olFolderContacts)
        For i = 0 To UBound(arrAddress) - 1
            ' 受信者のアドレスを連絡先から検索
            Set objContact = objContacts.Items.Find("[Email1Address] = '" & arrAddress(i) _
                & "' or [Email2Address] = '" & arrAddress(i) _
                & "' or [Email3Address] = '" & arrAddress(i) & "'")
            If Not objContact Is Nothing Then
                ' 連絡先アイテムが存在したら、分類項目をチェック
                If objContact.Categories <> "" Then
                    ' 分類項目を配列に格納
                    arrPattern = Split(objContact.Categories, ", ")
                    For j = 0 To UBound(arrPattern)
                        ' 分類項目を件名に含む場合は社外アドレスから除外
                        If InStr(Item.Subject, arrPattern(j)) > 0 Then
                            strExtAddr = Replace(strExtAddr, ";" & arrAddress(i) & ";", ";")
                            Exit For
                        End If
                    Next
                End If
            End If
        Next
        ' 連絡先がない、もしくは分類項目の文字列が件名にないアドレスが存在した場合
        If strExtAddr <> ";;" Then
            strPrompt = "このメッセージには以下の社外アドレスが含まれています。[OK] をクリックすると送信します。" & Replace(strExtAddr, ";", vbLf)
            If MsgBox(strPrompt, vbOKCancel + vbExclamation) = vbCancel Then
                CheckRecipients = True ' 送信しない
                Exit Function
            End If
        End If
    End If
    CheckRecipients = False ' 送信する
End Function

マクロの登録方法やメニューへの追加について