【Access VBA】Outlookの指定フォルダ配下のメールをPCの指定フォルダに保存する

【Access VBA】Outlookの指定フォルダ配下のメールをPCの指定フォルダに保存する

Outlookの指定フォルダ配下のメールをPCの指定フォルダに保存する

この記事では、Microsoft Access上で利用可能な「SaveMailItemBodyFromOutlookFolder」というユーザー定義関数について紹介します。

この関数を「MakeFolderNameTableForOutlook」と合わせて Access 内のマクロ内に数行追加して呼び出すことで、Outlookの指定フォルダ内のメールを、PCの指定フォルダに簡単に保存できます。

しかもこの記述の中に利用者個人のアカウント名、フォルダの絶対パス名等を記述する必要がないため、これらの関数を使って作成したOutlookメールの保存ツールのチーム内での横展開も簡単です。

この情報が読者の皆様のお役に立てることを願っています。

解決できること

毎日、Microsoft Outlookのメールを手動保存し、売上やプロジェクトの管理表等を更新するのは、本当に面倒ですよね。

こうした作業を行うために部下の方や、派遣社員の方にこうした作業を任せている方も多いのではないでしょうか。

でもそれって本来かけなくていい、時間やコストをかけているのではありませんか?

この記事では、Microsoft Accessで利用できる「SaveMailItemBodyFromOutlookFolder」という優れたユーザー定義関数をご紹介します。

この関数を「MakeFolderNameTableForOutlook」と合わせて Access の autoexec マクロ内に数行追加して呼び出すことで、自動的にOutlookの指定入力フォルダ内の全てのメールを%USERPROFILE%からの相対パスで指定されたWindowsフォルダに保存し、更に必要に応じてそれらのメールをOutlookの指定出力フォルダに移動するツールを数分で作成することができます。

そして作成したこのツールをタスクスケジューラ等から自動起動されるバッチファイルから呼び出すことで、Microsoft Outlookのメールの保存作業を自動化し、劇的に時間やコストの効率化を図れます。

是非ご利用を検討ください。

【Access VBA】Outlookのフォルダ名を保存するテーブルを自動生成する

読んでほしい方

この記事では、Access VBAでツールの開発をしている方や、業務効率化や費用削減を推進されている方に向けMicrosoft Outlookのメールの自動保存ツール作成方法に関する情報を提供しています。

特に、ツールを第三者に提供する際に利用者の環境差分を Access VBAや、マクロの中に記述したく無い方には、必見の内容です。

この関数を「MakeFolderNameTableForOutlook」と合わせて Access の autoexec マクロ内に数行追加して呼び出すことで、自動的にOutlookの指定入力フォルダ内の全てのメールを%USERPROFILE%からの相対パスで指定されたWindowsフォルダに保存し、更に必要に応じてそれらのメールをOutlookの指定出力フォルダに移動するツールを柔軟性や拡張性、保守性の高いツールを数分で作成することができます。

SaveMailItemBodyFromOutlookFolder 関数 の紹介

説明

MakeFolderNameTableForOutlook」を利用して作成した、以下のテーブルを参照して

Outlookの入力フォルダを指定し、そのフォルダ内の全てのメールを%USERPROFILE%からの相対パスで指定された PC のフォルダ配下に 入力フォルダ名 & “_” & メール受信時間 & “.txt” というファイル名で保存します。

更に同様にこのテーブルを参照したOutlookの出力フォルダが指定された場合、これらのメールを指定された出力フォルダに移動します。

【Access VBA】Outlookの指定フォルダ配下のメールをPCの指定フォルダに保存する
MakeFolderNameTableForOutlook で自動作成されたテーブル
【Access VBA】Outlookの指定フォルダ配下のメールをPCの指定フォルダに保存する
指定フォルダに保存されたメール本文
【Access VBA】Outlookの指定フォルダ配下のメールをPCの指定フォルダに保存する
しらかば堂

この関数の利用にあたっては

  • Outlookは起動状態となっていること
  • 対象メールはユーザーが作成したOutlook自身のメール振り分けルールによりこの関数の中で指定する入力フォルダに仕分け保存されていること

が必要です。

つまり受信メールの仕分けは、Outlookの機能を使って前もって行っておきます。また

  • 対象メールの未保存、保存済という状態をOutlook側で確認できること
  • 不測の事態への対応を考慮し、メールそのものはそのままの形で保存する
  • 保存済メールに対して再度保存する等の無駄な処理をしないようにすること

を目的として、対象メールは本文の保存後、オプションで指定する出力フォルダに移動できるようにしています。

出力フォルダ側に移動したメールは他のフォルダ配下のメール同様、Outlookのフォルダの プロパティ>古いアイテムの整理 を使って、一定期間前に受信したメールに対して以下のオプションを選択し、Outlookのメール格納フォルダが無駄に増大し、Outlookがクラッシュしたりしないようにしておきましょう。

  • 古いアイテムを既定の保存フォルダに移動する(F)
  • 古いアイテムを移動する(M)
  • 古いアイテムを削除する(P)
【Access VBA】Outlookの指定フォルダ配下のメールをPCの指定フォルダに保存する
Outlookのフォルダプロパティ設定画面

参照オブジェクト

このユーザー定義関数を利用するためにはこの関数の実行前に

データベースツール > Visual Basic > ツール > 参照設定
で以下の画面を表示し

【Access VBA】Outlookの指定フォルダ配下のメールをPCの指定フォルダに保存する

 

  • Microsoft Office 16.0 Access Database engine
  • Microsoft Outlook 16.0 Object Library
  • Microsoft ActiveX Data Object 6.1 Library

にチェックを入れる必要があります。

利用例

Access のマクロ定義 “autoexec“マクロの中で 以下のように
M0000_Call_MakeFolderNameTableForOutlook” の次に “M0010_Call_SaveMailItemBodyFromOutlookFolder” を実行するようにしておき

【Access VBA】Outlookの指定フォルダ配下のメールをPCの指定フォルダに保存する
autoexec マクロ


M0010_Call_SaveMailItemBodyFromOutlookFolder” の中では

【Access VBA】Outlookの指定フォルダ配下のメールをPCの指定フォルダに保存する
M0010_Call_SaveMailItemBodyFromOutlookFolder マクロ


以下のように

If SaveMailItemBodyFromOutlookFolder("OutLookFolderes","number_info_In","Tools_Data_Temp\accdb","number_info_Out")>0 Then
メッセージボックス ("number_info_In" 配下のメールの保存に失敗しました。,はい,なし) 
If 文の最後


SaveMailItemBodyFromOutlookFolder を “OutLookFolderes“、”number_info_In“、”Tools_Data_Temp\accdb“、”number_info_Out“のようなパラメータを付けて呼び出すようにしておきます。

そして Outlookを起動状態にして

この “autoexec” マクロをダブルクリックして実行すると、Outlook の “number_info_In” 配下の全メールが %USERPROFILE% からの相対パス “Tools_Data_Temp\accdb” 配下にメール本文をテキスト化して格納し、そのメールそのものを Outlook の “number_info_Out” 配下へ移動します。

【Access VBA】Outlookの指定フォルダ配下のメールをPCの指定フォルダに保存する
しらかば堂

メール本文保存先フォルダ名として指定する%USERPROFILE% からの相対パスについては必要に応じて以下の記事を参考にしてください。

【Windows業務効率化】バッチファイルの基本テクニックを知ろう

またこのツールの起動前にOutlookが起動していることを保証するための方法については同様に以下の記事を参考にしてください。

【Windows業務効率化】バッチファイルを使って未起動状態のアプリケーションを自動起動する

引数

属性 入力条件 意味
テーブル名 文字型 必須 MakeFolderNameTableForOutlook で作成された参照テーブルの名前を””で囲んだ文字列で関数のパラメータとして指定します。
Outlook内対象フォルダ名 文字型 必須 Outlook または “OutLookFolderes” テーブルの内容を事前に確認し、メール保存したいOutlook の対象フォルダ名を、””で囲んだ文字列で関数のパラメータとして指定します。
メール本文保存先フォルダ名 文字型 必須 %USERPROFILE% からの相対パスで指定されたメール本文の保存先フォルダ名を””で囲んだ文字列で関数のパラメータとして指定します。
Outlook内移動先フォルダ名 文字型 任意

Outlook または “OutLookFolderes” テーブルの内容を事前に確認し、メール本文保存後のこのメールの移動先Outlookフォルダ名を、””で囲んだ文字列で関数のパラメータとして指定します。

このパラメータはオプション指定であり、指定されなかった場合には対象メールの移動は行いません。

戻り値

意味
0 正常終了
1 異常終了

VBAコード

SaveMailItemBodyFromOutlookFolder

このAccess VBAコードは、Outlookフォルダ内のメールアイテムの本文をテキストファイルに保存する関数です。

この関数のパラメータには、保存するメールアイテムを含む入力フォルダの名前、保存するテキストファイルの出力パス、および必要に応じてメールアイテムを移動する出力フォルダの名前が必要です。

この関数は、指定された入力フォルダ内のすべてのメールアイテムに対して、一意なファイル名を生成し、そのファイルにメールアイテムの本文を書き込み、また出力フォルダが指定された場合、メールアイテムを移動します。

最後にこの関数は成功コード0または失敗コード1を返します。

Function SaveMailItemBodyFromOutlookFolder(ByVal table_name As String, ByVal in_folder_name As String, ByVal out_path As String, Optional ByVal out_folder_name As String) As Integer
    
    ' 成功コードと失敗コードを定数として設定する
    Const C_SUCCESS As Integer = 0
    Const C_FAILURE As Integer = 1
    
    ' 必要な変数を宣言する
    Dim myNamespace As Object
    Dim inFolder As Object
    Dim outFolder As Object
    Dim currentFolder As Object
    Dim mailItem As Object
    
    Dim yyyymmddhhmmss As String
    Dim fullpath As String
    
    Dim mailItemsToProcess As Collection
    Set mailItemsToProcess = New Collection
    
    On Error GoTo ErrorHandler
    
    ' Outlook アプリケーションおよび名前空間オブジェクトを作成する
    Set myNamespace = CreateObject("Outlook.Application").GetNamespace("MAPI")
    
    ' 入力フォルダーをフォルダーパスを解析して取得する
    Set inFolder = getOutlookFolder(table_name, in_folder_name, myNamespace)
    
    ' 出力フォルダーが指定されている場合は取得する
    If Not out_folder_name = "" Then
        Set outFolder = getOutlookFolder(table_name, out_folder_name, myNamespace)
    End If
    
    ' 出力先のパスを設定する
    fullpath = Environ("UserProfile") & "\" & out_path & "\"
    
    ' 処理するメールアイテムのコレクションを作成する
    For Each mailItem In inFolder.Items
        mailItemsToProcess.Add mailItem
    Next mailItem
    
    ' メールアイテムコレクションの各メールアイテムに対して処理を実行する
    For Each mailItem In mailItemsToProcess
        Debug.Print inFolder.Items.Count
        ' メールの送信日に基づいて一意なファイル名を生成する
        yyyymmddhhmmss = in_folder_name & "_" & Format(mailItem.SentOn, "yyyymmddhhmmss")
        
        ' テキストファイルを作成し、メールの本文を書き込む
        Open fullpath & yyyymmddhhmmss & ".txt" For Output As #1
        Print #1, mailItem.Body
        Close #1
        
        ' 出力フォルダーが指定されている場合はメールを移動する
        If Not out_folder_name = "" Then
            mailItem.Move outFolder
        End If
        
    Next mailItem
    
    ' オブジェクトを解放する
    Set mailItem = Nothing
    Set outFolder = Nothing
    Set inFolder = Nothing
    Set myNamespace = Nothing
    
    ' 成功コードを返す
    SaveMailItemBodyFromOutlookFolder = C_SUCCESS
    
ExitFunction:
    Exit Function
    
ErrorHandler:
    Debug.Print Err.Description
    ' エラーが発生した場合はオブジェクトを解放し、失敗コードを返す
    Set mailItem = Nothing
    Set outFolder = Nothing
    Set inFolder = Nothing
    Set myNamespace = Nothing
    
    ' 失敗コードを返す
    SaveMailItemBodyFromOutlookFolder = C_FAILURE
    Resume ExitFunction
    
End Function

SaveMailItemBodyFromOutlookFolderの簡単な説明

 

行番号 説明
1 関数名と関数の戻り値の型(Integer:整数型)、値参照型の入力パラメータtable_namein_folder_nameout_pathout_folder_name の名前、型(String:文字列型)を定義しています。ここに out_folder_name  は省略可能ですが、省略した場合にはメールのOutlookフォルダ間での移動は行いません。
3-5 このプログラムの中で利用する定数C_SUCCESS(0:成功)、C_FAILURE(1:失敗)を定義しています。ここでは66行目、80行目でこの関数の戻り値が 成功か失敗かが明確にわかるように定数定義しています。
7-15

この関数の中で利用される
オブジェクト myNamespaceinFolderoutFoldercurrentFoldermailItem、および
変数  yyyymmddhhmmssfullpath 、および
コレクション mailItemsToProcess の定義をしています。
これらのオブジェクトは Outlook のフォルダ、メールアイテムを扱うのに必要なもので.
変数はPC上の保存先フォルダを扱うのに必要なもの、
コレクションは、関連オブジェクトのグループとしてまとめて操作するときに使うもので、ここでは指定フォルダ配下のメールアイテムをコレクションを使ってグループ化し、Outlookフォルダ間での移動を行っています。

17-18 Outlook アプリケーションと名前空間オブジェクトを作成する。
20 この関数の実行中にエラーが発生したときの例外処理として、exitWithFailure にジャンプします。
25-26

入力フォルダーのフォルダーパスを解析してOutlookのフォルダを取得する。

28-31

出力フォルダーが指定されている場合はそのフォルダーパスを解析してOutlookのフォルダを取得する。

34

出力先PCフォルダの絶対パス名を設定する。

36-39

処理するメールアイテムのコレクションを作成する。

これは、inFolder.Items を直接参照して 41行目以降の処理を実行すると、メールの移動の際にin.Folder.Itemsの内容が変化し、処理が途中で中断してしまうため、この回避処理としてメールアイテムをコレクション化しています。

41-57

メールアイテムコレクションの各メールアイテム本文を元にテキストファイルを作成し、指定PCフォルダに書き込む。
また出力フォルダーが指定されている場合はメールを移動する。

59-69 使用オブジェクトをメモリ解放し、この関数の戻り値に C_SUCCESS(0:成功) を設定して関数を終わります。
71-81 エラーが発声した場合、そのエラー原因をVBEのイミディエイトウインドウに出力し、使用オブジェクトをメモリ解放し、最後にこの関数の戻り値に C_FAILURE (1:失敗) を設定して関数を終わります。
【Access VBA】Outlookの指定フォルダ配下のメールをPCの指定フォルダに保存する
しらかば堂

ご覧頂いているように Outlook のオブジェクト構造はなかなか複雑なので
必要に応じて以下の参考図書を参照されることをお勧めします。

getOutlookFolder

この関数は、Outlookのフォルダーを取得する関数で、入力パラメータとして取得するフォルダーが含まれるテーブル名、フォルダーパス、およびOutlookの名前空間オブジェクトが必要です。

この関数は、指定されたフォルダーパスをバックスラッシュで分割しOutlookの名前空間オブジェクトを使用して、Outlookのフォルダーオブジェクトを取得し、最終的に指定されたフォルダーパスに対応するOutlookフォルダーを返します。

Function getOutlookFolder(ByVal table_name As String, ByVal folder_path As String, ByVal my_name_space As Object) As Object
    
    Dim fullPathOfOutlookFolder As String
    fullPathOfOutlookFolder = getFullPathOfOutlookFolder(table_name, folder_path)
    
    ' フォルダーパスをバックスラッシュで分割する
    Dim strArray() As String
    strArray = Split(fullPathOfOutlookFolder, "\")
    ' フォルダーオブジェクトを取得する
    Dim currentFolder As Object
    Set currentFolder = my_name_space.Folders(strArray(0)).Folders(strArray(1))
    Dim index As Integer
    For index = 3 To UBound(strArray)
        Set currentFolder = currentFolder.Folders.Item(strArray(index))
    Next index
    ' 取得した Outlook フォルダーを返す
    Set getOutlookFolder = currentFolder
End Function

getOutlookFolderの簡単な説明

 

行番号 説明
1 サブルーチン名 getOutlookFolderと値渡型変数 table_namefolder_pathmy_name_space  の名前、型を定義しています。
3-4 入力パラメータ table_name、 folder_path を引数としたgetFullPathOfOutlookFolder  使って folder_path に一致する最初の Outlookフォルダーのフルパス fullPathOfOutlookFolder  を取得します。
6-18  fullPathOfOutlookFolder  をバックスラッシュで分割し、my_name_space で指定されたOutlookのネームスペースを起点として、アカウント名、INBOX名、フォルダを順にたどりOutlookのフォルダオブジェクトを返します。

getFullPathOfOutlookFolder

この関数は、指定されたテーブル名内のレコードを検索し、キーワードに一致するOutlookフォルダーのフルパスを取得する関数です。

この関数は、指定されたテーブル内の各レコードに対し、アカウント名、Inbox名、およびサブフォルダーの数を組み合わせたパスを生成した後、指定されたキーワードがこのパスに含まれるかどうかをチェックします。そして含まれる場合、キーワードに一致する最初のパスを返します。エラーが発生した場合、関数は空の文字列を返します。

Public Function getFullPathOfOutlookFolder(ByVal reference_table_name As String, ByVal key_word As String) As String
    ' 変数を宣言する
    Dim intIndex As Integer
    Dim fullPathOfOutlookFolder As String
    
    ' エラーハンドリング
    On Error GoTo exitWithFailure
    
    ' fullPathOfOutlookFolder変数を初期化する
    fullPathOfOutlookFolder = ""
    
    ' レコードセットオブジェクトを作成し、テーブルを開く
    Dim tableName As New ADODB.Recordset
    tableName.Open reference_table_name, CurrentProject.Connection
    
    ' テーブル内のレコードを検索し、キーワードに一致するパスを取得する
    Do Until tableName.EOF
        ' パスの初期化
        fullPathOfOutlookFolder = tableName!accountName & "\" & tableName!InboxName & "\" & tableName!NumberOfSubFolders
        
        ' サブフォルダの列をループして、レコードを追加する
        For intIndex = 1 To tableName!NumberOfSubFolders
            ' サブフォルダのパスを追加
            fullPathOfOutlookFolder = fullPathOfOutlookFolder & "\" & tableName.Fields("SubFolder" & CStr(intIndex)).Value
            
            ' キーワードが含まれている場合、パスを返してループを終了する
            If InStr(fullPathOfOutlookFolder, key_word) > 0 Then
                getFullPathOfOutlookFolder = fullPathOfOutlookFolder
                Exit Do
            End If
        Next intIndex
    
        ' 次のレコードに移動する
        tableName.MoveNext
    Loop
    
    ' レコードセットを閉じる
    tableName.Close
    
    ' 関数からパスを返す
    Exit Function
   
exitWithFailure:
    ' fullPathOfOutlookFolder変数を返す
    getFullPathOfOutlookFolder = fullPathOfOutlookFolder
End Function

getFullPathOfOutlookFolderの簡単な説明

行番号 説明
1 関数名 getFullPathOfOutlookFolder と関数の戻り値の型(String:文字型)、値渡型変数 reference_table_namekey_word の名前、型を定義しています。
3-4 この関数の中で利用される
変数  intIndexfullPathOfOutlookFolder の定義をしています。

7 エラー発生時のジャンプ先を定義しています。
9-41 DAO(注1)を利用して reference_table_name で指定されたテーブルをオープンし、そのレコードを順に読み出しながら それらを “\” で連結して fullPathOfOutlookFolder を作り、その中に  key_word  で指定されるキーワードの有無を確認して、マッチした最初のfullPathOfOutlookFolder を戻す。
43-46 エラーが発生したら、その時点までのfullPathOfOutlookFolder を戻す。

(注1) DAO(Microsoft Data Access Objects) : ソフトウェアからデータベースへの接続、データの読み書きなどの操作を行うためのプログラム部品およびその呼び出し規約(API)の一つ。マイクロソフト社が提供する同社のデータベースソフト「Microsoft Access」での利用に最適化されている。ソフトウェア開発者はDAOを呼び出して処理を依頼することにより、簡潔なコードでデータベースへのアクセスを実現することができます。

 

まとめ

この記事では、Microsoft Access上で利用可能な「SaveMailItemBodyFromOutlookFolder」というユーザー定義関数について紹介しました。

この関数を「MakeFolderNameTableForOutlook」と合わせて Access 内のマクロ内に数行追加して呼び出すことで、Outlookの指定フォルダ内のメールを、PCの指定フォルダに簡単に保存できます。

しかもこの記述の中に利用者個人のアカウント名、フォルダの絶対パス名等を記述する必要がないため、これらの関数を使って作成したOutlookメールの保存ツールのチーム内での横展開も簡単です。

この情報が読者の皆様のお役に立てると幸いです。

ライブラリ一覧