所以,我已经尝试了一个星期,仍然出现错误。可以正确获取电子表格ID。
Currently I have this code:
function getSS(e,getSS) {
//If not yet authorized - get current spreadsheet
if (e && e.authMode != ScriptApp.AuthMode.FULL) {
var getSS = SpreadsheetApp.getActiveSpreadsheet();
}
//Else if authorized set/get property to open spreadsheet by ID for time-driven triggers
else {
if(!PropertiesService.getDocumentProperties().getProperty('SOURCE_DATA_ID')){
PropertiesService.getDocumentProperties().setProperty('SOURCE_DATA_ID', e.source.getId());
}
var getSSid = PropertiesService.getDocumentProperties().getProperty('SOURCE_DATA_ID');
var getSS = SpreadsheetApp.openById(getSSid);
}
return getSS;
}
var SS = getSS();
应该在未授权插件的情况下获取活动的电子表格ID,并在获得授权后从属性获取电子表格ID。但是,在安装后进行测试时,总是会得到一个错误,表明我无权使用openById()
或getDocumentProperties()
如何在所有authMode中将SS保持为全局变量而又不为null的情况下?
答案 0 :(得分:3)
请注意,每次加载/使用Apps Script项目时,都会构造全局变量。还要注意,没有参数会自动传递给函数-在Google向其发送参数之前,您必须将函数指定为简单触发器(特殊函数名称)或已安装的触发器,在所有其他情况下,您都必须明确指定论点。
然后的问题是,您在全局范围内声明了var SS = getSS();
,并且不向其传递任何参数(也没有参数可以传递给它)。因此,在getSS()
的定义中,即使您将其命名为function getSS(e) {
,也没有输入参数可以绑定到变量e
。
因此,此条件if (e && ...)
总是 false
,因为e
是undefined
,这意味着您的else
分支始终被执行。在您的else
分支中,您假设自己具有权限,而测试从未能够尝试对其进行检查。因此,您的错误。您可能打算写if (!e || e.authMode !== ScriptApp.AuthMode.FULL)
,如果其中一个的条件为true,则为true。考虑查看JavaScript逻辑运算符。
虽然您没有分享代码如何使用此电子表格,但我敢肯定,它不需要作为评估的全局变量可用。在使用SS
变量的任何地方,都可以只使用SpreadsheetApp.getActiveSpreadsheet()
来代替。
您的getSS()
函数还通过使用openById
来强制使用许可范围-您不能使用首选的...spreadsheets.currentonly
范围。
附加代码示例:
function onInstall(e) {
const wb = e.source;
const docProps = PropertiesService.getDocumentProperties();
docProps.setProperty('SOURCE_DATA_ID', wb.getId());
/**
* set other document properties, create triggers, etc.
*/
// Call the normal open event handler with elevated permissions.
onOpen(e);
}
function onOpen(e) {
if (!e || e.authMode === ScriptApp.AuthMode.NONE) {
// No event object, or we have no permissions.
} else {
// We have both an event object and either LIMITED or FULL AuthMode.
}
}
考虑查看Apps脚本指南以进行附加授权和设置:https://developers.google.com/apps-script/add-ons/lifecycle
答案 1 :(得分:0)
所以我这样做了:
//Because onInstall() only runs once and user might want to launch addon in different spreadsheets I moved getting ID to onOpen(),
function onInstall (e) {
getAuthUrl();
onOpen(e);
}
//I call authoriation function in both onInstall() and onOpen() just in case, also there is a menu item for manual authorization dialog.
function onOpen(e) {
getAuthUrl();
var menu = SpreadsheetApp.getUi().createAddonMenu();
if (!e || e.authMode === ScriptApp.AuthMode.NONE) {
menu.addItem('Authorize this add-on', 'auth');
}
else {
//If addon is authorized add menu with functions that required it. Also get the id of the current spreadsheet and save it into properties, for use in other functions.
menu.addItem('Run', 'run');
var ssid = SpreadsheetApp.getActive().getId();
var docProps = PropertiesService.getDocumentProperties();
docProps.setProperty('SOURCE_DATA_ID', ssid);
}
menu.addToUi();
}