Google Sheet Script - 如果找到单元格值,则返回标头值

时间:2017-05-22 05:19:07

标签: javascript google-apps-script google-sheets google-sheets-api

提前感谢您的帮助。

我有一张包含第一行标题值的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:无法读取属性&#34; 2&#34;来自undefined。这是由于脚本移动到下一行时推入for循环引起的。我不确定为什么我收到这个错误。从我读过的其他内容来看,数组设置为undefined。我试图将数组设置为空并将其长度设置为0,但它没有帮助。我不认为我理解阵列运行时的范围。

编辑: 想出来了,&#34;我&#34;不应该迭代。它应该是:

missingAssignments.push(headervalues[0][j]);

第一个for循环的结束我清除了下一行的数组。

missingAssignments.length = 0;

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

使用应用程序脚本的电子表格非常慢,特别是如果您有大量数据需要阅读。

检查这些tips from Apps doc

使用批处理操作

  

脚本通常需要从电子表格中读取数据,然后执行   计算,然后将数据的结果写出来   电子表格。 Google Apps脚本已经有一些内置功能   优化,比如使用先行缓存来检索什么   脚本可能会获取和编写缓存以保存可能的内容   集。

     

您可以编写脚本以最大限度地利用内置功能   通过最小化读写次数来缓存。交替   读写命令很慢。要加速脚本,请读取所有数据   使用一个命令进入数组,对数据执行任何操作   数组,并用一个命令写出数据。

     

这是一个例子 - 你不应该遵循或使用的例子。该   图库中的电子表格分形艺术脚本(仅适用于   旧版Google表格)使用以下代码来设置   100 x 100电子表格网格中每个单元格的背景颜色:

// 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();
}
  

脚本效率低下:它遍历100行和100列,   连续写入10,000个单元格。 Google Apps脚本   回写缓存有帮助,因为它强制使用flush at进行回写   每一行的结尾。由于缓存,只有100   调用电子表格。

     

但是通过批量调用可以使代码更有效率。   这是一个重写,其中单元格范围被读入一个名为的数组   颜色,颜色分配操作是对数据执行的   数组,并将数组中的值写出到电子表格中:

// 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); 

  

效率低下的代码大约需要70秒才能运行。高效的代码   只需1秒就可以运行!

     

如果您正在查看电子表格分形艺术脚本(仅限   请参阅旧版Google表格中的相关信息,请注意   我们对它做了一个小改动,使这个例子更容易理解。   发布的脚本使用setBackgroundRGB调用,而不是   setBackgroundColor,你在上面看到。 getColor_函数是   改变如下:

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');
}