Google Apps Script按条件使用setValues()的问题及代码报错求助
Hey there! Let's break down your questions step by step, starting with the bits you're confused about in the sample code, then fix that error in your script.
First, let's clear up your three key questions about the example forEach loop:
1. What does row refer to in function(row)?
The data variable comes from getValues(), which returns a 2D array (an array of arrays) where each subarray represents one row from your spreadsheet. When you use data.forEach(function(row) { ... }), the row parameter is just a placeholder for each subarray in data—so on each iteration of the loop, row is exactly one row of your spreadsheet data (e.g., [cellAValue, cellBValue, cellCValue] for a 3-column row).
2. What do row[7] or row[10] mean?
Arrays in JavaScript are zero-indexed—meaning the first element is at position 0. So:
row[0]= the first cell in the row (column A)row[7]= the 8th cell in the row (column H)row[10]= the 11th cell in the row (column K)
The number inside the brackets is the column's index, counting left-to-right starting at 0.
3. How do push() and unshift() work?
These are built-in array methods to add elements:
kept.push(row): Adds the filteredrowarray to the end of thekeptarray. Ifkeptwas empty before, it becomes[row]; if it had rows already, it grows to[row1, row2, row3].row.unshift(sheetName): Adds thesheetNamevalue to the start of therowarray. For example, ifrowwas[val1, val2, val3], after unshift it becomes[sheetName, val1, val2, val3]—like inserting a new column at the beginning of that row.
The biggest issue with your code is that you defined the latestrows() function but never called it! Your filtering logic never runs, so the kept array stays empty. That's why you get TypeError: Cannot read property "length" from undefined—when you try kept[0].length, kept[0] is undefined (since the array is empty), and you can't access length on an undefined value.
There are a few other small fixes needed too. Here's the corrected version of your script with explanations:
function importtest() { // Source sheet setup var sheetX = SpreadsheetApp.openById("XXX-XXX-XXX"); var tabX = sheetX.getSheetByName("EXPORTER"); // Calculate correct range: start at row 6, column 2, get only rows with data var lastRow = tabX.getLastRow(); var lastCol = tabX.getLastColumn(); // Rows: from row 6 to lastRow = lastRow - 6 + 1 = lastRow -5 // Columns: from column 2 to lastCol = lastCol - 2 +1 = lastCol -1 var rangeX = tabX.getRange(6, 2, lastRow - 5, lastCol - 1).getValues(); var kept = [] ; var data = rangeX ; // Filtering function function latestrows() { // Declare 'i' with var to avoid scope issues for (var i = 0; i < data.length ; i++) { // Get values from the CURRENT row (moved inside the loop!) var datesent = data[i][2] ; // Column 4 (index 2, since we started at column 2) var datarow = data[i] ; if (datesent == 1) { kept.push(datarow); } } } latestrows(); // Critical: call the function to run the filter! // Target sheet setup var sheetX3 = SpreadsheetApp.openById("XXX-XX-XX"); var tabX3 = sheetX3.getSheetByName("IMPORTED"); // Only write data if we found matching rows if (kept.length > 0) { var rangeX3 = tabX3.getRange(7, 3, kept.length, kept[0].length); rangeX3.setValues(kept); } else { // Optional: alert if no rows matched SpreadsheetApp.getUi().alert("No rows matched the condition (B column = 1)!"); } }
Key Fixes Explained:
- Called
latestrows(): This executes your filtering logic sokeptgets populated with matching rows. - Moved row data inside the loop:
datesentanddataroware now set inside theforloop, so they update for every row instead of only using the last row's value. - Fixed range calculation: Used
tabX.getLastRow()/tabX.getLastColumn()(specific to your source sheet) instead of the whole spreadsheet's values, and calculated the correct number of rows/columns to avoid empty data. - Added empty array check: Prevents errors if no rows match your condition by checking
kept.length > 0before writing.
- Always call functions you define—otherwise their code never runs!
getValues()returns a 2D array:data[rowIndex][columnIndex], with indexes starting at 0.push()adds elements to the end of an array,unshift()adds to the start.
内容的提问来源于stack exchange,提问作者Tea




