GAS当工作表在动态电子表格中包含完整的列数组表时,如何使用getDataRange和getLastRow

时间:2015-11-13 23:20:36

标签: google-apps-script google-api google-sheets google-calendar-api

我正在尝试使用表单提交电子表格来创建一整天的Google日历活动。 问题是我的电子表格中有多个ARRAYFORMULA,因为代码使用了:

var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var lr = rows.getLastRow();

它计算整个表格,因为ARRAYFormula欺骗了.getDataRange来计算行而没有提交它们

完整代码:

var calendarId = CalendarApp.getCalendarById("xxxxxxxxxx");
//below are the column ids of that represents the values used in the spreadsheet (these are non zero indexed)

//Column containg the Start Date/Time for the event
var startDtId = 2;
//Column containg the End Date/Time for the event
var endDtId = 2;
//Column containg the First Part of the Title for the event (In this case, Shift Area)
var areaId = 9;
//Column containg the Second part of the Title for the event (In this case, Shift)
var shiftId = 3;
//Column containg the Second part of the Title for the event (In this case, Name)
var nameId = 7;
//Column containg the Third part of the Title for the event (In this case, Reason)
var reasonId = 13;
//Column containg the Description for the event (In this case, Phone)
var phoneId = 8;
//Column containg the Time Stamp for the event (This will always be 1)
var formTimeStampId = 1;
//Column containg the Location for the event
var addressId = 14;


function getLatestAndSubmitToCalendar() {
//Allow access to the Spreadsheet
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var lr = rows.getLastRow();
//Removed setting of Hour and Minute for the Start and End times as they are all day
var startDt = sheet.getRange(lr,startDtId,1,1).getValue();
var endDt = sheet.getRange(lr,endDtId,1,1).getValue();
//Create an addition to the Description to included who added it and when
var subOn = "This shift was added: "+sheet.getRange(lr,formTimeStampId,1,1).getValue()+" by: "+sheet.getRange(lr,nameId,1,1).getValue()+" - Phone: "+sheet.getRange(lr,phoneId,1,1).getValue();
//Setting the Comments as the description, and adding in the Time stamp and Submision info
var desc = sheet.getRange(lr,reasonId,1,1).getValue()+", "+sheet.getRange(lr,nameId,1,1).getValue()+" is scheduled to ride on the "+sheet.getRange(lr,shiftId,1,1).getValue()+" in "+sheet.getRange(lr,areaId,1,1).getValue()+<br/>+subOn;
//Create the Title
var title = sheet.getRange(lr,areaId,1,1).getValue()+"-"+sheet.getRange(lr,shiftId,1,1).getValue()+"["+sheet.getRange(lr,reasonId,1,1).getValue()+"] - "+sheet.getRange(lr,nameId,1,1).getValue();
//Run the Create event Function
createEvent(calendarId,title,startDt,desc);
};

function createEvent(calendarId,title,startDt,endDt,desc) {
var cal = CalendarApp.getCalendarById("xxxxxxxxxxxxxxxxxxxxxxxxx");
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var lr = rows.getLastRow();
var start = new Date(startDt);
var end = new Date(endDt);
var subOn = "This shift was added: "+sheet.getRange(lr,formTimeStampId,1,1).getValue()+" by: "+sheet.getRange(lr,nameId,1,1).getValue()+" - Phone: "+sheet.getRange(lr,phoneId,1,1).getValue();
var desc = sheet.getRange(lr,reasonId,1,1).getValue()+", "+sheet.getRange(lr,nameId,1,1).getValue()+" is scheduled to ride on the "+sheet.getRange(lr,shiftId,1,1).getValue()+" in "+sheet.getRange(lr,areaId,1,1).getValue()+<br/>+subOn;
//Manually set the Location, this can be modified to be dynamic by modifying the code if need be
var loc = sheet.getRange(lr,addressId,1,1).getValue();

//Set the Options, in this case we are only using Description and Location, as we do not need Guests or sendInvites
var event = cal.createAllDayEvent(title, start, {
description : desc,
location : loc
});
};

请帮助:)

1 个答案:

答案 0 :(得分:0)

我实际上已经找到了解决这个问题的方法。我保留了上面的.getLastRow()路由而不是在工作表中使用数组公式,我再次使用了.getLastRow()并通过.setFormula()添加了我的公式。这允许我擦除数组,因此.getDataRange()现在只能正确获取包含数据的行而不是由于数组而导致的所有行。

为了使所有内容按正确的顺序排列,我将包含公式输入的函数设置为.onFormSubmit触发器,并从该函数的末尾调用日历事件生成器。 这现在很有效。

// Declare the columns needed to access for formula input first and set to their index

var columnId = 3;

// Now set the formulas

function formulaInput() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet = ss.getSheetByName('Sheet 1')
var range = sheet.getDataRange()
var last = range.getLastRow()


//This sets a formula in the columns of the last row of data that used to have an array formula sheet-side (Using the onFormSubmit trigger)

sheet.getRange(last,columnId,1,1).setFormula('= insert former array without the arrayformula prefix')

// Now use this to initiate the calendar event from the original code in question which ensures the formula input occurs 1st and subsequently triggers the calendar event after ALL the deaired data is present.

return getLatestAndSubmitToCalendar()

}