获取电子表格的 ID

Get the ID of a spreadsheet

所以,我已经试了一个星期了,仍然出错。可以正确获取电子表格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?

请注意,每次加载/使用 Apps 脚本项目时都会构造全局变量。另请注意,没有参数会自动传递给函数 - 在 Google 将向其发送参数之前,您必须将函数指定为简单触发器(特殊函数名称)或已安装的触发器,并且在所有其他情况下您有明确指定参数。

那么问题是你在全局范围内声明了 var SS = getSS();,并且没有给它传递任何参数(也没有你可以给它传递的参数)。因此在 getSS() 的定义中,即使您将它定义为 function getSS(e) {,也没有输入参数绑定到变量 e.

因此这个标准if (e && ...)总是false,因为eundefined,这意味着你的else 分支总是被执行。在您的 else 分支中,您假设您拥有权限,而您的测试甚至无法尝试检查该权限。因此,你的错误。您可能打算写 if (!e || e.authMode !== ScriptApp.AuthMode.FULL) 如果 任一 条件为真,则为真。考虑查看 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

所以我这样做了:

    //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);
    }

不同授权模式的案例。

    function onOpen(e) {

    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();
    }

弹出授权的函数window:

function getAuthUrl() {
  var authInfo,msg;

  authInfo = ScriptApp.getAuthorizationInfo(ScriptApp.AuthMode.FULL);
  msg = 'This addon needs authorization to work properly on this spreadsheet.  Click ' +
    'this url to authorize: <br><br>' + 
      '<a href="' + authInfo.getAuthorizationUrl() +
      '" style="cursor:pointer;padding:5px;background: #4285f4;border:1px #000;text-align: center;margin-top: 15px;width: calc(100% - 10px);font-weight: 600;color: #fff">AUTHORIZE</a>' +      
      '<br><br> This spreadsheet needs to either ' +
      'be authorized or re-authorized.';

  //return msg;//Use this for testing

  //ScriptApp.AuthMode.FULL is the auth mode to check for since no other authorization mode requires
  //that users grant authorization
  if (authInfo.getAuthorizationStatus() === ScriptApp.AuthorizationStatus.REQUIRED) {
    return msg;
  } else {
    return "No Authorization needed";
  };
  console.info('Authorization window called');
}