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

时间:2017-01-05 00:37:05

标签: javascript for-loop google-apps-script google-sheets conditional

我在向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

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

问题是我需要能够动态地从所选工作表中提取数据(在这种情况下为“Miranda”工作表。)换句话说,当用户在Miranda的第I列中选择“是”选项时表,这个脚本需要做的第一件事是在用户选择“是”的同一行中的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];
            }
        }

1 个答案:

答案 0 :(得分:1)

在实际的脚本编辑器中,所有那些空格都在哪里? :d

您已正确使用.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服务电话。