엑셀 매크로(VBA) 보안 경고 끝! 파이썬으로 똑같은 작업 대체하기

이미지
엑셀 매크로(VBA) 보안 경고 끝! 파이썬으로 똑같은 작업 대체하기 (완성 코드 공개) "매크로가 포함된 파일을 다른 사람에게 보내면 보안 경고 때문에 매크로 사용 설정을 매번 따로 해야 한다", "VBA 코드가 회사 PC마다 다르게 작동해서 디버깅이 어렵다", "매크로를 쓰는 동료가 퇴사하면 그 파일을 아무도 수정하지 못한다"… VBA 매크로는 엑셀 안에서 바로 실행되는 장점이 있지만, 보안 정책으로 차단되거나, 회사 PC마다 설정이 달라 오작동하거나, 코드 관리가 어려운 한계가 있습니다. 이 글에서는 이 블로그에서 지금까지 소개한 파이썬 코드들이 VBA의 어떤 기능을 대체할 수 있는지 비교하고, 대표적인 매크로 작업을 파이썬으로 구현하는 방법을 소개합니다. VBA 매크로 vs 파이썬 비교 VBA 매크로 파이썬 실행 환경 엑셀 안에서만 동작 독립적으로 어디서나 동작 보안 경고 매번 발생, 차단 가능 해당 없음 배포 파일에 코드 포함 스크립트 파일만 공유 디버깅 엑셀 VBA 편집기 사용 다양한 코드 에디터 사용 가능 다른 프로그램 연동 제한적 (Win API 필요) 매우 풍부함 (이메일, 웹, DB 등) 버전 관리(깃 등) 거의 불가능 일반적인 코드처럼 관리 가능 배우는 난이도 엑셀에 특화된 문법 범용 프로그래밍 언어, 활용도 넓음 💡 언제 VBA가 더 나을까: 엑셀을 열자마자 버튼 클릭으로 즉시 실행하고 싶거나, 엑셀 전용 UI(사용자 정의 양식)가 필요한 경우는 VBA가 더 간단할 수 있습니다. 하지만 안정성, 보안, 확장성을 고려하면 대부분의 반복 작업은 파이썬이 더 유리합니다. 대표 매크로 작업 1 — 여러 시트 합치기 VBA로 흔히 작성하는 "모...

중요 엑셀 실수로 덮어썼을 때 끝! 파이썬으로 자동 백업·버전 관리하기

중요 엑셀 실수로 덮어썼을 때 끝! 파이썬으로 자동 백업·버전 관리하기 (완성 코드 공개)

파이썬으로 엑셀 파일을 자동으로 백업하고 버전 관리하는 모습


"어제까지 있던 데이터가 오늘 보니 사라졌는데 누가 언제 지웠는지 모르겠다", "수정하다가 실수로 저장을 눌러서 이전 내용을 영영 잃어버렸다", "여러 명이 같은 파일을 작업하는데 누가 무엇을 바꿨는지 추적이 안 된다"…

중요한 엑셀 파일은 한 번의 실수로 되돌릴 수 없는 손실이 생길 수 있습니다. 파이썬을 한 번만 세팅해두면 파일이 변경될 때마다 자동으로 버전별 백업을 만들고, 언제 어떤 변경이 있었는지 이력을 기록해서 필요할 때 이전 버전으로 즉시 되돌릴 수 있습니다.


1단계: 준비물 설치

파이썬이 설치되어 있어야 합니다. 없다면 python.org에서 최신 버전을 받아 설치하세요. 설치 시 반드시 "Add Python to PATH"에 체크해야 합니다.

변경 감지에 필요한 라이브러리를 설치합니다. 터미널(윈도우: CMD 또는 파워셸)을 열고 아래 명령어를 실행하세요:

pip install watchdog pandas openpyxl

watchdog은 파일이 수정되는 순간을 실시간으로 감지하는 라이브러리입니다. pandasopenpyxl은 변경 전후 데이터를 비교해 이력을 기록하는 데 사용합니다.

💡 이 코드로 할 수 있는 것: 지정한 엑셀 파일이 저장될 때마다 자동으로 타임스탬프가 포함된 백업을 생성하고, 변경 이력을 텍스트 로그로 남깁니다. 보관할 백업 개수를 제한해 저장 공간도 관리합니다. 필요할 때 특정 시점의 백업으로 즉시 복원할 수 있습니다.

2단계: 완성 코드 — 실시간 자동 백업 감시

아래 코드를 그대로 복사해서 메모장에 붙여넣고, excel_watcher.py로 저장하세요. 저장 시 파일 형식은 "모든 파일", 인코딩은 UTF-8로 설정합니다.

import shutil
import time
from pathlib import Path
from datetime import datetime
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

# ① 설정
WATCH_FOLDER  = r"C:\Users\내이름\Desktop\중요엑셀파일"       # ← 감시할 폴더
BACKUP_FOLDER = r"C:\Users\내이름\Desktop\엑셀백업저장소"     # ← 백업 저장 폴더
LOG_FILE      = r"C:\Users\내이름\Desktop\엑셀백업저장소\변경이력.txt"
MAX_VERSIONS  = 20    # ← 파일별 보관할 최대 버전 수 (초과 시 오래된 것부터 삭제)
TARGET_EXT    = {".xlsx", ".xlsm"}   # ← 감시할 확장자

# ② 백업 폴더 준비
backup_dir = Path(BACKUP_FOLDER)
backup_dir.mkdir(parents=True, exist_ok=True)

def log_change(message):
    """변경 이력을 로그 파일에 기록"""
    now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    with open(LOG_FILE, "a", encoding="utf-8") as f:
        f.write(f"[{now}] {message}\n")
    print(f"  {message}")

def cleanup_old_versions(file_stem):
    """오래된 백업 버전 정리 (MAX_VERSIONS 초과 시)"""
    versions = sorted(backup_dir.glob(f"{file_stem}_*"),
                      key=lambda f: f.stat().st_mtime)
    while len(versions) > MAX_VERSIONS:
        old = versions.pop(0)
        old.unlink()
        log_change(f"🗑 오래된 버전 삭제: {old.name}")

# ③ 파일 변경 감지 핸들러
class ExcelChangeHandler(FileSystemEventHandler):
    def __init__(self):
        self.last_backup = {}   # 중복 이벤트 방지용 (파일별 마지막 백업 시각)

    def on_modified(self, event):
        if event.is_directory:
            return

        file_path = Path(event.src_path)
        if file_path.suffix.lower() not in TARGET_EXT:
            return

        # 같은 파일에 대해 2초 이내 중복 이벤트 무시 (저장 시 여러 이벤트 발생 방지)
        now = time.time()
        if file_path.name in self.last_backup:
            if now - self.last_backup[file_path.name] < 2:
                return
        self.last_backup[file_path.name] = now

        # 백업 생성
        timestamp  = datetime.now().strftime("%Y%m%d_%H%M%S")
        backup_name = f"{file_path.stem}_{timestamp}{file_path.suffix}"
        backup_path = backup_dir / backup_name

        try:
            time.sleep(0.5)   # 저장이 완전히 끝날 때까지 잠시 대기
            shutil.copy2(file_path, backup_path)
            log_change(f"✔ 백업 생성: {file_path.name} → {backup_name}")
            cleanup_old_versions(file_path.stem)
        except Exception as e:
            log_change(f"✘ 백업 실패: {file_path.name} → {e}")

# ④ 감시 시작
event_handler = ExcelChangeHandler()
observer = Observer()
observer.schedule(event_handler, WATCH_FOLDER, recursive=False)
observer.start()

print(f"▶ 엑셀 자동 백업 감시 시작: {WATCH_FOLDER}")
print(f"  백업 저장 위치: {BACKUP_FOLDER}")
print(f"  종료하려면 Ctrl+C를 누르세요.\n")

try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    observer.stop()
    print("\n  감시를 종료합니다.")
observer.join()

3단계: 실행 방법

  1. 코드 ① 설정의 WATCH_FOLDER에 감시할 엑셀 파일이 있는 폴더 경로를 입력합니다.
  2. BACKUP_FOLDER에 백업을 저장할 폴더 경로를 입력합니다.
  3. MAX_VERSIONS에 파일별로 보관할 최대 백업 개수를 입력합니다.
  4. 터미널에서 아래 명령어로 실행합니다. 실행 후에는 터미널 창을 계속 열어둡니다:
python excel_watcher.py

실행 중 감시 대상 폴더의 엑셀 파일을 수정하고 저장하면 터미널에 이렇게 출력됩니다:

▶ 엑셀 자동 백업 감시 시작: C:\Users\내이름\Desktop\중요엑셀파일
  백업 저장 위치: C:\Users\내이름\Desktop\엑셀백업저장소
  종료하려면 Ctrl+C를 누르세요.

  [2026-06-22 09:15:32] ✔ 백업 생성: 거래처현황.xlsx → 거래처현황_20260622_091532.xlsx
  [2026-06-22 10:42:18] ✔ 백업 생성: 거래처현황.xlsx → 거래처현황_20260622_104218.xlsx

파일을 저장할 때마다 자동으로 타임스탬프가 포함된 백업 파일이 생성되고, 변경 이력이 로그 파일에 누적됩니다.


4단계: 자주 발생하는 오류와 해결법

오류 1: 같은 저장에 백업이 2~3개씩 중복 생성됨

엑셀 저장 시 임시 파일 생성 등으로 여러 이벤트가 발생하는 경우입니다. 코드에 이미 2초 이내 중복 방지 로직이 포함되어 있습니다. 여전히 중복된다면 time.sleep(2)로 대기 시간을 늘려보세요.

오류 2: ModuleNotFoundError: No module named 'watchdog'

설치가 제대로 되지 않은 경우입니다. 아래 명령어로 다시 시도하세요.

python -m pip install watchdog

오류 3: 백업이 생성되지 않음

엑셀 파일이 WATCH_FOLDER에 직접 있는지 확인하세요. 하위 폴더는 감시 대상이 아닙니다. 하위 폴더까지 감시하려면 observer.schedule(event_handler, WATCH_FOLDER, recursive=True)로 변경하세요.


응용: 이전 버전으로 복원하기

백업된 버전 목록을 확인하고 원하는 시점으로 복원하는 코드입니다. 아래 코드를 restore.py로 저장하세요.

import shutil
from pathlib import Path

BACKUP_FOLDER = r"C:\Users\내이름\Desktop\엑셀백업저장소"
RESTORE_TARGET = r"C:\Users\내이름\Desktop\중요엑셀파일\거래처현황.xlsx"   # ← 복원할 원본 위치
FILE_STEM = "거래처현황"   # ← 확인할 파일 이름 (확장자 제외)

backup_dir = Path(BACKUP_FOLDER)
versions   = sorted(backup_dir.glob(f"{FILE_STEM}_*"),
                    key=lambda f: f.stat().st_mtime, reverse=True)

print(f"  '{FILE_STEM}' 백업 버전 목록 (최신순):\n")
for i, v in enumerate(versions):
    mtime = v.stat().st_mtime
    from datetime import datetime
    time_str = datetime.fromtimestamp(mtime).strftime("%Y-%m-%d %H:%M:%S")
    print(f"  [{i}] {v.name}  ({time_str})")

# 복원할 버전 번호 선택
choice = int(input("\n복원할 버전 번호를 입력하세요: "))
selected = versions[choice]

shutil.copy2(selected, RESTORE_TARGET)
print(f"\n✅ 완료! '{selected.name}' 버전으로 복원했습니다.")
💡 이전 게시글과 결합하면: 폴더 자동 백업 편과 결합하면 백업소 자체를 외장 하드에 추가로 보관할 수 있고, 텔레그램 자동 발송 편과 결합하면 백업이 생성될 때마다 알림을 받는 것도 가능합니다.

핵심 요약

  • 준비물: Python + watchdog + pandas + openpyxl 설치 (pip install watchdog pandas openpyxl)
  • 설정: WATCH_FOLDER, BACKUP_FOLDER, MAX_VERSIONS 수정
  • 실행: 터미널에서 python excel_watcher.py 입력 후 계속 실행 상태 유지
  • 결과: 파일 저장마다 타임스탬프 백업 자동 생성, 변경 이력 로그 누적, 오래된 버전 자동 정리
  • 복원: restore.py로 원하는 시점 버전을 선택해 즉시 복원

이 코드를 응용하면 여러 파일을 동시에 감시하거나, 변경 전후 데이터를 비교해 무엇이 바뀌었는지 자동으로 분석하는 것도 가능합니다.

이 블로그의 인기 게시물

느려진 구글 크롬 속도 2배 빨라지는 3가지 설정 방법 (2026년 최신 가이드)

카카오톡 용량 줄이기! 대화방 파일 삭제로 스마트폰 용량 확보법 (1분 해결)

업무 속도 3배 빨라지는 윈도우 기본 캡처 도구 단축키 및 200% 활용 꿀팁