TL;DR
- Excel 테이블 변경 추적을 수작업에서 자동화로: Refresh 한 번에 Added/Removed/Modified 판별
- RowHash 기반 스냅샷 비교로 중복 키, 행 순서 변경에도 정확한 결과
- 회계 실무 확장: 예산 vs 실적, MoM/YoY 비교, 원가 분석, 감사 추적에 즉시 적용 가능
- 재사용 가능한 Power Query 템플릿 제공
실무 문제: 왜 이 자동화가 필요했나
회계 실무에서 반복되는 고통스러운 시나리오:
월말 마감 시점
– 오더북 배포본과 회수본 비교
– “어떤 발주가 추가됐지?”
– “수량이나 금액이 바뀐 건 뭐지?”
– “삭제된 항목은?”
기존 방식의 한계
– VLOOKUP으로 매칭 → 중복 발주번호 처리 어려움
– 조건부 서식으로 눈으로 확인 → 사람 실수 발생
– 수작업 비교 → 시간 오래 걸림, 마감 지연
필요한 것
– 자동으로 변경사항 감지
– 중복 키도 정확하게 처리
– 어떤 열이 어떻게 바뀌었는지 상세 추적
– 그리고 이 로직을 다른 분석에도 재사용
솔루션: RowHash 기반 스냅샷 비교
핵심 아이디어
RowHash란?
각 행의 데이터를 하나의 문자열로 압축한 “지문”
예: 발주번호 PO-001
제품: 밸브A, 수량: 10, 금액: 100,000
→ RowHash: "밸브A|10|100000"
데이터가 바뀌면 RowHash도 바뀜
제품: 밸브A, 수량: 15, 금액: 150,000
→ RowHash: "밸브A|15|150000"
비교 로직
1. 배포 전/후 테이블 각각에 RowHash 생성
2. 발주번호 + 중복인덱스로 양쪽 테이블 병합 (Full Outer Join)
3. RowHash 비교로 변경 유형 판별:
– Removed: 배포 전에만 존재
– Added: 배포 후에만 존재
– Unchanged: RowHash 동일
– Modified: RowHash 다름
4. Modified 행의 경우 열별 변경 내용 상세 추출
실제 구현: Power Query M 코드
사용 예시
배포 전 (P06_Start)
발주번호 | 제품명 | 수량 | 금액 |
---|---|---|---|
PO-001 | 밸브A | 10 | 100,000 |
PO-002 | 밸브B | 5 | 50,000 |
PO-002 | 밸브C | 3 | 30,000 |
배포 후 (P06_Ending)
발주번호 | 제품명 | 수량 | 금액 |
---|---|---|---|
PO-001 | 밸브A | 15 | 150,000 |
PO-002 | 밸브B | 5 | 50,000 |
PO-003 | 밸브D | 7 | 70,000 |
결과
발주번호 | 제품명 | ChangeType | 수량_Diff | 금액_Diff |
---|---|---|---|---|
PO-001 | 밸브A | Modified | 10 → 15 | 100000 → 150000 |
PO-002 | 밸브B | Unchanged | null | null |
PO-002 | 밸브C | Removed | null | null |
PO-003 | 밸브D | Added | null | null |
코드 템플릿
let
//--------------------------------------------------
// ① 사용자 설정
//--------------------------------------------------
StartName = "P06_Start", // 과거 테이블명
EndName = "P06_Ending", // 현재 테이블명
KeyCols = {"발주번호"}, // 키 열 (복합키는 {"A","B"})
Culture = "ko-KR", // 지역 설정
//--------------------------------------------------
// ② 원본 로드
//--------------------------------------------------
S0 = Excel.CurrentWorkbook(){[Name = StartName]}[Content],
E0 = Excel.CurrentWorkbook(){[Name = EndName ]}[Content],
//--------------------------------------------------
// ③ 중복 인덱스 부여 (같은 키 내 순번 구분)
//--------------------------------------------------
fnAddDupIdx = (tbl as table) as table =>
let
Grouped = Table.Group(
tbl, KeyCols,
{{"AllRows",
(g) => Table.AddIndexColumn(g, "__DupIndex", 1, 1, Int64.Type),
type table}}
),
Recombine = Table.Combine(Grouped[AllRows])
in Recombine,
S1 = fnAddDupIdx(S0),
E1 = fnAddDupIdx(E0),
//--------------------------------------------------
// ④ RowHash 생성
//--------------------------------------------------
AllCols = List.Union({Table.ColumnNames(S1), Table.ColumnNames(E1)}),
NonKeyCols = List.Difference(AllCols, List.Combine({KeyCols, {"__DupIndex"}})),
fnRowHash = (r as record) as text =>
Text.Combine(
List.Transform(
NonKeyCols,
(c) => Text.From(Record.FieldOrDefault(r, c, null), Culture)
),
"|"
),
S = Table.AddColumn(S1, "RowHash", each fnRowHash(_), type text),
E = Table.AddColumn(E1, "RowHash", each fnRowHash(_), type text),
//--------------------------------------------------
// ⑤ Full Outer Join
//--------------------------------------------------
JoinKeys = List.Combine({KeyCols, {"__DupIndex"}}),
Join = Table.NestedJoin(
S, JoinKeys,
E, JoinKeys,
"EndRec",
JoinKind.FullOuter
),
X = Table.ExpandTableColumn(
Join, "EndRec",
Table.ColumnNames(E),
List.Transform(Table.ColumnNames(E), each _ & "_End")
),
//--------------------------------------------------
// ⑥ ChangeType 판별
//--------------------------------------------------
AddStatus = Table.AddColumn(
X, "ChangeType",
(r) =>
let
missEnd = r[RowHash_End] = null,
missStart = r[RowHash] = null,
sameHash = r[RowHash] = r[RowHash_End]
in
if missEnd then "Removed"
else if missStart then "Added"
else if sameHash then "Unchanged"
else "Modified"
),
//--------------------------------------------------
// ⑦ 열별 변경 내용 추출
//--------------------------------------------------
AddDiffCols = Table.AddColumn(
AddStatus, "ChangedCols",
(r) =>
if r[ChangeType] <> "Modified" then null
else List.Select(
NonKeyCols,
(c) =>
let
old = Record.FieldOrDefault(r, c, null),
new = Record.FieldOrDefault(r, c & "_End", null)
in not Value.Equals(old, new)
)
),
AddDiffValues = List.Accumulate(
NonKeyCols, AddDiffCols,
(state, col) =>
Table.AddColumn(
state, col & "_Diff",
each
let
hasChanged = ([ChangedCols] <> null) and
List.Contains([ChangedCols], col),
oldVal = Record.FieldOrDefault(_, col, null),
newVal = Record.FieldOrDefault(_, col & "_End", null),
oldTxt = if oldVal = null then "" else Text.From(oldVal, Culture),
newTxt = if newVal = null then "" else Text.From(newVal, Culture)
in
if hasChanged then oldTxt & " → " & newTxt
else null,
type text
)
),
//--------------------------------------------------
// ⑧ 정리
//--------------------------------------------------
Result = Table.RemoveColumns(AddDiffValues, {"RowHash", "RowHash_End"})
in
Result
실무 확장: 회계 Variance 분석 활용
이 테이블 비교 로직은 단순 오더북 추적을 넘어 회계 실무의 핵심 분석들에 즉시 적용 가능합니다. 각 케이스별로 실제 적용 방법을 상세히 설명합니다.
확장 케이스 1: 예산 vs 실적 분석 (Budget vs Actual)
실무 배경
매월 예산 대비 실적을 분석하는 것은 모든 회계팀의 필수 업무입니다. 하지만 수작업으로 하면:
– 계정과목별로 일일이 비교
– 차이 계산 수작업
– 차이율 계산 실수
– 새로운 계정 추가/삭제 누락
데이터 준비 예시
Budget_2025 테이블
계정과목 | 부서 | 예산금액 | 비고 |
---|---|---|---|
급여 | 영업팀 | 50,000,000 | 월간 |
급여 | 관리팀 | 30,000,000 | 월간 |
복리후생비 | 영업팀 | 5,000,000 | |
복리후생비 | 관리팀 | 3,000,000 | |
교육훈련비 | 관리팀 | 2,000,000 |
Actual_2025 테이블
계정과목 | 부서 | 실적금액 | 비고 |
---|---|---|---|
급여 | 영업팀 | 52,000,000 | 초과근무 증가 |
급여 | 관리팀 | 29,500,000 | 1명 퇴사 |
복리후생비 | 영업팀 | 5,200,000 | |
복리후생비 | 관리팀 | 2,500,000 | 행사 취소 |
마케팅비 | 영업팀 | 10,000,000 | 신규 항목 |
Power Query 설정
let
// ① 테이블 지정
StartName = "Budget_2025",
EndName = "Actual_2025",
// ② 키 열 설정 (복합키)
KeyCols = {"계정과목", "부서"},
// ③ 나머지는 기본 템플릿 그대로 사용
Culture = "ko-KR",
// ... (기본 템플릿 로직)
in
Result
출력 결과
계정과목 | 부서 | ChangeType | 예산금액 | 실적금액 | 예산금액_Diff | 실적금액_Diff | ChangedCols |
---|---|---|---|---|---|---|---|
급여 | 영업팀 | Modified | 50,000,000 | 52,000,000 | null | null | [“실적금액”,”비고”] |
급여 | 관리팀 | Modified | 30,000,000 | 29,500,000 | null | null | [“실적금액”,”비고”] |
복리후생비 | 영업팀 | Modified | 5,000,000 | 5,200,000 | null | null | [“실적금액”] |
복리후생비 | 관리팀 | Modified | 3,000,000 | 2,500,000 | null | null | [“실적금액”,”비고”] |
교육훈련비 | 관리팀 | Removed | 2,000,000 | null | null | null | null |
마케팅비 | 영업팀 | Added | null | 10,000,000 | null | null | null |
추가 분석 컬럼
기본 결과에 차이액, 차이율을 자동 계산하는 컬럼을 추가합니다:
// Result 테이블에 추가 분석 컬럼 생성
// 1) 차이액 계산
AddVariance = Table.AddColumn(
Result, "차이액",
each
if [ChangeType] = "Modified" then
[실적금액_End] - [예산금액]
else if [ChangeType] = "Added" then
[실적금액_End]
else if [ChangeType] = "Removed" then
-[예산금액]
else null,
type number
),
// 2) 차이율 계산 (%)
AddVarianceRate = Table.AddColumn(
AddVariance, "차이율(%)",
each
if [ChangeType] = "Modified" and [예산금액] <> 0 then
Number.Round(([실적금액_End] - [예산금액]) / [예산금액] * 100, 1)
else null,
type number
),
// 3) 중요도 플래그 (차이율 절대값 10% 이상)
AddFlag = Table.AddColumn(
AddVarianceRate, "주의필요",
each
if [차이율(%)] <> null and Number.Abs([차이율(%)]) >= 10 then
"⚠️ 중요"
else null,
type text
)
최종 결과 (분석 컬럼 포함)
계정과목 | 부서 | ChangeType | 예산금액 | 실적금액 | 차이액 | 차이율(%) | 주의필요 |
---|---|---|---|---|---|---|---|
급여 | 영업팀 | Modified | 50,000,000 | 52,000,000 | +2,000,000 | +4.0 | null |
급여 | 관리팀 | Modified | 30,000,000 | 29,500,000 | -500,000 | -1.7 | null |
복리후생비 | 영업팀 | Modified | 5,000,000 | 5,200,000 | +200,000 | +4.0 | null |
복리후생비 | 관리팀 | Modified | 3,000,000 | 2,500,000 | -500,000 | -16.7 | ⚠️ 중요 |
교육훈련비 | 관리팀 | Removed | 2,000,000 | null | -2,000,000 | null | null |
마케팅비 | 영업팀 | Added | null | 10,000,000 | +10,000,000 | null | null |
경영진 보고용 피벗 테이블
이 결과를 피벗 테이블로 요약:
부서별 예산 집행률
부서 | 예산 합계 | 실적 합계 | 차이액 | 집행률(%) |
---|---|---|---|---|
영업팀 | 55,000,000 | 67,200,000 | +12,200,000 | 122.2 |
관리팀 | 35,000,000 | 32,000,000 | -3,000,000 | 91.4 |
주의 필요 항목 필터
– 복리후생비(관리팀): -16.7% (행사 취소로 절감)
– 마케팅비(영업팀): 예산 없이 10백만원 집행 (신규)
확장 케이스 2: 기간 비교 분석 (MoM / YoY)
실무 배경
매출 트렌드 분석에서 가장 중요한 것은 전월(MoM) 또는 전년 동기(YoY) 대비 변동입니다.
– 어떤 제품이 성장하고 있는가?
– 어떤 지역에서 매출이 감소하는가?
– 신규 제품/중단 제품은?
데이터 준비 예시 (MoM)
Sales_202409 테이블 (9월)
제품코드 | 지역 | 매출액 | 판매량 |
---|---|---|---|
PROD-A | 서울 | 100,000,000 | 1,000 |
PROD-A | 부산 | 50,000,000 | 500 |
PROD-B | 서울 | 80,000,000 | 800 |
PROD-B | 부산 | 40,000,000 | 400 |
PROD-C | 서울 | 30,000,000 | 300 |
Sales_202410 테이블 (10월)
제품코드 | 지역 | 매출액 | 판매량 |
---|---|---|---|
PROD-A | 서울 | 120,000,000 | 1,200 |
PROD-A | 부산 | 45,000,000 | 450 |
PROD-B | 서울 | 85,000,000 | 850 |
PROD-B | 부산 | 42,000,000 | 420 |
PROD-D | 서울 | 50,000,000 | 500 |
Power Query 설정
let
// MoM 분석
StartName = "Sales_202409", // 9월 (과거)
EndName = "Sales_202410", // 10월 (현재)
KeyCols = {"제품코드", "지역"},
Culture = "ko-KR",
// ... (기본 템플릿)
in
Result
추가 분석: 성장률 계산
// 매출 성장률
AddSalesGrowth = Table.AddColumn(
Result, "매출성장률(%)",
each
if [ChangeType] = "Modified" and [매출액] <> 0 then
Number.Round(([매출액_End] - [매출액]) / [매출액] * 100, 1)
else if [ChangeType] = "Added" then
null // 신규는 성장률 계산 불가
else null,
type number
),
// 판매량 성장률
AddQtyGrowth = Table.AddColumn(
AddSalesGrowth, "판매량성장률(%)",
each
if [ChangeType] = "Modified" and [판매량] <> 0 then
Number.Round(([판매량_End] - [판매량]) / [판매량] * 100, 1)
else null,
type number
),
// 트렌드 분류
AddTrend = Table.AddColumn(
AddQtyGrowth, "트렌드",
each
if [ChangeType] = "Added" then "🆕 신규"
else if [ChangeType] = "Removed" then "❌ 중단"
else if [매출성장률(%)] >= 10 then "📈 고성장"
else if [매출성장률(%)] >= 0 then "➡️ 안정"
else if [매출성장률(%)] >= -10 then "📉 주의"
else "🚨 급감"
,
type text
)
최종 결과
제품코드 | 지역 | ChangeType | 9월매출 | 10월매출 | 매출성장률(%) | 판매량성장률(%) | 트렌드 |
---|---|---|---|---|---|---|---|
PROD-A | 서울 | Modified | 100,000,000 | 120,000,000 | +20.0 | +20.0 | 📈 고성장 |
PROD-A | 부산 | Modified | 50,000,000 | 45,000,000 | -10.0 | -10.0 | 📉 주의 |
PROD-B | 서울 | Modified | 80,000,000 | 85,000,000 | +6.3 | +6.3 | ➡️ 안정 |
PROD-B | 부산 | Modified | 40,000,000 | 42,000,000 | +5.0 | +5.0 | ➡️ 안정 |
PROD-C | 서울 | Removed | 30,000,000 | null | null | null | ❌ 중단 |
PROD-D | 서울 | Added | null | 50,000,000 | null | null | 🆕 신규 |
YoY 분석 (동일 로직)
// YoY 분석
StartName = "Sales_202310", // 2023년 10월
EndName = "Sales_202410", // 2024년 10월
KeyCols = {"제품코드", "지역"},
계절성 패턴, 연간 성장 추세를 파악하는 데 활용합니다.
확장 케이스 3: 원가 분석 (Standard vs Actual Cost)
실무 배경
제조업에서 가장 중요한 관리회계 업무 중 하나가 원가 차이 분석입니다:
– 표준원가 대비 실제원가 차이가 얼마나 발생했는가?
– 어떤 원가 요소(재료비, 노무비, 경비)에서 차이가 큰가?
– 수량 차이인가, 가격 차이인가?
데이터 준비 예시
StandardCost 테이블
제품코드 | 재료비(표준) | 노무비(표준) | 제조경비(표준) | 표준수량 | 표준단가 |
---|---|---|---|---|---|
PROD-001 | 1,000 | 500 | 200 | 100 | 1,700 |
PROD-002 | 2,000 | 800 | 300 | 50 | 3,100 |
PROD-003 | 1,500 | 600 | 250 | 80 | 2,350 |
ActualCost 테이블
제품코드 | 재료비(실제) | 노무비(실제) | 제조경비(실제) | 실제수량 | 실제단가 |
---|---|---|---|---|---|
PROD-001 | 1,200 | 480 | 220 | 110 | 1,900 |
PROD-002 | 1,950 | 820 | 310 | 48 | 3,080 |
PROD-003 | 1,600 | 650 | 270 | 85 | 2,520 |
Power Query 설정
let
StartName = "StandardCost",
EndName = "ActualCost",
KeyCols = {"제품코드"},
Culture = "ko-KR",
// ... (기본 템플릿)
in
Result
고급 분석: Variance 세분화
제조 원가 분석의 핵심은 수량 차이와 가격 차이를 분리하는 것입니다:
// 1) 재료비 수량 차이 (Material Quantity Variance)
AddMQV = Table.AddColumn(
Result, "재료비_수량차이",
each
if [ChangeType] = "Modified" then
([실제수량_End] - [표준수량]) * [표준단가]
else null,
type number
),
// 2) 재료비 가격 차이 (Material Price Variance)
AddMPV = Table.AddColumn(
AddMQV, "재료비_가격차이",
each
if [ChangeType] = "Modified" then
([실제단가_End] - [표준단가]) * [실제수량_End]
else null,
type number
),
// 3) 총 원가 차이
AddTotalVar = Table.AddColumn(
AddMPV, "총원가차이",
each
if [ChangeType] = "Modified" then
([재료비(실제)_End] + [노무비(실제)_End] + [제조경비(실제)_End]) -
([재료비(표준)] + [노무비(표준)] + [제조경비(표준)])
else null,
type number
),
// 4) 차이 분류
AddVarType = Table.AddColumn(
AddTotalVar, "차이유형",
each
if [총원가차이] = null then null
else if [총원가차이] > 0 then "🔴 불리한 차이"
else if [총원가차이] < 0 then "🟢 유리한 차이"
else "⚪ 차이 없음",
type text
)
최종 결과
제품코드 | ChangeType | 표준원가 | 실제원가 | 재료비_수량차이 | 재료비_가격차이 | 총원가차이 | 차이유형 |
---|---|---|---|---|---|---|---|
PROD-001 | Modified | 1,700 | 1,900 | +170 | +2,200 | +200 | 🔴 불리한 차이 |
PROD-002 | Modified | 3,100 | 3,080 | -310 | -96 | -20 | 🟢 유리한 차이 |
PROD-003 | Modified | 2,350 | 2,520 | +235 | +425 | +170 | 🔴 불리한 차이 |
인사이트
PROD-001 분석
– 총원가차이: +200 (불리)
– 수량차이: +170 (실제 110개 vs 표준 100개)
– 가격차이: +2,200 (실제 단가 상승)
– 조치: 재료 구매 단가 협상 필요
PROD-002 분석
– 총원가차이: -20 (유리)
– 수량차이: -310 (실제 48개 vs 표준 50개, 효율 향상)
– 가격차이: -96 (재료비 절감)
– 평가: 공정 개선 효과 확인
확장 케이스 4: 감사 추적 (Audit Trail)
실무 배경
SOX 법규 준수 또는 내부 통제를 위해 데이터 변경 이력을 추적해야 하는 경우:
– 재무제표 수정 내역
– 재고 수량 변경 기록
– 고정자산 변동 이력
데이터 준비
FixedAssets_Before (마감 전)
자산번호 | 자산명 | 취득가액 | 감가상각누계액 | 장부가액 | 담당부서 |
---|---|---|---|---|---|
FA-001 | 서버장비 | 10,000,000 | 6,000,000 | 4,000,000 | IT팀 |
FA-002 | 차량 | 30,000,000 | 15,000,000 | 15,000,000 | 영업팀 |
FA-003 | 사무기기 | 5,000,000 | 3,000,000 | 2,000,000 | 관리팀 |
FixedAssets_After (마감 후)
자산번호 | 자산명 | 취득가액 | 감가상각누계액 | 장부가액 | 담당부서 |
---|---|---|---|---|---|
FA-001 | 서버장비 | 10,000,000 | 6,200,000 | 3,800,000 | IT팀 |
FA-002 | 차량 | 30,000,000 | 15,500,000 | 14,500,000 | 영업팀 |
FA-004 | 복합기 | 3,000,000 | 0 | 3,000,000 | 관리팀 |
Power Query 설정
let
StartName = "FixedAssets_Before",
EndName = "FixedAssets_After",
KeyCols = {"자산번호"},
Culture = "ko-KR",
// ... (기본 템플릿)
// 감사 추적용 메타데이터 추가
AddAuditMeta = Table.AddColumn(
Result, "검증일시",
each DateTime.LocalNow(),
type datetime
),
AddUser = Table.AddColumn(
AddAuditMeta, "검증자",
each Environment.UserName,
type text
),
// 변경 중요도 플래그
AddSeverity = Table.AddColumn(
AddUser, "중요도",
each
if [ChangeType] = "Added" then "🆕 신규 취득"
else if [ChangeType] = "Removed" then "⚠️ 폐기/매각"
else if [ChangedCols] <> null and
List.Contains([ChangedCols], "취득가액") then
"🚨 취득가액 수정"
else if [ChangedCols] <> null and
List.Contains([ChangedCols], "감가상각누계액") then
"📝 정상 감가상각"
else "ℹ️ 기타 변경",
type text
)
in
AddSeverity
최종 감사 리포트
자산번호 | 자산명 | ChangeType | ChangedCols | 중요도 | 검증일시 | 검증자 |
---|---|---|---|---|---|---|
FA-001 | 서버장비 | Modified | [“감가상각누계액”,”장부가액”] | 📝 정상 감가상각 | 2025-10-04 15:30 | bjt |
FA-002 | 차량 | Modified | [“감가상각누계액”,”장부가액”] | 📝 정상 감가상각 | 2025-10-04 15:30 | bjt |
FA-003 | 사무기기 | Removed | null | ⚠️ 폐기/매각 | 2025-10-04 15:30 | bjt |
FA-004 | 복합기 | Added | null | 🆕 신규 취득 | 2025-10-04 15:30 | bjt |
감사 대응 활용
1) 외부 감사 대응
– “FA-003이 왜 사라졌나요?” → Removed 확인, 폐기 승인 문서와 매칭
– “FA-004는 언제 추가됐나요?” → Added 확인, 검증일시 제공
2) 내부 통제
– 취득가액 수정이 발생하면 “🚨 취득가액 수정” 플래그로 즉시 감지
– 정기 감가상각은 “📝 정상 감가상각”으로 필터링하여 제외
3) 컴플라이언스 리포트 자동 생성
// 중요 변경 사항만 필터링
Table.SelectRows(
AddSeverity,
each [중요도] = "🚨 취득가액 수정" or
[중요도] = "⚠️ 폐기/매각" or
[중요도] = "🆕 신규 취득"
)
실무 적용 시 체크리스트
확장 적용 전 확인사항
- 데이터 품질
- [ ] 테이블에 중복 데이터 없는지 확인
- [ ] 키 열에 null 값 없는지 확인
- [ ] 숫자 필드가 텍스트로 저장되지 않았는지 확인
- 키 열 선정
- [ ] 단일 키로 충분한가? 복합 키가 필요한가?
- [ ] 키 열 조합이 고유성을 보장하는가?
- 비교 범위
- [ ] 모든 열을 비교해야 하는가?
- [ ] 제외해야 할 열이 있는가? (예: 타임스탬프, 시스템 생성 ID)
- 성능 고려
- [ ] 테이블 크기가 적절한가? (수만 행 이상이면 데이터베이스 활용 고려)
- [ ] Refresh 시간이 허용 범위인가?
확장 시 추천 순서
- 오더북 비교 (기본) → 로직 숙지
- 예산 vs 실적 (단순 확장) → 분석 컬럼 추가 연습
- MoM/YoY (시계열) → 피벗 테이블 활용
- 원가 분석 (고급) → Variance 세분화
- 감사 추적 (메타데이터) → 컴플라이언스 리포트
실무 적용 가이드
Step 1: 파일 준비
- Excel 파일에 비교할 두 테이블 생성
- 테이블 이름 지정 (예: “Budget_2025”, “Actual_2025”)
- 중요: 깨끗한 데이터 사용 (숨겨진 서식 제거)
Step 2: Power Query 편집기
- Excel → 데이터 탭 → “데이터 가져오기” → “기타 원본에서” → “빈 쿼리”
- 고급 편집기 열기
- 위 템플릿 코드 붙여넣기
- 설정 섹션 수정 (테이블명, 키 열)
Step 3: 실행 및 확인
- “닫기 및 로드”
- 결과 테이블 확인
- 피벗 테이블로 요약 분석
Troubleshooting: 모든 행이 “Modified”로 나올 때
증상: 육안으로 동일한 데이터인데 전부 Modified
원인
– Excel 테이블의 숨겨진 서식/메타데이터 오염
– Power Query 캐시 문제
– 보이지 않는 공백 문자
해결책
1. 새 Excel 파일 생성
2. 두 테이블을 값으로만 복사 (Ctrl+Alt+V → 값)
3. 새 테이블로 다시 Power Query 실행
교훈: Power Query 결과가 이상하면 데이터 자체보다 컨테이너(테이블 객체) 문제일 수 있음
Power Query vs SQL: 개념적 유사성
회계 실무자들은 SQL을 모르는 경우가 많지만, Power Query는 “비주얼 SQL”입니다.
SQL | Power Query | 설명 |
---|---|---|
SELECT | 열 선택 UI | 필요한 컬럼만 |
WHERE | Table.SelectRows | 조건 필터링 |
JOIN | Table.NestedJoin | 테이블 병합 |
GROUP BY | Table.Group | 그룹화/집계 |
CASE WHEN | if…then…else | 조건부 로직 |
WITH CTE | let…in | 중간 결과 저장 |
장점
– 시각적 피드백: 각 단계별 즉시 확인
– Undo 가능: 실수해도 쉽게 되돌리기
– Excel과 자연스러운 통합
마무리: AI 시대, 회계사의 생존 전략
이 프로젝트가 증명하는 것
AI는 도메인 없이는 쓸모없다
– GPT가 오더북 마감 프로세스를 이해할 수 없다
– “중복 발주번호가 왜 문제인지” AI는 모른다
– “마감 자료 변동 체크”의 중요성도 모른다
회계사 + AI = 진짜 가치
– 회계사: 문제 정의, 도메인 지식
– AI (Power Query/Python): 자동화, 확장
– 결과: 마감 시간 3시간 → 20분
실제 효과
Before
– 수작업으로 VLOOKUP, 눈으로 확인
– 마감 시간: 3시간
– 실수 발생 위험
After
– Power Query Refresh 한 번
– 마감 시간: 20분
– 정확도 100%
– 다른 분석에도 재사용
마치며
이 글에서 소개한 테이블 비교 로직은 단순한 Excel 트릭이 아닙니다.
회계 실무의 반복 작업을 시스템화하고, AI 시대에 생존하는 회계 실무자의 모습을 보여주는 실전 사례입니다.
도메인 지식(회계) + 기술(Power Query) + AI 협업 = 대체 불가능한 가치
여러분도 지금 당장 적용해보세요. 다음 월말 마감이 기다려질 겁니다.
Tags: #회계실무 #PowerQuery #Excel자동화 #데이터분석 #변경추적 #VarianceAnalysis #AI시대생존전략
카테고리: 회계, 데이터 분석, 자동화
© 2025 B.J.T. – Boundless Journey of Thought
https://www.boundlessjourneyofthought.com/
Leave a Reply