문제 정의 — 영업 데이터나 재고 데이터처럼 열이 많은 시트에서는 한 셀에 계산을 몰아넣는 습관이 생기기 쉽습니다. 할인 금액을 구하고 세액을 계산한 뒤 합계와 단가를 만드는 흐름을 괄호로만 이어 붙이면, 수식은 길어지고 누군가가 읽기 어려워집니다. 더 큰 문제는 같은 중간 계산을 여러 번 반복하는 순간부터 재계산 비용이 눈덩이처럼 불어난다는 점입니다. Excel 365와 Google Sheets가 제공하는 LET
은 이런 문제를 정면에서 해결합니다. 중간 결과에 이름을 붙여 한 번만 계산하고 여러 번 재사용하게 해 주므로, 수식은 읽히고 시트는 빨라집니다.
샘플 파일 내려받기
- 샘플 원본 CSV: A9_let_sample.csv
- 결과 CSV(계산 열 포함본): A9_let_result.csv
샘플 데이터 설명
데이터는 일자와 품목, 지역, 채널, 수량, 단가, 할인율, 세율로 구성되어 있습니다. 결과 파일에는 매출 총액, 할인 금액, 과세 대상 금액, 세액, 실청구액, 단위당 실청구액이 계산된 열이 추가되어 있습니다. 이 글의 수식은 해당 열을 만드는 과정을 그대로 따릅니다.
원본 A9_let_sample.csv
컬럼 | 의미 | 예시 | 비고 |
---|---|---|---|
date |
거래일 | 2025-07-14 | YYYY-MM-DD |
item |
품목 코드 | D | 문자 |
region |
지역 | Seoul | 문자 |
channel |
판매 채널 | Online | 문자 |
qty |
수량 | 12 | 정수 |
price |
단가 | 3100 | 정수 |
discount_rate |
할인율 | 0.1 | 소수 |
tax_rate |
세율 | 0.1 | 소수 |
결과 A9_let_result.csv
컬럼 | 의미 | 예시 | 계산 개념 |
---|---|---|---|
gross |
매출 총액 | 32266 | qty×price |
discount_amt |
할인 금액 | 3226.6 | gross×discount_rate |
tax_base |
과세 대상 금액 | 29039.4 | gross−discount_amt |
tax_amt |
세액 | 2463.04 | tax_base×tax_rate |
net_amount |
실청구액 | 27093.49 | tax_base+tax_amt |
unit_net |
단위당 실청구액 | 2084.11 | net_amount÷qty |
먼저 나쁜 예. 괄호만으로 이어 붙인 긴 수식
다음과 같은 형태의 계산은 작성은 빠르지만 유지보수와 성능에 나쁩니다. 같은 중간 항을 여러 번 계산하기 때문입니다.
=(([@qty]*[@price]) - ([@qty]*[@price])*[@discount_rate]) * (1+[@tax_rate])
여기서는 [@qty]*[@price]
가 두 번 등장합니다. 행이 수천 개라면 불필요한 계산이 바로 비용이 됩니다. 또한 할인 전 금액과 과세 대상 금액을 구분해서 읽기 어렵습니다.
LET로 바꾸면 이렇게 달라집니다
=LET(
q, [@qty],
p, [@price],
dr, [@discount_rate],
tr, [@tax_rate],
gross, q*p,
disc, gross*dr,
base, gross-disc,
net, base*(1+tr),
net
)
중간 결과가 이름을 얻었습니다. q와 p는 한 번만 곱해지고, discount와 tax 계산이 무엇을 뜻하는지 수식만 읽어도 이해가 됩니다. 마지막 줄에 반환할 이름을 두면 해당 값을 셀에 출력합니다. 이 패턴은 앞으로 소개할 모든 레시피의 기본형입니다.
배열과 LET. 한 번의 선언 여러 셀의 결과
동적 배열 함수와 결합하면 표 전체를 한 번에 계산할 수 있습니다. 예를 들어 매출 총액, 할인 금액, 과세 대상 금액, 세액, 실청구액 열을 동시에 생성하려면 다음과 같이 작성하실 수 있습니다.
=LET(
t, Table1,
q, t[qty], p, t[price], dr, t[discount_rate], tr, t[tax_rate],
gross, q*p,
disc, gross*dr,
base, gross-disc,
tax, base*tr,
net, base+tax,
HSTACK(gross, disc, base, tax, net)
)
이 수식은 다섯 개의 열을 한 번에 흘려보냅니다. 계산 순서가 분명하고, 같은 벡터를 여러 번 곱하거나 더하지 않습니다. 만약 단위당 실청구액까지 필요하다면 마지막 HSTACK
에 net/q
를 추가하면 됩니다.
실전 패턴 1. 표시와 계산을 분리
보고서에서는 같은 숫자를 다른 형식으로 표시해야 하는 일이 잦습니다. LET 내부에서 숫자를 계산하고, 표시 형식은 외부에서 셀 서식으로 처리하십시오. 수식 안에서 TEXT
를 남발하면 이후 합계나 평균 같은 2차 계산이 깨질 수 있습니다. 예를 들어 net을 반환한 뒤 열 서식을 통화로 지정하면 텍스트가 아닌 숫자 상태를 유지할 수 있습니다.
실전 패턴 2. 조건과 예외를 변수로 추출
할인 적용 여부가 채널이나 지역에 따라 바뀐다면 조건식도 변수로 승격시키는 편이 좋습니다.
=LET(
t, Table1,
q, t[qty], p, t[price],
dr, t[discount_rate],
tr, t[tax_rate],
is_sale, --(t[channel]="Online"),
eff_dr, IF(is_sale, dr, 0),
gross, q*p,
disc, gross*eff_dr,
base, gross-disc,
net, base*(1+tr),
net
)
조건에 이름을 붙이면 나중에 정책이 바뀌어도 그 한 줄만 수정하면 됩니다. 또한 --
로 논리를 숫자 벡터로 바꾸면 집계에도 바로 활용할 수 있습니다.
실전 패턴 3. 중복 방지와 성능
같은 참조를 여러 번 쓰면 Excel과 Sheets는 매번 계산을 수행합니다. LET로 중간 항을 모아두면 같은 연산을 반복하지 않아 계산 횟수가 줄어듭니다. 5만 행 정도에서 할인과 세금 계산을 여러 번 반복하던 수식을 LET로 치환하면 체감 시간이 분명히 개선됩니다. 특히 대용량에서 SUMPRODUCT
처럼 무거운 함수가 반복되는 경우 LET로 인자를 변수화하고 재사용하십시오.
비교 예. 피벗 없이 지표 카드 만들기
오늘, 이번 달, 올해 누계를 한 번에 계산하는 전형적인 카드 지표를 LET 하나로 묶을 수 있습니다. 날짜 열이 Table1[date]라고 가정합니다.
=LET(
d, Table1[date],
amt, Table1[net_amount],
today, TODAY(),
is_today, --(d=today),
is_month, --(TEXT(d,"yyyymm")=TEXT(today,"yyyymm")),
is_year, --(YEAR(d)=YEAR(today)),
HSTACK(SUM(amt*is_today), SUM(amt*is_month), SUM(amt*is_year))
)
조건을 벡터로 미리 만들어 곱해 버리면 FILTER를 두 번 세 번 호출하는 것보다 가볍고 직관적입니다. 각 합계는 숫자 상태를 유지하므로 추가 계산에 안전합니다.
Google Sheets에서의 LET
Sheets에서도 LET 구문은 동일합니다. 다만 구조적 참조가 없으므로 INDEX
나 열 번호로 접근하시면 됩니다.
=LET(
d, A2:H, -- 원본 범위
q, INDEX(d,,5),
p, INDEX(d,,6),
dr, INDEX(d,,7),
tr, INDEX(d,,8),
gross, q*p,
disc, gross*dr,
base, gross-disc,
tax, base*tr,
net, base+tax,
HSTACK(gross, disc, base, tax, net, net/q)
)
Sheets는 BYROW, BYCOL, SCAN 같은 함수와 조합했을 때 진가가 드러납니다. 행 단위로 조건을 검사하거나 누계를 추가하는 로직도 LET 내부에서 단계별로 명시하세요.
검증과 테스트를 자동화하는 방식
LET로 수식을 분해해 두면 검증도 쉬워집니다. 다음 검증 스니펫을 사용해 결과 열이 논리적으로 일관되는지 확인하십시오.
-- 총액은 과세 대상 금액과 할인 금액으로 정확히 분해되어야 합니다
=SUM(Table1[gross]) = SUM(Table1[tax_base] + Table1[discount_amt])
-- 실청구액 합은 과세 대상 금액 합과 세액 합의 합과 같아야 합니다
=SUM(Table1[net_amount]) = SUM(Table1[tax_base]) + SUM(Table1[tax_amt])
-- 단위당 실청구액의 합이 아닌 평균을 보고할 때
=AVERAGE(Table1[unit_net]) -- 합계가 아니라 평균이 지표인 경우가 많습니다
자주 묻는 질문과 해결책
- 변수 이름은 어디까지 길게 써도 되나요 — 읽히는 선에서 충분히 길게 쓰십시오. team_disc_rate처럼 의미가 분명한 이름이 유지보수에 유리합니다.
- LET 안에서 또 LET을 써도 되나요 — 가능합니다. 다만 과도한 중첩은 다시 읽기 어려워집니다. 단계별 블록을 HSTACK으로 나누어 반환하는 것도 방법입니다.
- IFERROR는 어디에 두나요 — 가장 바깥쪽 반환 위치에 두면 불필요한 삼항 분기가 줄어듭니다. 예
=IFERROR(LET(..., net), "")
- 형식 지정은 어디서 하나요 — 가능한 한 셀 서식으로 처리하십시오. 수식 내부의 TEXT는 계산을 텍스트로 바꿔 2차 집계를 막을 수 있습니다.
작성 루틴을 표준화해 보세요
실무에서는 다음 순서를 추천드립니다. 하나. 입력 범위를 가장 위에서 변수로 선언합니다. 둘. 중간 계산을 의미 단위로 이름 붙여 나열합니다. 셋. 반환부에서 필요한 열이나 요약값을 HSTACK 혹은 VSTACK으로 모아 돌려줍니다. 표준 루틴을 팀에 공유해 두면 새로 합류한 동료도 같은 문법을 따라가기 쉬워집니다.
정리하며
LET의 핵심은 셀 한 칸에 작은 스크립트를 적는다는 감각입니다. 이름을 가진 단계가 생기는 순간 수식은 설명서가 되고, 중복 계산이 사라지면서 속도도 확보됩니다. 본문에 제시한 패턴을 그대로 적용하시고 제공된 CSV를 불러와 계산 열을 만들어 보십시오. 복잡해 보이던 할인과 세금 로직이 누구나 읽을 수 있는 규칙으로 바뀌는 경험을 하실 수 있습니다.