我正在寻找一些帮助和指导与Python脚本,因为我在我的智慧结束试图让它工作。
在某些情况下,每天早上都会有一封电子邮件从一个指定的电子邮件地址发来,里面有一个Excel附件。我的工作要求我打开Excel附件,删除第一行和所有空行,然后用新文件名将附件保存到一个新位置。
上周脚本99%的工作,它做的一切,但会损坏Excel文件的过程中-抛出以下错误:
https://i.stack.imgur.com/kwess.png
https://i.stack.imgur.com/aZIZF.png
更糟糕的是,我花了一个星期左右的时间中断这个脚本,因为我无法理解它--尽管没有任何代码更改,但脚本现在抛出了以下错误:
“* 第112行,在电子邮件_项目=共享_收件箱.项目.限制(文件““,第2行,在限制pywintypes.com中_错误:(-2147352567,'发生异常。',(4096,'Microsoft Outlook','条件无效。',无,0,-2147352567),无)*”
import win32com.client
import datetime
import os
import openpyxl
# 'medocc_path' is a variable containing the path of the MedOCC shared drive folder.
medocc_path = r"S:\File\Path"
# Get the previous day's date in the format yyyymmdd which is required for
# job 'MFT_DW - MedOCC', represented by variable {yesterday}.
yesterday = (datetime.datetime.now() - datetime.timedelta(days=1)).strftime("%Y%m%d")
# Define a function to check for Excel attachments to remove the first row and all blank rows.
def process_excel_attachment(file_path):
# Save the attachment to a temporary folder
temp_path = os.path.join(os.getcwd(), "temp")
if not os.path.exists(temp_path):
os.makedirs(temp_path)
temp_file = os.path.join(temp_path, os.path.basename(file_path))
with open(file_path, "rb") as f:
data = f.read()
with open(temp_file, "wb") as f:
f.write(data)
# Open the workbook and process it
workbook = openpyxl.load_workbook(temp_file)
sheet = workbook.active
# Remove first row and blank rows
sheet.delete_rows(1)
counter = 0 # Initialize counter to zero
for row in sheet.iter_rows():
if all(cell.value is None for cell in row):
sheet.delete_rows(row[0].row)
# Subtract 1 from counter to account for deleted row
counter -= 1
# Remove all filters and freezed rows
sheet.auto_filter.ref = None
sheet.freeze_panes = None
# Apply filter and freeze to the first row
first_row = next(sheet.iter_rows(min_row=1, max_row=1))
for cell in first_row:
if cell.value:
col_letter = cell.column_letter
values = [
sheet.cell(row=row, column=cell.column).value
for row in range(2, sheet.max_row + 1)
if sheet.cell(row=row, column=cell.column).value
]
sheet.auto_filter.ref = f"{col_letter}1:{col_letter}{sheet.max_row}"
sheet.auto_filter.add_filter_column(cell.col_idx, values)
sheet.column_dimensions[cell.column_letter].auto_size = True
sheet.freeze_panes = "A2"
# Remove all blank rows
for row in sheet.iter_rows(min_row=2):
if all(cell.value is None for cell in row):
sheet.delete_rows(row[0].row)
# Remove the temporary file
os.remove(temp_file)
# Return the processed workbook
return workbook
# Connect to Outlook
print("Connecting to Outlook...")
outlook = win32com.client.Dispatch("Outlook.Application.16").GetNamespace("MAPI")
# Open the shared inbox
print("Opening inbox...")
try:
shared_inbox = outlook.Folders.Item(
"TEAM"
).Folders.Item("Inbox")
print("Successfully connected to shared inbox")
except:
print("Error: Failed to connect to shared inbox")
# Search for emails from specific senders in the past 5 days
email_senders = [
"email1@email.net",
"email2@email.net",
"email3@email.net",
]
# Define a time frame of the past 5 days
start_time = (datetime.datetime.now() - datetime.timedelta(days=5)).strftime(
"%m/%d/%Y %I:%M %p"
)
end_time = datetime.datetime.now().strftime("%m/%d/%Y %I:%M %p")
# Update date format to match Outlook's format
start_time = datetime.datetime.strptime(start_time, "%m/%d/%Y %I:%M %p").strftime("%m/%d/%Y %I:%M %p")
end_time = datetime.datetime.strptime(end_time, "%m/%d/%Y %I:%M %p").strftime("%m/%d/%Y %I:%M %p")
# Check if the medocc_path folder exists
if not os.path.exists(medocc_path):
print(f"Error: The folder {medocc_path} does not exist.")
exit()
# Define a flag to check if an email with attachment has been found
email_with_attachment_found = False
for sender in email_senders:
print(f"Searching for emails from sender '{sender}' in the past 5 days...")
# Get the email items from the past 5 days
email_items = shared_inbox.Items.Restrict(
f"[ReceivedTime] >= '{start_time}' AND [ReceivedTime] <= '{end_time}' AND ([SenderName] = 'Person1' OR [SenderName] = 'Person2' OR [SenderName] = 'Person3') AND (SUBJECT LIKE '%type 3%')"
)
# Sort the email items by ReceivedTime in descending order
email_items.Sort("[ReceivedTime]", True)
email_item = None # default value
# Process only the most recent email
if len(email_items) > 0:
email_item = email_items[0]
print("Processing email with subject:", email_item.Subject)
# Set the flag to True if an email with attachment has been found
if email_item.Attachments is not None and email_item.Attachments.Count > 0:
email_with_attachment_found = True
# Iterate over the attachments
for attachment in email_item.Attachments:
if attachment.FileName.endswith(".xlsx"):
print(
"Found Excel attachment with filename",
attachment.FileName,
"from sender",
sender,
"with subject:",
email_item.Subject,
)
# Save the attachment temporarily...
temp_path = os.path.join(os.getcwd(), "temp")
if not os.path.exists(temp_path):
os.makedirs(temp_path)
temp_file = os.path.join(temp_path, attachment.FileName)
attachment.SaveAsFile(temp_file)
# Process the attachment
workbook = process_excel_attachment(temp_file)
# Remove the temporary file
if os.path.exists(temp_file):
os.remove(temp_file)
# Save the processed workbook to the MedOCC folder
new_file_name = os.path.join(medocc_path, f"MedOCC_{yesterday}.xlsx")
workbook.save(new_file_name)
# Check if the file has been saved in the path
if os.path.exists(new_file_name):
print("Attachment processed and saved as:", new_file_name)
else:
print(
"Error: The file could not be saved in the folder", medocc_path
)
# Print a message if no email with attachment is found from the current sender
if not email_with_attachment_found:
print(
f"No emails found from sender '{sender}' with the specified attachment file name in the past 5 days."
)
else:
email_with_attachment_found = False
else:
print("No email found.")
如果有人有空闲时间可以回顾一下脚本/澄清我所面临的错误,我将非常感激。
我试着提示ChatGPT提供答案,但似乎没有一个能修复脚本。
1条答案
按热度按时间mzaanser1#
首先,您需要确保日期-时间比较字符串的格式符合Microsoft Outlook的要求,请使用
Format
函数(或编程语言中的等效函数)。下面的VBA示例创建一个Jet筛选器,以查找在2022年6月12日当地时间下午3:30之前修改过的所有联系人:在搜索条件行中,最后一个检查看起来未知:
如果需要将
Subject
属性包括在搜索条件中,则需要使用方括号:在Jet查询中,只能对keywords属性执行短语匹配。不能对Jet查询执行开头为或子字符串匹配。要克服使用Jet查询语法的关键字限制的限制,请使用允许开头为或子字符串限制的DASL语法。例如:
因此,如果您想在搜索字符串中包含短语匹配搜索,则需要使用如上所示的DASL语法重写它。
第二步,获取
Inbox
文件夹,如下所示:使用
Namespace
类的GetDefaultFolder方法。该方法返回一个Folder对象,表示当前配置文件所请求类型的默认文件夹;例如,获取当前登录用户的默认日历文件夹。此外,您可能会发现Store.GetDefaultFolder方法很有用。它返回
Folder
对象,该对象表示存储中的默认文件夹,并且具有FolderType
参数指定的类型。此方法类似于NameSpace
对象的GetDefaultFolder
方法。不同之处在于,此方法获取与帐户关联的传递存储上的默认文件夹。而NameSpace.GetDefaultFolder
返回当前配置文件的默认存储上的默认文件夹。