Apps Script Từ A Đến Z - Bài 1: Giới Thiệu và Các Khái Niệm Cơ Bản

Apps Script Từ A Đến Z - Bài 1: Giới Thiệu và Các Khái Niệm Cơ Bản
Chào mừng bạn đến với series Apps Script Từ A Đến Z — loạt bài hướng dẫn toàn diện nhất về Google Apps Script bằng tiếng Việt. Đây là bài mở đầu, nơi chúng ta sẽ xây dựng nền tảng vững chắc trước khi đi vào các kỹ thuật nâng cao hơn trong các bài tiếp theo.
- Người dùng Google Sheets muốn tự động hóa công việc
- Developer biết JavaScript muốn mở rộng sang G Suite
- Người đã quen VBA Excel muốn chuyển sang Google Workspace
- Analyst muốn tạo dashboard và report tự động
Apps Script Là Gì?
Google Apps Script (viết tắt: GAS) là nền tảng scripting dựa trên JavaScript V8, được tích hợp sẵn trong hệ sinh thái Google Workspace. Nó cho phép bạn tự động hóa, mở rộng và kết nối các sản phẩm Google (Sheets, Docs, Drive, Gmail, Calendar, Forms...) với nhau và với dịch vụ bên ngoài qua API.
Ra mắt năm 2009 dưới tên "Google Apps Script" (trước khi Google Workspace đổi tên từ G Suite), GAS đã trải qua nhiều cột mốc quan trọng:
- 2009: Ra mắt lần đầu, tích hợp vào Google Spreadsheets
- 2011: Mở rộng sang Google Sites, Gmail add-ons
- 2015: Hỗ trợ Google Forms và Calendar
- 2017: Clasp CLI ra đời, cho phép phát triển local
- 2020: Nâng cấp runtime lên V8 (ES6+ syntax support)
- 2023-2027: Tích hợp Gemini AI, Advanced Services, Workspace Add-ons mới
Apps Script vs VBA Excel: Khi Nào Dùng Cái Nào?
| Tiêu chí | Google Apps Script | VBA Excel |
|---|---|---|
| Ngôn ngữ | JavaScript (ES6+) | Visual Basic for Applications |
| Chạy trên | Cloud (Google servers) | Local máy tính |
| Collaboration | Real-time, nhiều người | Khó chia sẻ |
| API Integration | UrlFetchApp, dễ dàng | WinHttp, phức tạp hơn |
| Scheduled tasks | Triggers tích hợp sẵn | Cần Task Scheduler Windows |
| Performance | Chậm hơn với file lớn | Nhanh hơn với tính toán nặng |
| Cost | Miễn phí (trong quota) | Cần license Microsoft Office |
| Cross-platform | Windows, Mac, Linux, Mobile | Chỉ Windows |
Kết luận: Nếu tổ chức bạn dùng Google Workspace, Apps Script là lựa chọn rõ ràng. Nếu vẫn dùng Excel On-premise, VBA vẫn có chỗ đứng. Ngày nay với xu hướng cloud, GAS đang dần thay thế VBA trong nhiều doanh nghiệp Việt Nam.
Cài Đặt IDE: Hai Cách Viết Apps Script
Cách 1: Online Editor (Apps Script IDE)
Cách đơn giản nhất để bắt đầu:
- Mở Google Sheets (hoặc Docs, Drive)
- Vào menu Extensions → Apps Script
- IDE mở ra tại
script.google.com - Code, Save, Run ngay trong trình duyệt
Online IDE hỗ trợ:
- Syntax highlighting và autocomplete
- Execution log real-time
- Debugger với breakpoints
- Version history
- Deployment manager
Cách 2: Clasp CLI (Local Development)
Clasp (Command Line Apps Script Projects) cho phép phát triển Apps Script trên máy local với editor yêu thích (VS Code):
# Cài đặt clasp
npm install -g @google/clasp
# Đăng nhập Google account
clasp login
# Clone script có sẵn từ Google
clasp clone SCRIPT_ID
# Hoặc tạo project mới
clasp create --title "My Project" --type sheets
# Push code lên Google
clasp push
# Pull code từ Google về local
clasp pull
# Mở IDE online
clasp open
Ưu điểm của Clasp: TypeScript support, Git version control, IDE features đầy đủ (ESLint, Prettier), team collaboration qua GitHub.
Cấu Trúc Project Apps Script
File chính: Code.gs
Mỗi project có ít nhất một file .gs (Google Script). Khi tạo mới, file mặc định là Code.gs:
// Code.gs - File script chính
function myFunction() {
// Code của bạn ở đây
Logger.log('Hello, Apps Script!');
}
function onOpen() {
// Chạy khi file mở
SpreadsheetApp.getUi().createMenu('My Menu')
.addItem('Run Task', 'myFunction')
.addToUi();
}
File cấu hình: appsscript.json
File manifest quan trọng, kiểm soát permissions và cấu hình project:
{
"timeZone": "Asia/Ho_Chi_Minh",
"dependencies": {
"libraries": []
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/gmail.send"
]
}
Libraries
Apps Script hỗ trợ libraries — tái sử dụng code giữa các project:
// Sử dụng library đã được add vào project
// (thêm qua Libraries + trong IDE)
const result = MyLibrary.myFunction(param1, param2);
// Tạo library của riêng bạn:
// 1. Tạo standalone script
// 2. Deploy as Library
// 3. Copy Script ID
// 4. Add vào project khác
Container-Bound vs Standalone Scripts
Container-Bound Script
Script được gắn với một file Google cụ thể (Sheets, Docs, Forms, Slides):
- Tạo từ: Extensions → Apps Script trong file đó
- Script chạy trong context của file cha
- Tự động có quyền truy cập file cha
- Không thể chia sẻ độc lập
- Xóa file cha → script bị xóa
// Container-bound: truy cập Spreadsheet cha
function containerBoundExample() {
// getActiveSpreadsheet() chỉ hoạt động trong container-bound
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getActiveSheet();
const value = sheet.getRange('A1').getValue();
Logger.log('Value in A1: ' + value);
}
Standalone Script
Script độc lập, không gắn với file nào:
- Tạo từ: script.google.com → New Project
- Linh hoạt hơn, có thể dùng như microservice
- Phù hợp cho automation không cần UI
- Có thể deploy làm Web App hoặc API
// Standalone: phải chỉ định file ID
function standaloneExample() {
const SHEET_ID = '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms';
const ss = SpreadsheetApp.openById(SHEET_ID);
const sheet = ss.getSheetByName('Data');
Logger.log('Rows: ' + sheet.getLastRow());
}
Authorization và OAuth2 Scopes
Apps Script sử dụng OAuth2 để xin quyền truy cập. Khi chạy script lần đầu, người dùng thấy popup xin phép:
Các Scope Phổ Biến
| Scope | Quyền truy cập |
|---|---|
spreadsheets |
Đọc/ghi tất cả Spreadsheets |
spreadsheets.readonly |
Chỉ đọc Spreadsheets |
drive |
Truy cập toàn bộ Drive |
gmail.send |
Gửi email qua Gmail |
calendar |
Đọc/ghi Google Calendar |
script.external_request |
Gọi API bên ngoài (UrlFetchApp) |
Best practice: Luôn dùng scope hẹp nhất có thể. Thay vì spreadsheets (full access), dùng spreadsheets.currentonly nếu chỉ cần truy cập file hiện tại.
Logging: Logger.log vs console.log
function loggingExamples() {
// Logger.log: hiển thị trong Execution Log (View → Logs)
Logger.log('Simple message');
Logger.log('Value: %s, Count: %d', 'hello', 42);
Logger.log(JSON.stringify({ key: 'value' }));
// console.log: hiển thị trong Stackdriver Logging
// (View → Stackdriver Logging) - lưu lâu hơn
console.log('This goes to Cloud Logging');
console.warn('Warning message');
console.error('Error occurred');
// Xem log:
// Logger.log → View → Logs (chỉ lưu trong session)
// console.log → View → Stackdriver Logging (lưu 30 ngày)
// Retrieve logs programmatically
const logs = Logger.getLog();
SpreadsheetApp.getActiveSheet().getRange('A1').setValue(logs);
}
Debugging với Breakpoints
Apps Script IDE hỗ trợ debugging trực quan:
- Click vào số dòng bên trái để đặt breakpoint (chấm đỏ xuất hiện)
- Nhấn nút Debug (biểu tượng bug) thay vì Run
- Execution dừng tại breakpoint
- Dùng panel bên phải xem giá trị variables
- Dùng Step Over (F10), Step Into (F11), Resume (F8)
function debugExample() {
const data = [1, 2, 3, 4, 5];
let sum = 0;
for (let i = 0; i < data.length; i++) {
sum += data[i]; // Đặt breakpoint ở đây để xem sum thay đổi
}
Logger.log('Total sum: ' + sum);
return sum;
}
Runtime Limits: Quan Trọng Cần Nhớ
- 6 phút — thời gian tối đa một script chạy liên tục
- 30 giây — thời gian tối đa một custom function trong Sheets
- 20MB — dung lượng data có thể đọc/ghi một lần
- 50MB — response size từ UrlFetchApp
| Giới hạn | Consumer (Free) | Workspace |
|---|---|---|
| Script runtime/ngày | 90 phút | 6 giờ |
| Trigger tối đa | 20 | 20 |
| UrlFetch calls/ngày | 20,000 | 100,000 |
| Email/ngày | 100 | 1,500 |
| Properties store | 500KB | 500KB |
Best Practices Tránh Vượt Limit
// BAD: Đọc/ghi từng cell một (chậm, tốn quota)
function slowApproach() {
const sheet = SpreadsheetApp.getActiveSheet();
for (let i = 1; i <= 1000; i++) {
const value = sheet.getRange(i, 1).getValue(); // 1000 API calls!
sheet.getRange(i, 2).setValue(value * 2); // 1000 API calls!
}
}
// GOOD: Batch read/write (nhanh, tiết kiệm quota)
function fastApproach() {
const sheet = SpreadsheetApp.getActiveSheet();
const data = sheet.getRange('A1:A1000').getValues(); // 1 API call
const results = data.map(row => [row[0] * 2]);
sheet.getRange('B1:B1000').setValues(results); // 1 API call
}
// GOOD: Checkpoint pattern cho script chạy lâu
function longRunningTask() {
const props = PropertiesService.getScriptProperties();
let startRow = parseInt(props.getProperty('lastRow') || '1');
const sheet = SpreadsheetApp.getActiveSheet();
const totalRows = sheet.getLastRow();
const startTime = new Date().getTime();
const TIME_LIMIT = 5 * 60 * 1000; // 5 phút, còn 1 phút buffer
while (startRow <= totalRows) {
// Xử lý batch 100 rows
processRows(sheet, startRow, Math.min(startRow + 99, totalRows));
startRow += 100;
if (new Date().getTime() - startTime > TIME_LIMIT) {
// Lưu checkpoint và thoát
props.setProperty('lastRow', startRow.toString());
Logger.log('Checkpoint saved at row: ' + startRow);
return; // Trigger sẽ chạy lại từ checkpoint
}
}
// Hoàn thành, xóa checkpoint
props.deleteProperty('lastRow');
Logger.log('Task completed!');
}
Hello World: Từng Loại Script
Hello World trong Spreadsheet
function helloSpreadsheet() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getActiveSheet();
sheet.getRange('A1').setValue('Hello, Apps Script! 🎉');
SpreadsheetApp.getUi().alert('Đã ghi vào A1!');
}
Hello World Web App
// Deploy → New deployment → Web App
function doGet(e) {
const name = e.parameter.name || 'World';
return ContentService
.createTextOutput(JSON.stringify({ message: 'Hello, ' + name + '!' }))
.setMimeType(ContentService.MimeType.JSON);
}
// Gọi API: https://script.google.com/macros/s/YOUR_ID/exec?name=SheetStore
Hello World Custom Function
/**
* Chào hỏi với tên truyền vào
* @param {string} name Tên người dùng
* @return {string} Lời chào
* @customfunction
*/
function XIN_CHAO(name) {
return 'Xin chào, ' + name + '! Từ Apps Script 👋';
}
// Dùng trong sheet: =XIN_CHAO("Nguyễn Văn A")
Tổng Quan Series Apps Script Từ A-Z
Đây là roadmap các bài học sắp tới trong series:
| Bài | Chủ đề | Nội dung chính |
|---|---|---|
| Bài 1 | Giới thiệu (bài này) | Khái niệm, IDE, structure, limits |
| Bài 2 | SpreadsheetApp | Đọc ghi dữ liệu, Range operations |
| Bài 3 | Triggers | Tự động hóa theo sự kiện và thời gian |
| Bài 4 | GmailApp | Gửi email, đọc inbox, tạo draft |
| Bài 5 | DriveApp | Quản lý file, folder trên Drive |
| Bài 6 | UrlFetchApp | Gọi REST API, webhook, Zalo/Telegram |
| Bài 7 | HTML Service | Tạo sidebar, dialog, web app UI |
| Bài 8+ | Advanced Topics | PropertiesService, CacheService, LockService... |
Câu Hỏi Thường Gặp
A: Có! Triggers chạy trên Google servers, không cần máy tính bạn online. Ví dụ: trigger backup lúc 2h sáng vẫn chạy dù bạn đang ngủ.
A: Miễn phí cho tất cả Google Account. Workspace users có quota cao hơn. Chỉ tính phí nếu dùng Advanced Services tốn tiền (BigQuery, Maps API...).
A: Rất dễ nếu biết JavaScript. Nếu biết Python/PHP, mất khoảng 1-2 tuần để quen syntax JS và GAS API. Logic tư duy lập trình giống nhau.
A: Script trong file Sheets chỉ thấy được khi có quyền edit file. Standalone script mặc định chỉ bạn thấy. Web App có thể public nhưng code vẫn private.
Chúng ta sẽ deep dive vào SpreadsheetApp — trái tim của mọi Apps Script làm việc với Google Sheets. Tất cả Range operations, batch processing, và ví dụ thực tế.
📚 Bài Viết Liên Quan
- Template Google Sheets Báo Cáo Bán Hàng Theo Vùng và Đại Lý 2027: Phân Tích Đa Chiều
- Google Sheets Nâng Cao Bài 9: Bảo Mật, Phân Quyền và Chia Sẻ Chuyên Nghiệp
- Google Sheets Nâng Cao Bài 4: Hàm QUERY - Lọc và Phân Tích Dữ Liệu Chuyên Nghiệp
- Template Google Sheets Quản Lý Phòng Khám và Bệnh Viện Nhỏ 2027
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.