Run onEdit script on a protected sheet as an editor, not an owner error TypeError: Cannot read property 'activeSheet' of undefined
Run onEdit script on a protected sheet as an editor, not an owner error TypeError: Cannot read property 'activeSheet' of undefined
我有一个复杂的任务列表sheet,它跟踪已完成的任务。由于这些设置,我需要保护一些公式和范围,以避免 sheet 的用户意外删除它们。问题是某些脚本需要 运行 在 sheet 的受保护部分。在所有者帐户下一切正常。当其他用户使用 sheet 时,他们会收到受保护范围的脚本错误。在网上搜索后,我设置了以下内容:
function doGet(e) {
this[e.parameter.run](e.parameter.sheetName || null);
return ContentService.createTextOutput();
}
function atEdit() {
const activeSheet = SpreadsheetApp.getActiveSheet();
const url = ScriptApp.getService().getUrl();
UrlFetchApp.fetch(url + "?run=script_atEdit&sheetName=" + activeSheet.getSheetName(), {headers: {authorization: "Bearer " + ScriptApp.getOAuthToken()}});
// DriveApp.getFiles() // This is used for automatically detecting the scope of "https://www.googleapis.com/auth/drive.readonly". This scope is used for the access token.
}
function readdTask() {
const activeSheet = SpreadsheetApp.getActiveSheet();
const url = ScriptApp.getService().getUrl();
UrlFetchApp.fetch(url + "?run=script_readdTask&sheetName=" + activeSheet.getSheetName(), {headers: {authorization: "Bearer " + ScriptApp.getOAuthToken()}});
// DriveApp.getFiles() // This is used for automatically detecting the scope of "https://www.googleapis.com/auth/drive.readonly". This scope is used for the access token.
}
基本上,在脚本作为 Web 应用程序发布后,即使其他用户 运行 它来自共享 sheet,它也会在所有者帐户下 运行。
但是我在 onEdit 脚本中遇到以下错误
(请注意,由于 onEdit 无法访问 Auth 调用,onEdit 已重命名为 atEdit)。
TypeError: 无法读取未定义的 属性 'activeSheet'
在 script_atEdit(sysW.1:57:34)
在 doGet(sysW.1:2:24)
这是我的 atEdit 脚本:
function script_atEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // → gets the spreadsheet we will use to get individual sheets from
var activeSheet = e.source.getActiveSheet(); // → gets the information and the active sheet
var globalsSheet = ss.getSheetByName("Admin"); // → gets the sheet where we store our global values, GAS handles globals a bit differently therfore declaring a dynamic global is inconvenient
if (activeSheet.getName() == 'Tasks') { // → specifies on what sheet within the worksheet the action below will happen
var aCell = e.source.getActiveCell(), col = aCell.getColumn(); // → gets the active cell and column the user clicks on and puts the info into aCell variable
if (col == 2) {
var dateCell = aCell.offset(0,1); // → offset, specifies what row and colum hold / will hold the date (- is up, + is down) and number of columns away (- is left, + is right)
var aRow = aCell.getRow();
if (aCell.getValue() === true) {
var newDate = new Date(); // → gets the current timestamp; the current date and the current time the user checked the cell
var taskID = activeSheet.getRange(aRow,7).getValue();
var taskDate = activeSheet.getRange(aRow,5).getValue();
globalsSheet.getRange(1, 2).setValue(taskID) // → sets the global value in the Admin sheet so that it becomes accessible to other functions, IE. other functions copy the value from Admin sheet
globalsSheet.getRange(2, 2).setValue(taskDate)
var everyNth = activeSheet.getRange(aRow,8).getValue();
globalsSheet.getRange(3, 2).setValue(everyNth)
dateCell.setValue(newDate); // → puts the above information into the actual cell the user checked
activeSheet.getRange(aRow,1,1,6).setBackground("#87868c"); // → changes the background color of the row in which the user checked the cell
script_readdTask() } // → calls readdTask function which will repeat the task and set its date to whatever repeat frequency it is set in the setTasks sheet
else {
dateCell.setValue(""); // → clears the date when the cell is unchecked
activeSheet.getRange(aRow,1,1,6).setBackground("#ffffff"); }}} // → restores the color of the row to what it was, white, if the cell is unchecked
var sheetName = activeSheet.getRange(1,15).getValue();
var nameCheck1 = activeSheet.getRange(1,1).getValue();
var nameCheck2 = activeSheet.getRange(1,6).getValue();
var currentSheet = "" + nameCheck1 + nameCheck2
if (sheetName == currentSheet){
var bCell = e.source.getActiveCell()
if (bCell.getValue() === true){
bCell.setBackground("green")
} else if (bCell.getValue() === false){
bCell.setBackground("#f3f3f3");
}
}
}
我认为您的问题是由于尽管 script_atEdit(e)
是从 doGet(e)
调用的,但您正试图将 script_atEdit(e)
用作 OnEdit 触发器调用的函数。
在你的情况下,从你的回复中,我了解到 script_atEdit(e)
是由 doGet(e)
从 atEdit()
调用的 运行。 atEdit()
由 OnEdit 触发器 运行。
这种情况下,请修改script_atEdit(e)
如下。在您的脚本中,script_atEdit(e)
的 e
是 sheet 名称。
发件人:
var activeSheet = e.source.getActiveSheet();
收件人:
var activeSheet = SpreadsheetApp.getActive().getSheetByName(e) || SpreadsheetApp.getActiveSheet();
还有,
发件人:
var aCell = e.source.getActiveCell(), col = aCell.getColumn();
收件人:
var aCell = activeSheet.getActiveCell(), col = aCell.getColumn();
还有,
发件人:
var bCell = e.source.getActiveCell()
收件人:
var bCell = activeSheet.getActiveCell();
注:
- 当您修改 Google Apps 脚本时,请将部署修改为新版本。这样,修改后的脚本就会反映在 Web Apps 中。请注意这一点。
- 您可以在“Redeploying Web Apps without Changing URL of Web Apps for new IDE”的报告中看到详细信息。
我有一个复杂的任务列表sheet,它跟踪已完成的任务。由于这些设置,我需要保护一些公式和范围,以避免 sheet 的用户意外删除它们。问题是某些脚本需要 运行 在 sheet 的受保护部分。在所有者帐户下一切正常。当其他用户使用 sheet 时,他们会收到受保护范围的脚本错误。在网上搜索后,我设置了以下内容:
function doGet(e) {
this[e.parameter.run](e.parameter.sheetName || null);
return ContentService.createTextOutput();
}
function atEdit() {
const activeSheet = SpreadsheetApp.getActiveSheet();
const url = ScriptApp.getService().getUrl();
UrlFetchApp.fetch(url + "?run=script_atEdit&sheetName=" + activeSheet.getSheetName(), {headers: {authorization: "Bearer " + ScriptApp.getOAuthToken()}});
// DriveApp.getFiles() // This is used for automatically detecting the scope of "https://www.googleapis.com/auth/drive.readonly". This scope is used for the access token.
}
function readdTask() {
const activeSheet = SpreadsheetApp.getActiveSheet();
const url = ScriptApp.getService().getUrl();
UrlFetchApp.fetch(url + "?run=script_readdTask&sheetName=" + activeSheet.getSheetName(), {headers: {authorization: "Bearer " + ScriptApp.getOAuthToken()}});
// DriveApp.getFiles() // This is used for automatically detecting the scope of "https://www.googleapis.com/auth/drive.readonly". This scope is used for the access token.
}
基本上,在脚本作为 Web 应用程序发布后,即使其他用户 运行 它来自共享 sheet,它也会在所有者帐户下 运行。
但是我在 onEdit 脚本中遇到以下错误
(请注意,由于 onEdit 无法访问 Auth 调用,onEdit 已重命名为 atEdit)。
TypeError: 无法读取未定义的 属性 'activeSheet' 在 script_atEdit(sysW.1:57:34) 在 doGet(sysW.1:2:24)
这是我的 atEdit 脚本:
function script_atEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // → gets the spreadsheet we will use to get individual sheets from
var activeSheet = e.source.getActiveSheet(); // → gets the information and the active sheet
var globalsSheet = ss.getSheetByName("Admin"); // → gets the sheet where we store our global values, GAS handles globals a bit differently therfore declaring a dynamic global is inconvenient
if (activeSheet.getName() == 'Tasks') { // → specifies on what sheet within the worksheet the action below will happen
var aCell = e.source.getActiveCell(), col = aCell.getColumn(); // → gets the active cell and column the user clicks on and puts the info into aCell variable
if (col == 2) {
var dateCell = aCell.offset(0,1); // → offset, specifies what row and colum hold / will hold the date (- is up, + is down) and number of columns away (- is left, + is right)
var aRow = aCell.getRow();
if (aCell.getValue() === true) {
var newDate = new Date(); // → gets the current timestamp; the current date and the current time the user checked the cell
var taskID = activeSheet.getRange(aRow,7).getValue();
var taskDate = activeSheet.getRange(aRow,5).getValue();
globalsSheet.getRange(1, 2).setValue(taskID) // → sets the global value in the Admin sheet so that it becomes accessible to other functions, IE. other functions copy the value from Admin sheet
globalsSheet.getRange(2, 2).setValue(taskDate)
var everyNth = activeSheet.getRange(aRow,8).getValue();
globalsSheet.getRange(3, 2).setValue(everyNth)
dateCell.setValue(newDate); // → puts the above information into the actual cell the user checked
activeSheet.getRange(aRow,1,1,6).setBackground("#87868c"); // → changes the background color of the row in which the user checked the cell
script_readdTask() } // → calls readdTask function which will repeat the task and set its date to whatever repeat frequency it is set in the setTasks sheet
else {
dateCell.setValue(""); // → clears the date when the cell is unchecked
activeSheet.getRange(aRow,1,1,6).setBackground("#ffffff"); }}} // → restores the color of the row to what it was, white, if the cell is unchecked
var sheetName = activeSheet.getRange(1,15).getValue();
var nameCheck1 = activeSheet.getRange(1,1).getValue();
var nameCheck2 = activeSheet.getRange(1,6).getValue();
var currentSheet = "" + nameCheck1 + nameCheck2
if (sheetName == currentSheet){
var bCell = e.source.getActiveCell()
if (bCell.getValue() === true){
bCell.setBackground("green")
} else if (bCell.getValue() === false){
bCell.setBackground("#f3f3f3");
}
}
}
我认为您的问题是由于尽管 script_atEdit(e)
是从 doGet(e)
调用的,但您正试图将 script_atEdit(e)
用作 OnEdit 触发器调用的函数。
在你的情况下,从你的回复中,我了解到 script_atEdit(e)
是由 doGet(e)
从 atEdit()
调用的 运行。 atEdit()
由 OnEdit 触发器 运行。
这种情况下,请修改script_atEdit(e)
如下。在您的脚本中,script_atEdit(e)
的 e
是 sheet 名称。
发件人:
var activeSheet = e.source.getActiveSheet();
收件人:
var activeSheet = SpreadsheetApp.getActive().getSheetByName(e) || SpreadsheetApp.getActiveSheet();
还有,
发件人:
var aCell = e.source.getActiveCell(), col = aCell.getColumn();
收件人:
var aCell = activeSheet.getActiveCell(), col = aCell.getColumn();
还有,
发件人:
var bCell = e.source.getActiveCell()
收件人:
var bCell = activeSheet.getActiveCell();
注:
- 当您修改 Google Apps 脚本时,请将部署修改为新版本。这样,修改后的脚本就会反映在 Web Apps 中。请注意这一点。
- 您可以在“Redeploying Web Apps without Changing URL of Web Apps for new IDE”的报告中看到详细信息。