0

所以,我已经尝试了一个星期,仍然错误。可以正确获取电子表格 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 保留为全局变量而不使其为空?

4

2 回答 2

3

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

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

因此这个条件if (e && ...)总是,因为是,这意味着你的分支总是被执行 在您的分支中,您假设您拥有权限,而您的测试甚至无法尝试检查该权限。因此,您的错误。如果任一标准为真,您可能打算写下哪个为真。考虑查看 JavaScript 逻辑运算符。falseeundefinedelseelseif (!e || e.authMode !== ScriptApp.AuthMode.FULL)

虽然您没有分享您的代码如何使用此电子表格,但我很确定它不需要作为评估的全局可用。在您使用SS变量的任何地方,您都可以简单地使用它SpreadsheetApp.getActiveSpreadsheet()

您的getSS()函数还通过 using 强制使用许可范围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

于 2018-08-15T00:47:43.157 回答
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);
    }

不同 AuthModes 的案例。

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

弹出授权窗口的功能:

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');
}
于 2018-08-20T11:43:16.023 回答