콘텐츠데이터모델
수식
수식을 사용하여 자동 계산을 설정하세요.
수식 기본 사용법
수식 속성 추가
- + 속성 추가 → 수식(Formula) 선택
- 수식 편집기에서 수식 입력
- 저장
기본 구문
prop("속성이름")prop() 함수로 다른 속성의 값을 가져와 계산합니다.
// 총 금액 계산
prop("단가") * prop("수량")속성 참조
prop()
다른 속성의 값을 가져옵니다.
prop("속성이름")| 속성 타입 | 반환 값 |
|---|---|
| 텍스트 | 문자열 |
| 숫자/통화 | 숫자 |
| 날짜 | 날짜 객체 |
| 체크박스 | true/false |
| 선택 | 선택된 값 문자열 |
| 다중 선택 | 값 배열 |
연산자
산술 연산자
기본적인 수학 계산을 수행합니다.
| 연산자 | 설명 | 예시 |
|---|---|---|
+ | 덧셈 | prop("A") + prop("B") |
- | 뺄셈 | prop("A") - prop("B") |
* | 곱셈 | prop("A") * prop("B") |
/ | 나눗셈 | prop("A") / prop("B") |
% | 나머지 | prop("A") % prop("B") |
// 총 금액
prop("단가") * prop("수량")
// 할인 적용 가격
prop("정가") * (1 - prop("할인율") / 100)
// 세금 포함 가격
prop("금액") * 1.1비교 연산자
두 값을 비교하여 true/false를 반환합니다.
| 연산자 | 설명 | 예시 |
|---|---|---|
== | 같음 | prop("상태") == "완료" |
!= | 다름 | prop("상태") != "취소" |
> | 크다 | prop("점수") > 80 |
>= | 크거나 같다 | prop("점수") >= 80 |
< | 작다 | prop("재고") < 10 |
<= | 작거나 같다 | prop("재고") <= 10 |
논리 연산자
조건을 조합합니다.
| 연산자 | 설명 | 예시 |
|---|---|---|
and | AND | prop("A") and prop("B") |
or | OR | prop("A") or prop("B") |
not | NOT | not prop("완료") |
// 두 조건 모두 만족
prop("상태") == "진행중" and prop("우선순위") == "높음"
// 둘 중 하나 만족
prop("상태") == "완료" or prop("상태") == "취소"
// 조건 부정
not prop("취소됨")조건문
if()
조건에 따라 다른 값을 반환합니다.
if(조건, 참일때값, 거짓일때값)// 상태 이모지
if(prop("완료"), "✅", "⏳")
// 재고 상태
if(prop("재고") <= 10, "⚠️ 저재고", "정상")
// 등급 계산
if(prop("점수") >= 90, "A", "B 이하")중첩 조건
여러 조건을 순차적으로 검사합니다.
if(prop("점수") >= 90, "A",
if(prop("점수") >= 80, "B",
if(prop("점수") >= 70, "C",
if(prop("점수") >= 60, "D", "F"))))중첩이 깊어지면 가독성이 떨어집니다. 간단한 조건을 먼저 검사하세요.
텍스트 함수
concat()
텍스트를 연결합니다.
concat(텍스트1, 텍스트2, ...)// 이름 결합
concat(prop("성"), " ", prop("이름"))
// 결과: "김 철수"
// 주소 조합
concat(prop("시"), " ", prop("구"), " ", prop("동"))
// 결과: "서울시 강남구 역삼동"
// 라벨 생성
concat("[", prop("카테고리"), "] ", prop("제목"))
// 결과: "[버그] 로그인 오류 수정"length()
텍스트의 길이를 반환합니다.
length(텍스트)// 제목 길이
length(prop("제목"))
// 글자 수 제한 확인
if(length(prop("설명")) > 100, "⚠️ 너무 김", "✅ 적정")contains()
텍스트에 특정 문자열이 포함되어 있는지 확인합니다.
contains(텍스트, 검색어)// 이메일 도메인 확인
if(contains(prop("이메일"), "@gmail.com"), "Gmail", "기타")
// 키워드 포함 여부
if(contains(prop("제목"), "긴급"), "🚨 긴급", "일반")숫자 함수
round(), floor(), ceil()
숫자를 반올림/내림/올림합니다.
// 반올림
round(prop("평균점수")) // 85.4 → 85
// 내림
floor(prop("평균점수")) // 85.9 → 85
// 올림
ceil(prop("평균점수")) // 85.1 → 86abs()
절대값을 반환합니다.
abs(prop("차이")) // -10 → 10min(), max()
최소값/최대값을 반환합니다.
// 최소값
min(prop("예산"), prop("실제비용"))
// 최대값
max(prop("시작일"), prop("종료일"))날짜 함수
now()
현재 날짜와 시간을 반환합니다.
now() // 현재 날짜/시간dateBetween()
두 날짜 사이의 차이를 계산합니다.
dateBetween(날짜1, 날짜2, 단위)| 단위 | 설명 |
|---|---|
"years" | 연 단위 |
"months" | 월 단위 |
"days" | 일 단위 |
"hours" | 시간 단위 |
"minutes" | 분 단위 |
// 마감일까지 남은 일수
dateBetween(prop("마감일"), now(), "days")
// 근무 기간 (년)
dateBetween(now(), prop("입사일"), "years")
// 경과 시간
dateBetween(now(), prop("시작시간"), "hours")dateAdd()
날짜에 기간을 더합니다.
dateAdd(날짜, 숫자, 단위)// 7일 후
dateAdd(now(), 7, "days")
// 1개월 후
dateAdd(prop("시작일"), 1, "months")formatDate()
날짜를 특정 형식의 문자열로 변환합니다.
formatDate(날짜, 형식)// 년-월-일
formatDate(prop("날짜"), "yyyy-MM-dd") // "2024-01-15"
// 월/일
formatDate(prop("날짜"), "MM/dd") // "01/15"
// 요일 포함
formatDate(prop("날짜"), "MM월 dd일 (EEE)") // "01월 15일 (월)"빈 값 처리
empty()
값이 비어있는지 확인합니다.
empty(prop("속성이름")) // 비어있으면 true// 담당자 미지정 표시
if(empty(prop("담당자")), "❌ 미지정", prop("담당자"))
// 마감일 없으면 "미정"
if(empty(prop("마감일")), "미정", formatDate(prop("마감일"), "MM/DD"))실전 예시
기본 계산
// 총 금액
prop("단가") * prop("수량")
// 할인가
prop("정가") * (1 - prop("할인율") / 100)
// 부가세 포함
prop("금액") * 1.1
// 수수료 계산
prop("매출") * 0.03진행률
// 백분율 진행률
round(prop("완료 수") / prop("전체 수") * 100)
// 진행률 바 (텍스트)
concat(
"▓".repeat(round(prop("진행률") / 10)),
"░".repeat(10 - round(prop("진행률") / 10)),
" ",
prop("진행률"),
"%"
)
// 결과: "▓▓▓▓▓▓░░░░ 60%"D-Day 표시
// 마감일 D-Day
if(prop("마감일") < now(),
concat("D+", dateBetween(now(), prop("마감일"), "days")),
if(prop("마감일") == now(),
"D-Day",
concat("D-", dateBetween(prop("마감일"), now(), "days"))
)
)
// 결과: "D-3" 또는 "D+2" 또는 "D-Day"상태 이모지
// 상태별 이모지
if(prop("상태") == "완료", "✅",
if(prop("상태") == "진행중", "🔄",
if(prop("상태") == "대기", "⏳",
if(prop("상태") == "취소", "❌", "📋"))))우선순위 점수
// 긴급도와 중요도로 우선순위 계산
if(prop("긴급") and prop("중요"), "🔴 1순위",
if(prop("긴급") or prop("중요"), "🟡 2순위",
"🟢 3순위"))재고 상태
// 재고 상태 자동 표시
if(prop("재고") <= 0, "🔴 품절",
if(prop("재고") <= prop("안전재고"), "🟡 저재고",
"🟢 정상"))근무일 계산
// 근속 연수
concat(
dateBetween(now(), prop("입사일"), "years"),
"년 ",
dateBetween(now(), prop("입사일"), "months") % 12,
"개월"
)
// 결과: "3년 5개월"이메일 도메인 추출
// @ 이후 도메인
slice(prop("이메일"), indexOf(prop("이메일"), "@") + 1)수식 작성 팁
1. 작게 시작하기
복잡한 수식은 단계별로 작성하고 테스트하세요.
// 1단계: 기본 계산
prop("단가") * prop("수량")
// 2단계: 할인 적용
prop("단가") * prop("수량") * (1 - prop("할인율") / 100)
// 3단계: 최소 금액 적용
max(prop("단가") * prop("수량") * (1 - prop("할인율") / 100), 10000)2. 빈 값 처리
속성이 비어있을 수 있으면 항상 처리하세요.
// ❌ 빈 값 미처리
prop("단가") * prop("수량") // 빈 값이면 에러
// ✅ 빈 값 처리
if(empty(prop("수량")), 0, prop("단가") * prop("수량"))3. 가독성 유지
긴 수식은 줄바꿈과 들여쓰기로 가독성을 높이세요.
// 가독성 좋은 중첩 조건
if(prop("점수") >= 90, "A",
if(prop("점수") >= 80, "B",
if(prop("점수") >= 70, "C",
"D")))4. 단위 주의
숫자 계산 시 단위를 확인하세요.
// 할인율이 0~100 범위인 경우
prop("정가") * (1 - prop("할인율") / 100)
// 할인율이 0~1 범위인 경우
prop("정가") * (1 - prop("할인율"))목록/배열 함수
count()
배열의 항목 수를 반환합니다.
count(배열)// 다중 선택 항목 수
count(prop("태그")) // ["버그", "긴급", "UI"] → 3unique()
배열에서 중복을 제거한 고유 값 목록을 반환합니다.
unique(배열)// 중복 제거
unique(prop("카테고리")) // ["A", "B", "A", "C"] → ["A", "B", "C"]includes()
배열에 특정 값이 포함되어 있는지 확인합니다.
includes(배열, 값)// 태그 포함 여부
if(includes(prop("태그"), "긴급"), "🚨 긴급!", "일반")join()
배열의 항목들을 구분자로 연결하여 문자열로 반환합니다.
join(배열, 구분자)// 태그 표시
join(prop("태그"), ", ") // ["버그", "UI"] → "버그, UI"slice()
배열의 일부분을 추출합니다.
slice(배열, 시작인덱스, 끝인덱스)// 처음 3개만
slice(prop("목록"), 0, 3)at()
특정 인덱스의 요소를 반환합니다.
at(배열, 인덱스)// 첫 번째 항목
at(prop("목록"), 0)
// 마지막 항목 (-1은 뒤에서 첫 번째)
at(prop("목록"), -1)listMin(), listMax()
배열의 최소값/최대값을 반환합니다.
listMin(배열)
listMax(배열)// 점수 배열에서 최저점
listMin(prop("점수들")) // [85, 92, 78, 95] → 78
// 최고점
listMax(prop("점수들")) // [85, 92, 78, 95] → 95전체 함수 목록
수학 함수
| 함수 | 설명 | 예시 |
|---|---|---|
add(a, b) | 덧셈 | add(1, 2) → 3 |
subtract(a, b) | 뺄셈 | subtract(10, 3) → 7 |
multiply(a, b) | 곱셈 | multiply(3, 4) → 12 |
divide(a, b) | 나눗셈 | divide(10, 2) → 5 |
mod(a, b) | 나머지 | mod(10, 3) → 1 |
pow(x, y) | 거듭제곱 | pow(2, 3) → 8 |
abs(x) | 절대값 | abs(-10) → 10 |
round(x, decimals?) | 반올림 | round(3.14159, 2) → 3.14 |
floor(x) | 내림 | floor(3.7) → 3 |
ceil(x) | 올림 | ceil(3.2) → 4 |
min(a, b, ...) | 최소값 | min(5, 3) → 3 |
max(a, b, ...) | 최대값 | max(5, 3) → 5 |
sqrt(x) | 제곱근 | sqrt(9) → 3 |
cbrt(x) | 세제곱근 | cbrt(27) → 3 |
exp(x) | e의 거듭제곱 | exp(1) → 2.718... |
ln(x) | 자연로그 | ln(e()) → 1 |
log10(x) | 상용로그 | log10(100) → 2 |
log2(x) | 밑이 2인 로그 | log2(8) → 3 |
sign(x) | 부호 (-1, 0, 1) | sign(-5) → -1 |
sin(x) | 사인 (라디안) | sin(0) → 0 |
cos(x) | 코사인 (라디안) | cos(0) → 1 |
tan(x) | 탄젠트 (라디안) | tan(0) → 0 |
pi() | 원주율 | pi() → 3.14159... |
e() | 자연상수 | e() → 2.71828... |
toNumber(x) | 숫자 변환 | toNumber("123") → 123 |
텍스트 함수
| 함수 | 설명 | 예시 |
|---|---|---|
concat(a, b, ...) | 문자열 연결 | concat("Hello", " ", "World") |
join(arr, sep) | 배열을 구분자로 연결 | join(["a", "b"], ",") → "a,b" |
split(text, sep) | 문자열 분리 | split("a,b,c", ",") → ["a", "b", "c"] |
contains(text, sub) | 포함 여부 | contains("Hello", "ell") → true |
indexOf(text, sub) | 위치 찾기 | indexOf("hello", "l") → 2 |
startsWith(text, sub) | 시작 여부 | startsWith("hello", "he") → true |
endsWith(text, sub) | 끝 여부 | endsWith("hello", "lo") → true |
slice(text, start, end?) | 부분 문자열 | slice("Hello", 0, 2) → "He" |
substring(text, start, end?) | 부분 문자열 | substring("Hello", 1, 3) → "el" |
left(text, count) | 왼쪽에서 추출 | left("Hello", 2) → "He" |
right(text, count) | 오른쪽에서 추출 | right("Hello", 2) → "lo" |
length(text) | 문자열 길이 | length("Hello") → 5 |
upper(text) | 대문자 변환 | upper("hello") → "HELLO" |
lower(text) | 소문자 변환 | lower("HELLO") → "hello" |
capitalize(text) | 첫 글자 대문자 | capitalize("hello") → "Hello" |
trim(text) | 양쪽 공백 제거 | trim(" hi ") → "hi" |
trimStart(text) | 왼쪽 공백 제거 | trimStart(" hi") → "hi" |
trimEnd(text) | 오른쪽 공백 제거 | trimEnd("hi ") → "hi" |
replace(text, old, new) | 첫 번째 치환 | replace("abc", "b", "x") → "axc" |
replaceAll(text, old, new) | 전체 치환 | replaceAll("aba", "a", "x") → "xbx" |
test(text, regex) | 정규식 검사 | test("abc123", "[0-9]+") → true |
match(text, regex) | 정규식 매치 | match("abc123", "[0-9]+") → "123" |
repeat(text, count) | 문자열 반복 | repeat("ab", 3) → "ababab" |
padStart(text, len, char?) | 왼쪽 패딩 | padStart("5", 3, "0") → "005" |
padEnd(text, len, char?) | 오른쪽 패딩 | padEnd("5", 3, "0") → "500" |
format(template, ...) | 포맷팅 | format("{0}님", "홍길동") → "홍길동님" |
toString(value) | 문자열 변환 | toString(123) → "123" |
논리 함수
| 함수 | 설명 | 예시 |
|---|---|---|
if(cond, then, else) | 조건문 | if(true, "A", "B") → "A" |
ifs(c1, v1, c2, v2, ..., default?) | 다중 조건 (switch 대용) | ifs(x=="A", "우수", x=="B", "양호", "보통") |
and(a, b, ...) | 논리 AND | and(true, false) → false |
or(a, b, ...) | 논리 OR | or(true, false) → true |
not(x) | 논리 NOT | not(true) → false |
equal(a, b) | 동등 비교 | equal(1, 1) → true |
unequal(a, b) | 부등 비교 | unequal(1, 2) → true |
larger(a, b) | 크다 | larger(5, 3) → true |
largerEq(a, b) | 크거나 같다 | largerEq(5, 5) → true |
smaller(a, b) | 작다 | smaller(3, 5) → true |
smallerEq(a, b) | 작거나 같다 | smallerEq(3, 3) → true |
empty(x) | 빈 값 확인 | empty("") → true |
ifEmpty(value, default) | 빈 값이면 기본값 반환 | ifEmpty(prop("메모"), "없음") |
isNumber(x) | 숫자 여부 | isNumber(123) → true |
isText(x) | 텍스트 여부 | isText("hello") → true |
isBoolean(x) | 불리언 여부 | isBoolean(true) → true |
isDate(x) | 날짜 여부 | isDate(now()) → true |
isArray(x) | 배열 여부 | isArray([1, 2]) → true |
날짜 함수
| 함수 | 설명 | 예시 |
|---|---|---|
now() | 현재 날짜/시간 | now() |
today() | 오늘 날짜 (시간 00:00) | today() |
date(year, month, day) | 날짜 생성 | date(2024, 1, 15) |
dateAdd(date, num, unit) | 날짜 더하기 | dateAdd(now(), 7, "days") |
dateSubtract(date, num, unit) | 날짜 빼기 | dateSubtract(now(), 1, "months") |
dateBetween(d1, d2, unit) | 날짜 차이 | dateBetween(d1, d2, "days") |
year(date) | 연도 추출 | year(now()) → 2024 |
month(date) | 월 추출 (1-12) | month(now()) → 12 |
day(date) | 일 추출 | day(now()) → 14 |
weekday(date) | 요일 추출 (0=일, 1=월, ...) | weekday(now()) |
hour(date) | 시간 추출 | hour(now()) → 15 |
minute(date) | 분 추출 | minute(now()) → 30 |
second(date) | 초 추출 | second(now()) → 45 |
startOfDay(date) | 해당일 시작 (00:00) | startOfDay(now()) |
endOfDay(date) | 해당일 종료 (23:59) | endOfDay(now()) |
startOfWeek(date) | 해당 주 시작 (월요일) | startOfWeek(now()) |
endOfWeek(date) | 해당 주 종료 (일요일) | endOfWeek(now()) |
startOfMonth(date) | 해당 월 시작 | startOfMonth(now()) |
endOfMonth(date) | 해당 월 종료 | endOfMonth(now()) |
startOfYear(date) | 해당 연도 시작 | startOfYear(now()) |
endOfYear(date) | 해당 연도 종료 | endOfYear(now()) |
isAfter(d1, d2) | d1이 d2 이후인지 | isAfter(prop("마감일"), now()) |
isBefore(d1, d2) | d1이 d2 이전인지 | isBefore(now(), prop("마감일")) |
isSameDay(d1, d2) | 같은 날인지 | isSameDay(prop("날짜"), today()) |
formatDate(date, format?) | 날짜 포맷 | formatDate(now(), "yyyy-MM-dd") |
timestamp(date) | 타임스탬프 변환 (ms) | timestamp(now()) |
fromTimestamp(ts) | 타임스탬프 → 날짜 | fromTimestamp(1704067200000) |
parseDate(str) | 문자열 → 날짜 | parseDate("2024-01-15") |
목록 함수
| 함수 | 설명 | 예시 |
|---|---|---|
map(arr, callback) | 각 요소에 함수 적용 | prop("주문").map(current.금액) |
filter(arr, callback) | 조건 만족 요소만 | prop("주문").filter(current.상태 == "완료") |
find(arr, callback) | 조건 만족 첫 요소 | prop("담당자").find(current.역할 == "팀장") |
findIndex(arr, callback) | 조건 만족 첫 인덱스 | prop("태그").findIndex(current == "긴급") |
some(arr, callback) | 하나라도 만족하면 true | prop("체크리스트").some(current.완료) |
every(arr, callback) | 모두 만족하면 true | prop("항목").every(current.검토완료) |
sort(arr, callback?) | 정렬 | prop("점수").sort() |
reverse(arr) | 역순 | prop("날짜").reverse() |
flat(arr) | 중첩 배열 평탄화 | prop("태그목록").flat() |
unique(arr) | 중복 제거 | unique([1, 1, 2]) → [1, 2] |
slice(arr, start, end?) | 부분 배열 | slice([1,2,3,4], 0, 2) → [1, 2] |
concat(arr1, arr2) | 배열 연결 | concat(prop("태그1"), prop("태그2")) |
at(arr, idx) | 인덱스 접근 | at([1, 2, 3], -1) → 3 |
first(arr) | 첫 번째 요소 | prop("담당자").first() |
last(arr) | 마지막 요소 | prop("이력").last() |
includes(arr, val) | 포함 여부 | includes([1, 2], 2) → true |
listIndexOf(arr, val) | 값 인덱스 | listIndexOf([1, 2], 2) → 1 |
sum(arr) | 합계 | sum([1, 2, 3]) → 6 |
mean(arr) | 평균 | mean([2, 4, 6]) → 4 |
average(arr) | 평균 (mean의 별칭) | average([2, 4, 6]) → 4 |
count(arr) | 항목 수 | count([1, 2, 3]) → 3 |
listMin(arr) | 배열 최소값 | listMin([3, 1, 2]) → 1 |
listMax(arr) | 배열 최대값 | listMax([3, 1, 2]) → 3 |
listJoin(arr, sep?) | 배열 → 문자열 | listJoin(["a", "b"], ", ") → "a, b" |