
이 글은 대단한 자동화 도구를 소개하는 글이 아닙니다. 매일 똑같이 반복하던 단순한 일을 파이썬으로 하나씩 없애 가면서 얻은, 실제 업무에서 쓸 만한 팁을 적은 기록입니다. 코드 자체보다는 "왜 이렇게 짜게 됐는지"에 더 집중해서 썼습니다.
DB와 ETL 일을 하다 보면, 정작 SQL을 짜거나 시스템을 설계하는 일보다 매일 반복되는 엑셀 모으기나 파일 정리 같은 잡일에 생각보다 많은 시간을 빼앗깁니다. 저도 어느 순간부터 "이거 매번 손으로 하지 말고 스크립트로 짜 두면 되는데" 하는 생각이 쌓였고, 그래서 파이썬으로 자동화 스크립트를 하나둘 만들기 시작했습니다.
인터넷에 찾아보면 판다스(pandas)나 오픈파이엑셀(openpyxl) 문법을 알려 주는 글은 많습니다. 그런데 실제 사무실 업무에서 자주 쓰는 소소한 자동화 방법을 진짜 업무 예제로 정리한 글은 생각보다 드물었습니다. 그래서 이 글을 써 보게 됐습니다.
왜 파이썬으로 업무 자동화를 시작했는지, 그리고 처음 만난 현실의 벽
처음 자동화를 시작한 이유는 간단했습니다. 매일 여러 부서에서 보내오는 엑셀 파일들을 하나로 모아서, 정해진 양식으로 다시 정리하는 일을 반복하고 있었습니다. 그런데 부서마다 파일 이름 짓는 방식이 조금씩 다르고, 시트 구성도 미묘하게 달라서 "완전 자동화"가 생각보다 훨씬 까다로웠습니다. 처음엔 "판다스로 다 읽어서 합치면 끝나겠지" 하고 가볍게 생각했는데, 실제로는 예외적인 경우를 하나씩 처리하는 데 훨씬 많은 시간이 들었습니다.
두 번째 벽은 엑셀 파일 자체의 특징이었습니다. 합쳐진 셀(병합 셀), 숨겨 둔 행과 열, 형식이 깨진 날짜 값, 사람이 손으로 입력하다 생긴 오타와 공백까지. 데이터베이스처럼 깔끔하게 정리된 데이터가 아니라는 걸 몸으로 느꼈습니다. 특히 날짜 칸이 어떤 파일에는 글자(문자열)로, 어떤 파일에는 진짜 날짜 형식으로 섞여 들어 있었습니다. 이걸 구분하지 않고 한꺼번에 처리하다가 데이터가 한 칸씩 밀리는 사고를 겪은 적도 있습니다.
세 번째는 자동화 스크립트를 주변 사람들이 믿어 주느냐의 문제였습니다. 처음 스크립트로 모은 결과를 공유했을 때 "이거 사람이 직접 확인 안 하고 그냥 믿어도 되는 거예요?"라는 반응이 많았습니다. 결국 자동화 자체보다, 결과가 맞다는 걸 보여 주는 검증 코드와 기록(로그)을 같이 만들어서 믿음을 쌓아 가는 과정이 기술만큼이나 중요했습니다.
네 번째는 실행 환경 문제였습니다. 제 컴퓨터에서는 잘 돌던 스크립트가 다른 담당자 PC에서는 패키지 버전이 다르거나 파일 경로가 달라서 그대로 실행되지 않는 일이 종종 있었습니다. 처음엔 "코드는 똑같은데 왜 안 되지?" 하고 당황했습니다. 결국 실행 환경을 문서로 남기거나, 최소한 설치용 스크립트라도 같이 만들어 두지 않으면 자동화가 "나만 쓸 수 있는 도구"로 끝난다는 걸 알게 됐습니다.
실전 예제 — 엑셀 모으기·정리 자동화, 파일 정리 자동화
실제로 자주 쓰는 방법 몇 가지를 코드와 함께 나눠 보겠습니다.
1) 여러 엑셀 파일을 하나로 모으기. 특정 폴더 안에 있는 엑셀 파일을 전부 읽어서 하나의 표(데이터프레임)로 합치는 기본 방법입니다. 각 줄이 어느 파일에서 왔는지 알 수 있도록 원래 파일 이름을 컬럼에 같이 적어 두면, 나중에 문제가 생겼을 때 원인을 찾는 데 큰 도움이 됩니다.
import pandas as pd
import glob
files = glob.glob("./reports/*.xlsx")
df_list = []
for f in files:
df = pd.read_excel(f, sheet_name="Sheet1")
df["원본파일"] = f.split("/")[-1]
df_list.append(df)
merged = pd.concat(df_list, ignore_index=True)
merged.to_excel("./merged_report.xlsx", index=False)
2) 날짜나 공백처럼 지저분한 값 정리하기. 사람이 직접 입력한 엑셀에는 쓸데없는 공백이나 형식이 안 맞는 값이 흔합니다. 저는 파일을 모은 직후에 꼭 아래 같은 정리 단계를 거칩니다.
merged["담당자"] = merged["담당자"].astype(str).str.strip()
merged["처리일자"] = pd.to_datetime(merged["처리일자"], errors="coerce")
# 날짜 파싱 실패 건은 원본 파일명과 함께 별도 로그로 남긴다
error_rows = merged[merged["처리일자"].isna()]
if not error_rows.empty:
error_rows.to_excel("./date_parse_errors.xlsx", index=False)
3) 파일 정리 자동화 — 날짜·부서별로 폴더 나누기. 매일 쌓이는 원본 파일을 날짜별 폴더로 자동으로 옮겨 주는 스크립트입니다. 원본 파일을 곧바로 옮기기보다는, 항상 먼저 복사하고 확인한 다음 옮기는 방식으로 짜는 걸 원칙으로 하고 있습니다.
import shutil, os
from datetime import datetime
src_dir = "./incoming"
for filename in os.listdir(src_dir):
if filename.endswith(".xlsx"):
mtime = os.path.getmtime(os.path.join(src_dir, filename))
date_str = datetime.fromtimestamp(mtime).strftime("%Y%m%d")
target_dir = os.path.join("./archive", date_str)
os.makedirs(target_dir, exist_ok=True)
shutil.move(os.path.join(src_dir, filename),
os.path.join(target_dir, filename))
여러 번 실수하면서 얻은 자동화 스크립트 설계 노하우
몇 번 사고를 겪고 나서 팀 안에서 정리한 원칙들을 나눠 보겠습니다.
가장 중요한 원칙: 원본 파일은 절대 직접 고치거나 덮어쓰지 않는다. 자동화 스크립트가 원본을 건드리다가 문제가 생기면 되돌리는 것 자체가 불가능해집니다. 저는 원본은 항상 읽기만 하는 파일로 다루고, 결과는 따로 새 파일로 저장하는 걸 절대 원칙으로 삼습니다.
모든 자동화 스크립트에 실행 기록(로그)을 남긴다. 언제, 어떤 파일을 몇 건 처리했는지, 오류는 없었는지를 따로 로그 파일에 남기지 않으면, 나중에 "왜 이 데이터가 이렇게 됐지?" 하고 추적할 방법이 없습니다. 저는 파이썬의 logging 모듈로 실행 시각, 처리 건수, 오류가 났는지를 항상 기록합니다.
오류는 조용히 넘기지 말고 반드시 드러나게 한다. 처음에는 오류가 나면 그냥 try/except로 넘어가게 짰습니다. 그런데 이게 오히려 문제를 숨기는 결과가 됐습니다. 어떤 파일 처리에 실패했다면 그 사실을 로그와 따로 만든 오류 보고서에 확실히 남겨서, 사람이 놓치지 않게 하는 게 훨씬 중요하다는 걸 깨달았습니다.
작은 단위로 나눠서 다시 쓸 수 있게 만든다. 처음엔 긴 스크립트 하나에 모든 코드를 다 넣었습니다. 그랬더니 나중에 비슷한 자동화 요청이 또 들어왔을 때 다시 쓰기가 거의 불가능했습니다. 그 뒤로는 "파일 읽기", "정리", "저장", "알림"처럼 기능별로 함수를 나눠 두고, 새 요청이 오면 이 부품들을 조립하는 방식으로 작업 시간을 크게 줄였습니다. 처음엔 시간이 조금 더 드는 것 같아도, 몇 번째 요청부터는 이 구조 덕분에 개발 시간이 눈에 띄게 짧아졌습니다.
결과는 사람이 확인하기 편한 모양으로 알려 준다. 아무리 정확하게 처리했더라도, 결과를 보는 사람이 믿을 수 있는 모양으로 전달하지 않으면 소용이 없었습니다. 처리 건수, 오류 건수, 처리 시각을 요약해서 메일이나 메신저로 같이 보내는 습관을 들인 뒤로, 자동화 결과를 믿어 주는 사람이 눈에 띄게 늘었습니다.
실행 환경은 최대한 단순하게 하고, 문서로 남긴다. 필요한 패키지 목록과 버전을 requirements.txt 파일로 정리해 두고, 간단한 실행 방법을 README 파일로 남겨 두는 것만으로도 나중에 다른 담당자에게 일을 넘길 때 부담이 크게 줄었습니다. 처음엔 귀찮아서 건너뛰던 부분이었는데, 결국 이 문서 정리 습관이 자동화 스크립트를 얼마나 오래 쓸 수 있을지를 결정했습니다.
한마디로 정리하면, 업무 자동화 스크립트에서 진짜 어려운 건 판다스 문법이 아니었습니다. "지저분한 실제 데이터를 어떻게 안전하게 다루고, 그 결과를 어떻게 믿게 만드느냐"가 훨씬 어려웠습니다. 코드는 생각보다 짧아도, 이 믿음을 쌓는 데는 훨씬 오랜 시간이 걸렸습니다.
다음 글에서는 이 스크립트들이 매일 알아서 실행되도록 예약해 두고, 처리 결과를 메신저로 알림 받게 만든 과정을 예제 코드와 함께 더 자세히 다뤄 보겠습니다.