脚本:如何跳过包含不完整数据集的 Google 工作表行
Script: How to skip Google Sheets rows with incomplete data sets
我正在跟踪我的当地立法 session 工作,这需要监控和调整 300 多个账单的日历事件并计算(到 session 结束时有 800 个以上)。我从几个来源编译了一个脚本,sheet 为我节省了大量时间。
它复制事件的日历 ID 以避免创建重复的事件。除一件事外,它工作得很好 - 对于任何没有在第 8 列和第 9 列中分别指定 date/time 的账单,脚本会在 1969 年星期三创建一个日历事件。
我希望脚本:
A) 简单地跳过处理第 9 列中的单元格为空的所有行,或者
B) 获取过滤视图的范围并仅为可见的行创建事件。
如果可能的话,我更喜欢B。我已经尝试了几件事,但我不知所措。虽然我可以手动将日历事件复制粘贴到另一个 sheet 和 运行 那里的脚本没有问题,但我希望它比这更简单。任何帮助将不胜感激。
目前的代码:
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name : "Export Calendared Bills",
functionName : "exportEvents"
}];
sheet.addMenu("Calendar Actions", entries);
};
function exportEvents() {
var sheet = SpreadsheetApp.getActiveSheet();
var headerRows = 2;
var range = sheet.getDataRange();
var data = range.getValues();
var calId = "redactedaddress@group.calendar.google.com";
var cal = CalendarApp.getCalendarById(calId);
for (i=0; i<data.length; i++) {
if (i < headerRows) continue;
var row = data[i];
var date = new Date(row[8]);
var title = row[2];
var tstart = new Date(row[9]);
tstart.setDate(date.getDate());
tstart.setMonth(date.getMonth());
tstart.setYear(date.getYear());
var tstop = new Date(row[9]);
tstop.setDate(date.getDate());
tstop.setMonth(date.getMonth());
tstop.setYear(date.getYear());
var loc = row[4];
var desc = row[15];
var id = row[3];
try {
var event = cal.getEventSeriesById(id);
}
catch (e) {
}
if (!event) {
var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc,}).getId();
row[3] = newEvent; Utilities.sleep(1000);
}
else {
event.setTitle(title);
event.setDescription(desc);
event.setLocation(loc);
}
debugger;
}
range.setValues(data);
}
您可以使用 date.valueOf() function and isNaN() function as shown here 检查日期对象是否为有效日期。
如果日期有效,valueOf()
函数 returns 一个数字,您可以使用 isNaN()
函数
检查数字
最后,您可以使用 continue
在日期无效时跳过该特定迭代。像这样:
var tstart = new Date(row[9])
if(isNaN(tstart.valueOf()))
continue;
您的最终代码如下所示:
function exportEvents() {
var sheet = SpreadsheetApp.getActiveSheet();
var headerRows = 2;
var range = sheet.getDataRange();
var data = range.getValues();
var calId = "redactedaddress@group.calendar.google.com";
var cal = CalendarApp.getCalendarById(calId);
for (i=0; i<data.length; i++) {
if (i < headerRows) continue;
var row = data[i];
var date = new Date(row[8]);
var title = row[2];
var tstart = new Date(row[9]);
if(isNaN(tstart.valueOf()))
continue; // skip row, go to the next row
tstart.setDate(date.getDate());
tstart.setMonth(date.getMonth());
tstart.setYear(date.getYear());
var tstop = new Date(row[9]);
tstop.setDate(date.getDate());
tstop.setMonth(date.getMonth());
tstop.setYear(date.getYear());
var loc = row[4];
var desc = row[15];
var id = row[3];
try {
var event = cal.getEventSeriesById(id);
}
catch (e) {
}
if (!event) {
var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc,}).getId();
row[3] = newEvent; Utilities.sleep(1000);
}
else {
event.setTitle(title);
event.setDescription(desc);
event.setLocation(loc);
}
debugger;
}
range.setValues(data);
}
我正在跟踪我的当地立法 session 工作,这需要监控和调整 300 多个账单的日历事件并计算(到 session 结束时有 800 个以上)。我从几个来源编译了一个脚本,sheet 为我节省了大量时间。
它复制事件的日历 ID 以避免创建重复的事件。除一件事外,它工作得很好 - 对于任何没有在第 8 列和第 9 列中分别指定 date/time 的账单,脚本会在 1969 年星期三创建一个日历事件。
我希望脚本:
A) 简单地跳过处理第 9 列中的单元格为空的所有行,或者
B) 获取过滤视图的范围并仅为可见的行创建事件。
如果可能的话,我更喜欢B。我已经尝试了几件事,但我不知所措。虽然我可以手动将日历事件复制粘贴到另一个 sheet 和 运行 那里的脚本没有问题,但我希望它比这更简单。任何帮助将不胜感激。
目前的代码:
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name : "Export Calendared Bills",
functionName : "exportEvents"
}];
sheet.addMenu("Calendar Actions", entries);
};
function exportEvents() {
var sheet = SpreadsheetApp.getActiveSheet();
var headerRows = 2;
var range = sheet.getDataRange();
var data = range.getValues();
var calId = "redactedaddress@group.calendar.google.com";
var cal = CalendarApp.getCalendarById(calId);
for (i=0; i<data.length; i++) {
if (i < headerRows) continue;
var row = data[i];
var date = new Date(row[8]);
var title = row[2];
var tstart = new Date(row[9]);
tstart.setDate(date.getDate());
tstart.setMonth(date.getMonth());
tstart.setYear(date.getYear());
var tstop = new Date(row[9]);
tstop.setDate(date.getDate());
tstop.setMonth(date.getMonth());
tstop.setYear(date.getYear());
var loc = row[4];
var desc = row[15];
var id = row[3];
try {
var event = cal.getEventSeriesById(id);
}
catch (e) {
}
if (!event) {
var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc,}).getId();
row[3] = newEvent; Utilities.sleep(1000);
}
else {
event.setTitle(title);
event.setDescription(desc);
event.setLocation(loc);
}
debugger;
}
range.setValues(data);
}
您可以使用 date.valueOf() function and isNaN() function as shown here 检查日期对象是否为有效日期。
如果日期有效,valueOf()
函数 returns 一个数字,您可以使用 isNaN()
函数
最后,您可以使用 continue
在日期无效时跳过该特定迭代。像这样:
var tstart = new Date(row[9])
if(isNaN(tstart.valueOf()))
continue;
您的最终代码如下所示:
function exportEvents() {
var sheet = SpreadsheetApp.getActiveSheet();
var headerRows = 2;
var range = sheet.getDataRange();
var data = range.getValues();
var calId = "redactedaddress@group.calendar.google.com";
var cal = CalendarApp.getCalendarById(calId);
for (i=0; i<data.length; i++) {
if (i < headerRows) continue;
var row = data[i];
var date = new Date(row[8]);
var title = row[2];
var tstart = new Date(row[9]);
if(isNaN(tstart.valueOf()))
continue; // skip row, go to the next row
tstart.setDate(date.getDate());
tstart.setMonth(date.getMonth());
tstart.setYear(date.getYear());
var tstop = new Date(row[9]);
tstop.setDate(date.getDate());
tstop.setMonth(date.getMonth());
tstop.setYear(date.getYear());
var loc = row[4];
var desc = row[15];
var id = row[3];
try {
var event = cal.getEventSeriesById(id);
}
catch (e) {
}
if (!event) {
var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc,}).getId();
row[3] = newEvent; Utilities.sleep(1000);
}
else {
event.setTitle(title);
event.setDescription(desc);
event.setLocation(loc);
}
debugger;
}
range.setValues(data);
}