Công thức (Formula)
Tính toán tự động trong một cột bằng công thức — tham chiếu cột khác, dùng hàm có sẵn, và lồng nhiều hàm vào nhau cho các quy tắc phức tạp hơn.
Formula là một kiểu cột tính toán: thay vì nhập tay, giá trị của cột được Base tự tính từ một công thức bạn viết, tham chiếu tới các cột khác trong cùng bảng (và có thể cả bảng khác). Công thức chạy lại mỗi khi dữ liệu đầu vào đổi — bạn không cần cập nhật tay.
Mở dialog soạn công thức
Khi thêm cột mới (hoặc sửa một cột Formula có sẵn), chọn kiểu Formula trong danh sách kiểu dữ liệu — dialog Chỉnh sửa công thức mở ra.
Dialog chia 3 vùng: bên trái là danh sách cột trong bảng và các hàm có sẵn (bấm để chèn nhanh vào công thức); giữa là ô soạn công thức cùng bảng xem trước kết quả tính trên chính bản ghi thật của bảng; bên phải là mô tả + ví dụ của hàm bạn đang gõ hoặc đang rê chuột tới.

Cách dùng cơ bản
- Tham chiếu một cột bằng cách bọc tên cột trong dấu ngoặc nhọn, ví dụ
{Số lượng}. Gõ dấu{để Base gợi ý danh sách cột. - Gõ tên hàm (vd
IF,SUM) để chèn nhanh — con trỏ sẽ đặt sẵn giữa hai dấu ngoặc để bạn gõ tiếp tham số. - Khu vực "Xem trước trên bản ghi thật" luôn tính công thức trên vài bản ghi thật của bảng — không phải dữ liệu mẫu giả định — để bạn biết ngay công thức có đúng ý trước khi lưu.
- Khi công thức còn sai cú pháp hoặc sai kiểu tham số, dialog báo lỗi ngay kèm gợi ý sửa (nếu có), và nút Lưu công thức bị khoá cho tới khi công thức hợp lệ.
Kiểu dữ liệu trả về
Base tự suy ra kiểu dữ liệu của cột Formula từ chính công thức (Văn bản, Số,
Đúng/Sai, Ngày hoặc Ngày giờ) — hiển thị ngay cạnh dòng "Công thức hợp lệ" ở
chân dialog. Với IF/SWITCH, nếu các nhánh trả về kiểu khác nhau (ví dụ một
nhánh trả số, nhánh kia trả chữ), Base sẽ hợp nhất theo kiểu chung gần nhất
(thường là Văn bản).
Bảng tra cứu đầy đủ các hàm
Logic
| Hàm | Cú pháp | Mô tả | Ví dụ | Kết quả |
|---|---|---|---|---|
IF | IF(điều_kiện, nếu_đúng, nếu_sai) | Trả về giá trị đầu nếu điều kiện đúng, ngược lại trả giá trị sau. | IF({Số lượng} > 10, "Sỉ", "Lẻ") | "Sỉ" |
SWITCH | SWITCH(biểu_thức, khớp1, giá_trị1, …, mặc_định) | Chọn kết quả theo giá trị khớp; không khớp thì lấy mặc định. | SWITCH({Cấp}, 1, "Vàng", 2, "Bạc", "Đồng") | "Bạc" |
AND | AND(a, b, …) | Đúng khi TẤT CẢ điều kiện đúng. | AND({Tuổi} >= 18, {Đã duyệt}) | true |
OR | OR(a, b, …) | Đúng khi CÓ ÍT NHẤT một điều kiện đúng. | OR({Vip}, {Tổng} > 1000000) | true |
NOT | NOT(a) | Phủ định giá trị đúng/sai. | NOT({Đã đóng}) | false |
Văn bản
| Hàm | Cú pháp | Mô tả | Ví dụ | Kết quả |
|---|---|---|---|---|
CONCAT | CONCAT(a, b, …) | Nối các chuỗi lại; giá trị rỗng thành "". | CONCAT({Họ}, " ", {Tên}) | "Nguyễn An" |
UPPER | UPPER(text) | Chuyển thành chữ HOA. | UPPER("abc") | "ABC" |
LOWER | LOWER(text) | Chuyển thành chữ thường. | LOWER("ABC") | "abc" |
TRIM | TRIM(text) | Bỏ khoảng trắng đầu/cuối. | TRIM(" a ") | "a" |
LEN | LEN(text) | Số ký tự của chuỗi. | LEN("Inforact") | 8 |
LEFT | LEFT(text, n) | Lấy n ký tự đầu. | LEFT("Inforact", 3) | "Inf" |
RIGHT | RIGHT(text, n) | Lấy n ký tự cuối. | RIGHT("Inforact", 3) | "act" |
MID | MID(text, bắt_đầu, n) | Lấy n ký tự từ vị trí bắt_đầu (tính từ 1). | MID("Inforact", 3, 4) | "fora" |
REPLACE | REPLACE(text, bắt_đầu, n, mới) | Thay n ký tự từ vị trí bắt_đầu bằng chuỗi mới. | REPLACE("abcdef", 2, 3, "XY") | "aXYef" |
SUBSTITUTE | SUBSTITUTE(text, cũ, mới, [lần]) | Thay chuỗi cũ bằng mới; bỏ [lần] thì thay tất cả. | SUBSTITUTE("a-b-c", "-", "+") | "a+b+c" |
FIND | FIND(cần_tìm, trong, [từ]) | Vị trí xuất hiện (từ 1), phân biệt hoa/thường; không thấy trả 0. | FIND("b", "abc") | 2 |
SEARCH | SEARCH(cần_tìm, trong, [từ]) | Như FIND nhưng KHÔNG phân biệt hoa/thường. | SEARCH("B", "abc") | 2 |
REPT | REPT(text, n) | Lặp chuỗi n lần. | REPT("ab", 3) | "ababab" |
PROPER | PROPER(text) | Viết hoa chữ cái đầu mỗi từ. | PROPER("hello world") | "Hello World" |
VALUE | VALUE(text) | Chuyển chuỗi số thành số; không parse được trả rỗng. | VALUE("42.5") | 42.5 |
T | T(x) | Trả về x nếu là văn bản, ngược lại rỗng. | T("hi") | "hi" |
Số
| Hàm | Cú pháp | Mô tả | Ví dụ | Kết quả |
|---|---|---|---|---|
ROUND | ROUND(số, [chữ_số]) | Làm tròn tới số chữ số thập phân. | ROUND(3.14159, 2) | 3.14 |
ROUNDUP | ROUNDUP(số, [chữ_số]) | Làm tròn LÊN (xa số 0). | ROUNDUP(1.01, 0) | 2 |
ROUNDDOWN | ROUNDDOWN(số, [chữ_số]) | Làm tròn XUỐNG (về số 0). | ROUNDDOWN(1.99, 0) | 1 |
ABS | ABS(số) | Trị tuyệt đối. | ABS(-5) | 5 |
CEIL | CEIL(số) | Làm tròn lên số nguyên gần nhất. | CEIL(2.1) | 3 |
FLOOR | FLOOR(số) | Làm tròn xuống số nguyên gần nhất. | FLOOR(2.9) | 2 |
INT | INT(số) | Phần nguyên (làm tròn về âm vô cùng). | INT(-1.1) | -2 |
MOD | MOD(a, b) | Số dư của a chia b. | MOD(10, 3) | 1 |
POWER | POWER(a, b) | a mũ b. | POWER(2, 10) | 1024 |
SQRT | SQRT(a) | Căn bậc hai (a âm trả rỗng). | SQRT(144) | 12 |
EXP | EXP(a) | e mũ a. | EXP(0) | 1 |
LOG | LOG(a, [cơ_số]) | Logarit của a theo cơ số (mặc định 10). | LOG(1000) | 3 |
LN | LN(a) | Logarit tự nhiên (cơ số e). | LN(1) | 0 |
MIN | MIN(a, b, …) | Giá trị nhỏ nhất. | MIN(3, 1, 2) | 1 |
MAX | MAX(a, b, …) | Giá trị lớn nhất. | MAX(3, 1, 2) | 3 |
SUM | SUM(a, b, …) | Tổng các số (bỏ qua giá trị rỗng). | SUM({Q1}, {Q2}, {Q3}) | 60 |
AVERAGE | AVERAGE(a, b, …) | Trung bình cộng (bỏ qua giá trị rỗng). | AVERAGE(2, 4, 6) | 4 |
Ngày & giờ
| Hàm | Cú pháp | Mô tả | Ví dụ | Kết quả |
|---|---|---|---|---|
NOW | NOW() | Thời điểm hiện tại (ngày + giờ). | NOW() | "2026-07-06T10:00:00Z" |
TODAY | TODAY() | Ngày hôm nay. | TODAY() | "2026-07-06" |
DATE | DATE(năm, tháng, ngày) | Tạo ngày từ 3 thành phần. | DATE(2026, 7, 6) | "2026-07-06" |
DATEADD | DATEADD(ngày, n, 'days') | Cộng/trừ khoảng thời gian (days/weeks/months/years/hours/minutes). | DATEADD({Ngày}, 7, "days") | "2026-07-13" |
DATETIME_DIFF | DATETIME_DIFF(a, b, 'days') | Khoảng cách giữa hai mốc theo đơn vị. | DATETIME_DIFF({Hạn}, TODAY(), "days") | 5 |
DATETIME_FORMAT | DATETIME_FORMAT(ngày, 'mẫu') | Định dạng ngày theo mẫu (YYYY MM DD HH mm ss), giờ VN. | DATETIME_FORMAT({Ngày}, "DD/MM/YYYY") | "06/07/2026" |
YEAR | YEAR(ngày) | Năm (giờ VN). | YEAR("2026-07-06") | 2026 |
MONTH | MONTH(ngày) | Tháng 1–12 (giờ VN). | MONTH("2026-07-06") | 7 |
DAY | DAY(ngày) | Ngày trong tháng (giờ VN). | DAY("2026-07-06") | 6 |
HOUR | HOUR(datetime) | Giờ 0–23 (giờ VN). | HOUR("2026-07-06T10:30:00Z") | 17 |
MINUTE | MINUTE(datetime) | Phút 0–59. | MINUTE("2026-07-06T10:30:00Z") | 30 |
SECOND | SECOND(datetime) | Giây 0–59. | SECOND("2026-07-06T10:30:45Z") | 45 |
WEEKDAY | WEEKDAY(ngày) | Thứ trong tuần: 1=Thứ Hai … 7=Chủ Nhật. | WEEKDAY("2026-07-06") | 1 |
WEEKNUM | WEEKNUM(ngày) | Số tuần trong năm (ISO-8601). | WEEKNUM("2026-01-01") | 1 |
WORKDAY | WORKDAY(ngày, n) | Cộng n ngày làm việc (bỏ Thứ Bảy/Chủ Nhật). | WORKDAY("2026-07-06", 5) | "2026-07-13" |
WORKDAY_DIFF | WORKDAY_DIFF(a, b) | Số ngày làm việc giữa hai ngày (có dấu). | WORKDAY_DIFF("2026-07-06", "2026-07-13") | 5 |
Kiểm tra
| Hàm | Cú pháp | Mô tả | Ví dụ | Kết quả |
|---|---|---|---|---|
BLANK | BLANK() | Giá trị rỗng. | IF({Số} > 0, {Số}, BLANK()) | (rỗng) |
ISBLANK | ISBLANK(x) | Đúng nếu x rỗng. | ISBLANK({Ghi chú}) | true |
Tổng hợp chéo bảng
| Hàm | Cú pháp | Mô tả | Ví dụ | Kết quả |
|---|---|---|---|---|
FILTER | FILTER({Bảng.Cột}, điều_kiện) | Chọn giá trị một cột ở BẢNG KHÁC theo điều kiện. Luôn phải bọc trong một hàm tổng hợp (SUM/COUNT/AVERAGE/MIN/MAX/CONCAT/AND/OR). | SUM(FILTER({Đơn hàng.tiền}, {Đơn hàng.Mã KH} = {Mã KH})) | 1.400.000 |
COUNT | COUNT(FILTER(…)) | Đếm số bản ghi khớp điều kiện của FILTER(). Chỉ dùng được cùng FILTER(). | COUNT(FILTER({Đơn hàng.tiền}, {Đơn hàng.Mã KH} = {Mã KH})) | 3 |
FILTER() luôn phải đứng trong một hàm tổng hợp
FILTER() một mình không phải là một giá trị — nó là một tập bản ghi
của bảng khác. Base sẽ báo lỗi nếu bạn đặt FILTER() trực tiếp làm công
thức của cột; nó chỉ hợp lệ khi làm đối số của SUM/COUNT/AVERAGE/
MIN/MAX/CONCAT/AND/OR, ví dụ SUM(FILTER(...)). Điều kiện lọc bên
trong là các phép so sánh nối bằng AND/OR/NOT, vế trái là một cột của
bảng kia, vế phải là hằng số, một cột của bảng này, hoặc TODAY().
Ví dụ hàm lồng nhau
Sức mạnh thật sự của Formula nằm ở việc lồng nhiều hàm vào nhau trong một công thức — kết quả của hàm này làm đầu vào cho hàm khác. Ba ví dụ dưới đây lấy từ dữ liệu vận hành thật của một công ty thương mại, mỗi ví dụ đều đã được thử trực tiếp trong dialog và cho ra "Công thức hợp lệ".
Cảnh báo đơn hàng trễ giao
Trên bảng Đơn hàng, muốn có một cột tự động cảnh báo đơn nào đã quá hạn
giao mà vẫn chưa hoàn thành — vừa cần so ngày (DATETIME_DIFF/TODAY),
vừa cần kết hợp hai điều kiện (AND), vừa cần ghép chữ hiển thị số ngày trễ
(CONCAT):
IF(
AND(
{Trạng thái} <> "Hoàn thành",
DATETIME_DIFF(TODAY(), {Ngày giao dự kiến}, "days") > 0
),
CONCAT("Trễ ", DATETIME_DIFF(TODAY(), {Ngày giao dự kiến}, "days"), " ngày"),
"Đúng hạn"
)IF là hàm ngoài cùng; nhánh điều kiện của nó là một AND gồm hai vế; nhánh
kết quả "trễ" của nó lại là một CONCAT có chứa DATETIME_DIFF bên trong —
ba tầng lồng nhau trong cùng một công thức.

Nhãn khách VIP theo doanh thu
Vẫn trên bảng Đơn hàng, muốn gắn nhãn ưu đãi cho các đơn có doanh thu từ 10 triệu trở lên, kèm số tiền tiết kiệm được đã làm tròn:
IF(
{Doanh thu} >= 10000000,
CONCAT("VIP - tiết kiệm ", ROUND({Doanh thu}*0.05, 0), "đ"),
"Khách thường"
)Ở đây IF lồng CONCAT, và CONCAT lại lồng ROUND cùng một phép tính số
học ({Doanh thu}*0.05) ngay bên trong nó.

Phân loại khách hàng thân thiết
Trên bảng Khách hàng, muốn phân loại khách thành 3 mức dựa trên độ tín
nhiệm và thời gian hợp tác — cần một IF lồng bên trong nhánh else của một
IF khác (kiểu bậc thang, thay cho việc viết nhiều cột phụ):
IF(
AND({Tín nhiệm} >= 4, DATETIME_DIFF(TODAY(), {Ngày hợp tác}, "days") > 365),
"Khách hàng thân thiết",
IF({Tín nhiệm} >= 4, "Khách hàng tốt", "Khách hàng thường")
)
Mẹo khi công thức lồng nhiều tầng
Công thức càng lồng sâu càng khó đọc lại sau này. Đặt tên cột rõ ràng, và nếu một công thức bắt đầu quá dài, cân nhắc tách thành nhiều cột Formula nhỏ hơn rồi tham chiếu cột này vào cột kia — dễ đọc và dễ sửa hơn một công thức khổng lồ.
Formula là một trong những kiểu cột tính toán của Base — xem thêm về
tạo bảng và chọn kiểu cột nếu bạn chưa quen
với các kiểu cột khác, hoặc liên kết bảng để
hiểu cách một bảng tham chiếu bảng khác trước khi dùng FILTER().