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 服务。
我在 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 服务。