10 Custom Function (UDF) Thường Dùng Trong Google Sheets
Trả lời nhanh: Custom Function (UDF) là hàm tự viết bằng Apps Script rồi gõ thẳng vào ô như hàm có sẵn, ví dụ =SOTIEN_BANGCHU(A2), không cần macro hay trigger. Bài có 10 UDF hay dùng: tính ngày làm việc trừ cuối tuần, lấy tỷ giá từ API, chuẩn hóa số điện thoại Việt Nam, tính tuổi, tính VAT, tạo slug tiếng Việt và vài hàm tiện ích khác, kèm lưu ý về giới hạn thời gian chạy và cache.
Custom Function (UDF) Là Gì?
UDF (User Defined Function) là hàm tự viết bằng Apps Script, dùng trực tiếp trong ô Sheets như =SOTIEN_BANGCHU(A2). Không cần macro hay trigger — chỉ cần gõ tên hàm vào ô là Google Sheets gọi code của bạn.
Cách Tạo Custom Function
// Trong Apps Script Editor, viết hàm với JSDoc:
/**
* Chuyển số thành chữ tiếng Việt.
* @param {number} amount Số tiền cần chuyển.
* @return {string} Số tiền bằng chữ.
* @customfunction
*/
function SOTIEN_BANGCHU(amount) {
if (!amount || isNaN(amount)) return '';
// Rút gọn: dùng thư viện hoặc logic chuyển đổi
const units = ['', 'một', 'hai', 'ba', 'bốn', 'năm', 'sáu', 'bảy', 'tám', 'chín'];
// ... (logic đầy đủ theo chuẩn đọc số tiếng Việt)
return String(amount).replace(/\B(?=(\d{3})+(?!\d))/g, '.') + ' đồng';
}
10 UDF Thường Dùng Nhất
1. Tính Số Ngày Làm Việc (Loại Trừ Cuối Tuần)
/**
* Tính số ngày làm việc giữa 2 ngày (không kể T7, CN).
* @customfunction
*/
function WORKDAYS(startDate, endDate) {
if (!startDate || !endDate) return 0;
const start = new Date(startDate);
const end = new Date(endDate);
let count = 0;
const current = new Date(start);
while (current <= end) {
const day = current.getDay();
if (day !== 0 && day !== 6) count++;
current.setDate(current.getDate() + 1);
}
return count;
}
2. Lấy Tỷ Giá Thực Từ API
/**
* Lấy tỷ giá hiện tại từ ExchangeRate API.
* @param {string} from Mã tiền gốc (vd: "USD").
* @param {string} to Mã tiền đích (vd: "VND").
* @customfunction
*/
function EXCHANGE_RATE(from, to) {
try {
const url = 'https://api.exchangerate-api.com/v4/latest/' + from.toUpperCase();
const resp = UrlFetchApp.fetch(url, { muteHttpExceptions: true });
const data = JSON.parse(resp.getContentText());
return data.rates[to.toUpperCase()] || 'N/A';
} catch (e) {
return 'ERROR';
}
}
3. Chuẩn Hóa Số Điện Thoại Việt Nam
/**
* Chuẩn hóa số điện thoại VN về dạng 0xxxxxxxxx.
* @customfunction
*/
function NORMALIZE_PHONE(phone) {
if (!phone) return '';
let p = String(phone).replace(/D/g, '');
if (p.startsWith('84')) p = '0' + p.slice(2);
if (p.startsWith('+84')) p = '0' + p.slice(3);
if (p.length === 9) p = '0' + p;
return p.length === 10 ? p : 'Không hợp lệ';
}
4. Tính Tuổi Từ Ngày Sinh
/** @customfunction */
function TUOI(birthDate) {
if (!birthDate) return '';
const dob = new Date(birthDate);
const today = new Date();
let age = today.getFullYear() - dob.getFullYear();
const m = today.getMonth() - dob.getMonth();
if (m < 0 || (m === 0 && today.getDate() < dob.getDate())) age--;
return age;
}
5. Tính VAT
/**
* Tính giá sau VAT.
* @param {number} price Giá chưa VAT.
* @param {number} rate Thuế suất % (mặc định 10).
* @customfunction
*/
function TINH_VAT(price, rate) {
rate = rate || 10;
return price * (1 + rate / 100);
}
6. Slugify Tiêu Đề Tiếng Việt
/** @customfunction */
function SLUGIFY(text) {
if (!text) return '';
const map = { 'à':'a','á':'a','ả':'a','ã':'a','ạ':'a','â':'a','ă':'a','đ':'d','è':'e','é':'e','ê':'e','ì':'i','í':'i','ò':'o','ó':'o','ô':'o','ơ':'o','ù':'u','ú':'u','ư':'u','ỳ':'y','ý':'y' };
return text.toLowerCase()
.replace(/[àáảãạâăđèéêìíòóôơùúưỳý]/g, c => map[c] || c)
.replace(/[^a-z0-9\s-]/g, '')
.trim().replace(/\s+/g, '-');
}
7–10. Các UDF Tiện Ích Khác
/** Kiểm tra email hợp lệ. @customfunction */
function IS_EMAIL(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(email));
}
/** Lấy tháng năm dạng "Tháng 6/2026". @customfunction */
function THANG_NAM(date) {
const d = date ? new Date(date) : new Date();
return 'Tháng ' + (d.getMonth() + 1) + '/' + d.getFullYear();
}
/** Mã hóa base64. @customfunction */
function BASE64_ENCODE(text) {
return Utilities.base64Encode(text, Utilities.Charset.UTF_8);
}
/** Đếm từ trong chuỗi. @customfunction */
function DEM_TU(text) {
if (!text) return 0;
return String(text).trim().split(/\s+/).length;
}
Lưu Ý Khi Dùng Custom Function
- Cache kết quả: UDF gọi UrlFetchApp sẽ không tự cập nhật. Dùng
CacheServicehoặc trigger để refresh định kỳ. - Không dùng UI services: UDF không được gọi
SpreadsheetApp.getUi(),Browser, hayMailApp. - Xử lý mảng: UDF nhận và trả về mảng 2 chiều — phù hợp với công thức dạng array formula.
- Timeout: UDF có giới hạn 30 giây — không dùng cho tác vụ nặng.
Chia sẻ bài viết:
Tuân Hoang
Đội ngũ SheetStore
Google Workspace Certified, 5+ years experience
Công cụ liên quan
Giải pháp cho bài viết này
Phần Mềm Quản Lý Bán Hàng Bằng Google Sheets
Phần mềm bán hàng trên Google Sheets — mua 1 lần dùng trọn đời, cài đặt trong 5 phút, dữ liệu thuộc về bạn. Dùng thử miễn phí trước khi mua.
799.000 đ
Xem chi tiếtPhần Mềm Content AI V2.0
Tạo nội dung chuyên nghiệp với Content AI Tool. Tự động hóa nội dung bán hàng trên nhiều nền tảng!
119.000 đ
Xem chi tiếtBạn thấy bài viết hữu ích?
Đăng ký nhận thông báo khi có bài viết mới.