Sự cố hệ thống vào đêm muộn
Lúc đó là 2 giờ sáng. Bạn đang chạy một đoạn mã (script) để tổng hợp dữ liệu từ 15 tab khu vực khác nhau vào một bảng điều khiển chính (master dashboard). Mọi thứ vẫn hoạt động tốt vào ngày hôm qua, nhưng giờ đây nhật ký thực thi (execution log) đang "đỏ rực" lỗi. Đoạn mã đã dừng lại với một lỗi cụ thể:
Exception: The target range is too small to receive the source data.
Lỗi này xảy ra khi phương thức copyTo() gặp phải sự không đồng nhất về kích thước. Nếu dữ liệu nguồn của bạn có 100 hàng và 10 cột, nhưng bạn xác định vùng đích là 99 hàng và 10 cột, Google Apps Script sẽ dừng thực thi để tránh mất dữ liệu. Nó từ chối việc "nhồi nhét" một khối dữ liệu lớn vào một ngăn chứa nhỏ hơn.
Cách khắc phục trong 10 giây
Giải pháp đáng tin cậy nhất là chỉ nhắm mục tiêu vào ô trên cùng bên trái của vùng đích. Khi bạn cung cấp một ô duy nhất thay vì toàn bộ dải ô (range), Apps Script sẽ tự động tính toán không gian cần thiết. Nó sẽ mở rộng dữ liệu vào các ô lân cận mà không phàn nàn về kích thước.
Tránh sử dụng các dải ô được mã hóa cứng (hardcoded):
// Lệnh này sẽ thất bại nếu dữ liệu nguồn tăng lên 11 hàng
sourceRange.copyTo(targetSheet.getRange("A1:C10"));
Thay vào đó, hãy sử dụng một ô neo (anchor cell):
// Cách này hoạt động tốt cho dù bạn có 1 hàng hay 10.000 hàng
sourceRange.copyTo(targetSheet.getRange("A1"));
Tại sao lỗi này xảy ra
Khi bạn truyền một đối tượng Range làm tham số cho copyTo(destination), hệ thống sẽ thực hiện kiểm tra nghiêm ngặt. Nếu dải ô đích đó chứa nhiều hơn một ô (ví dụ: A1:B20), đoạn mã sẽ yêu cầu kích thước phải khớp hoàn toàn với nguồn.
Các tình huống điển hình gây ra lỗi này bao gồm:
- Sự tăng trưởng động: Trang tính nguồn của bạn có thêm ba cột dữ liệu mới vốn không tồn tại khi bạn viết mã.
- Lỗi chênh lệch 1 đơn vị (Off-by-one): Bạn đã sử dụng
getLastRow()nhưng quên mất rằng hàng tiêu đề (header row) làm thay đổi tổng số hàng. - Ô bị hợp nhất (Merged Cells): Một ô hợp nhất duy nhất trong vùng đích có thể khiến hệ thống hiểu lầm rằng chiều rộng khả dụng nhỏ hơn thực tế.
Ba giải pháp đáng tin cậy
1. Phương pháp ô neo (Cách tốt nhất)
Chỉ cung cấp ô bắt đầu là cách tiếp cận gọn gàng nhất. Nó loại bỏ nhu cầu tính toán xem dữ liệu của bạn chiếm bao nhiêu hàng hoặc cột. Cách này lý tưởng cho việc di chuyển dữ liệu đơn giản.
function consolidateData() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sourceSheet = ss.getSheetByName("Monthly_Report");
const targetSheet = ss.getSheetByName("Archive");
const sourceRange = sourceSheet.getDataRange();
const destCell = targetSheet.getRange("A1");
// Hệ thống sẽ tự động xử lý việc mở rộng
sourceRange.copyTo(destCell);
}
2. Khớp kích thước động
Bạn có thể cần xác định dải ô đầy đủ nếu bạn đang áp dụng định dạng có điều kiện hoặc xác thực dữ liệu (data validation) cho khu vực cụ thể đó ngay sau khi sao chép. Trong trường hợp này, hãy sử dụng chính kích thước của nguồn để xây dựng vùng đích.
function copyWithExplicitRange() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const source = ss.getSheetByName("Source").getRange("B2:F15");
const targetSheet = ss.getSheetByName("Target");
// Lấy kích thước chính xác của nguồn
const rows = source.getNumRows();
const cols = source.getNumColumns();
// Tạo vùng đích khớp hoàn toàn (Bắt đầu tại Hàng 1, Cột 1)
const targetRange = targetSheet.getRange(1, 1, rows, cols);
source.copyTo(targetRange);
}
3. Làm việc với setValues()
Nếu bạn đang sử dụng setValues() để dán dữ liệu thô mà không có định dạng, các quy tắc sẽ thay đổi. Không giống như copyTo(), phương thức setValues() yêu cầu sự khớp chính xác. Bạn không thể truyền một ô duy nhất vào setValues(). Bạn phải tính toán kích thước dải ô, nếu không đoạn mã sẽ thất bại.
// Cách chính xác để sử dụng setValues
const data = sourceRange.getValues();
targetSheet.getRange(1, 1, data.length, data[0].length).setValues(data);
Cách kiểm tra việc khắc phục
Kiểm tra khả năng phục hồi của đoạn mã với ba bước sau:
- Kiểm tra Nhật ký: Mở nhật ký thực thi Apps Script. Tìm thông báo "Execution completed" mà không có bất kỳ văn bản Exception màu đỏ nào.
- So sánh số lượng hàng: Nếu nguồn của bạn có 1.250 hàng, hãy xác nhận rằng đích của bạn cũng kết thúc ở hàng 1.250.
- Kiểm tra áp lực (Stress Test): Thêm thủ công 10 hàng dữ liệu giả vào nguồn và chạy lại đoạn mã. Nếu bạn đã sử dụng phương pháp Ô neo, nó sẽ xử lý sự gia tăng này mà không cần can thiệp thủ công.
Những cạm bẫy tiềm ẩn
- Dải ô được bảo vệ: Nếu một ô duy nhất trong vùng đích bị bảo vệ, đoạn mã có thể báo lỗi kích thước dải ô vì nó không thể "mở rộng" vào không gian bị hạn chế.
- Giới hạn 10 triệu ô: Google Sheets giới hạn mỗi bảng tính tối đa 10 triệu ô. Nếu thao tác sao chép của bạn đẩy trang tính vượt quá giới hạn này, bạn có thể nhận được các lỗi dải ô chung chung.
- Chế độ xem được lọc: Sao chép dữ liệu vào một trang tính có các bộ lọc đang hoạt động có thể gây ra kết quả không mong muốn. Đoạn mã nhìn thấy lưới dữ liệu bên dưới, ngay cả khi một số hàng bị ẩn khỏi chế độ xem của bạn.

