Hướng dẫn

Cách Tạo Cảnh Báo Tự Động Khi Giá Trị Vượt Ngưỡng Trong Google Sheets

Tuân HoangTuân Hoang
25 tháng 8, 2026
8 phút đọc
Ảnh minh họa bài viết: Cách Tạo Cảnh Báo Tự Động Khi Giá Trị Vượt Ngưỡng Trong Google Sheets

Ngưỡng cảnh báo bằng công thức: nhanh nhưng có giới hạn

Cách đơn giản nhất mà hầu như ai làm Sheets cũng thử trước tiên là dùng Conditional Formatting kết hợp công thức so sánh. Ví dụ bạn theo dõi tồn kho ở cột C, đặt điều kiện =C2<10 để tô đỏ khi số lượng dưới 10. Cách này giải quyết được nhu cầu "nhìn thấy bằng mắt" nhưng có một lỗ hổng mà nhiều người mất cả tuần mới nhận ra: nếu không mở file, bạn không biết gì cả. Conditional Formatting không gửi thông báo, nó chỉ đổi màu ô — tức là bạn vẫn phải chủ động vào kiểm tra.

Với nhu cầu cao hơn một chút, có thể dùng công thức IF kết hợp TEXT để tạo một cột "trạng thái" tự sinh nội dung cảnh báo:

=IF(C2<10, "⚠️ Sắp hết hàng", "OK")

Cách này phù hợp khi bạn hoặc nhân viên vẫn thường xuyên mở sheet để làm việc — ví dụ file quản lý đơn hàng dùng hàng ngày. Nhưng nếu ngưỡng cần theo dõi là doanh thu tụt dưới mục tiêu, hay chi phí vượt ngân sách vào lúc 2 giờ sáng, công thức tĩnh này vô dụng vì chẳng ai đang mở sheet để thấy.

Dùng Apps Script để gửi email khi vượt ngưỡng

Đây mới là phần giải quyết đúng vấn đề: cảnh báo chủ động, không cần ai mở file. Apps Script cho phép bạn viết một hàm kiểm tra dữ liệu và gửi email tự động khi điều kiện bị vi phạm.

Ví dụ thực tế: một cửa hàng dùng Sheets quản lý tồn kho 200 mặt hàng, cột B là tên sản phẩm, cột C là số lượng tồn, ngưỡng cảnh báo lưu ở ô E1 (mặc định 10). Đoạn script sau sẽ quét toàn bộ và gửi một email tổng hợp các mặt hàng dưới ngưỡng:

function kiemTraTonKho() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TonKho");
  var nguong = sheet.getRange("E1").getValue();
  var data = sheet.getRange("B2:C" + sheet.getLastRow()).getValues();
  var canhBao = [];

  data.forEach(function(row) {
    var tenSP = row[0];
    var soLuong = row[1];
    if (soLuong < nguong && tenSP !== "") {
      canhBao.push(tenSP + ": còn " + soLuong);
    }
  });

  if (canhBao.length > 0) {
    var noiDung = "Các mặt hàng dưới ngưỡng " + nguong + ":\n\n" + canhBao.join("\n");
    MailApp.sendEmail("ban@congty.com", "Cảnh báo tồn kho thấp", noiDung);
  }
}

Điểm hay của cách viết này là ngưỡng lấy từ ô E1 chứ không hardcode trong code — sau này đổi ngưỡng từ 10 xuống 5, chỉ cần sửa một ô, không đụng vào script. Đây là thói quen nên giữ khi viết Apps Script cho bất kỳ mục đích gì, không riêng cảnh báo.

Đặt lịch chạy tự động bằng Trigger

Script trên chỉ chạy khi bạn bấm nút thủ công, nên bước tiếp theo là gắn Time-driven Trigger:

  • Mở Apps Script Editor, vào menu bên trái chọn biểu tượng đồng hồ (Triggers)
  • Chọn "Add Trigger", chọn hàm kiemTraTonKho
  • Chọn loại "Time-driven" → "Hour timer" → chạy mỗi 1 giờ, hoặc "Day timer" nếu chỉ cần kiểm tra 1 lần/ngày lúc 8 giờ sáng
  • Lưu lại — Google sẽ tự chạy hàm này theo lịch, kể cả khi bạn không mở file

Một điều cần lưu ý: trigger theo giờ của Google Sheets không chính xác đến từng phút, nó dao động trong khung ±15 phút. Nếu bạn cần cảnh báo tức thời khi dữ liệu vừa thay đổi (ví dụ giá cổ phiếu, hoặc đơn hàng vừa nhập), phải dùng cách khác ở phần dưới.

Cảnh báo tức thời bằng onEdit Trigger

Khi ngưỡng cần theo dõi gắn với hành động nhập liệu — ví dụ nhân viên nhập số liệu chi phí vượt ngân sách phòng ban — trigger theo thời gian không phù hợp vì có độ trễ. Lúc này dùng onEdit, một trigger đơn giản chạy ngay khi có ô bị chỉnh sửa:

function onEdit(e) {
  var sheet = e.source.getActiveSheet();
  if (sheet.getName() !== "ChiPhi") return;

  var range = e.range;
  if (range.getColumn() !== 3) return; // chỉ theo dõi cột C

  var giaTri = range.getValue();
  var nguong = sheet.getRange("F1").getValue();

  if (giaTri > nguong) {
    var email = Session.getActiveUser().getEmail();
    MailApp.sendEmail(email, "Cảnh báo chi phí vượt ngưỡng",
      "Ô " + range.getA1Notation() + " vừa nhập giá trị " + giaTri +
      ", vượt ngưỡng " + nguong);
  }
}

Cách này nhạy hơn hẳn cách chạy theo lịch, nhưng có cái giá phải trả: nếu ai đó dán (paste) nhiều dòng cùng lúc, onEdit đơn giản (simple trigger) không nhận diện được thao tác paste hàng loạt — nó chỉ bắt sự kiện gõ tay từng ô. Muốn xử lý paste hàng loạt, phải chuyển sang installable trigger (gắn qua menu Triggers giống ở trên, chọn "On edit") thay vì để hàm chạy dạng simple trigger mặc định.

So sánh các phương án theo tình huống thực tế

Phương ánĐộ trễPhù hợp khiHạn chế
Conditional FormattingTức thời (chỉ đổi màu)File mở thường xuyên, cần nhìn nhanhKhông gửi thông báo chủ động
Trigger theo giờ/ngày±15 phútKiểm tra định kỳ: tồn kho, KPI cuối ngàyKhông phù hợp cảnh báo tức thời
onEdit TriggerGần như tức thờiCảnh báo ngay khi nhập liệu vượt ngưỡngCần installable trigger nếu có paste hàng loạt

Trong thực tế, nhiều file quản lý dùng cả hai: onEdit để bắt các trường hợp nhập tay bất thường, và trigger theo giờ để quét toàn bộ dữ liệu phòng trường hợp có công thức tự tính toán ra giá trị vượt ngưỡng mà không qua thao tác gõ tay (vì công thức tự cập nhật không kích hoạt onEdit).

Gửi cảnh báo qua kênh khác ngoài email

Email đôi khi bị bỏ lỡ vì nằm lẫn trong hộp thư đầy ắp thông báo khác. Nếu team dùng Slack hoặc Telegram để trao đổi công việc hàng ngày, gắn cảnh báo trực tiếp vào đó hiệu quả hơn nhiều.

Với Telegram, chỉ cần tạo bot qua BotFather, lấy token, rồi gọi API bằng UrlFetchApp trong Apps Script:

function guiTelegram(noiDung) {
  var token = "BOT_TOKEN_CUA_BAN";
  var chatId = "CHAT_ID_CUA_BAN";
  var url = "https://api.telegram.org/bot" + token + "/sendMessage";
  UrlFetchApp.fetch(url, {
    method: "post",
    payload: { chat_id: chatId, text: noiDung }
  });
}

Gọi hàm này thay cho MailApp.sendEmail ở các ví dụ trên, cảnh báo sẽ hiện ngay trong group chat của team — không ai bỏ lỡ vì mọi người đều mở Telegram/Slack liên tục trong giờ làm việc, khác với email vốn chỉ kiểm tra vài lần/ngày.

Những lỗi thường gặp khi setup cảnh báo tự động

Một lỗi phổ biến là quên giới hạn tần suất gửi. Nếu để trigger chạy mỗi 5 phút và điều kiện vượt ngưỡng kéo dài nhiều giờ, hộp thư sẽ ngập hàng chục email giống hệt nhau. Cách xử lý là lưu trạng thái "đã gửi cảnh báo lần cuối lúc nào" vào một ô riêng hoặc dùng PropertiesService, chỉ gửi lại nếu đã quá một khoảng thời gian nhất định (ví dụ 4 tiếng) kể từ lần gửi trước.

Lỗi thứ hai là đặt trigger onEdit ở cấp toàn bảng tính nhưng không kiểm tra tên sheet — dẫn đến script chạy nhầm khi người dùng sửa ở sheet khác hoàn toàn không liên quan, vừa tốn quota vừa dễ gây lỗi runtime nếu code giả định cấu trúc cột cố định.

Lỗi thứ ba, hay gặp ở người mới: quên rằng giới hạn gửi email của tài khoản Gmail cá nhân là 100 email/ngày (Google Workspace là 1.500/ngày). Nếu file theo dõi nhiều mục tiêu và có khả năng kích hoạt cảnh báo dồn dập, nên gộp nhiều cảnh báo thành một email tổng hợp thay vì gửi riêng lẻ từng cái, giống cách viết trong ví dụ tồn kho ở phần đầu.

Ngoài cảnh báo ngưỡng, nếu bạn đang xây cả một quy trình quản lý dựa trên Sheets — từ nhập liệu, phê duyệt đến báo cáo — có thể tham khảo thêm cách số hóa quy trình kinh doanh với Google Sheets để thấy cảnh báo tự động chỉ là một mảnh trong bức tranh lớn hơn. Còn nếu bạn cần thêm lối tắt thao tác cho người dùng không rành Apps Script, tạo menu tùy chỉnh bằng Apps Script là cách để gắn nút "Kiểm tra ngay" ngay trên thanh menu thay vì phải mở Script Editor mỗi lần muốn chạy thủ công.

Kết hợp cảnh báo với báo cáo định kỳ

Cảnh báo ngưỡng phát huy giá trị nhất khi đặt cạnh dữ liệu báo cáo có ngữ cảnh, thay vì đứng độc lập. Một con số "doanh thu chi nhánh A giảm 15%" trong email cảnh báo sẽ hữu ích hơn nhiều nếu người nhận có thể đối chiếu ngay với báo cáo doanh thu theo từng chi nhánh mà họ đã quen xem hàng tuần. Nếu bạn chưa có cấu trúc báo cáo theo chi nhánh, bài cách tạo báo cáo doanh thu theo từng chi nhánh mô tả khá chi tiết cách tổ chức dữ liệu để vừa dùng cho báo cáo, vừa dễ gắn thêm điều kiện cảnh báo sau này.

Với các đội SME đang tự build hệ thống quản lý trên nền Sheets, SheetStore có sẵn một số mẫu tích hợp cảnh báo ngưỡng dựng sẵn (tồn kho, công nợ, ngân sách) nếu bạn muốn tiết kiệm thời gian viết script từ đầu — nhưng bản chất kỹ thuật vẫn xoay quanh đúng ba khối: Conditional Formatting để hiển thị, Trigger để tự động hóa, và kênh gửi (email/Telegram) để đảm bảo thông báo đến đúng người đúng lúc.

Câu hỏi thường gặp

Cảnh báo vượt ngưỡng trong Google Sheets hoạt động dựa trên nguyên lý gì?

Sheet dùng công thức so sánh giá trị ô với ngưỡng đặt trước (ví dụ tồn kho < 10, doanh thu > mục tiêu). Khi điều kiện đúng, Conditional Formatting đổi màu ô hoặc Apps Script chạy trigger gửi email, Telegram, Slack tự động mà không cần mở file kiểm tra.

Không biết lập trình có tự làm được cảnh báo tự động không?

Có. Conditional Formatting làm được cảnh báo trực quan (đổi màu, in đậm) chỉ bằng thao tác chuột không cần code. Muốn gửi email/Telegram tự động thì cần đoạn Apps Script ngắn, copy-paste theo mẫu có sẵn và chỉnh vài dòng là chạy được.

Làm sao để cảnh báo chạy tự động mà không cần mở file Sheet?

Dùng Apps Script với Time-driven Trigger (chạy theo giờ, ngày) hoặc Installable Trigger onEdit/onChange. Trigger sẽ tự kiểm tra dữ liệu theo lịch đã đặt và gửi cảnh báo kể cả khi không ai mở file, miễn Sheet còn tồn tại trên Drive.

Có thể cảnh báo cho nhiều ngưỡng khác nhau trên cùng một sheet không?

Được, mỗi cột hoặc dòng dữ liệu có thể gắn quy tắc Conditional Formatting riêng, hoặc trong Apps Script dùng vòng lặp kiểm tra từng ngưỡng theo từng sản phẩm/chi nhánh rồi gửi cảnh báo tổng hợp theo nhóm.

Bạn muốn áp dụng ngay mà không phải tự xây từ đầu?

Khám phá các mẫu Google Sheets và phần mềm quản lý dựng sẵn cho doanh nghiệp Việt tại SheetStore Marketplace.

Chia sẻ bài viết:

Tuân Hoang

Tuân Hoang

Đội ngũ SheetStore

Google SheetsGoogle Apps ScriptCRMAutomationPhần mềm quản lý doanh nghiệp

Google Workspace Certified, 5+ years experience

Bạ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.

Nhận thông báo khi có bài viết mới. Không spam, hứa luôn! 😊

Bình luận (0)

Vui lòng đăng nhập để tham gia thảo luận