0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Accessをメール検索GUIとして使う】PowerShellでOutlookのメールアイテム一覧をcsvで吐いてAccessに食わせる

Last updated at Posted at 2022-03-20

またまた前回からの続きです。

ExcelのPowerQueryではなくAccessに食わせるようにしました。

Accessの方が楽なので今後はAccessで作り込んでいこうと思います。

PowerShell

前回からの変更点

csv1行目の"TYPE System.Management.Automation.PSCustomObject"を消すようにした

Accessにインポートする際に、1行目の非テーブル行が邪魔なので

image.png

  1. 最初の書き出しをテンポラリーファイルにして
  2. パイプ処理で1行目をスキップして別名保存
  3. テンポラリーファイルを削除

という工程を追加しました。

PowerQueryに食わせる場合でもこの処理をやっておくとクエリの編集で1行目を削除したりフィールド名設定が不要になります。

EntryIDプロパティを追加

Outlookでメールアイテムを開くのに必要なので列を追加

コード:PowerShell

# Outlookのフォルダからメール一覧を作成、CSVに吐き出す

# 参考(Outlook取得):https://www.itlab51.com/?p=6171
# 参考(CSV出力):https://use-computer.net/powershell/powershell-course-5
# 参考(列挙型):https://docs.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_enum?view=powershell-7.2


$oOutlook = New-Object -ComObject Outlook.Application
$oNamespace = $oOutlook.GetNamespace("MAPI")


# フォルダIndexの配列を作成
$arr_oFolders = @(5,6)
#$olFolderInbox = 6 #受信トレイ
#$olFolderSentMail = 5 #送信済みトレイ

# ループ回数の上限を設定(CSVに書き出すメール数)
$LimLoopCnt=10000

# 取得する文字数に制限をかける
$LimLenStr=10000                

# 変数の初期化
$CsvData = @()
$rr=0
 
# $ary_namesの要素を 1 つずつ $oFolder に格納してループする
for($fld = 0; $fld -lt $arr_oFolders.Count; $fld++){
    $oFolder = $oNamespace.GetDefaultFolder($arr_oFolders[$fld])

    # $oFolder内の全アイテムを巡回して1レコードずつCSV出力用の変数に格納していく
    foreach($oItem in $oFolder.Items){
            # 取得する文字数に制限をかける(文字数が多すぎるとセルをはみ出してテーブル構造が崩れるため)
            $Str = $oItem.Body
            $LenStr = ($oItem.Body).Length
            if ( $LenStr -gt $LimLenStr)
                {$Str = $Str.Substring(0,$LimLenStr)}
            
            # 添付ファイルリストを取得
            $attList=""
            foreach($att in $oItem.Attachments){
                $attList += ";" + $att.FileName
            }
            
            # 1レコードずつCSV用の変数につぎ足していく
            $CsvData += [PSCustomObject]@{
                No = $rr+1 # 0始まりのため出力は1始まりにする
                件名 = $oItem.Subject
                本文 = $Str.Replace("`r`n","") #改行殺し
                受信日時 = $oItem.ReceivedTime
                受信者名  =$oItem.To #ReceivedByNameだと自分以外が空白になる
                送信者名  =$oItem.SenderName
                CC = $oItem.CC
                ConversationID = $oItem.ConversationID
                添付ファイル = $attList

            }

            # ループ脱出
            $rr = $rr + 1
            if( $rr -gt $LimLoopCnt){break}
        }

} 

# CSVに吐き出す
$CsvData | ft -AutoSize

$path = "C:\Users\●●●\●●●\"
$tmp = "temp.csv"
$csvName1 = "ol_受信BOX_Items.csv"

#テンポラリーファイル(csv)に書き出す
$CsvData | Export-Csv -Path $path$tmp -Encoding Default

#1行目を消して別名保存する( これ→ "TYPE System.Management.Automation.PSCustomObject")
Get-content $path$tmp | Select-Object -Skip 1 | Set-Content $path$csvName

#テンポラリーファイルを削除する
Remove-Item $path$tmp 

Access

csvを取り込む

PowerShellで吐き出したcsvファイルを選択します。

image.png

image.png

image.png

取り込みできました。
image.png

フォームの作成

最終的には

  • 検索ボックス
  • メール一覧
  • メール詳細

を同時に並べたいところですが、まずは

  • 最低限のフォームを作成
  • 表示中のメールアイテムをOutlookで開く

だけを作ります。

リボンからフォームを作成します。
このボタン1つでフィールドに合わせたフォームが自動生成されます。
(ExcelやOutlookでユーザーフォーム作ろうと思ったらここがもう面倒)

image.png

作成したフォームをデザインビューで開いてボタンを追加します。

image.png

ボタンに適宜名前をつけて、プロパティシートからクリック時イベントを追加します。
image.png

image.png

以下コードを貼り付けます。

コード:Access

GetNamespace("MAPI").GetItemFromID(EntryID)で指定したメールアイテムを表示(Display)するだけの超簡単なコードです。

Option Compare Database
Option Explicit

Private Sub btnアイテムをolで開く_Click()
  Call EntryIDからメールを開く(EntryID.Value)
End Sub

Sub EntryIDからメールを開く(EntryID As String)
  'appOLを呼び出す
  Dim appOL As Outlook.Application
  Set appOL = New Outlook.Application

  Dim objMailItem As MailItem 'GetItemFromIDメソッドでEntryIDからメールアイテムを抽出する
  Set objMailItem = appOL.GetNamespace("MAPI").GetItemFromID(EntryID)
  
  objMailItem.Display
    
  'オブジェクトをNothingしておく
  Set appOL = Nothing
  Set objMailItem = Nothing
    
End Sub

以上です。

残課題

Accessを開いたままPowerShellからcsvを更新したい

csvインポート時に「リンク」を選ぶと、PowerShellでcsvを更新したものがAccess側で自動でテーブルが更新されます。

image.png

が、Accessを開いたままでPowerShellを実行すると

Set-Content : 別のプロセスで使用されているため、プロセスはファイル 'C:\Users\●●●\●●●\ol_受信BOX_Items.csv' にアクセスできません。

とエラーが出ます。

リンクせずに取り込んでおいて、csvを読み直すのは別処理をすればいけるのかな?

メールアイテムの検索クエリを追加していく

クエリでテーブル抽出ができることは既知なので、メールアイテムをOutlookで開くことができるかの確認と、PowerShellの出力にEntryIDが必要と知ることが先だと思い、スモールステップで作りました。

次回は選択クエリの復習も兼ねてここやっていこうかな。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?