Tự Động Hóa Quản Lý Kho Với Google Sheets & Apps Script
Tự động hóa quản lý kho với Google Sheets & Apps Script — từ cảnh báo hàng sắp hết đến báo cáo PDF tự động gửi email mỗi tháng.
Hướng dẫn step-by-step kèm code mẫu hoàn chỉnh. Không cần biết lập trình — chỉ cần copy-paste và cấu hình là dùng được ngay.
Mục lục:
1. Tại Sao Cần Tự Động Hóa Quản Lý Kho?
Quản lý kho thủ công tốn rất nhiều thời gian lặp đi lặp lại: kiểm tra tồn kho mỗi sáng, lập báo cáo cuối tháng, gửi thông báo cho từng bộ phận khi hàng sắp hết. Với Google Apps Script (miễn phí 100%), bạn có thể tự động hóa toàn bộ những việc này.
Tiết kiệm/tuần kiểm tra kho thủ công
Chi phí Apps Script (miễn phí)
Tự động chạy không cần giám sát
Giảm sai sót do nhập thủ công
2. Google Apps Script Là Gì?
Google Apps Script (GAS) là ngôn ngữ lập trình dựa trên JavaScript, được tích hợp miễn phí trong Google Workspace. Bạn có thể viết script để tự động hóa Google Sheets, Gmail, Drive, Calendar mà không cần server hay hosting.
Để truy cập Apps Script trong Google Sheets:
- Mở file Google Sheets kho hàng
- Click menu Extensions → Apps Script
- Cửa sổ editor mở ra — paste code vào đây
- Click nút Save (Ctrl+S) và Run
3. Script 1: Cảnh Báo Hàng Sắp Hết Qua Email
Script này tự động kiểm tra tồn kho mỗi sáng 8h và gửi email/Telegram cảnh báo khi có hàng dưới mức tối thiểu.
// Script 1: Cảnh báo hàng sắp hết qua Email
function kiemTraTonKhoVaGuiEmail() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheetTonKho = ss.getSheetByName('TonKho');
const sheetDanhMuc = ss.getSheetByName('DanhMuc');
// Lấy dữ liệu tồn kho (từ dòng 2 đến hết)
const data = sheetTonKho.getDataRange().getValues();
const hangSapHet = [];
for (let i = 1; i < data.length; i++) {
const maSP = data[i][0];
const tenSP = data[i][1];
const tonHienTai = data[i][5]; // Cột F: Tồn hiện tại
const tonToiThieu = data[i][6]; // Cột G: Tồn tối thiểu
if (maSP && tonHienTai <= tonToiThieu) {
hangSapHet.push({
maSP: maSP,
tenSP: tenSP,
ton: tonHienTai,
toiThieu: tonToiThieu,
thieuSL: tonToiThieu - tonHienTai
});
}
}
// Chỉ gửi email nếu có hàng sắp hết
if (hangSapHet.length > 0) {
let noiDung = '<h2>⚠️ Cảnh Báo: ' + hangSapHet.length + ' mặt hàng sắp hết kho</h2>';
noiDung += '<table border="1" cellpadding="8" style="border-collapse:collapse">';
noiDung += '<tr style="background:#f3f4f6"><th>Mã SP</th><th>Tên SP</th><th>Tồn hiện tại</th><th>Tối thiểu</th><th>Cần nhập thêm</th></tr>';
hangSapHet.forEach(function(sp) {
noiDung += '<tr style="color:red">';
noiDung += '<td>' + sp.maSP + '</td>';
noiDung += '<td>' + sp.tenSP + '</td>';
noiDung += '<td style="text-align:center">' + sp.ton + '</td>';
noiDung += '<td style="text-align:center">' + sp.toiThieu + '</td>';
noiDung += '<td style="text-align:center;font-weight:bold">' + sp.thieuSL + '</td>';
noiDung += '</tr>';
});
noiDung += '</table>';
// Thay EMAIL_QUAN_LY bằng email thực của bạn
MailApp.sendEmail({
to: 'EMAIL_QUAN_LY@gmail.com',
subject: '⚠️ [Kho Hàng] ' + hangSapHet.length + ' mặt hàng sắp hết — ' + new Date().toLocaleDateString('vi-VN'),
htmlBody: noiDung
});
Logger.log('Đã gửi email cảnh báo: ' + hangSapHet.length + ' mặt hàng');
} else {
Logger.log('Tồn kho ổn định, không cần cảnh báo');
}
}
// Cài trigger tự động chạy mỗi sáng 8h:
// Apps Script → Triggers → Add Trigger → kiemTraTonKhoVaGuiEmail → Time-driven → Day timer → 8am-9am
💡 Cách cài trigger tự động:
- Trong Apps Script Editor, click biểu tượng đồng hồ (Triggers) ở sidebar trái
- Click + Add Trigger góc dưới phải
- Chọn function:
kiemTraTonKhoVaGuiEmail - Event source: Time-driven
- Type: Day timer → 8am to 9am
- Save — script sẽ tự chạy mỗi sáng!
4. Script 2: Nhập Kho Từ Google Form Qua Điện Thoại
Thay vì nhân viên kho phải mở laptop để nhập phiếu, họ dùng điện thoại submit Google Form → dữ liệu tự động ghi vào sheet nhập kho và cập nhật tồn.
// Script 2: Xử lý dữ liệu từ Google Form nhập kho
// Gắn trigger: Form submit → onFormSubmitNhapKho
function onFormSubmitNhapKho(e) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheetNhap = ss.getSheetByName('NhapKho');
const sheetTon = ss.getSheetByName('TonKho');
// Lấy dữ liệu từ form response
const responses = e.values; // [timestamp, maSP, tenSP, slNhap, giaNhap, ncc, ghiChu]
const timestamp = responses[0];
const maSP = responses[1].trim().toUpperCase();
const slNhap = parseInt(responses[3]);
const giaNhap = parseFloat(responses[4].replace(/,/g, ''));
// Tạo số phiếu tự động
const lastRow = sheetNhap.getLastRow();
const soPhieu = 'NK' + new Date().getFullYear() + String(lastRow).padStart(4, '0');
// Ghi vào sheet NhapKho
sheetNhap.appendRow([
new Date(),
soPhieu,
maSP,
responses[2], // Tên SP
slNhap,
giaNhap,
slNhap * giaNhap, // Thành tiền
responses[5], // NCC
responses[6] // Ghi chú
]);
// Cập nhật tồn kho trong sheet TonKho
const dataTon = sheetTon.getDataRange().getValues();
for (let i = 1; i < dataTon.length; i++) {
if (dataTon[i][0] === maSP) {
const tonHienTai = dataTon[i][5];
sheetTon.getRange(i + 1, 6).setValue(tonHienTai + slNhap);
break;
}
}
Logger.log('Nhập kho thành công: ' + maSP + ' x ' + slNhap);
}
5. Script 3: Báo Cáo Tồn Kho Tự Động Cuối Tháng
// Script 3: Tổng hợp báo cáo tồn kho và gửi email cuối tháng
function baoCaoTonKhoCuoiThang() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheetTon = ss.getSheetByName('TonKho');
const data = sheetTon.getDataRange().getValues();
let tongGiaTri = 0;
let soSPSapHet = 0;
let soSPHetHang = 0;
let hangTonLau = [];
const today = new Date();
for (let i = 1; i < data.length; i++) {
if (!data[i][0]) continue;
const ton = data[i][5] || 0;
const giaNhap = data[i][4] || 0;
const toiThieu = data[i][6] || 0;
const ngayNhapCuoi = data[i][8] ? new Date(data[i][8]) : null;
tongGiaTri += ton * giaNhap;
if (ton === 0) soSPHetHang++;
else if (ton <= toiThieu) soSPSapHet++;
// Hàng tồn hơn 90 ngày
if (ngayNhapCuoi && ((today - ngayNhapCuoi) / 86400000) > 90 && ton > 0) {
hangTonLau.push(data[i][1] + ' (' + ton + ' SP)');
}
}
const thang = today.getMonth() + 1;
const nam = today.getFullYear();
let noiDung = `<h2>📊 Báo Cáo Tồn Kho Tháng ${thang}/${nam}</h2>`;
noiDung += `<p><strong>Tổng giá trị tồn kho:</strong> ${tongGiaTri.toLocaleString('vi-VN')}đ</p>`;
noiDung += `<p><strong>Hàng sắp hết:</strong> ${soSPSapHet} mặt hàng</p>`;
noiDung += `<p><strong>Hàng hết kho:</strong> ${soSPHetHang} mặt hàng</p>`;
if (hangTonLau.length > 0) {
noiDung += `<p><strong>Hàng tồn lâu >90 ngày (${hangTonLau.length} SP):</strong></p>`;
noiDung += '<ul>' + hangTonLau.map(h => '<li>' + h + '</li>').join('') + '</ul>';
}
MailApp.sendEmail({
to: 'EMAIL_QUAN_LY@gmail.com',
subject: `📊 Báo Cáo Kho Tháng ${thang}/${nam}`,
htmlBody: noiDung
});
}
// Cài trigger: ngày 1 hàng tháng lúc 7am
6. Script 4: Tự Động Tạo Đề Xuất Đơn Nhập Hàng
// Script 4: Tạo sheet đề xuất nhập hàng dựa trên ROP
function taoDeXuatNhapHang() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheetTon = ss.getSheetByName('TonKho');
const data = sheetTon.getDataRange().getValues();
// Tạo hoặc xóa sheet đề xuất cũ
let sheetDeXuat = ss.getSheetByName('DeXuatNhap');
if (sheetDeXuat) ss.deleteSheet(sheetDeXuat);
sheetDeXuat = ss.insertSheet('DeXuatNhap');
// Header
sheetDeXuat.appendRow(['Mã SP', 'Tên SP', 'Tồn hiện tại', 'ROP', 'Cần nhập', 'NCC gợi ý', 'Ưu tiên']);
let soHangDeXuat = 0;
for (let i = 1; i < data.length; i++) {
if (!data[i][0]) continue;
const ton = data[i][5] || 0;
const rop = data[i][7] || 0; // Cột H: Reorder Point
if (ton <= rop) {
const canNhap = Math.max(rop * 2 - ton, 0); // Nhập đủ cho 2x ROP
const uuTien = ton === 0 ? 'KHẨN CẤP' : (ton < rop * 0.5 ? 'Cao' : 'Bình thường');
sheetDeXuat.appendRow([
data[i][0], data[i][1], ton, rop, canNhap, data[i][9] || '', uuTien
]);
soHangDeXuat++;
}
}
// Format màu sắc
if (soHangDeXuat > 0) {
const range = sheetDeXuat.getRange(2, 7, soHangDeXuat, 1);
// Highlight KHẨN CẤP màu đỏ (cần thêm logic nếu muốn)
}
SpreadsheetApp.getUi().alert(`✅ Đã tạo đề xuất nhập ${soHangDeXuat} mặt hàng trong sheet "DeXuatNhap"`);
}
7. Hướng Dẫn Triển Khai Từng Bước
Chuẩn bị template Google Sheets kho
Đặt tên sheet đúng: "TonKho", "NhapKho", "XuatKho", "DanhMuc". Đảm bảo cột dữ liệu khớp với script.
Mở Apps Script Editor
Extensions → Apps Script. Paste code script vào. Thay "EMAIL_QUAN_LY@gmail.com" bằng email thực.
Test thủ công
Chọn function → Run để test. Lần đầu sẽ hỏi cấp quyền Gmail/Sheets — chọn Allow.
Cài trigger tự động
Click biểu tượng đồng hồ → Add Trigger → chọn thời gian chạy tự động hàng ngày/tháng.
Template Kho + Apps Script Sẵn Sàng Dùng
SheetStore cung cấp template Google Sheets quản lý kho đã tích hợp sẵn tất cả 4 script trên — chỉ cần nhập email và dữ liệu sản phẩm là chạy ngay, không cần tự viết code.
Xem Template Kho + Automation →8. Câu Hỏi Thường Gặp
Bài viết liên quan:
Chia sẻ bài viết:
Tuân Hoang
Đội ngũ SheetStore
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.