使用for循环根据条件从范围中提取数据

问题描述 投票:0回答:1

我在从 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;
        }
    }
}

这是我正在处理的表格的副本

我首先需要跟踪原始表,然后创建一个对象来保存从 returnedValues() 函数返回的数据。稍后,我将调用该对象的属性到发送电子邮件函数中。

问题是我需要能够动态地从所选工作表(本例中为“Miranda”工作表)中提取数据。换句话说,当用户在 Miranda 工作表的第一列中选择“是”选项时,该脚本需要做的第一件事是拉取 for 循环顶部的变量值在用户选择“是”的同一行中。然后,我将该数据推送到自定义对象稍后打电话。

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

编辑: 在查看了 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];
            }
        }
javascript for-loop google-apps-script google-sheets conditional-statements
1个回答
1
投票

您已经正确使用

.getValues()
将整个表拉入数组中。您现在需要做的是让 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 中删除代码,尽管我真的不明白为什么您需要同时获取活动工作表和按名称获取工作表。如果您知道名称将是不变的,那么只需始终通过名称(或索引)获取正确的工作表,从而消除使用错误工作表的可能性。

   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
     }
   }

仔细检查我添加到这些变量中的列是否是您想要的。据我了解,该对象存储整个行数组、“管理操作”列中的值以及“日期/期间(如果适用)”列中的值。如果不是,请进行相应调整,但正如您所看到的,我们通过简单地操作整个数据数组来最大限度地减少对工作表本身所做的工作。始终尽可能少地调用 Google 服务。

© www.soinside.com 2019 - 2024. All rights reserved.