Featured image

はじめに:私がPython自動化に目覚めたきっかけ 見出しへのリンク

「毎週金曜日に、20個以上のExcelファイルを開いて、データをコピペして、レポートを作る…」

これが私の3年前の姿でした。毎週3時間かかるこの作業、金曜の午後がほぼ潰れていました。

ある日、同僚が「それ、Pythonで自動化できるよ」と一言。半信半疑で始めたPython学習が、私の仕事を劇的に変えました。あの3時間の作業が、今では3分で終わります。

この記事では、プログラミング未経験だった私が実際に作って使っている自動化スクリプトを10個紹介します。コードの意味も丁寧に解説するので、「なぜそうなるのか」を理解しながら学べます。

自動化で得られた3つのメリット 見出しへのリンク

  1. 時間の節約:週15時間→2時間に削減(月52時間の節約!)
  2. ミスの削減:手作業でのコピペミスがゼロに
  3. 精神的余裕:単純作業から解放され、創造的な仕事に集中できる

必要な環境 見出しへのリンク

1
2
3
4
5
# Pythonのインストール確認
python --version  # Python 3.8以上推奨

# 必要なライブラリのインストール
pip install pandas openpyxl requests pillow

1. 複数のExcelファイルを1つに結合 見出しへのリンク

実体験:25個のExcelファイルと格闘した日々 見出しへのリンク

営業部門から毎月届く25個の地域別売上レポート。これを1つに統合する作業に、以前は毎月2時間かけていました。ファイルを1つずつ開いて、コピー、ペースト…そして必ず起こるミス。「あれ、このデータ、もう入れたっけ?」

このスクリプトを作ってから、2時間→30秒になりました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import pandas as pd
import glob

# すべてのExcelファイルを読み込み
excel_files = glob.glob("*.xlsx")  # *.xlsxは「現在のフォルダのすべての.xlsxファイル」という意味
df_list = []  # データを入れる箱を用意

for file in excel_files:
    df = pd.read_excel(file)  # 1つずつExcelファイルを読み込む
    df['ファイル名'] = file  # どのファイルから来たか記録(重要!後で確認できる)
    df_list.append(df)  # 箱にデータを追加

# 結合して保存
result = pd.concat(df_list, ignore_index=True)  # ignore_index=Trueで連番を振り直す
result.to_excel("統合結果.xlsx", index=False)  # index=Falseで余計な番号列を削除
print(f"✅ {len(excel_files)}個のファイルを結合しました!")

実際に使って分かった3つの注意点 見出しへのリンク

注意点1:列名が統一されていないと失敗する

1
2
3
4
# 解決策:列名を確認して統一する
df = pd.read_excel(file)
df.columns = df.columns.str.strip()  # 前後の空白を削除
df.columns = ['売上', '地域', '日付']  # 列名を強制的に統一

注意点2:空のファイルがあるとエラーになる

1
2
3
# 解決策:空ファイルをスキップ
if not df.empty:  # 空でなければ処理
    df_list.append(df)

注意点3:メモリ不足で落ちることがある 大量のファイル(100個以上)を処理する場合は、チャンク処理が必要です。通常の業務では問題ありませんが、覚えておくと便利です。

このスクリプトが威力を発揮する場面 見出しへのリンク

  • 📊 月次レポートの集計(営業、経理、人事など)
  • 📈 複数店舗のデータ統合
  • 📋 アンケート結果の一括処理
  • 💼 複数部署からのデータ収集

2. Excelデータを自動的にフィルタリング 見出しへのリンク

実体験:10,000行のデータから目視で探していた無駄な時間 見出しへのリンク

経理部門から「今月の高額取引先だけリストアップして」と頼まれた時、Excelのフィルター機能を使って30分かけていました。しかも、フィルター設定を間違えて、やり直し…なんてことも。

今では5秒で完了。しかも条件を変えるのも一瞬です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import pandas as pd

# Excelファイルを読み込み
df = pd.read_excel("売上データ.xlsx")

# フィルタリング条件(例:売上が100万円以上)
filtered = df[df['売上'] >= 1000000]  # 角括弧内が条件式

# 結果を保存
filtered.to_excel("高額売上_抽出結果.xlsx", index=False)
print(f"✅ {len(filtered)}件のデータを抽出しました!")

実務で使える条件式の実例 見出しへのリンク

1. 複数条件(AND条件)

1
2
3
# 売上が100万円以上「かつ」地域が東京
filtered = df[(df['売上'] >= 1000000) & (df['地域'] == '東京')]
# 注意:& の前後に括弧が必要!これを忘れるとエラーになります

2. OR条件

1
2
# 地域が東京「または」大阪
filtered = df[(df['地域'] == '東京') | (df['地域'] == '大阪')]

3. 複数の値を含む条件

1
2
3
# 地域が東京、大阪、名古屋のいずれか
target_areas = ['東京', '大阪', '名古屋']
filtered = df[df['地域'].isin(target_areas)]

4. 文字列を含む条件

1
2
3
# 商品名に「スマホ」を含む
filtered = df[df['商品名'].str.contains('スマホ', na=False)]
# na=False は空欄があってもエラーにならないようにする設定

5. 日付の範囲指定

1
2
3
# 2024年1月のデータだけ
df['日付'] = pd.to_datetime(df['日付'])  # 日付型に変換
filtered = df[(df['日付'] >= '2024-01-01') & (df['日付'] < '2024-02-01')]

私が実際にハマった落とし穴 見出しへのリンク

失敗談1:全角・半角の違いでデータが抽出できない

1
2
3
# これで解決:データを統一してから検索
df['地域'] = df['地域'].str.strip()  # 前後の空白削除
filtered = df[df['地域'].str.contains('東京', regex=False)]

失敗談2:空欄(NaN)でエラーになる

1
2
3
4
# 解決策:空欄を先に処理
df['売上'].fillna(0, inplace=True)  # 空欄を0に置き換え
# または
filtered = df[df['売上'].notna()]  # 空欄じゃないものだけ

3. フォルダ内のファイルを種類別に整理 見出しへのリンク

実体験:デスクトップが書類の山に… 見出しへのリンク

リモートワークが始まってから、ダウンロードフォルダが悲惨なことに。請求書、議事録、スクリーンショット、プレゼン資料…全部が混在して、「あのファイル、どこだっけ?」と毎回5分は探す羽目に。

このスクリプトで、毎朝1クリックで整理整頓。ファイル探しの時間がゼロになりました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import os
import shutil
from datetime import datetime

# 整理したいフォルダのパス
source_folder = "Downloads"  # Macの場合は "/Users/あなたの名前/Downloads"

# ファイルの種類ごとのフォルダ
file_types = {
    '画像': ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg', '.webp'],
    'ドキュメント': ['.pdf', '.docx', '.xlsx', '.pptx', '.txt', '.csv'],
    '動画': ['.mp4', '.avi', '.mov', '.mkv', '.wmv'],
    '音楽': ['.mp3', '.wav', '.flac', '.aac', '.m4a'],
    'プログラム': ['.py', '.js', '.html', '.css', '.java', '.cpp'],
    '圧縮ファイル': ['.zip', '.rar', '.7z', '.tar', '.gz'],
}

# フォルダを作成(exist_ok=True で既存フォルダがあってもエラーにしない)
for folder_name in file_types.keys():
    os.makedirs(os.path.join(source_folder, folder_name), exist_ok=True)

# ファイルを移動
moved_count = 0
for filename in os.listdir(source_folder):
    filepath = os.path.join(source_folder, filename)
    
    # ファイルだけを処理(フォルダは無視)
    if os.path.isfile(filepath):
        file_ext = os.path.splitext(filename)[1].lower()  # 拡張子を小文字で取得
        
        for folder_name, extensions in file_types.items():
            if file_ext in extensions:
                dest = os.path.join(source_folder, folder_name, filename)
                
                # 同名ファイルがある場合はリネーム
                if os.path.exists(dest):
                    name, ext = os.path.splitext(filename)
                    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
                    filename = f"{name}_{timestamp}{ext}"
                    dest = os.path.join(source_folder, folder_name, filename)
                
                shutil.move(filepath, dest)
                print(f"✅ {filename}{folder_name}フォルダ")
                moved_count += 1
                break

print(f"🎉 ファイル整理完了! {moved_count}個のファイルを移動しました")

実際に使って改良したポイント 見出しへのリンク

改良1:同名ファイル対策 最初、同名ファイルがあると上書きされて困りました。タイムスタンプを付けることで解決。

改良2:「その他」フォルダを追加

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 分類できないファイルを「その他」フォルダに
file_types['その他'] = []  # 空リストを追加

# 最後に分類されなかったファイルを処理
for filename in os.listdir(source_folder):
    if os.path.isfile(os.path.join(source_folder, filename)):
        shutil.move(
            os.path.join(source_folder, filename),
            os.path.join(source_folder, 'その他', filename)
        )

改良3:バックアップを取ってから実行 最初の実行前は、必ずバックアップを!私は一度間違えて重要ファイルを動かしてしまいました…

毎朝自動実行する設定 見出しへのリンク

Windows:タスクスケジューラーで毎朝8:00に実行 Mac:Automatorでログイン時に実行

これで「ファイルどこ?」から解放されます。

4. 画像を一括リサイズ 見出しへのリンク

実体験:300枚の写真を1枚ずつリサイズした悪夢 見出しへのリンク

社内イベントの写真300枚を、社内ポータルにアップロードする仕事。「画像サイズは1200px以下で」という指定があり、Photoshopで1枚ずつリサイズ…3時間かかりました。

このスクリプトなら30秒。品質も完璧です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from PIL import Image
import os

# 設定
input_folder = "元画像"
output_folder = "リサイズ済み"
max_width = 1200  # 横幅の最大値(ピクセル)
max_height = 1200  # 高さの最大値

# 出力フォルダ作成
os.makedirs(output_folder, exist_ok=True)

success_count = 0
for filename in os.listdir(input_folder):
    if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):
        try:
            # 画像を開く
            img_path = os.path.join(input_folder, filename)
            img = Image.open(img_path)
            
            # 元のサイズを記録
            original_size = img.size
            
            # アスペクト比を維持してリサイズ
            img.thumbnail((max_width, max_height), Image.LANCZOS)
            
            # ファイル形式に応じた保存
            output_path = os.path.join(output_folder, filename)
            if filename.lower().endswith('.png'):
                img.save(output_path, 'PNG', optimize=True)
            else:
                # JPEGは品質を指定
                img.save(output_path, 'JPEG', quality=85, optimize=True)
            
            print(f"✅ {filename}: {original_size}{img.size}")
            success_count += 1
            
        except Exception as e:
            print(f"⚠️ {filename} の処理に失敗: {e}")

print(f"🎉 {success_count}枚の画像をリサイズ完了!")

実務で役立つ応用例 見出しへのリンク

応用1:ファイルサイズも圧縮

1
2
3
4
5
6
7
# 1MB以下にしたい場合
quality = 85
while True:
    img.save(output_path, 'JPEG', quality=quality)
    if os.path.getsize(output_path) <= 1024*1024:  # 1MB
        break
    quality -= 5  # 品質を下げる

応用2:ウォーターマーク(透かし)を追加

1
2
3
4
5
from PIL import ImageDraw, ImageFont

draw = ImageDraw.Draw(img)
text = "© 2024 Your Company"
draw.text((10, 10), text, fill=(255, 255, 255))

実際にハマった問題と解決策 見出しへのリンク

問題1:HEIC形式(iPhoneの写真)が開けない

1
2
# 解決:pillow-heifをインストール
pip install pillow-heif

問題2:画質が悪くなりすぎる

1
2
# 解決:quality値を上げる(デフォルト75 → 90以上)
img.save(output_path, 'JPEG', quality=95)

5. CSVファイルをExcelに変換(複数シート対応) 見出しへのリンク

こんな時に便利: 複数のCSVファイルを1つのExcelファイルにまとめたい

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import pandas as pd
import glob

# すべてのCSVファイルを取得
csv_files = glob.glob("*.csv")

# Excelファイルを作成
with pd.ExcelWriter("統合データ.xlsx", engine='openpyxl') as writer:
    for csv_file in csv_files:
        # CSVを読み込み
        df = pd.read_csv(csv_file, encoding='utf-8-sig')
        
        # ファイル名からシート名を作成(拡張子を除去)
        sheet_name = os.path.splitext(csv_file)[0][:31]  # Excel制限対応
        
        # シートに書き込み
        df.to_excel(writer, sheet_name=sheet_name, index=False)
        print(f"✅ {csv_file}{sheet_name}シート")

print("🎉 変換完了!")

6. 定期的にWebサイトの情報をチェック 見出しへのリンク

実体験:欲しい商品が「在庫切れ」で買えなかった悔しさ 見出しへのリンク

限定商品の再入荷を待っていたのですが、気づいた時には売り切れ…そんな経験、ありませんか?

このスクリプトで、24時間自動監視。再入荷の瞬間を逃しません。

実際に、PS5の抽選販売開始を5分以内に検知して、無事に購入できました!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import requests
from datetime import datetime
import time

def check_website(url, keyword):
    """
    指定したURLに特定のキーワードが含まれているかチェック
    """
    try:
        # ヘッダーを設定(botと判定されないように)
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        }
        
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()
        
        if keyword in response.text:
            print(f"✅ {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}: '{keyword}' が見つかりました!")
            # ここに通知処理を追加(後述)
            return True
        else:
            print(f"⏳ {datetime.now().strftime('%H:%M:%S')}: まだ '{keyword}' は見つかりません")
            return False
    except Exception as e:
        print(f"⚠️ エラー: {e}")
        return False

# 使用例:5分おきに自動チェック
url = "https://example.com/product"
keyword = "在庫あり"

while True:
    if check_website(url, keyword):
        # 見つかったら音を鳴らす(Windowsの場合)
        import winsound
        winsound.Beep(1000, 1000)  # 1秒間ビープ音
        break
    
    time.sleep(300)  # 5分待機(300秒)

実務での活用例 見出しへのリンク

活用例1:競合他社の価格監視

1
2
3
4
5
6
7
8
9
# 特定の価格以下になったら通知
def check_price(url):
    response = requests.get(url, headers=headers)
    # 価格を抽出(実際のサイト構造に応じて調整)
    price = extract_price(response.text)
    
    if price <= target_price:
        print(f"🎉 目標価格以下! 現在: {price}円")
        return True

活用例2:採用サイトの更新監視

1
2
3
4
5
# 特定企業の求人ページを監視
keywords = ["エンジニア", "募集開始"]
for keyword in keywords:
    if keyword in response.text:
        print(f"✅ 新規求人発見! キーワード: {keyword}")

通知機能の追加 見出しへのリンク

LINE通知を追加

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import requests

def send_line_notify(message, token):
    """LINE Notifyでスマホに通知"""
    url = "https://notify-api.line.me/api/notify"
    headers = {"Authorization": f"Bearer {token}"}
    data = {"message": message}
    requests.post(url, headers=headers, data=data)

# キーワードが見つかったら通知
if check_website(url, keyword):
    send_line_notify("在庫が見つかりました!", "YOUR_LINE_TOKEN")

実際にハマった注意点 見出しへのリンク

注意1:アクセス頻度に気をつける 短時間に何度もアクセスすると、サーバーに負荷がかかります。最低でも1分以上の間隔をあけましょう。

注意2:robots.txtを確認する

1
2
3
4
# 適切なUser-Agentを設定
headers = {
    'User-Agent': 'Mozilla/5.0 ...',
}

注意3:Webサイトの利用規約を確認 自動アクセスが禁止されているサイトもあります。必ず確認してから使用してください。

7. ファイル名を一括変更 見出しへのリンク

こんな時に便利: 大量の写真に連番を付けたい

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import os

folder_path = "写真フォルダ"
prefix = "旅行_"  # 接頭辞
extension = ".jpg"

# ファイル一覧を取得(ソート)
files = [f for f in os.listdir(folder_path) if f.endswith(extension)]
files.sort()

# リネーム
for index, filename in enumerate(files, start=1):
    old_path = os.path.join(folder_path, filename)
    new_filename = f"{prefix}{index:03d}{extension}"  # 001, 002, 003...
    new_path = os.path.join(folder_path, new_filename)
    
    os.rename(old_path, new_path)
    print(f"✅ {filename}{new_filename}")

print(f"🎉 {len(files)}個のファイルをリネーム完了!")

8. Excelの複数シートを個別のファイルに分割 見出しへのリンク

こんな時に便利: 部門ごとのシートを個別のファイルにしたい

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import pandas as pd

# 元のExcelファイル
excel_file = "統合データ.xlsx"

# すべてのシート名を取得
xl_file = pd.ExcelFile(excel_file)

for sheet_name in xl_file.sheet_names:
    # シートを読み込み
    df = pd.read_excel(excel_file, sheet_name=sheet_name)
    
    # 個別のファイルとして保存
    output_file = f"{sheet_name}.xlsx"
    df.to_excel(output_file, index=False)
    print(f"✅ {sheet_name}シート → {output_file}")

print("🎉 すべてのシートを分割完了!")

9. テキストファイルから特定の行を抽出 見出しへのリンク

こんな時に便利: ログファイルからエラー行だけを抽出したい

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import re

def extract_lines(input_file, output_file, keyword):
    """
    テキストファイルから特定のキーワードを含む行を抽出
    """
    matched_lines = []
    
    with open(input_file, 'r', encoding='utf-8') as f:
        for line_num, line in enumerate(f, 1):
            if keyword.lower() in line.lower():
                matched_lines.append(f"[行{line_num}] {line.strip()}")
    
    # 結果を保存
    with open(output_file, 'w', encoding='utf-8') as f:
        f.write('\n'.join(matched_lines))
    
    print(f"✅ {len(matched_lines)}行を抽出しました → {output_file}")
    return len(matched_lines)

# 使用例
extract_lines("log.txt", "error_log.txt", "ERROR")

10. メールで自動レポート送信(Gmail) 見出しへのリンク

こんな時に便利: 毎日の業務レポートを自動送信したい

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from datetime import datetime

def send_email_with_attachment(to_email, subject, body, file_path):
    """
    添付ファイル付きメールを送信
    """
    from_email = "your_email@gmail.com"
    password = "your_app_password"  # Gmailアプリパスワード
    
    # メッセージ作成
    msg = MIMEMultipart()
    msg['From'] = from_email
    msg['To'] = to_email
    msg['Subject'] = subject
    
    # 本文
    msg.attach(MIMEText(body, 'plain'))
    
    # ファイル添付
    if file_path:
        with open(file_path, 'rb') as f:
            attachment = MIMEApplication(f.read())
            attachment.add_header('Content-Disposition', 'attachment', 
                                filename=os.path.basename(file_path))
            msg.attach(attachment)
    
    # 送信
    try:
        with smtplib.SMTP('smtp.gmail.com', 587) as server:
            server.starttls()
            server.login(from_email, password)
            server.send_message(msg)
        print("✅ メールを送信しました!")
    except Exception as e:
        print(f"⚠️ エラー: {e}")

# 使用例
subject = f"日次レポート - {datetime.now().strftime('%Y/%m/%d')}"
body = """
お疲れ様です。

本日のレポートを添付いたします。
ご確認をお願いいたします。
"""

send_email_with_attachment(
    to_email="boss@example.com",
    subject=subject,
    body=body,
    file_path="日次レポート.xlsx"
)

注意: Gmailの場合、2段階認証を有効にして「アプリパスワード」を生成する必要があります。

これらのスクリプトを組み合わせる:真の威力 見出しへのリンク

実体験:バラバラのスクリプトが、完全自動システムに進化した日 見出しへのリンク

最初は個別のスクリプトを手動で実行していました。でも、ある日気づいたんです。

「これ、全部繋げたら、完全自動になるんじゃない?」

そして誕生したのが、私の「毎朝自動レポートシステム」。今では毎朝8:00に自動実行され、9:00には上司のメールボックスに完璧なレポートが届いています。

実例:毎朝の自動レポート作成システム 見出しへのリンク

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
import pandas as pd
from datetime import datetime, timedelta
import glob
import os

def daily_report_automation():
    """
    毎朝の自動レポート作成フルシステム
    所要時間:手動3時間 → 自動3分
    """
    print("📊 レポート作成を開始...")
    start_time = datetime.now()
    
    try:
        # 1. 複数のCSVファイルを結合
        print("⏳ ステップ1: データ収集中...")
        csv_files = glob.glob("data/*.csv")
        if not csv_files:
            print("⚠️ CSVファイルが見つかりません")
            return None
        
        df_list = []
        for f in csv_files:
            try:
                df = pd.read_csv(f, encoding='utf-8-sig')
                df_list.append(df)
                print(f"  ✅ {os.path.basename(f)} を読み込みました")
            except Exception as e:
                print(f"  ⚠️ {f} の読み込みに失敗: {e}")
        
        merged_df = pd.concat(df_list, ignore_index=True)
        print(f"  📋 合計 {len(merged_df)} 件のデータを結合")
        
        # 2. データをフィルタリング(昨日のデータ)
        print("⏳ ステップ2: データフィルタリング中...")
        yesterday = (datetime.now() - timedelta(days=1)).date()
        merged_df['日付'] = pd.to_datetime(merged_df['日付']).dt.date
        filtered_df = merged_df[merged_df['日付'] == yesterday]
        print(f"  ✅ {len(filtered_df)} 件の昨日データを抽出")
        
        # 3. 集計(複数の観点で)
        print("⏳ ステップ3: データ集計中...")
        summary_by_dept = filtered_df.groupby('部門')['売上'].agg(['sum', 'mean', 'count']).reset_index()
        summary_by_dept.columns = ['部門', '合計売上', '平均売上', '件数']
        
        top_products = filtered_df.groupby('商品名')['売上'].sum().sort_values(ascending=False).head(10)
        
        # 4. Excelに出力(複数シート)
        print("⏳ ステップ4: レポート作成中...")
        output_file = f"日次レポート_{yesterday.strftime('%Y%m%d')}.xlsx"
        
        with pd.ExcelWriter(output_file, engine='openpyxl') as writer:
            # サマリーシート
            summary_by_dept.to_excel(writer, sheet_name='部門別サマリー', index=False)
            
            # 商品ランキング
            top_products.to_excel(writer, sheet_name='売上TOP10', header=['売上'])
            
            # 詳細データ
            filtered_df.to_excel(writer, sheet_name='詳細データ', index=False)
            
            # 統計情報
            stats_df = pd.DataFrame({
                '項目': ['総売上', '平均売上', 'データ件数', '対象日'],
                '値': [
                    f"{filtered_df['売上'].sum():,.0f}円",
                    f"{filtered_df['売上'].mean():,.0f}円",
                    f"{len(filtered_df)}件",
                    yesterday.strftime('%Y年%m月%d日')
                ]
            })
            stats_df.to_excel(writer, sheet_name='統計', index=False)
        
        # 5. 処理時間を計算
        elapsed_time = (datetime.now() - start_time).total_seconds()
        print(f"✅ レポート作成完了: {output_file}")
        print(f"⏱️  処理時間: {elapsed_time:.1f}秒")
        
        # 6. メール送信(オプション)
        # send_email_with_attachment(
        #     to_email="boss@example.com",
        #     subject=f"日次レポート {yesterday}",
        #     body="おはようございます。本日のレポートを送付いたします。",
        #     file_path=output_file
        # )
        
        return output_file
        
    except Exception as e:
        print(f"❌ エラーが発生しました: {e}")
        # エラー通知を送信
        # send_error_notification(str(e))
        return None

# 実行
if __name__ == "__main__":
    result = daily_report_automation()
    if result:
        print("🎉 すべての処理が正常に完了しました!")
    else:
        print("⚠️ 処理中にエラーが発生しました")

この組み合わせで得られた効果 見出しへのリンク

Before(手動作業):

  • 毎朝8:00〜11:00:3時間かけてレポート作成
  • ミスのチェックに30分
  • 上司への提出が11:30

After(自動化):

  • 毎朝8:00:自動実行開始
  • 8:03:レポート完成
  • 8:05:上司のメールに自動送信
  • 私:その時間、別の仕事ができる

年間効果:780時間の節約 = 約97営業日分!

Windowsタスクスケジューラーで自動実行 見出しへのリンク

スクリプトを毎日自動実行する設定方法:

1. バッチファイルを作成(run_script.bat) 見出しへのリンク

1
2
3
4
@echo off
cd /d "C:\path\to\your\project"
python daily_report.py
pause

2. タスクスケジューラーに登録 見出しへのリンク

  1. Windowsキー + R → taskschd.msc
  2. 「タスクの作成」をクリック
  3. トリガーで「毎日 8:00」などを設定
  4. 操作で作成した .bat ファイルを指定

これで毎朝自動的にスクリプトが実行されます!

エラーが出た時のチェックポイント:私が実際にハマった問題集 見出しへのリンク

私が最もハマったエラーTOP5 見出しへのリンク

1位:ModuleNotFoundError: No module named 'pandas'

私の失敗談: 最初、「Pythonをインストールしたのになぜ?」と3時間悩みました。Pythonとライブラリは別物だと知らなかったんです…

1
2
3
4
5
# 解決法:ライブラリをインストール
pip install pandas openpyxl

# 確認方法
pip list  # インストール済みライブラリを表示

さらにハマったポイント: 複数のPythonがインストールされていて、違うPythonにpipでインストールしていた…

1
2
3
4
# どのPythonを使っているか確認
python --version
which python  # Mac/Linux
where python  # Windows

2位:FileNotFoundError: [Errno 2] No such file or directory

私の失敗談: 「ファイル、ここにあるのに!」と画面を見ながら叫んでました。原因は、ファイル名の全角スペースと、作業ディレクトリの違い。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 解決法1:絶対パスを使う
import os
file_path = r"C:\Users\YourName\Documents\data.xlsx"  # rを付けると特殊文字を無視
df = pd.read_excel(file_path)

# 解決法2:現在のディレクトリを確認
print("現在のディレクトリ:", os.getcwd())

# 解決法3:ファイルの存在確認を事前に行う
if os.path.exists("data.xlsx"):
    df = pd.read_excel("data.xlsx")
else:
    print("⚠️ ファイルが見つかりません!")
    print("以下のファイルがあります:")
    print(os.listdir("."))  # 現在のディレクトリのファイル一覧

3位:日本語ファイル名で文字化け

私の失敗談: Excelで保存したCSVファイルが、読み込むと全部文字化け。「譛ャ譌・縺ョ繝?繝?繧ソ」って何??

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 解決法:エンコーディングを明示
df = pd.read_csv("data.csv", encoding='utf-8-sig')  # Excel日本語はこれ
# または
df = pd.read_csv("data.csv", encoding='shift-jis')  # 古いExcelの場合

# エンコーディングが分からない時
import chardet
with open("data.csv", 'rb') as f:
    result = chardet.detect(f.read())
    print(result['encoding'])  # 推測されるエンコーディングを表示

4位:Excelが開いていて保存できない

私の失敗談: スクリプトを実行すると「Permission denied」。なぜ?… Excelで開いてました…

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 解決法1:エラーハンドリングを追加
try:
    df.to_excel("output.xlsx")
    print("✅ 保存成功!")
except PermissionError:
    print("⚠️ ファイルを閉じてから実行してください")
    # 別名で保存
    from datetime import datetime
    alt_name = f"output_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
    df.to_excel(alt_name)
    print(f"✅ 別名で保存しました: {alt_name}")

5位:KeyError: '列名'

私の失敗談: 「この列、絶対あるのに!」… 実は前後に空白が入っていました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 解決法1:列名を確認
print(df.columns.tolist())  # すべての列名を表示

# 解決法2:列名の前後の空白を削除
df.columns = df.columns.str.strip()

# 解決法3:列名が存在するか確認してから処理
if '売上' in df.columns:
    print(df['売上'].sum())
else:
    print(f"⚠️ '売上' 列が見つかりません。利用可能な列: {df.columns.tolist()}")

デバッグの極意:私が3年で学んだこと 見出しへのリンク

極意1:エラーメッセージは友達 最後の行を読む → そこにほぼ答えが書いてある

極意2:print()を入れまくる

1
2
print("ここまで実行された")  # どこで止まるか確認
print(f"変数の中身: {variable}")  # 期待と違う値が入っていないか確認

極意3:小さく試す いきなり全部実行せず、1行ずつ確認

極意4:ChatGPTに聞く エラーメッセージをそのままコピペ → ほぼ解決

次のステップ:さらなる自動化 見出しへのリンク

レベルアップのための学習リソース 見出しへのリンク

  1. 公式ドキュメント

  2. 実践練習

    • 自分の業務で繰り返している作業を1つ選ぶ
    • それを自動化するスクリプトを書いてみる
    • 少しずつ機能を追加していく
  3. コミュニティ

    • Stack Overflow(エラー解決)
    • Qiita(日本語の技術記事)
    • GitHub(他の人のコードを参考に)

私の自動化の旅:3年間の振り返り 見出しへのリンク

最初の1ヶ月:失敗の連続 見出しへのリンク

正直に言います。最初は全然うまくいきませんでした。

  • エラーメッセージの意味が分からず、3時間悩んだことも
  • 「これ、手作業でやった方が早いんじゃ…」と何度も思いました
  • 最初に作ったスクリプトは、今見ると穴だらけ

でも、諦めずに続けました。

転機:最初の成功体験 見出しへのリンク

1ヶ月後、最初の自動化(Excelファイル結合)が完成。2時間の作業が30秒になった瞬間、「これだ!」と感じました。

その達成感が、次のスクリプト作成への原動力になりました。

3年後の今:自動化が当たり前の日常 見出しへのリンク

今では、「これ自動化できるな」という視点で仕事を見るようになりました。

具体的な成果:

  • 週の作業時間:15時間削減(年間780時間!)
  • ミス:ほぼゼロ(手作業のヒューマンエラーが消滅)
  • ストレス:激減(単純作業からの解放)
  • 評価:社内で「業務効率化の達人」と呼ばれるように

年間780時間って、**約32日分です。**1ヶ月以上の時間を手に入れた計算になります。

あなたへの3ステップロードマップ 見出しへのリンク

ステップ1:まず1つ、完成させる(目標:1週間) 見出しへのリンク

  • この記事から、自分の仕事に一番近いスクリプトを1つ選ぶ
  • コピペして、とにかく動かしてみる
  • エラーが出ても、諦めずにGoogle検索(「python pandas エラーメッセージ」で検索)

ポイント:完璧を目指さない。動けばOK!

ステップ2:カスタマイズする(目標:2週間) 見出しへのリンク

  • ファイル名を自分の環境に合わせる
  • 条件を変えてみる
  • 少しずつ機能を追加する

このフェーズで本当の理解が深まります。

ステップ3:習慣化する(目標:1ヶ月) 見出しへのリンク

  • 毎日の業務で使ってみる
  • 「これも自動化できるかも?」と考える癖をつける
  • 新しいスクリプトに挑戦する

1ヶ月続けられたら、もう後戻りできません。

初心者がつまずきやすい3つのポイントと解決法 見出しへのリンク

つまずき1:「エラーが出て動かない…」 見出しへのリンク

解決法:

  1. エラーメッセージをよく読む(最後の行が重要)
  2. Google検索:「python [エラーメッセージ] 解決」
  3. ChatGPTに聞く:「このエラーの意味と解決法を教えて」

私の経験:エラーの90%は、ファイル名の間違いかライブラリの未インストールです。

つまずき2:「自分の環境に合わせる方法が分からない」 見出しへのリンク

解決法:

  • まず、サンプルファイルを作って、そのまま実行
  • 動いたら、少しずつ自分のファイルに置き換える
  • 一度に全部変えずに、1箇所ずつ確認

つまずき3:「やる気が続かない」 見出しへのリンク

解決法:

  • 小さな成功体験を積む
  • 自動化で節約できた時間を記録する
  • SNSで「○○を自動化できた!」と発信(モチベーション維持)

私が実際に使っているツールとリソース 見出しへのリンク

開発環境 見出しへのリンク

  • Visual Studio Code(無料、使いやすい)
  • Anaconda(Python + 必要なライブラリが全部入り)

学習リソース 見出しへのリンク

  • 公式ドキュメント(正確だが初心者には難しい)
  • Qiita(日本語の実践的な記事が豊富)
  • Stack Overflow(エラー解決の宝庫)
  • ChatGPT(24時間いつでも質問できる先生)

私のおすすめ学習順序 見出しへのリンク

  1. まずこの記事のスクリプトを全部試す
  2. うまくいったものを、自分の仕事用にカスタマイズ
  3. 公式ドキュメントで深掘り
  4. 新しい課題に挑戦

最後に:自動化がもたらした本当の価値 見出しへのリンク

「時間が節約できた」というのは、実は副次的な効果でした。

本当に得られたのは:

  1. クリエイティブな時間

    • 単純作業が減って、企画や改善に時間を使えるように
  2. 心の余裕

    • 「金曜日はレポート作成で潰れる」というストレスが消えた
  3. スキルの向上

    • プログラミングができるという自信
    • 問題解決能力の向上
  4. キャリアの可能性

    • 社内で重宝される存在に
    • 副業でも自動化スキルが活きています

まとめ:今日が、あなたの「自動化元年」 見出しへのリンク

今日から実践できる3つのアクション:

  1. 今すぐ: この記事のスクリプトを1つコピーして保存
  2. 今日中に: Python環境をセットアップして実行
  3. 今週中に: 自分の業務で実際に使ってみる

3年前の私に伝えたいこと:

「もっと早く始めればよかった」

あなたには、そう思ってほしくありません。

始めるなら、今日です。


追伸:あなたの自動化ストーリーを聞かせてください 見出しへのリンク

この記事のスクリプトを使って自動化に成功したら、ぜひ教えてください。あなたの成功体験が、次の誰かの背中を押すかもしれません。

質問、相談、成功報告、お待ちしています!


P.S. 「いいね」や「ブックマーク」をしていただけると、続編の執筆モチベーションが上がります!次回は「中級者向け自動化テクニック」を予定しています。

節約できる時間 = あなたの新しい可能性 = 未来への投資

さあ、今日から自動化の世界へ!🚀