피벗 없이 ‘월별 누적합’ 자동 계산하기: SCAN 함수로 보고서 한 줄 줄이는 법

피벗 없이 월별 누적합을 자동으로 계산하는 방법
매출, 입금, 출고, 비용 데이터를 정리하다 보면 단순 합계보다 누적합이 더 중요할 때가 많습니다. 예를 들어 “이번 달 10일까지 매출이 얼마까지 쌓였는지”, “담당자별로 실적이 누적되는 흐름이 어떤지”, “월별 목표 대비 현재 어디까지 왔는지”를 보고 싶을 때가 그렇습니다.
보통은 보조열에 =SUM($D$2:D2) 같은 수식을 넣고 아래로 복사합니다. 이 방식도 나쁘지 않지만, 데이터가 추가될 때마다 범위를 확인해야 하고, 정렬이 바뀌면 누적 결과가 엉킬 수 있습니다. 이번 글에서는 Microsoft 365 환경에서 사용할 수 있는 SCAN 함수를 이용해 피벗테이블 없이도 누적합을 자동으로 계산하는 방법을 정리해보겠습니다.
예제 데이터 구조
아래처럼 거래일, 담당자, 구분, 금액이 있는 매출 원장을 기준으로 설명하겠습니다. 실무에서는 이 범위를 먼저 표로 바꿔두는 것이 좋습니다. 데이터 영역 아무 셀이나 클릭한 뒤 Ctrl + T를 누르면 표로 변환됩니다.
| 거래일 | 담당자 | 구분 | 금액 |
|---|---|---|---|
| 2026-06-01 | 김대리 | 매출 | 350000 |
| 2026-06-01 | 이과장 | 매출 | 420000 |
| 2026-06-03 | 김대리 | 매출 | 180000 |
| 2026-06-05 | 박차장 | 매출 | 610000 |
| 2026-06-07 | 김대리 | 반품 | -90000 |
표 이름은 예를 들어 tblSales라고 하겠습니다. 표 이름은 표 디자인 > 표 이름에서 확인하거나 변경할 수 있습니다.
1단계: 전체 누적합을 한 번에 계산하기
가장 기본 형태는 아래 수식입니다. 금액 열을 위에서부터 차례대로 더하면서 누적 결과를 배열로 반환합니다.
=SCAN(0, tblSales[금액], LAMBDA(a, v, a+v))
여기서 각 인수의 의미는 다음과 같습니다.
| 부분 | 의미 |
|---|---|
0 | 누적을 시작할 초기값입니다. |
tblSales[금액] | 차례대로 누적할 금액 범위입니다. |
LAMBDA(a, v, a+v) | a는 이전까지의 누적값, v는 현재 행의 금액입니다. |
이 수식은 아래로 복사하지 않아도 결과가 자동으로 쭉 펼쳐집니다. 그래서 원본 표에 행이 추가되면 누적합 결과도 같이 늘어납니다. 보고서용 시트에 연결해두면 매번 수식을 끌어내리는 일을 줄일 수 있습니다.
2단계: 날짜순으로 정렬한 뒤 누적하기
실무에서 누적합이 틀리는 가장 흔한 이유는 원본 데이터가 날짜순으로 정렬되어 있지 않기 때문입니다. 누적합은 순서가 매우 중요합니다. 입력 순서가 뒤섞여 있으면 계산 자체는 맞아도 보고서 의미가 달라집니다.
이럴 때는 SORTBY와 LET을 같이 쓰면 좋습니다.
=LET(
data, SORTBY(tblSales, tblSales[거래일], 1),
amt, CHOOSECOLS(data, 4),
HSTACK(data, SCAN(0, amt, LAMBDA(a, v, a+v)))
)
위 수식은 원본 표를 거래일 오름차순으로 정렬한 다음, 금액 열을 누적하고, 마지막 열에 누적합을 붙여서 보여줍니다. HSTACK은 옆으로 붙이는 함수이고, CHOOSECOLS(data, 4)는 정렬된 데이터에서 4번째 열인 금액만 가져오는 역할입니다.
3단계: 특정 구분만 누적하기
매출과 반품이 같이 들어있는 원장에서 “매출만 누적”하고 싶을 때가 있습니다. 이때는 FILTER로 먼저 필요한 데이터만 남긴 뒤 누적하면 됩니다.
=LET(
f, FILTER(tblSales, tblSales[구분]="매출"),
s, SORTBY(f, CHOOSECOLS(f, 1), 1),
amt, CHOOSECOLS(s, 4),
HSTACK(s, SCAN(0, amt, LAMBDA(a, v, a+v)))
)
이 수식의 장점은 조건이 바뀌어도 구조가 안정적이라는 점입니다. 예를 들어 "매출" 대신 셀 주소 G2를 넣어두면, G2에 선택한 구분에 따라 누적표가 자동으로 바뀝니다.
=LET(
f, FILTER(tblSales, tblSales[구분]=G2),
s, SORTBY(f, CHOOSECOLS(f, 1), 1),
amt, CHOOSECOLS(s, 4),
HSTACK(s, SCAN(0, amt, LAMBDA(a, v, a+v)))
)
4단계: 월별 누적합 만들기
월별 보고서에서는 전체 기간 누적보다 월이 바뀌면 다시 0부터 시작하는 누적합이 더 자주 필요합니다. 이 경우에는 먼저 해당 월 데이터만 필터링한 뒤 SCAN을 적용하면 깔끔합니다.
예를 들어 기준월을 H1 셀에 입력해두었다고 가정하겠습니다. H1에는 2026-06-01처럼 해당 월의 아무 날짜나 입력해도 됩니다.
=LET(
startDate, EOMONTH(H1,-1)+1,
endDate, EOMONTH(H1,0),
f, FILTER(tblSales, (tblSales[거래일]>=startDate)*(tblSales[거래일]<=endDate)),
s, SORTBY(f, CHOOSECOLS(f,1), 1),
amt, CHOOSECOLS(s,4),
HSTACK(s, SCAN(0, amt, LAMBDA(a, v, a+v)))
)
여기서 startDate는 기준월의 1일, endDate는 기준월의 말일입니다. 날짜 조건을 직접 손으로 바꾸지 않아도 되기 때문에 월별 보고서 양식에 넣어두기 좋습니다.
담당자별 누적합은 어떻게 할까?
담당자별로 누적합을 보고 싶다면 방법이 두 가지입니다. 첫 번째는 담당자를 선택하는 셀을 만들고 해당 담당자 데이터만 필터링하는 방식입니다. 이 방식이 보고서에서는 가장 관리하기 쉽습니다.
=LET(
name, H2,
f, FILTER(tblSales, tblSales[담당자]=name),
s, SORTBY(f, CHOOSECOLS(f,1), 1),
amt, CHOOSECOLS(s,4),
HSTACK(s, SCAN(0, amt, LAMBDA(a, v, a+v)))
)
두 번째는 담당자별 누적을 원본 행 옆에 표시하는 방식입니다. 이때는 SCAN만으로 처리하려고 하면 행마다 그룹이 바뀌는 문제 때문에 수식이 복잡해집니다. 원본 행 기준 담당자별 누적은 아래처럼 SUMIFS가 오히려 실무적으로 안전합니다.
=SUMIFS(tblSales[금액], tblSales[담당자], [@담당자], tblSales[거래일], "<="&[@거래일])
단, 같은 날짜에 같은 담당자의 거래가 여러 건 있으면 이 수식은 같은 날짜까지 한꺼번에 누적합니다. “입력 순서까지 반영한 행별 누적”이 필요하다면 거래번호 또는 입력순번 열을 하나 추가해두는 편이 좋습니다.
흔한 실수 5가지
- 날짜가 텍스트인 경우: 겉보기에는 날짜처럼 보여도 실제 값이 텍스트면 정렬과 조건식이 틀어질 수 있습니다. 셀 서식을 바꿔도 해결되지 않으면 날짜 변환이 필요합니다.
- 금액에 쉼표가 문자로 들어간 경우:
350,000이 숫자가 아니라 텍스트면 누적합에서 오류가 나거나 0처럼 취급될 수 있습니다. - 정렬 없이 누적하는 경우: 누적합은 반드시 기준 순서가 먼저 정해져야 합니다. 날짜, 거래번호, 입력순번 중 어떤 기준인지 명확히 잡아야 합니다.
- 동적 배열 결과 영역에 값이 있는 경우: 수식 결과가 아래로 펼쳐질 공간에 다른 값이 있으면
#SPILL!오류가 발생합니다. - 표 열 순서가 바뀐 경우:
CHOOSECOLS(data, 4)처럼 열 번호를 쓰는 수식은 열 위치가 바뀌면 결과가 달라질 수 있습니다.
확인 순서: 누적합이 이상할 때 먼저 볼 것
- 거래일이 실제 날짜 값인지 확인합니다.
- 금액 열이 숫자인지 확인합니다.
- 누적 기준 정렬이 맞는지 확인합니다.
- 필터 조건에 빠지는 데이터가 없는지 확인합니다.
- 동일 날짜 거래가 여러 건일 때 어떤 순서로 누적할지 결정합니다.
응용 팁: 누적률까지 같이 표시하기
목표금액이 J1 셀에 있다면 누적합 옆에 누적률도 같이 붙일 수 있습니다.
=LET(
f, FILTER(tblSales, tblSales[구분]="매출"),
s, SORTBY(f, CHOOSECOLS(f,1), 1),
amt, CHOOSECOLS(s,4),
run, SCAN(0, amt, LAMBDA(a, v, a+v)),
HSTACK(s, run, run/$J$1)
)
결과의 마지막 열을 백분율 서식으로 바꾸면 목표 대비 누적 달성률을 바로 확인할 수 있습니다. 조건부 서식을 추가해 80% 이상은 노랑, 100% 이상은 초록으로 표시하면 월간 실적판으로도 충분히 쓸 수 있습니다.
마무리
SCAN 함수는 처음 보면 낯설지만, 누적합을 자주 다루는 분들에게는 꽤 강력한 도구입니다. 특히 LET, FILTER, SORTBY와 함께 쓰면 “정렬 → 조건 추출 → 누적 계산 → 결과표 생성”까지 한 번에 처리할 수 있습니다.
다만 모든 상황에서 SCAN이 정답은 아닙니다. 행별 담당자 누적처럼 원본 표 옆에 계산 결과를 붙이는 구조라면 SUMIFS가 더 단순할 때도 많습니다. 핵심은 누적 기준이 무엇인지 먼저 정하고, 보고서용 출력인지 원본 관리용 계산인지에 따라 방식을 고르는 것입니다.
반복해서 내려 쓰던 누적합 수식이 있다면, 이번 기회에 표와 동적 배열 수식으로 한 번 바꿔보세요. 데이터가 늘어날수록 관리 차이가 꽤 크게 느껴질 겁니다.