Google 应用程序脚本 - 使用 for 循环根据条件从范围中提取数据

Google apps script - using for loop to pull data from range based on condition

我在 Google 表格中从 for 循环中提取正确的值时遇到问题。 这是我的代码: 注意:这是一个较大函数的片段

function sendEmails() {
var trackOriginSheet = SpreadsheetApp.getActiveSpreadsheet().getName();
var getMirSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Miranda");

//Set a new object to hold conditional data
var holdingData = new Object();

//Create function to get values from origin sheet
var returnedValues = function (trackOriginSheet) {

//Load dynamic variables into an object via returnedValues()
    if (trackOriginSheet === getMirSheet) {

        var startMirRow = 2; // First row of data to process
        var numRowsMir = 506; // Number of rows to process

        // Fetch the range of cells A2:Z506
        var dataRangeMir = getMirSheet.getRange(startMirRow, 1, numRowsMir, 26);

        // Fetch values for each cell in the Range.
        var dataMir = dataRangeMir.getValues();

        for (var k in dataMir) {
            var secondRowMir = dataMir[k];
            var intRefDescMir = secondRowMir[3];
            var intAdminActionsMir = secondRowMir[4];

            //Push returned data to holdingData Object
            holdingData.selectedData = secondRowMir;
            holdingData.refDesc = intRefDescMir;
            holdingData.adminActions = intAdminActionsMir;
        }
    }
}

Here's a copy of the sheet I'm working on

我首先需要做的是跟踪原点 sheet,然后创建一个对象来保存从 returnedValues() 函数返回的数据。稍后,我会调用这个对象的属性来发送电子邮件功能。

问题是我需要能够动态地从选定的 sheet 中提取数据(在本例中为 "Miranda" sheet。)换句话说,当用户选择 Miranda sheet 的第 I 列中的 "Yes" 选项,此脚本需要做的第一件事是拉取 for 循环顶部的变量值 用户选择的行 "Yes." 然后,我将该数据推送到稍后调用的自定义对象。

很明显,我做错了。至少,我的循环有问题。我做了什么? :)

编辑: 在查看 VyTautas 的建议后,这是我对工作循环的尝试:

for (var k = 0; k < dataMir.length; k++) {
            var mirColI = dataMir[k][8];
            var mirRefDesc = dataMir[k][2];
            var mirAdminActions = dataMir[k][3];
            var mirDates = dataMir[k][4];
            if (mirColI === "Yes") {
              var activeRowMir = mirColI.getActiveSelection.getRowIndex();
              //Pull selected values from the active row when Yes is selected
              var mirRefDescRange = getMirSheet.getRange(activeRowMir, mirRefDesc);
              var mirRefDescValues = mirRefDescRange.getValues();
              var mirAdminActionsRange = getMirSheet.getRange(activeRowMir, mirAdminActions);
              var mirAdminActionsValues = mirAdminActionsRange.getValues();
              var mirDatesRange = getMirSheet.getRange(activeRowMir, mirDates);
              var mirDatesValues = mirAdminActionsRange.getValues();
              var mirHoldingArray = [mirRefDescValues, mirAdminActionsValues, mirDatesValues];
              //Push mirHoldingArray values to holdingData
              holdingData.refDesc = mirHoldingArray[0];
              holdingData.adminActions = mirHoldingArray[1];
              holdingData.dates = mirHoldingArray[2];
            }
        }

在实际的脚本编辑器中所有这些空格都去了哪里? :D

您已经正确地使用 .getValues() 将整个 table 拉入数组。您现在需要做的是让 for 循环遍历 dataMir[k][8] 并简单地获取数据 if dataMir[k][8] === 'Yes'。我还觉得没有必要使用 for (var k in dataMir),因为 for (var k = 0; k < dataMir.length; k++) 更简洁,而且你有一个 for 循环来保证控制(尽管这可能更像是一种偏好)。

您还可以通过

减少使用的变量数量
holdingData.selectedData = mirData[k]
holdingData.refDesc = mirData[k][2] //I assume you want the 3rd column for this variable, not the 4th
holdingData.adminActions = mirData[k][3] //same as above

记住,数组从 0 开始,所以如果 mirData[k][0] 是 A 列,mirData[k][1] 是 B 列,依此类推。

编辑: 您在编辑中所写的内容似乎加倍了代码。您已经拥有数据,但您正在尝试再次提取它,并且您使用的一些变量应该会给您一个错误。我将从 if 中删除代码,尽管我真的不明白为什么您需要通过名称同时获取活动的 sheet 和 sheet。如果您知道名称将保持不变,那么只需始终通过名称(或索引)获得正确的 sheet,从而消除使用错误 sheet.

的可能性
   var titleMirRows = 1; // First row of data to process
   var numRowsMir = getMirSheet.getLastRow(); // Number of rows to process

// Fetch the range of cells A2:Z506
   var dataRangeMir = getMirSheet.getRange(titleMirRows + 1, 1, numRowsMir - titleMirRows, 26); // might need adjusting but now it will only get as many rows as there is data, you can do the same for columns too

// Fetch values for each cell in the Range.
   var dataMir = dataRangeMir.getValues();

   for (var k = 0; k < dataMir.length; k++) {
     if (dataMir[k][7] === 'Yes') {    //I assume you meant column i
       holdingData.refDesc = dataMir[k] //this will store the entire row
       holdingData.adminActions = dataMir[k][3] //this stores column D
       holdingData.dates = dataMir[k][4] //stores column E
     }
   }

仔细检查我添加到这些变量的列是否是您想要的。据我了解,该对象存储整个行数组,名为 Administrative Actions 的列中的值和 Dates/Periods 列中的值(如果适用) .如果不是,请相应地进行调整,但如您所见,我们通过简单地操作整个数据数组来最大限度地减少我们对 sheet 本身所做的工作。尽量少调用 Google 服务。