TL;DR
setValues() yêu cầu một mảng 2 chiều — mảng của các mảng. Truyền vào mảng 1 chiều như [1, 2, 3] sẽ gây ra lỗi này. Cách sửa là thêm một cặp ngoặc vuông nữa: [[1, 2, 3]] cho một hàng đơn, hoặc [[1], [2], [3]] cho một cột đơn.
// ❌ Sai — mảng 1 chiều
range.setValues([1, 2, 3]);
// ✅ Đúng — mảng 2 chiều (một hàng)
range.setValues([[1, 2, 3]]);
// ✅ Đúng — mảng 2 chiều (một cột)
range.setValues([[1], [2], [3]]);
Nguyên nhân gốc rễ
Trong nhật ký thực thi Apps Script, lỗi đầy đủ như sau:
Exception: The parameters (number[]) don't match the method signature for SpreadsheetApp.Range.setValues.
Bảng tính là dạng lưới. Có hàng và có cột. setValues() ánh xạ trực tiếp lên cấu trúc đó, nên nó luôn kỳ vọng một mảng 2 chiều:
- Mảng ngoài = các hàng.
- Mỗi mảng trong = các ô trong hàng đó.
Truyền vào [10, 20, 30] thì Apps Script nhận thấy một number[] — một chiều. Nó cần number[][]. Chữ ký không khớp nên phương thức báo lỗi trước khi ghi bất kỳ dữ liệu nào.
Kiểu dữ liệu trong ngoặc đơn thay đổi tùy theo dữ liệu của bạn — bạn có thể thấy (number[]), (string[]), hoặc (String[]). Không quan trọng. Cách sửa luôn giống nhau: bọc nó trong một mảng nữa.
Các tình huống thường gặp và cách sửa
Tình huống 1: Ghi một hàng giá trị
Giả sử bạn có ba giá trị — tên, tuổi và chức danh — và muốn đưa chúng vào hàng 1.
// ❌ Lỗi
function writeRow() {
var sheet = SpreadsheetApp.getActiveSheet();
var values = ["Alice", 30, "Engineer"];
sheet.getRange(1, 1, 1, 3).setValues(values); // TypeError!
}
// ✅ Đã sửa
function writeRow() {
var sheet = SpreadsheetApp.getActiveSheet();
var values = [["Alice", 30, "Engineer"]];
sheet.getRange(1, 1, 1, 3).setValues(values);
}
getRange(1, 1, 1, 3) có nghĩa là 1 hàng × 3 cột. Mảng 2 chiều của bạn phải khớp: một mảng trong chứa đúng 3 phần tử.
Tình huống 2: Ghi một cột giá trị
Ghi theo chiều dọc một cột thì ngược lại — mỗi giá trị có mảng trong riêng của nó.
// ❌ Lỗi
function writeColumn() {
var sheet = SpreadsheetApp.getActiveSheet();
var values = [100, 200, 300];
sheet.getRange(1, 1, 3, 1).setValues(values); // TypeError!
}
// ✅ Đã sửa — mỗi giá trị nằm trong mảng hàng riêng của nó
function writeColumn() {
var sheet = SpreadsheetApp.getActiveSheet();
var values = [[100], [200], [300]];
sheet.getRange(1, 1, 3, 1).setValues(values);
}
Tình huống 3: Xây dựng mảng động trong vòng lặp
Mảng được tạo trong vòng lặp là nơi lỗi này ẩn náu phổ biến nhất. Bạn duyệt qua dữ liệu, đẩy các giá trị vào, và quên rằng mỗi lần đẩy phải là một hàng — không phải giá trị đơn thuần.
// ❌ Lỗi — đẩy số thuần
function processData() {
var sheet = SpreadsheetApp.getActiveSheet();
var output = [];
var data = [10, 20, 30, 40];
data.forEach(function(val) {
output.push(val * 2); // đẩy một số, không phải một mảng
});
sheet.getRange(1, 1, output.length, 1).setValues(output); // TypeError!
}
// ✅ Đã sửa — đẩy một mảng nhỏ mỗi lần lặp
function processData() {
var sheet = SpreadsheetApp.getActiveSheet();
var output = [];
var data = [10, 20, 30, 40];
data.forEach(function(val) {
output.push([val * 2]); // mỗi hàng là một mảng riêng
});
sheet.getRange(1, 1, output.length, 1).setValues(output);
}
Tình huống 4: Vô tình làm phẳng kết quả getValues()
getValues() luôn trả về mảng 2 chiều — phần đó an toàn. Vấn đề bắt đầu khi bạn gọi .flat(), nối thêm .map() trả về kiểu nguyên thủy, hoặc cắt kết quả một hàng đơn. Bất kỳ thao tác nào trong số đó đều có thể âm thầm loại bỏ mảng ngoài.
// ❌ Lỗi — .flat() phá vỡ cấu trúc 2 chiều
function copyRow() {
var sheet = SpreadsheetApp.getActiveSheet();
var sourceValues = sheet.getRange("A1:C1").getValues().flat();
// sourceValues bây giờ là ["x", "y", "z"] — 1 chiều!
sheet.getRange("A2:C2").setValues(sourceValues); // TypeError!
}
// ✅ Đã sửa — dùng trực tiếp kết quả của getValues()
function copyRow() {
var sheet = SpreadsheetApp.getActiveSheet();
var sourceValues = sheet.getRange("A1:C1").getValues();
// sourceValues là [["x", "y", "z"]] — vẫn 2 chiều
sheet.getRange("A2:C2").setValues(sourceValues);
}
Tình huống 5: Ghi một ô đơn
Ghi một ô đơn có cách dễ hơn. setValue() (không có 's') nhận một giá trị thông thường. Nếu bạn vẫn muốn dùng setValues(), bạn vẫn cần dùng dấu ngoặc vuông kép.
// Lựa chọn A — gọn hơn cho một ô
sheet.getRange("A1").setValue(42);
// Lựa chọn B — setValues() vẫn cần mảng 2 chiều
sheet.getRange("A1").setValues([[42]]);
Danh sách kiểm tra khi gỡ lỗi
Không chắc mảng của bạn có hình dạng gì? Hãy ghi log trước khi gọi hàm:
var values = buildMyArray(); // bất kỳ logic nào của bạn
Logger.log(JSON.stringify(values));
Logger.log("Is array: " + Array.isArray(values));
Logger.log("Is 2D: " + Array.isArray(values[0]));
var numRows = values.length;
var numCols = values[0].length;
Logger.log("Dimensions: " + numRows + " rows x " + numCols + " cols");
// Sau đó xác nhận vùng khớp với các kích thước đó
sheet.getRange(startRow, startCol, numRows, numCols).setValues(values);
Kích thước vùng phải khớp chính xác. Mảng 3×2 cần vùng 3 hàng, 2 cột. Kích thước không khớp sẽ gây ra lỗi khác — nhưng việc cấu trúc 2 chiều đúng trước sẽ loại bỏ lỗi cụ thể này.
Xác nhận bản sửa lỗi
- Mở trình soạn thảo script: Tiện ích mở rộng → Apps Script trong bảng tính của bạn.
- Chạy hàm bằng nút ▶ hoặc Ctrl+R.
- Kiểm tra Nhật ký thực thi (Xem → Nhật ký) — không có ngoại lệ có nghĩa là lệnh gọi thành công.
- Quay lại bảng tính và xác nhận các ô đích chứa đúng giá trị.
Tham khảo nhanh
- Một hàng, nhiều cột:
[[val1, val2, val3]] - Nhiều hàng, một cột:
[[val1], [val2], [val3]] - Nhiều hàng, nhiều cột:
[[a1, b1], [a2, b2], [a3, b3]] - Một ô qua setValues:
[[val]] - Cách viết tắt cho một ô:
setValue(val)— không cần dấu ngoặc vuông

