【发布时间】:2018-04-16 15:14:02
【问题描述】:
目前,我正在尝试为 Google 表格创建一个 Google Apps 脚本,该脚本将允许为即将发生的事件批量添加每周重复发生的事件。然后,我的同事将对这些添加的事件进行细微更改(例如,更正日期和时间、更改联系人、添加事件所需的材料等)。
到目前为止,我已经编写了以下脚本:
function CopyWeeklyEventRows() {
var ss = SpreadsheetApp.getActiveSheet();
var repeatingWeeks = ss.getRange(5,1).getValue(); // gets how many weeks it should repeat
var startDate = ss.getRange(6, 1).getValue(); // gets the start date
var startWeekday = startDate.getDay(); // gives the weekday of the start date
var regWeek = ss.getRange(9, 2, 4, 7).getValues(); // gets the regular week data
var regWeekdays = new Array(regWeek.length); // creates an array to store the weekdays of the regWeek
var ArrayStartDate = new Array(startDate); // helps to store the We
for (var i = 0; i < regWeek.length; i++){ // calculates the difference between startWeekday and each regWeekdays
regWeekdays[i] = regWeek[i][1].getDay() - startWeekday;
Logger.log(regWeekdays[i]);
// Add 7 to move to the next week and avoid negative values
if (regWeekdays[i] < 0) {
regWeekdays[i] = regWeekdays[i] + 7;
}
// Add days according to difference between startWeekday and each regWeekdays
regWeek[i][0] = new Date(ArrayStartDate[0].getTime() + regWeekdays[i]*3600000*24);
}
// I'm struggling with this line. The array regWeek is not sorted:
//regWeek.sort([{ column: 1, ascending: true }]);
ss.getRange(ss.getLastRow() + 1, 2, 4, 7).setValues(regWeek); // copies weekly events after the last row
}
它允许根据开始日期将一周的重复事件添加到电子表格的概览部分。如果开始日期是星期二,则从星期二开始添加常规周。 However, the rows are not sorted according to the dates: .
在将行添加到概览之前,如何按升序日期(后跟时间)对行进行排序?
我对类似问题的搜索显示Google Script sort 2D Array by any column,这是我找到的最接近的命中。使用 sort 行运行我的脚本时会显示相同的错误消息。我不明白Range 和array 之间的区别,这可能有助于解决问题。
为了给你一个更广泛的了解,这是我目前正在做的事情:
- 我注意到添加时格式不一定会保留 新的重复事件。到目前为止,我还没有找到规则并格式化为 进行第二步。
- 目前的一个缺点是每周重复事件部分是
固定的。我试图找到最后填写的条目并使用它来设置
regWeek的范围,但卡住了。 - 使用 A 列从添加中排除重复事件 使用下拉菜单处理。
- 允许我的同事使用 下拉菜单(例如 A26)。然后应该通过排序添加此事件 一周中的正确日期和开始时间。排序会进来 方便。
在此先感谢您提供有关排序的意见以及有关如何总体改进代码的建议。
A demo version of the spreadsheet
UpdateV01:
这里是复制和排序的代码行(首先按日期,然后按时间)
ss.getRange(ss.getLastRow()+1,2,4,7).setValues(regWeek); // copies weekly events after the last row
ss.getRange(ss.getLastRow()-3,2,4,7).sort([{column: 2, ascending: true}, {column: 4, ascending: true}]); // sorts only the copied weekly events chronologically
正如@tehhowch 指出的那样,这很慢。最好在写作之前进行排序。 我将实现此方法并在此处发布。
UpdateV02:
regWeek.sort(function (r1, r2) {
// sorts ascending on the third column, which is index 2
return r1[2] - r2[2];
});
regWeek.sort(function (r1, r2) {
// r1 and r2 are elements in the regWeek array, i.e.
// they are each a row array if regWeek is an array of arrays:
// Sort ascending on the first column, which is index 0:
// if r1[0] = 1, r2[0] = 2, then 1 - 2 is -1, so r1 sorts before r2
return r1[0] - r2[0];
});
UpdateV03:
这里尝试在几周内重复重复发生的事件。还不知道如何包含整个“周”的推送。
// Repeat week for "A5" times and add to start/end date
for (var j = 0; j < repeatingWeeks; j++){
for (var i = 0; i < numFilledRows; i++){
regWeekRepeated[i+j*6][0] = new Date(regWeek[i][0].getTime() + j*7*3600000*24); // <-This line leads to an error message
regWeekRepeated[i+j*6][3] = new Date(regWeek[i][3].getTime() + j*7*3600000*24);
}
}
我的问题得到了解答,我能够使代码按预期工作。
【问题讨论】:
-
不清楚 - 您是要对要写入的位 (
regWeek) 还是整个“即将发生的事件”位进行排序,即单元格B22:K?两者的解决方案不同。您的排序对象适用于电子表格Range,但不是对 JavascriptArray进行排序的有效函数。 -
@tehhowch 感谢您指出歧义。我想对将要写入的位进行排序(
regWeek)。对位进行排序后,for循环将允许我在“即将发生的事件”部分添加 X(以A5输入)周(每个循环将日期增加 7 天)。根据您的评论,我会将当前for循环的代码从Array更改为Range。数组regWeekdays和ArrayStartDate被用作解决方法,因为我还不知道如何操作Range中的数据。 -
您不想对
Range进行批量操作 - 这非常慢,因为每个操作都必须使用 JavaScript 和电子表格之间的接口代码。您希望尽可能操作原生 JavaScript,并限制使用接口代码,如getRange和getValue查看 Mozilla 开发者网络上的数组排序
标签: sorting google-apps-script google-sheets