Pythonに挑戦#2

お久しぶりです。Crane&I長谷川です。
今回の記事は前回に続く、Pythonに挑戦している記事となります。

前回はPythonの開発環境やインストール方法など環境周りの内容でした。
今回はいよいよPythonのコードの話に移っていきます。

今回Pythonに挑戦するきっかけをおさらいすると、私が働いている職場にてPythonで効率化・自動化してほしいという要望があった為となります。

現在自動化に勤しんでいるのですがその中で知ったことなどを書いていこうかなと思っています。

# 効率化したい内容
私の仕事ではoutlookで他の会社から連絡や依頼を受けることが多く、メールから必要な情報を引っ張ってきてエクセルなどで管理をしております。
メールの件数がすくなければいいのですが、想像以上に来るので時間がものすごくかかってしまいがちです。
※キーボードとマウスを酷使するので、腱鞘炎と指の関節が痛くなります。。。笑

ということで、Pythonで以下の内容を自動化してみました。
* Outlookから条件に当てはまったメールの情報を取得
* 取得した情報をエクセルに1行ずつ書き出す
* エクセルファイルを自動作成し、シート名も変更する。

一旦上記の3つを自動化させてみました。

# コード内容
流石に職場のメールを使うことはできない為、ダミーメールを作成して使います。

まず、取得する対象のメール(ダミー)は以下の通りです。
![テストメール.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3742179/196ee3fd-6cb0-de33-1cb5-87d9420d8c85.jpeg)

よくある形の作業連絡メールです。
※日時はPythonに取り組んでいた時間を記載しているだけとなります。

コードは以下の通り
import win32com.client
import openpyxl
from datetime import datetime
import re
def get_outlook_environment():
    outlook = win32com.client.Dispatch("Outlook.Application")
    namespace = outlook.GetNamespace("MAPI")
    inbox = namespace.GetDefaultFolder(6)  # 6は受信トレイを指します
    today = datetime.now().date()
    messages = inbox.Items
    filtered_messages = []
    for message in messages:
        received_time = message.ReceivedTime
        received_date = received_time.date()
        if received_date == today:
            if "作業連絡" in message.Subject and "以下の作業を行います" in message.Body:
                filtered_messages.append({
                    "subject": message.Subject,
                    "received_time": received_time,
                    "body": message.Body
                })
    return filtered_messages
def extract_data_from_body(body):
    patterns = {
        "日時": r"【日時】：(.+?)\n",
        "作業場所": r"【作業場所】：(.+?)\n",
        "影響区間": r"【影響区間】：(.+?)\n",
        "管理番号": r"【管理番号】：(.+?)\n"
    }
    extracted_data = {}
    for key, pattern in patterns.items():
        match = re.search(pattern, body)
        if match:
            extracted_data[key] = match.group(1).strip()
    return extracted_data
def write_to_excel(messages):
    workbook = openpyxl.Workbook()
    sheet = workbook.active
    sheet.title = "テスト"
    headers = ["件名", "受信日時", "作業日時", "作業場所", "影響区間", "管理番号"]
    sheet.append(headers)
    for message in messages:
        extracted_data = extract_data_from_body(message["body"])
        row = [
            message["subject"],
            message["received_time"].strftime("%Y-%m-%d %H:%M:%S"),
            extracted_data.get("日時", ""),
            extracted_data.get("作業場所", ""),
            extracted_data.get("影響区間", ""),
            extracted_data.get("管理番号", "")
        ]
        sheet.append(row)
    workbook.save("テスト.xlsx")
if __name__ == "__main__":
    messages = get_outlook_environment()
    if messages:
        write_to_excel(messages)
        print("メール情報をエクセルに書き出しました")
    else:
        print("条件に該当するメールを受信していません。")

条件は「件名に作業連絡が含まれていること」且つ「本文に、以下の作業を行いますが含まれていること」
また、Pythonを実行したリアルタイムの日時を自動取得して、同じ日に受領したメールだけを対象としています。
該当するメールが１件でもあれば、件名と本文の情報を取得してエクセルに書き出す。という内容となっています。

一番苦労したのは、本文の内容を取得するところでした。※正規表現に躓きました。

結果は以下の通り。
![結果.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3742179/5590c10e-7ae7-5006-ff44-492560e545b9.jpeg)

ということで無事エクセルに書き出すことはできました。
次はもう少しつっこんだ内容にしたいと思います。
それではまた。