パスワード別送メールのzipを自動で解凍したい #5

Outlook

さて、前回に引き続きシリーズ5回目、最終回です。いよいよzipを解凍する部分になります。それ以降の部分は簡単なので一気に最後まで行ってしまいましょう。

  1. メール受信時のイベントプロシージャとして記述する
  2. 受信したメールのIDを取得する
  3. パスワード別送の送信元かを判定する
  4. 添付ファイルが含まれているかを判定する
  5. zipファイルであるのかを判定する
  6. メールを含むフォルダを取得する
  7. パスワードメールを特定する
  8. パスワードメールの本文からパスワードを抽出する
  9. 7-zipをコマンドラインで起動してzipをテンポラリに解凍する
  10. 解凍されたファイルを元のメールの添付ファイルとして追加する
  11. 解凍されたファイルをテンポラリから削除する
  12. (必要なら)処理完了のメッセージボックスを表示する

コマンドラインから7-Zipを起動する

パスワードありzipの解凍は7-Zip(64bit)で行います。Windows標準の展開ツールだとSendKeyなど安定性が悪い手法になってしまうので7-Zipをおすすめします。

7-Zipのコマンドとオプションは非常に多いですが、今回使うのはたったの4つです。

<Commands>
e : Extract files from archive (without using directory names)
x : eXtract files with full paths
<Switches>
-o{Directory} : set Output directory
-p{Password} : set Password
-y : assume Yes on all queries

解凍する際には、ディレクトリ構造を保たず解凍先ディレクトリ直下にすべて展開するeコマンドと、ディレクトリ構造を保つxコマンドがあります。メールの添付ファイルにはフォルダは追加できませんので基本的にeコマンドを使います。

使用目的にもよると思いますが、解凍後にフォルダが含まれる場合にパスなしzipとして再圧縮して添付したいなどさらなるひと手間を加えるならxを使用してもよいかもしれません。

今回はeコマンドでやるとして、コマンドプロンプトに渡すべき命令文は以下のようになります。

{7-Zip_directory} e -y -p{Password} -o{Output_directory} {Input_directory}

ということで命令文に必要となるのは、以下の4つです。

  • 7-Zip本体のファイルパス
  • 解凍するZipのファイルパス
  • 解凍先のフォルダパス
  • パスワード文字列

解凍するZipのパスが必要となるので、いったんテンポラリに置いて、処置が終わったら削除するようにするイメージです。

Const ZIP_PATH As String = "D:\tmp000.zip"
Const TGT_PATH As String = "D:\tmp000"
Const EXE_7ZIP As String = "C:\Program Files-Zipz.exe"
tgtMail.Attachments(1).SaveAsFile ZIP_PATH
Dim myWsh  As Object
Set myWsh = CreateObject("WScript.Shell")
Dim myExec  As Object
Dim myCmd As String
If Dir(EXE_7ZIP) &lt;> "" Then
    myCmd = Chr(34) &amp; EXE_7ZIP &amp; Chr(34)
Else
    Exit Sub '7-Zipがインストールされていない場合
End If
    myCmd = myCmd &amp; " e -y -p" &amp; Chr(34) &amp; myPassword &amp; Chr(34)
    myCmd = myCmd &amp; " -o" &amp; Chr(34) &amp; TGT_PATH &amp; Chr(34) &amp; Chr(32) &amp; Chr(34) &amp; ZIP_PATH &amp; Chr(34)
Set myExec = myWsh.Exec("cmd.exe /c """ &amp; myCmd &amp; "")
If (myExec.Status = 2) Then
    Exit Sub 'コマンドプロンプトの実行エラーの場合
End If
Do While (myExec.Status = 0)
    DoEvents '処理実行中の場合は待機
Loop

上記では、仮にテンポラリをDドライブ直下にしていますが、ここは任意に変更して使用してください。

解凍ファイルをメールの添付ファイルとして追加

ここのポイントは1つだけです。
添付ファイルの変更後に上書き保存を実行すること。そうしないと操作結果が破棄されます。

添付ファイルの追加は.Attachments.Addメソッドを使用してください。

Dim tgtFilename As String
tgtFilename = Dir(TGT_PATH & "\*.*", vbNormal)
'tgtMail.Attachments.Remove 1 '必要であればコメントアウトを戻して元ファイルを削除
Do While tgtFilename <> ""
    tgtMail.Attachments.Add TGT_PATH & "\" & tgtFilename
    tgtFilename = Dir()
Loop
tgtMail.Save

一時的に保存したファイルを削除

処理は完了しているので最後にテンポラリへ展開したファイルを削除します。

ファイル操作にはFileSystemObjectライブラリを使用します。ファイルとフォルダーで削除のコマンドが別々であることに注意してください

Dim myFSO As Object
Set myFSO = CreateObject("Scripting.FileSystemObject")
With myFSO
    .DeleteFile ZIP_PATH, True
    .DeleteFolder TGT_PATH, True
End With

まとめ

以上で、パスワード別送のZipを受信時に自動で解凍するためのパーツがすべてそろいました。

意外と大事なポイントが多く含まれていて、

  • CreateObjectによる外部ライブラリの読み込み
  • FileSystemObjectによるファイル操作
  • WScript.Shellによるシェルコマンド操作
  • 正規表現によるパターンマッチング
  • イベントプロシージャ
  • Outlook VBAでのオブジェクト構造

といった感じで、1つ1つ深掘りしがいのある要素ばかりです。

これらの要素をしっかり勉強するだけで、普通の会社で必要なOffice操作はたいてい自分でコーディングできるようになると思います。

ただ、Excel VBAとOutlook VBAでは扱うオブジェクトやプロパティが異なります。すべてを覚えようとすると膨大な量となるので、そこは経験がものを言うところかもしれません。

まずは、今回紹介した要素を組み合わせつつ、実際に使う要件に合わせて改変していくことが最初の第一歩です!

管理人おすすめVBA書籍

すぐれた書籍は他にもたくさんあると思いますが、私のVBA上達にとって最も役に立ったのがこちらの書籍です。

VBA学習に必須の1冊です!

コメント

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