Google apps script 在另一列的循环中查找与条件匹配的日期?
我有一个包含多个列的google工作表,其中一列是date(它是F列,从最早到最晚排序),另一列(G)是time duration值。我提出了一个条件,每当三个持续时间的组合被采用时,如果它大于10小时,则采用相应的组合,并将组合中最早的日期作为另一个程序的参考。这个组合应该是最新的(我指的是日期)。我试过的代码是Google apps script 在另一列的循环中查找与条件匹配的日期?,google-apps-script,google-sheets,Google Apps Script,Google Sheets,我有一个包含多个列的google工作表,其中一列是date(它是F列,从最早到最晚排序),另一列(G)是time duration值。我提出了一个条件,每当三个持续时间的组合被采用时,如果它大于10小时,则采用相应的组合,并将组合中最早的日期作为另一个程序的参考。这个组合应该是最新的(我指的是日期)。我试过的代码是 function calculation(){ var source = SpreadsheetApp.getActiveSpreadsheet(); var sheet =
function calculation(){
var source = SpreadsheetApp.getActiveSpreadsheet();
var sheet = source.getSheetByName("10017135ASR");
var lastRow = sheet.getLastRow();
var time = sheet.getRange('G1:G'+lastRow).getValues();
var cell = sheet.getRange('F1:F'+lastRow).getValues();
var range1 = sheet.getRange('H1:H'+lastRow).setValues(time).setNumberFormat('[hh]:mm');
var refer = sheet.getRange('N2').setValue("10:00").setNumberFormat("[hh]:mm");
var refer1= refer.getValue();
var range = range1.getValues();
var time = sheet.getRange('H1:H');
time.setNumberFormat('[hh]:mm');
sheet.getRange('I2:I'+lastRow).setValue('0').setNumberFormat('[hh]:mm');
var one= sheet.getRange('H'+(lastRow)).getValue();
sheet.getRange('I'+lastRow).setValue(one).setNumberFormat('[hh]:mm');
var two = sheet.getRange('H'+(lastRow-1)).getValue();
sheet.getRange('I'+(lastRow-1)).setValue(two).setNumberFormat('[hh]:mm');
loop1:
for (var i = lastRow-3; i>0; i--){
var value1 = range[i][0];
var V2 = sheet.getRange('K'+lastRow).setValue(value1).setNumberFormat("[hh]:mm");
var L2 = sheet.getRange('J'+lastRow).setFormula("=LARGE(I2:I,1)").setNumberFormat('[hh]:mm');
var L3= sheet.getRange('J'+(lastRow-1)).setFormula("=LARGE(I2:I,2)").setNumberFormat('[hh]:mm');
var sum = sheet.getRange('M2').setFormula("=SUM(J2:J)").setNumberFormat("[hh]:mm");
var vB= sum.getValue();
var V1 = V2.getValue();
var sum2 = vB + V1;
if((vB)>= refer1){
sheet.getRange('L2').setValue(sum2).setNumberFormat('[hh]:mm');
var da=sheet.getRange('F'+(i+2)).getValue();
sheet.getRange('N2').setValue(da).setNumberFormat('DD-mm-yyyy');
break loop1;
}
else {
sheet.getRange('I'+(i+1)).setValue(value1).setNumberFormat('[hh]:mm');
}
}
}
这里我没有得到输出,循环在第一行结束,即使不需要转到第一行。因为所需的输出在第30行,相应的日期是2020年7月30日。
工作表如下所示
所得结果是令人满意的
使用持续时间:
在应用程序脚本中使用工作表持续时间有点混乱:请参阅
通过应用程序脚本检索时,持续时间将变成JavaScript,基于Google表单中日期/时间的零标记(12/30/1899 0:00:00
)(请参阅)
在JS中,为了比较日期,您可以使用,它返回自1970年1月1日以来的毫秒数,它指的是1
。因此,从工作表持续时间检索的日期将导致毫秒数为负数。为了避免出现问题,您可以在每次比较日期时使用参考日期。一个选项是将sheets单元格设置为00:00
duration,并将该值用作参考。这就是我在下面的示例中所做的,在cellN3
中
工作流程:
- 将
设置为参考持续时间(N3
),将00:00
设置为N2
10:00
- 使用一个数组(
)来存储可能的持续时间组合,循环遍历comboData
中的所有持续时间。对于每个元素,(1)检查G2:G
是否少于3个元素,如果是,则添加当前元素,(2)否则,在comboData
中找到最小值,检查当前元素是否更高,如果是,则替换,(3)计算当前组合的总持续时间,如果高于comboData
,则断开循环10:00
- 将持续时间从毫秒转换为所需的持续时间格式(使用下面的函数
,基于by),并将其写入工作表,总持续时间使用msToHMS(ms)
,三个持续时间和日期使用setValue()
setValues()
- 此示例只需要
、F
和G
列中的数据。不需要N
,H
,I
,J
,K
等M
function getCombinationRowIndex() {
var source = SpreadsheetApp.getActiveSpreadsheet();
var sheet = source.getSheetByName("10017135ASR");
var lastRow = sheet.getLastRow();
var reference = sheet.getRange('N3').setValue('00:00').setNumberFormat('[hh]:mm').getValue().getTime();
var sourceData = sheet.getRange('F2:G' + lastRow).getValues().reverse().map(row => [row[1].getTime() - reference, row[0]]);
var limit = sheet.getRange('N2').setValue("10:00").setNumberFormat("[hh]:mm").getValue().getTime() - reference;
var comboData = []; // Array to store the combination
var totalDuration = 0;
for (var i = 0; i < sourceData.length; i++) {
var row = sourceData[i];
if (comboData.length < 3) comboData.push(row); // If combination has less than 3 elements, add current element
else {
var minimum = Math.min(...comboData.map(val => val[0])); // Find minimum in current combination
var index = comboData.findIndex(val => val[0] == minimum); // Find index for minimum in current combination
if (row[0] > minimum) comboData[index] = row; // Replace minimum if current element is higher
}
totalDuration = comboData.reduce(((acc, combo) => acc + combo[0]), 0); // Total duration in milliseconds
if (totalDuration > limit && comboData.length === 3) break; // If total duration is higher than 10 hours, break loop
}
sheet.getRange("K2:L4").setValues(comboData.map(combo => [msToHMS(combo[0]), combo[1]])); // Write combo data to K2:L4
var formattedDuration = msToHMS(totalDuration); // Total duration (formatted hh:mm:ss)
sheet.getRange("J2").setValue(formattedDuration); // Write total duration to J2
}
function msToHMS(ms) {
var seconds = ms / 1000;
var hours = parseInt( seconds / 3600 ); // 3,600 seconds in 1 hour
seconds = seconds % 3600; // seconds remaining after extracting hours
var minutes = parseInt( seconds / 60 ); // 60 seconds in 1 minute
seconds = seconds % 60;
return Utilities.formatString("%02d",hours) + ':' + Utilities.formatString("%02d",minutes) + ':' + Utilities.formatString("%02d",seconds);
}