Hey, Scripting Guy!

Scripting Guys が皆さんの質問にお答えします

Hey, Scripting Guy!

TechNet コラムへようこそ。このコラムでは、よく寄せられるシステム管理スクリプトに関する質問に Scripting Guys がお答えします。システム管理スクリプトについて質問がある場合は、scripter@microsoft.com (英語のみ) までお送りください。すべての質問に回答することはできないかもしれませんが、可能な限り対応いたします。

詳細情報

Hey, Scripting Guy! カテゴリ別アーカイブ

Hey, Scripting Guy! 日付別アーカイブ

Hey, Scripting Guy! ダウンロード

Spacer

*

1 か月より前に送信した電子メールを保存する方法はありますか

Hey, Scripting Guy! Question

Scripting Guy さん、よろしくお願いします。1 か月より前に送信した送信済みアイテム フォルダのすべてのアイテムを保存する方法はありますか。

-- RS

SpacerHey, Scripting Guy! AnswerScript Center

RS さん、こんにちは。ご質問にお答えしたいと思います。本当に、そう思っています。しかし、このコラムを執筆している Scripting Guy は明日から休暇を取って出掛けます。つまり、彼は Microsoft Corporation の有力で貴重な社員なので、出掛けるまでにしなければならないことが山ほどあります。たとえば、ええと・・・。何でもありません。もうその作業は任せてもらえないのですから。でも、その作業の準備をする必要はあります。やっぱり、今の発言は撤回します。だって、火災が発生したのは本当に彼のせいではないのに、もうその作業を任せてもらえないのですから。それでも、しなければならないことは当然あります。何のことだかわかりますか。そうですねえ。スケジュールは多忙ですが、ご質問にお答えします。次にそのコードを示します。

On Error Resume Next

Const olFolderSentMail = 5
Const olMSG = 3

Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objFolder = objNamespace.GetDefaultFolder(olFolderSentMail)

dtmTargetDate = Date - 30

Set colItems = objFolder.Items
Set colFilteredItems = colItems.Restrict("[CreationTime] <'" & dtmTargetDate & "'")

For Each objMessage In colFilteredItems
    strName = objMessage.Subject
    strName = Replace(strName, ":", "")
    strName = Replace(strName,"/","")
    strName = Replace(strName,"\","")
    strName = Replace(strName,",","")
    strName = Replace(strName, Chr(34),"")
    strName = Replace(strName,Chr(39),"")
    strName = Replace(strName,"?","")

    strName = "C:\Test\" & strName & ".msg"
    objMessage.SaveAs strName, olMSG  
Next

このスクリプトのしくみを説明しましょう (ちなみに、このスクリプトは見た目ほど複雑ではありません。心配しないでください。とても複雑に見える理由をすぐにご説明します)。

ご覧のとおり、まず 2 つの定数を定義しました。それは、(アクセスするメール フォルダ、つまり送信済みアイテム フォルダを表す) olFolderSentMail と、(フォルダに各アイテムを保存する際に使用するファイル形式、つまり Outlook メッセージ形式を表す) olMSG です。その後、Outlook.Application オブジェクトのインスタンスを作成して、MAPI 名前空間にバインドし、次のコード行を使用して送信済みアイテム フォルダに接続しています。

Set objFolder = objNamespace.GetDefaultFolder(olFolderSentMail)

ふう。

最終目標は、送信済みアイテム フォルダに接続した後、1 か月より前 (つまり、ここでは 30 日より前) に送信した各メッセージのコピーを保存することです。メッセージが 1 か月より前に送信したものかどうかは、どのようにして特定できるのでしょうか。実は、非常に簡単に特定できます。必要な作業は、メッセージの CreationTime プロパティを 1 か月前の日付と比較するだけです。CreationTime プロパティの値が比較する日付より小さい場合、そのメッセージは 1 か月より前に送信したものということになります。

もちろん、この処理を行うには、今日から 30 日前の日付を正確に把握する必要があります。さいわい、現在の日付から 30 日を引くだけでこの日付を特定できます。この処理を行うコードを次に示します。

dtmTargetDate = Date - 30

これで、30 日より前に送信したすべての送信済みメール アイテムのコレクションを取得する準備ができました。この処理では、まず、次のコード行を使用して、送信済みアイテム フォルダのすべてのアイテムのコレクションを取得します。

Set colItems = objFolder.Items

その後、次のように、コレクションにフィルタを適用して、CreationTime プロパティが dtmTargetDate 変数の値より以前の (小さい) アイテムにデータを制限します。

Set colFilteredItems = colItems.Restrict("[CreationTime] <'" & dtmTargetDate & "'")

今日のコラムでは Outlook のフィルタ処理については説明しません。詳細については、私たちが執筆した「Microsoft Outlook で電子メール メッセージをフィルタ処理する」という記事を参照してください。ここまでで注意すべき重要なことは、プロパティ名を角かっこで囲み ([CreationTime])、dtmTargetDate 変数は日時値ですが文字列値と同様に処理する必要があるということです。そのため、次のような一風変わった引用符を使用しています。

"[CreationTime] <'" & dtmTargetDate & "'"

これで、(ほとんど) 作業は完了ですが、あと 1 つ残っている作業があります。保存する各ファイルのファイル名として Subject プロパティの値を使用することにしました。これは問題ありませんが、電子メールの件名には、次のように、ファイル名に含めることができない記号 (コロンなど) が含まれていることがよくあります。

RE: The TechNet Script Center

このため、このような無効な記号を削除しないとメッセージを保存できません。どのようにすればこれを実現できるか、ですって。よくぞ聞いてくれました。

まず、コレクション内のすべてのアイテムをループ処理する For Each ループを設定します。そのループでは、Subject プロパティの値を strName という名前の変数に代入します。これを行うのが次の 2 行のコードです。

For Each objMessage In colFilteredItems
    strName = objMessage.Subject

その後、一連の Replace コマンドを使用して、ファイル名の無効な記号を (ここでは) 空文字に置き換えます。たとえば、次のコマンドを実行すると、strName 変数の値からすべてのコロンが削除されます。

strName = Replace(strName, ":", "")

For Each ループをよく見ると、ピリオド、コンマ、単一引用符 (chr(39))、および二重引用符 (chr(34)) を削除するのに同様のコマンドを使用していることがわかると思います。もちろん、有効なファイル名を作成するために削除する必要がある他の記号が含まれていることもあります。その場合、必要に応じて新たな Replace コマンドを追加するかどうかは皆さんにお任せします。

strName 変数の値から無効な記号を削除したら、次のコード行を使用して、新しいファイルのファイル パスを作成します。

strName = "C:\Test\" & strName & ".msg"

この結果、次のようなファイル パスが作成されます (RE の後のコロンが削除されていることに注目してください)。

C:\Test\RE The TechNet Script Center.msg

ここからは、次のように SaveAs メソッドを呼び出し、ファイル パスとファイルの種類 (olMSG 定数) を 2 つのメソッド パラメータとして渡すことでファイルを保存できます。

objMessage.SaveAs strName, olMSG

その後、ループの先頭に戻り、コレクション内の次のアイテムに対して同じ処理を繰り返します。

RS さんのお役に立てばと思います。冗談はさておき、そろそろこのコラムを執筆している Scripting Guy の日課の時間です。そう、他の Scripting Guys と昼食に行くのです。もちろん、きついですよ。でも、だれかがやらなければいけないんです。

: ちなみに、「だれかがやらなければならない」というのは単なる比ゆではありません。少なくとも、だれかが Scripting Guy の Dean Tsaltas と昼食に行かなければならないのです。というのも、彼は、必ず、カード キーか社員食堂までの道を忘れてしまうからです。

場合によっては、その両方を忘れてしまうこともあります。


ページのトップへページのトップへ