SuitsDocs
콘텐츠데이터모델

수식

수식을 사용하여 자동 계산을 설정하세요.

수식 기본 사용법

수식 속성 추가

  1. + 속성 추가 → 수식(Formula) 선택
  2. 수식 편집기에서 수식 입력
  3. 저장

기본 구문

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

논리 연산자

조건을 조합합니다.

연산자설명예시
andANDprop("A") and prop("B")
orORprop("A") or prop("B")
notNOTnot 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 → 86

abs()

절대값을 반환합니다.

abs(prop("차이"))  // -10 → 10

min(), 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"] → 3

unique()

배열에서 중복을 제거한 고유 값 목록을 반환합니다.

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, ...)논리 ANDand(true, false) → false
or(a, b, ...)논리 ORor(true, false) → true
not(x)논리 NOTnot(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)하나라도 만족하면 trueprop("체크리스트").some(current.완료)
every(arr, callback)모두 만족하면 trueprop("항목").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"

다음 단계

  • 속성 - 수식에서 사용할 수 있는 속성 타입
  • 관계 - 롤업으로 관계 데이터 집계하기
  • 워크플로우 - 수식 결과 기반 자동화