0
0

PyWin32 の Outlook でフォルダ内のメールが処理できない問題を解決する

Posted at

今回は PyWin32 の Outlook で、特定のフォルダ内にあるすべてのメールが処理できず、半分のメールしか処理できない問題を解決できた忘備録として記事を投稿します。

今回使用するコードと実行例

下書きボックスの中にある python_drafts に存在するメールをすべて削除済みアイテムボックスの中にある python_deleted に移動するというソースコードを想定します。

今回の特定のフォルダのメールをすべて移動させることを例に挙げておりますが、移動させることに限らず、フォルダ内のメールすべてに対して~~するという処理に対応します。

main.py
import win32com.client

outlook = win32com.client.Dispatch('Outlook.Application').GetNamespace('MAPI')
draft = outlook.GetDefaultFolder(16) # 16: 下書き
deleted = outlook.GetDefaultFolder(3) # 3: 削除済みアイテム

draft_folders = draft.Folders
deleted_folders = deleted.Folders

def delete_drafts():
    Draft_Folder = draft.Folders("python_draft")
    Deleted_Folder = deleted.Folders("python_deleted")
    i = 1 # カウンタ
    for item in Draft_Folder.Items:
        print(f"のこり {len(Draft_Folder.Items)} 件: {i} 件目メール破棄しました")
        item.Move(Deleted_Folder)

if __name__ == "__main__":
    delete_drafts()

実行結果

$ python main.py 
のこり 3 件: 1 件目メール破棄しました
のこり 2 件: 2 件目メール破棄しました

実行前
bad-1.png

実行後
bad-2.png

本来はメールが3件消えてほしいのですが、2件しか移動されず、どうしても1件残ってしまっています。

原因と対策

項目が頭から順次処理されることにより Draft_Folder.Items(フォルダ内のメールの集合)が減少するため、半分(奇数の場合は半分-1)のメールが残ってしまいます。そこで、For 文を逆順で回すことによって、Draft_Folder.Items を頭から処理するのではなく末尾から処理することにより、すべてのメールを削除することが可能になります。

解決したプログラムコード

逆順で処理する(Items コレクションの末尾から処理する)ことによって、特定のフォルダ内のすべてのメールに対して処理を行うことができました。
具体的には、Draft_Folder.Itemsreversed() 関数を用いて reversed(Draft_Folder.Items) とすることによって逆順の動作を実現しました。

解決したソースコード

main.py
import win32com.client

outlook = win32com.client.Dispatch('Outlook.Application').GetNamespace('MAPI')
draft = outlook.GetDefaultFolder(16) # 16: 下書き
deleted = outlook.GetDefaultFolder(3) # 3: 削除済みアイテム

draft_folders = draft.Folders
deleted_folders = deleted.Folders

def delete_drafts():
    Draft_Folder = draft.Folders("python_draft")
    Deleted_Folder = deleted.Folders("python_deleted")
    i = 1 # カウンタ
    for item in reversed(Draft_Folder.Items): # ここで reversed 関数を使用する
        print(f"のこり {len(Draft_Folder.Items)} 件: {i} 件目メール破棄しました")
        item.Move(Deleted_Folder)

if __name__ == "__main__":
    delete_drafts()

実行結果

$ python main.py
のこり 3 件: 1 件目メール破棄しました
のこり 2 件: 2 件目メール破棄しました
のこり 1 件: 3 件目メール破棄しました

実行前
bad-1.png

実行後
good-1.png

きちんとすべてのメールが処理されています。

参考文献

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