Google Sheet Script - 如果找到单元格值,则返回标题值
提前感谢您的帮助。
我有一个 Google 表格,其中包含第一行的标题值。我有一个脚本,可以逐行查看表格的其余部分,如果单元格是某种颜色,则脚本会进行计数。最后,如果计数数字大于我在表格中设置的变量,则脚本将触发电子邮件。
我想尝试做的是,如果脚本找到具有设置颜色的单元格,是否还要捕获列标题值?我确信我需要创建一个包含标题值的数组,然后比较位置,但我不知道如何有效地做到这一点。
function sendEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheet = ss.getSheets()[0];
var lastRow = dataSheet.getLastRow();
var lastColumn = dataSheet.getLastColumn();
//Project Range Information
var projectRange = dataSheet.getRange(6,3,lastRow-5,lastColumn);
var projectRangeValues = projectRange.getValues()[0];
var cellColors = projectRange.getBackgrounds();
//Student Information Range
var studentRange = dataSheet.getRange(6,1,lastRow-5,lastColumn);
var studentRangeValues = studentRange.getValues();
//Pull email template information
var emailSubject = ss.getRange("Variables!B1").getValue();
var emailText = ss.getRange("Variables!B2").getValue();
var triggerValue = ss.getRange("Variables!B4").getValue();
var ccValue = ss.getRange("Variables!B5").getValue();
//Where to Start and What to Check
var colorY = ss.getRange("Variables!B6").getValue();
var count = 0;
var startRow = 6;
//Loop through sheet and pull data
for(var i = 0; i < cellColors.length; i++) {
//Pull some information from the rows to use in email
var studentName = studentRangeValues[i][0];
var studentBlogUrl = studentRangeValues[i][1];
var studentEmail = studentRangeValues[i][2];
var studentData = [studentName,studentBlogUrl];
//Loop through cell colors and count them
for(var j = 0; j < cellColors[0].length ; j++) {
if(cellColors[i][j] == colorY) {
/*This is where I feel I need to add the array comparisons to get the header values */
count = count + 1;
};//end if statement
};//end for each cell in a row
//If the count is greater than trigger, send emails
if (count >= triggerValue) {
//A call to another function that merges the information
var emailBody = fillInTemplateFromObject(emailText, studentData);
MailApp.sendEmail({
to: studentEmail,
cc: ccValue,
subject: emailSubject,
htmlBody: emailBody,
});
} else {};
//reset count to 0 before next row
count = 0;
};//end for each row
};
编辑: 我已根据响应更新了上述代码部分:
//Header Information
var headers = dataSheet.getRange(4,4,1,lastColumn);
var headerValues = headers.getValues();
var missingAssignments = new Array();
在 for 循环中我添加了:
//Loop through cell colors and count them
for(var j = 0; j < cellColors[0].length ; j++) {
if(cellColors[i][j] == colorY) {
//This pushes the correct information into the array that matches up with the columns with a color.
missingAssignments.push(headervalues[i][j]);
count = count + 1;
};//end if statement
};//end for each cell in a row
我遇到的问题是出现错误 - TypeError:无法从未定义读取属性“2”。这是由于脚本移动到下一行时 for 循环中的推送导致的。我不确定为什么会出现此错误。从我读过的其他内容来看,数组设置为未定义。我尝试将数组设置为空并将其长度设置为 0,但这没有帮助。我认为我不明白数组在运行时的作用域。
编辑: 搞清楚了,“i”不应该迭代。它应该是:
missingAssignments.push(headervalues[0][j]);
第一个 for 循环结束时,我清除了下一行的数组。
missingAssignments.length = 0;
您应该获取整个工作表的值。然后使用 shift 方法仅获取标题。如果没有有关工作表的更多信息,我很难完全理解您的意图。如果我可以提供更多信息,请告诉我。
function sendEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheet = ss.getSheets()[0];
var lastRow = dataSheet.getLastRow();
var lastColumn = dataSheet.getLastColumn();
//below gets the whole sheet and shifts off the first row as headers
var fullSheet = dataSheet.getDataRange().getValues();
var headers = fullSheet.shift();
//then in your loops you can check against the index of the headers array
使用 Apps 脚本生成电子表格的速度非常慢,尤其是在需要读取大量数据的情况下。
请查看这些 来自 Apps 文档的提示 :
使用批处理操作
Scripts commonly need to read in data from a spreadsheet, perform calculations, and then write out the results of the data to a spreadsheet. Google Apps Script already has some built-in optimization, such as using look-ahead caching to retrieve what a script is likely to get and write caching to save what is likely to be set.
You can write scripts to take maximum advantage of the built-in caching, by minimizing the number of reads and writes. Alternating read and write commands is slow. To speed up a script, read all data into an array with one command, perform any operations on the data in the array, and write the data out with one command.
Here's an example — an example you should not follow or use. The Spreadsheet Fractal Art script in the Gallery (only available in the older version of Google Sheets) uses the following code to set the background colors of every cell in a 100 x 100 spreadsheet grid:
// DO NOT USE THIS CODE. It is an example of SLOW, INEFFICIENT code.
// FOR DEMONSTRATION ONLY
var cell = sheet.getRange('a1');
for (var y = 0; y < 100; y++) {
xcoord = xmin;
for (var x = 0; x < 100; x++) {
var c = getColor_(xcoord, ycoord);
cell.offset(y, x).setBackgroundColor(c);
xcoord += xincrement;
}
ycoord -= yincrement;
SpreadsheetApp.flush();
}
The script is inefficient: it loops through 100 rows and 100 columns, writing consecutively to 10,000 cells. The Google Apps Script write-back cache helps, because it forces a write-back using flush at the end of every line. Because of the caching, there are only 100 calls to the Spreadsheet.
But the code can be made much more efficient by batching the calls. Here's a rewrite in which the cell range is read into an array called colors, the color assignment operation is performed on the data in the array, and the values in the array are written out to the spreadsheet:
// OKAY TO USE THIS EXAMPLE or code based on it.
var cell = sheet.getRange('a1');
var colors = new Array(100);
for (var y = 0; y < 100; y++) {
xcoord = xmin;
colors[y] = new Array(100);
for (var x = 0; x < 100; x++) {
colors[y][x] = getColor_(xcoord, ycoord);
xcoord += xincrement;
}
ycoord -= yincrement;
}
sheet.getRange(1, 1, 100, 100).setBackgroundColors(colors);
inefficient code takes about 70 seconds to run. The efficient code runs in just 1 second!
If you're looking at the Spreadsheet Fractal Art script (only available in the older version of Google Sheets), please be aware that we made a minor change to it to make this example easier to follow. The script as published uses the setBackgroundRGB call, rather than setBackgroundColor, which you see above. The getColor_ function was changed as follows:
if (iteration == max_iteration) {
return '#000000';
} else {
var c = 255 - (iteration * 5);
c = Math.min(255, Math.max(0, c));
var hex = Number(c).toString(16);
while (hex.length < 2)
hex = '0' + hex;
return ('#' + hex + '3280');
}