처음 시도한 업무 자동화, 3번 실패하고서야 깨달은 것들

처음 시도한 업무 자동화, 3번 실패하고서야 깨달은 것들

여러 번의 시행착오를 거쳐 점차 개선되는 작업 과정을 표현한 모습


이 블로그에는 "완성 코드"만 올라오지만, 사실 모든 자동화가 처음부터 깔끔하게 완성되지는 않습니다. 이번 글에서는 실제로 겪었던 시행착오 하나를 그대로 풀어보려 합니다. 지금까지 소개한 완성 코드들이 왜 지금의 형태가 되었는지, 그 뒤에 있는 실패 과정을 공유하면 자동화를 처음 시도하는 분들께 더 도움이 될 것 같았습니다.

상황은 이랬습니다. 거래처별로 흩어진 엑셀 파일 수십 개를 매달 하나로 합쳐서 정리하는 작업을, 파이썬으로 자동화하기로 마음먹었습니다.


시도 1 — "일단 되겠지" 하고 짠 코드, 반나절 만에 무너짐

처음에는 이렇게 단순하게 접근했습니다.

import pandas as pd
from pathlib import Path

all_data = []
for file in Path("거래처파일").glob("*.xlsx"):
    df = pd.read_excel(file)
    all_data.append(df)

result = pd.concat(all_data)
result.to_excel("합친결과.xlsx")

파일 5개로 테스트했을 때는 잘 됐습니다. 문제는 실제 폴더에 파일 40개를 넣고 돌렸을 때 터졌습니다.

무엇이 잘못됐나: 거래처마다 엑셀 헤더 이름이 조금씩 달랐습니다. 어떤 파일은 "거래처명", 어떤 파일은 "업체명"이었고, 어떤 파일은 1행이 아니라 2행부터 데이터가 시작했습니다. pd.concat()은 이걸 그대로 합쳐버려서 결과 파일이 열 수십 개가 뒤죽박죽 섞인 형태로 나왔습니다. "일단 합치고 보자"는 접근이 실무 데이터의 비일관성 앞에서 완전히 무너진 순간이었습니다.

실패 원인: 테스트를 5개짜리 "깨끗한" 샘플로만 하고, 실제 40개 파일의 다양성을 확인하지 않았습니다.

시도 2 — 헤더는 맞췄는데, 이번엔 한글이 깨짐

헤더 이름을 통일하는 매핑 딕셔너리를 추가했습니다.

COLUMN_MAP = {"업체명": "거래처명", "회사명": "거래처명"}

all_data = []
for file in Path("거래처파일").glob("*.xlsx"):
    df = pd.read_excel(file)
    df = df.rename(columns=COLUMN_MAP)
    all_data.append(df)

result = pd.concat(all_data, ignore_index=True)
result.to_excel("합친결과.xlsx", index=False)

이번엔 대부분 잘 합쳐졌습니다. 그런데 결과 파일을 열어보니 일부 행의 거래처명이 물음표나 네모(□)로 깨져 있었습니다.

무엇이 잘못됐나: 나중에 알고 보니, 오래된 회계 프로그램에서 내보낸 몇몇 파일이 CSV.xlsx로 확장자만 바꾼 파일이었고, 인코딩이 EUC-KR이었습니다. pd.read_excel()은 진짜 엑셀 바이너리 형식을 기대하는데, 이 파일들은 사실 텍스트 파일이라 읽는 방식 자체가 틀렸던 것입니다.

실패 원인: "확장자가 .xlsx면 당연히 진짜 엑셀 파일"이라고 가정했습니다. 파일 형식은 확장자가 아니라 내용으로 확인해야 한다는 것을 이때 배웠습니다.

시도 3 — 파일 형식은 해결, 그런데 매달 반복하려니 또 문제

파일 형식을 자동으로 구분해서 처리하도록 개선했습니다.

import pandas as pd
import chardet
from pathlib import Path

def read_any_file(file):
    try:
        return pd.read_excel(file)   # 먼저 진짜 엑셀로 시도
    except Exception:
        with open(file, "rb") as f:
            enc = chardet.detect(f.read(10000))["encoding"] or "cp949"
        return pd.read_csv(file, encoding=enc)   # 실패하면 CSV로 재시도

all_data = []
for file in Path("거래처파일").glob("*.xlsx"):
    df = read_any_file(file)
    df = df.rename(columns=COLUMN_MAP)
    all_data.append(df)

result = pd.concat(all_data, ignore_index=True)
result.to_excel("합친결과.xlsx", index=False)

이제 파일 형식 문제는 해결됐습니다. 그런데 다음 달에 똑같은 스크립트를 다시 돌렸더니, 이번엔 중복 데이터가 생겼습니다. 지난달 파일을 폴더에서 안 지우고 그냥 뒀더니, 지난달 데이터와 이번 달 데이터가 둘 다 합쳐진 것입니다.

실패 원인: "한 번 실행하고 끝"이 아니라 "매달 반복 실행"한다는 것을 코드 설계 단계에서 고려하지 않았습니다.

결국 이렇게 정리됐습니다 — 3번의 실패에서 나온 최종 원칙

세 번의 실패를 거치고서야, 지금 이 블로그의 완성 코드들에 공통적으로 들어가는 원칙들이 자연스럽게 만들어졌습니다.

1. 헤더 이름은 반드시 매핑 딕셔너리로 통일한다
   → CSV 자동 병합 편의 열 이름 통일 로직이 여기서 나왔습니다.

2. 파일 형식은 확장자가 아니라 실제 내용으로 판단한다
   → 인코딩 자동 감지 편이 이 문제를 별도로 다루게 된 계기입니다.

3. 반복 실행을 전제로 설계한다 (중복 방지, 날짜 접두어, 로그 기록)
   → 엑셀 버전 관리 편의 타임스탬프 백업 방식이 이 교훈에서 나왔습니다.

4. "정상적으로 처리된 파일 수 / 실패한 파일 수"를 항상 출력한다
   → 지금까지 소개한 거의 모든 완성 코드에 "✔ 성공 / ✘ 실패" 로그가
     빠짐없이 들어가는 이유입니다.

돌아보며 — 이 시행착오가 알려준 것

완성된 코드만 보면 "처음부터 저렇게 짰겠지"라고 생각하기 쉽지만, 실제로는 실무 데이터의 예외 상황을 하나씩 마주치면서 코드가 점점 튼튼해지는 과정이었습니다. 특히 아래 세 가지는 자동화를 처음 시도하는 분들께 꼭 전하고 싶은 부분입니다.

첫째, 테스트는 반드시 "지저분한" 실제 데이터로 하세요. 깨끗하게 정리된 샘플 파일 5개로 테스트하면 코드가 작동하는 것처럼 보이지만, 실무 데이터의 예외 상황(다른 헤더명, 다른 형식, 빈 값)은 다릅니다.

둘째, "한 번 실행"이 아니라 "여러 번 실행"을 가정하고 설계하세요. 자동화 스크립트는 보통 반복 실행됩니다. 처음 실행할 때만 맞는 코드는 두 번째 실행에서 예상치 못한 문제를 일으킵니다.

셋째, 실패했을 때 무엇이 잘못됐는지 바로 알 수 있게 로그를 남기세요. 이 블로그의 모든 코드에 있는 , 출력이 괜히 있는 게 아닙니다. 조용히 실패하는 코드가 가장 위험합니다.

💡 지금 비슷한 상황이라면: 위에서 언급한 CSV 자동 병합 편은 이 시행착오를 모두 반영해서 처음부터 완성된 형태로 정리해둔 글입니다. 같은 실패를 반복하지 않도록 참고하시면 좋겠습니다.

핵심 요약

  • 실패 1: 깨끗한 샘플로만 테스트 → 실무 데이터의 헤더 불일치로 무너짐
  • 실패 2: 확장자만 믿고 파일 형식 가정 → 인코딩 문제로 한글 깨짐
  • 실패 3: 한 번 실행만 고려 → 반복 실행 시 중복 데이터 발생
  • 얻은 원칙: 헤더 매핑, 내용 기반 형식 판단, 반복 실행 대비, 성공/실패 로그 기록

이 블로그의 인기 게시물

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

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

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