Unable to loop correctly

Question:

I am working on assignment to extract emails from the mailbox.

Below are my codes, I am referencing from this case and combine with some other research online:

import win32com.client
import pandas as pd
import os

outlook = win32com.client.Dispatch("Outlook.Aplication").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6).Folders["Testmails"]
condition = pd.read_excel(r"C:UsersAsusDesktopPythonCondition.xlsx", sheet_name = 'endword')
emails = condition.iloc[:,1].tolist()
done = outlook.GetDefaultFolder(6).Folders["Testmails"].Folders["Done"]

Item = inbox.Items.GetFirst()
add = Item.SenderEmailAddress

for attachment in Item.Attachments:
    if any([add.endswith(m) for m in condition]) and Item.Attachments.Count > 0:
       print(attachment.FileName)
       dir = "C:\Users\Asus\Desktop\Python\Output\"
       fname = attachment.FileName
       outpath = os.path.join(dir, fname)
       attachment.SaveAsFile(outpath)
Item.Move(done)

The code above is running, but it only saves the first email attachment, and the other email that matches the condition is not saving.

The condition file is like below, if is gmail to save in file A. But I am not sure if we can do by vlookup in loops.

        mail end  Directory
0      gmail.com  "C:\Users\Asus\Desktop\Output\A\"
1    outlook.com  "C:\Users\Asus\Desktop\Output\A\"
2  microsoft.com  "C:\Users\Asus\Desktop\Output\B\"

Thanks for all the gurus who is helping much. I have edited the codes above but now is facing other issues on looping.

Asked By: mayliew

||

Answers:

Fix Application on Dispatch("Outlook.Aplication") should be double p

On filter add single quotation mark round 'emails'

Example

Filter = "[SenderEmailAddress] = 'emails'"

for loop, you are using i but then you have print(attachment.FileName) / attachment.SaveAsFile

use i for all – print(i.FileName) / i.SaveAsFile or attachment


import win32com.client

Outlook = win32com.client.Dispatch("Outlook.Application")
olNs = Outlook.GetNamespace("MAPI")
Inbox = olNs.GetDefaultFolder(6)

Filter = "[SenderEmailAddress] = '[email protected]'"

Items = Inbox.Items.Restrict(Filter)
Item = Items.GetFirst()

if Item.Attachments.Count > 0:
    for attachment in Item.Attachments:    
        print(Item.Attachments.Count)
        print(attachment.FileName)
        attachment.SaveAsFile(r"C:pathtomyfolderAttachment.xlsx")
Answered By: 0m3r

The 'NoneType' object has no attribute 'Attachments' error means that you’re trying to get attachments from something that is None.

You’re getting attachments in only one place:

for i in Item.Attachments:
    ...

so we can conclude that the Item here is None.

By looking at Microsoft’s documentation we can see that the method…

Returns Nothing if no first object exists, for example, if there are no objects in the collection

Therefore, I’d imagine there’s an empty collection, or no emails matching your filter

To handle this you could use an if statement

if Item is not None:
    for i in Item.Attachments:
        ...
else:
    pass  # Do something here if there's nothing matching your filter
Answered By: Minion3665