Google apps script 在单独的电子表格中自动生成可安装的触发器
我有一个脚本,在过去的几周里一直工作得很好,直到今天早上,由于项目上有太多可安装的触发器,它开始失败 主电子表格上的脚本根据模板生成新的电子表格。这些新的电子表格需要一个可安装的OneEdit触发器来编辑原始(主)电子表格上的值。我有一个函数,用于生成一个新的可安装触发器,但是这是添加到主电子表格中的,而不是新的。问题很明显是,对于可以绑定到一个电子表格的可安装触发器的数量有一个硬限制,因此我想用一种方法将它们与新生成的电子表格关联起来 我以前问过这个问题,没有太大的决心,先是在评论中,然后是在一个问题中。四年前我还发现了一个问题(这个问题的答案是没有解决方案,我只是想看看四年后有没有什么变化) 当我尝试在createInstallableTrigger函数中使用新电子表格的ID时,它仍然在主电子表格中生成触发器 我需要知道我所要求的是否可能,但如果不可能,我需要一个新的解决方案来解决这个问题。我在下面展示的代码确实有效,但只在达到触发器的限制之前有效 这些是相关的功能:Google apps script 在单独的电子表格中自动生成可安装的触发器,google-apps-script,google-sheets,Google Apps Script,Google Sheets,我有一个脚本,在过去的几周里一直工作得很好,直到今天早上,由于项目上有太多可安装的触发器,它开始失败 主电子表格上的脚本根据模板生成新的电子表格。这些新的电子表格需要一个可安装的OneEdit触发器来编辑原始(主)电子表格上的值。我有一个函数,用于生成一个新的可安装触发器,但是这是添加到主电子表格中的,而不是新的。问题很明显是,对于可以绑定到一个电子表格的可安装触发器的数量有一个硬限制,因此我想用一种方法将它们与新生成的电子表格关联起来 我以前问过这个问题,没有太大的决心,先是在评论中,然后是在
function createInstallableTrigger(funcName,ssId) {
if(!isTrigger()) {
ScriptApp.newTrigger(funcName).forSpreadsheet(ssId).onEdit().create();
}
}
function isTrigger(funcName){
var r=false;
if(funcName){
var allTriggers=ScriptApp.getProjectTriggers();
for(var i=0;i<allTriggers.length;i++){
if(funcName==allTriggers[i].getHandlerFunction()){
r=true;
break;
}
}
}
return r;
}
函数createInstallableTrigger(funcName,ssId){
如果(!isTrigger()){
ScriptApp.newTrigger(funcName).forSpreadsheet(ssId).OneEdit().create();
}
}
函数isTrigger(funcName){
var r=假;
如果(名称){
var allTriggers=ScriptApp.getProjectTriggers();
对于(var i=0;i您拥有哪种帐户?您可以检查不同帐户的当前配额,因此您可能有兴趣升级它。所有选项都有20/用户/脚本触发器限制。这是Google想要的限制,无法绕过。我理解。我想找到一种在新的排列上生成触发器的方法工作表(如果是这样的话,我会将它们触发的函数放在模板上)。遗憾的是,只有用户操作才能激活触发器,这是从脚本执行开始的。你拥有什么样的帐户?你可以检查不同帐户的当前配额,因此你可能有兴趣升级它。所有选项都有20个/用户/脚本触发器限制。这是谷歌想要的限制,不能绕过。我明白。我会的ike希望找到一种在新的电子表格上生成触发器的方法(如果是这样的话,我会将触发器触发的函数放在模板上)。遗憾的是,只有用户操作可以激活触发器,这是从脚本执行开始的。
function main(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = e.range;
var newId;
var newName;
var hyperlinkString;
var isJob;
var i;
if(sheet.getRange('L1').getValue() == 10) return;
//Check if edit occurred in relevant range
if((range.getColumn() !== 1) && (range.getColumn() !== 2)) return;
if((range.getRow() == 1) || (range.getRow() == 2)) return;
//Check if both columns were filled after edit
if((range.getColumn() == 1) && (range.offset(0,1).isBlank() == true)) return;
if((range.getColumn() == 2) && (range.offset(0,-1).isBlank() == true)) return;
//Get new document name from concatenate formula in column H
if(range.getColumn() == 1) newName = range.offset(0,7).getValue();
if(range.getColumn() == 2) newName = range.offset(0,6).getValue();
//Check whether the edits occurred on the jobs list or deliveries list (indicated by '4' or '5' in L1)
//Calls function to create new job sheet or delivery sheet from template, gets ID of new spreadsheet
if(((range.getColumn() == 1) && (range.offset(0,3).isBlank() == true)) || ((range.getColumn() == 2) && (range.offset(0,2).isBlank() == true))) {
if(sheet.getRange('L1').getValue() == 4) {
if(range.getColumn() == 1) range.offset(0,3).setValue("Please wait");
if(range.getColumn() == 2) range.offset(0,2).setValue("Please wait");
newId = newJob();
isJob = 1;
}
if(sheet.getRange('L1').getValue() == 5) {
if(range.getColumn() == 1) range.offset(0,3).setValue("Please wait");
if(range.getColumn() == 2) range.offset(0,2).setValue("Please wait");
newId = newdelivery();
isJob = 0;
}
}
//Updates hyperlink if sheet already exists
else {
if(range.getColumn() == 1) {
hyperlinkString = range.offset(0,3).getFormula();
newId = hyperlinkString.substring(77,121);
}
if(range.getColumn() == 2) {
hyperlinkString = range.offset(0,2).getFormula();
newId = hyperlinkString.substring(77,121);
}
return;
}
//Set the name of the new spreadsheet
SpreadsheetApp.openById(newId).rename(newName);
//Enter name and date information onto new spreadsheet
if((sheet.getRange('L1').getValue() == 4) || (sheet.getRange('L1').getValue() == 0) || (sheet.getRange('L1').getValue() == 1)) isJob = 1;
else isJob = 0;
//If it's on a job, update all sheets on itemization spreadsheet (rooftop/electrical pick/return)
if(isJob == 1) {
//If name is entered, update name first then date
if(range.getColumn() == 1) {
for(i=0;i<4;i++) {
SpreadsheetApp.openById(newId).getSheets()[i].getRange('B1').setValue(range.getValue());
SpreadsheetApp.openById(newId).getSheets()[i].getRange('B2').setValue(range.offset(0,1).getValue());
}
}
//If date is entered, update date first then name
if(range.getColumn() == 2) {
for(i=0;i<4;i++) {
SpreadsheetApp.openById(newId).getSheets()[i].getRange('B2').setValue(range.getValue());
SpreadsheetApp.openById(newId).getSheets()[i].getRange('B1').setValue(range.offset(0,-1).getValue());
}
}
}
//If it's on an incoming delivery, just update the main (only) sheet
if(isJob == 0) {
//If name is entered, update name first then date
if(range.getColumn() == 1) {
SpreadsheetApp.openById(newId).getSheets()[0].getRange('B1').setValue(range.getValue());
SpreadsheetApp.openById(newId).getSheets()[0].getRange('B2').setValue(range.offset(0,1).getValue());
}
//If date is entered, update date first then name
if(range.getColumn() == 2) {
SpreadsheetApp.openById(newId).getSheets()[0].getRange('B2').setValue(range.getValue());
SpreadsheetApp.openById(newId).getSheets()[0].getRange('B1').setValue(range.offset(0,-1).getValue());
}
}
//Creates hyperlink to new spreadsheet
if (range.getColumn() == 1) range.offset(0,3).setFormula("=HYPERLINK(\"" + SpreadsheetApp.openById(newId).getUrl() +"\",\"Click here for itemization\")");
if (range.getColumn() == 2) range.offset(0,2).setFormula("=HYPERLINK(\"" + SpreadsheetApp.openById(newId).getUrl() +"\",\"Click here for itemization\")");
//Sort list descending from most recent date
sheet.getRange("A3:D1000").sort({column: 2, ascending: false});
}
function newJob() {
//Open template
var jobTemplateSS = SpreadsheetApp.openById("ID Redacted");
//Create new spreadsheet from copy of template spreadsheet
var newSS = jobTemplateSS.copy("Untitled Job");
//Get folder
var jobFolder = DriveApp.getFolderById("ID Redacted");
//Get ID of new file
var newSSFile = DriveApp.getFileById(newSS.getId());
//Copy file to the correct directory and delete the instance created in root
jobFolder.addFile(newSSFile);
DriveApp.getRootFolder().removeFile(newSSFile);
//Automatically generate an installable trigger on new SS that detects edits
createInstallableTrigger('IncrementDecrement',newSS.getId());
//Pass ID of new spreadsheet back to calling function
return(newSS.getId());
}
function newdelivery() {
//Open template
var deliveryTemplateSS = SpreadsheetApp.openById("ID Redacted");
//Create new spreadsheet from copy of template spreadsheet
var newSS = deliveryTemplateSS.copy("Untitled Delivery");
//Get folder
var deliveryFolder = DriveApp.getFolderById("ID Redacted");
//Get ID of new file
var newSSFile = DriveApp.getFileById(newSS.getId());
//Copy file to the correct directory and delete the instance created in root
deliveryFolder.addFile(newSSFile);
DriveApp.getRootFolder().removeFile(newSSFile);
createInstallableTrigger('IncrementDecrement',newSS.getId());
//Pass ID of new spreadsheet back to calling function
return(newSS.getId());
}
function createInstallableTrigger(funcName,ssId) {
if(!isTrigger()) {
ScriptApp.newTrigger(funcName).forSpreadsheet(ssId).onEdit().create();
}
}
function isTrigger(funcName){
var r=false;
if(funcName){
var allTriggers=ScriptApp.getProjectTriggers();
for(var i=0;i<allTriggers.length;i++){
if(funcName==allTriggers[i].getHandlerFunction()){
r=true;
break;
}
}
}
return r;
}
function IncrementDecrement(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = e.range;
//Check if edit occurred in valid range, and whether the edit occurred on a job or delivery sheet (indicated by a 0,1,or 2 in L1)
if ((range.getColumn() !== 1) && (range.getColumn() !== 3) && (range.getColumn() !== 4) && (range.getColumn() !== 5) && (range.getColumn() !== 6)) return;
if(range.getRow() < 4) return;
if ((sheet.getRange('L1').getValue() !== 0) && (sheet.getRange('L1').getValue() !== 1) && (sheet.getRange('L1').getValue() !==2)) return;
//Wait to declare all variables until checks occur to maximize efficiency
var masterSS = SpreadsheetApp.openById("ID Redacted");
var invsheet = masterSS.getSheetByName("Inventory");
var q;
var deltaQ;
var sku;
var nextCell;
var currentCell;
var cellLink;
var total;
var desc;
var i;
//Set current cell to work on as the edited cell
currentCell = range;
//If edit occurred in first column (SKU) fetch description & value from inventory
if(range.getColumn() == 1) {
//Save SKU
sku = currentCell.getValue();
//Save current cell
cellLink = currentCell;
//Scan through inventory sheet and find matching SKU line, fetch info
currentCell = invsheet.getRange('A3');
while (currentCell.isBlank()==false) {
if(currentCell.getValue() == sku) {
desc = currentCell.offset(0,1).getValue();
q = currentCell.offset(0,2).getValue();
currentCell = cellLink;
break;
}
currentCell = currentCell.offset(1,0);
}
//Return to saved cell
currentCell = cellLink;
//Enter description and value on itemization sheet
currentCell.offset(0,1).setValue(desc);
currentCell.offset(0,3).setValue(q);
}
//If edit occurred in third column (quantity)
if(range.getColumn() == 3) {
//Save quantity and SKU
q = currentCell.getValue();
sku = currentCell.offset(0,-2).getValue();
//Saving prior quantity value. If no value, set to 0.
currentCell = currentCell.offset(0,8);
if (currentCell.isBlank() == true) currentCell.setValue(0);
//Find and save the change in quantity by subtracting new quantity by prior quantity
currentCell = currentCell.offset(0,1);
currentCell.setValue(q - currentCell.offset(0,-1).getValue());
deltaQ = currentCell.getValue();
//Save current cell
cellLink = currentCell;
//Search through inventory sheet and find matching SKU line
currentCell = invsheet.getRange('A3');
while (currentCell.isBlank()==false) {
if(currentCell.getValue() == sku) {
//If it's a pick ticket, subtract the quantity used from inventory quantity
if (sheet.getRange('L1').getValue() == 0) {
currentCell.offset(0,3).setValue(currentCell.offset(0,3).getValue() - deltaQ);
currentCell.offset(0,4).setValue(currentCell.offset(0,4).getValue() - deltaQ);
//Update total price on job list
for(i=3; i<1000; i++) {
if(masterSS.getSheetByName("Job List").getRange(i,1).getValue() == sheet.getRange(1,2).getValue()) {
masterSS.getSheetByName("Job List").getRange(i,1).offset(0,2).setValue(sheet.getRange(1,15).getValue());
break;
}
}
}
//If it's a return ticket or inbound delivery, add the quantity returned/received to the inventory quantity
if ((sheet.getRange('L1').getValue() == 1) || (sheet.getRange('L1').getValue() == 2)) {
Logger.log(q);
Logger.log(currentCell.offset(0,3).getValue());
Logger.log(deltaQ);
Logger.log(currentCell.offset(0,3).getValue() + deltaQ);
currentCell.offset(0,3).setValue(+(currentCell.offset(0,3).getValue()) + +deltaQ);
currentCell.offset(0,4).setValue(+(currentCell.offset(0,4).getValue()) + +deltaQ);
//If it's a return ticket, update total price on job list
if(sheet.getRange('L1').getValue() == 1) {
for(i=3; i<1000; i++) {
if(masterSS.getSheetByName("Job List").getRange(i,1).getValue() == sheet.getRange(1,2).getValue()) {
masterSS.getSheetByName("Job List").getRange(i,1).offset(0,2).setValue(sheet.getRange(1,15).getValue());
break;
}
}
}
//If it's an inbound delivery, update total price on delivery list.
if(sheet.getRange('L1').getValue() == 2){
for(i=3; i<1000; i++) {
if(masterSS.getSheetByName("Delivery List").getRange(i,1).getValue() == sheet.getRange(1,2).getValue()) {
masterSS.getSheetByName("Delivery List").getRange(i,1).offset(0,2).setValue(sheet.getRange(4,7).getValue());
break;
}
}
}
}
}
//Increment for the 'while loop' that searches for SKU in inventory
nextCell = currentCell.offset(1,0);
currentCell = nextCell;
}
//Return to saved cell
currentCell = cellLink;
//Change value of 'prior quantity' to new quantity in case of further changes
currentCell = currentCell.offset(0,-1);
currentCell.setValue(q);
//Return to orginally edited cell
currentCell = currentCell.offset(0,-8);
}
//If edit occurred in fourth, fifth, sixth columns (value, ext. value, total cost)
if((range.getColumn() == 4) || (range.getColumn() == 5) || (range.getColumn() == 6)) {
//If on job sheet, update total price on job list
if ((sheet.getRange('L1').getValue() == 0) || (sheet.getRange('L1').getValue()== 1)) {
for(i=3; i<1000; i++) {
if(masterSS.getSheetByName("Job List").getRange(i,1).getValue() == sheet.getRange(1,2).getValue()) {
masterSS.getSheetByName("Job List").getRange(i,1).offset(0,2).setValue(sheet.getRange(4,6).getValue());
break;
}
}
}
//If on delivery sheet, udate total price on delivery list
if (sheet.getRange('L1').getValue() == 2) {
for(i=3; i<1000; i++) {
if(masterSS.getSheetByName("Delivery List").getRange(i,1).getValue() == sheet.getRange(1,2).getValue()) {
masterSS.getSheetByName("Delivery List").getRange(i,1).offset(0,2).setValue(sheet.getRange(4,7).getValue())
break;
}
}
}
}
}