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

Google apps script GAS当工作表包含动态电子表格中的完整列数组公式时,如何使用getDataRange和getLastRow,google-apps-script,google-api,google-sheets,google-calendar-api,Google Apps Script,Google Api,Google Sheets,Google Calendar Api,我试图获得一个表单提交电子表格,以创建一个全天谷歌日历事件。 问题是我的电子表格中有多个ARRAYFORMULA,因为代码使用: var sheet = SpreadsheetApp.getActiveSheet(); var rows = sheet.getDataRange(); var numRows = rows.getNumRows(); var values = rows.getValues(); var lr = rows.getLastRow(); 它计算整个工作表,因为ARR

我试图获得一个表单提交电子表格,以创建一个全天谷歌日历事件。 问题是我的电子表格中有多个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
});
};
var calendarId=CalendarApp.getCalendarById(“xxxxxxxxx”);
//下面是的列ID,表示电子表格中使用的值(这些是非零索引的)
//包含事件开始日期/时间的列
var startDtId=2;
//包含事件结束日期/时间的列
var-endDtId=2;
//包含事件标题第一部分的列(在本例中为Shift区域)
var-areaId=9;
//包含事件标题第二部分的列(在本例中为Shift)
var-shiftId=3;
//包含事件标题第二部分的列(在本例中为名称)
var-nameId=7;
//包含事件标题第三部分的列(在本例中为原因)
var-reasonId=13;
//包含事件描述的列(在本例中为电话)
var-phoneId=8;
//包含事件时间戳的列(始终为1)
var formTimeStampId=1;
//包含事件位置的列
var-addressId=14;
函数getLatestAndSubmitToCalendar(){
//允许访问电子表格
var sheet=SpreadsheetApp.getActiveSheet();
var rows=sheet.getDataRange();
var numRows=rows.getNumRows();
var values=rows.getValues();
var lr=rows.getLastRow();
//删除了开始和结束时间的小时和分钟设置,因为它们是全天的
var startDt=sheet.getRange(lr,startDtId,1,1).getValue();
var endDt=sheet.getRange(lr,endDtId,1,1).getValue();
//在描述中创建一个添加项,以包括添加者和添加时间
var subOn=“添加此移位:“+sheet.getRange(lr,formTimeStampId,1,1).getValue()+”由:“+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()+”计划在“+sheet.getRange(lr,shiftId,1,1.getValue()+”子菜单中的“+sheet.getRange(lr,areaId,1,1).getValue()+”上运行;
//创建标题
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();
//运行创建事件函数
createEvent(日历ID、标题、开始、描述);
};
函数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=新日期(startDt);
var end=新日期(endDt);
var subOn=“添加此移位:“+sheet.getRange(lr,formTimeStampId,1,1).getValue()+”由:“+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()+”计划在“+sheet.getRange(lr,shiftId,1,1.getValue()+”子菜单中的“+sheet.getRange(lr,areaId,1,1).getValue()+”上运行;
//手动设置位置,如果需要,可以通过修改代码将其修改为动态
var loc=sheet.getRange(lr,addressId,1,1).getValue();
//设置选项,在这种情况下,我们只使用描述和位置,因为我们不需要客人或发送邀请
var event=cal.createAllDayEvent(标题、开始、{
描述:描述,
地点:loc
});
};

请帮助:)

我已经找到了解决这个问题的方法。我保留了上面的.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()

}

我已经找到了解决这个问题的方法。我保留了上面的.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()

}

请参阅:。我实际上阅读了该问题,但我不认为我可以使用该答案,因为我的工作表是表单提交,因此定义的范围不足以满足每次提交时范围的变化。请参阅:。我确实阅读了该问题,但我认为我不能使用该答案,因为我的工作表是表单提交,因此,定义的范围不足以满足每次提交时范围的变化。