且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使未经授权的用户保护电子表格

更新时间:2023-12-01 15:34:58

我相信您的情况和目标如下.

I believe your situation and goal as follows.

  • 登录Google帐户的用户通过单击Google Spreadsheet上的按钮来运行脚本.
  • 在您的问题中,当用户单击按钮时,错误为 Exception:您正在尝试编辑受保护的单元格或对象.如果需要编辑,请与电子表格所有者联系以删除保护.发生.
  • 您想在用户单击按钮时将工作表锁定在Google Spreadsheet中.

我认为在您的情况下,当用户单击按钮时,脚本将由每个用户运行.但是工作表已经被其他用户锁定.由此,发生这种错误.为了避免这种情况,作为一种解决方法,我建议由用户(在本例中是所有者)锁定表.此解决方法的流程如下.

I think that in your case, when the users click the button, the script is run by each user. But the sheet has already been locked by other users. By this, such error occurs. In order to avoid this, as a workaround, I would like to propose to lock the sheets by an user (in this case, it's the owner.). The flow of this workaround is as follows.

  1. 单击按钮时,脚本将请求Web Apps.在这种情况下,用户的电子邮件地址将发送到Web Apps.
  2. 在Web Apps中,工作表由所有者锁定.
  3. 锁定完成后,将运行 ui.alert .

用法:

1.准备脚本.

请将以下脚本复制并粘贴到脚本编辑器中并保存.

Usage:

1. Prepare script.

Please copy and paste the following script to the script editor and save it.

const key = "sampleKey";

function doGet(e) {
  if (e.parameter.key == key) {
    var me = e.parameter.me;
    
    // Below script is your script.
    as.getSheets().map(function(sheet) {
      var protection = sheet.protect().setDescription('The sprint has been closed. No further editing possible.');
      
      // Ensure the current user is an editor before removing others. Otherwise, if the user's edit
      // permission comes from a group, the script throws an exception upon removing the group.
      protection.addEditor(me);
      
      protection.removeEditors(protection.getEditors());
      if (protection.canDomainEdit()) {
        protection.setDomainEdit(false);
      }
    });

  } else {
    throw new Error("Wrong key.");
  }
  return ContentService.createTextOutput();
}

function lockSheet() {
  var lock = LockService.getDocumentLock();
  if (lock.tryLock(10000)) {
    try {
      var me = Session.getEffectiveUser();
      var as = SpreadsheetApp.getActiveSpreadsheet();
      var url = "https://script.google.com/macros/s/###/exec";  // Please set the URL of Web Apps.
      url += `?me=${me}&key=${key}`;
      try {
        var res = UrlFetchApp.fetch(url);
        var ui = SpreadsheetApp.getUi();
        var response = ui.alert('Sheet is now locked. The only editor now is: ' + me);
      } catch(er) {
        throw new Error(er.message);
      }
    } catch(e) {
      throw new Error(e);
    } finally {
      lock.releaseLock();
    }
  }
}

2.部署Web应用.

  1. 在脚本编辑器上,通过发布"打开对话框.->部署为网络应用".

  1. On the script editor, Open a dialog box by "Publish" -> "Deploy as web app".

将应用程序执行为:" 选择我" .

  • 通过这种方式,脚本以所有者身份运行.

有权访问该应用的用户:" 选择任何人,甚至是匿名的" .

  • 在这种情况下,不需要请求访问令牌.我认为我建议使用此设置来测试此变通办法.但是在此脚本中,使用了用于运行脚本的密钥.
  • 当然,您也可以使用访问令牌.但是,在这种情况下,当使用访问令牌时,该示例脚本不能直接用作自定义函数.因此,在这个答案中,我建议使用该密钥来运行Web Apps脚本.但是,如果您想使用访问令牌,我认为可以使用PropertiesService来实现.

点击部署"按钮作为新的项目版本".

Click "Deploy" button as new "Project version".

自动打开需要授权"对话框.

Automatically open a dialog box of "Authorization required".

  1. 点击查看权限".
  2. 选择自己的帐户.
  3. 点击高级"在此应用未验证"中.
  4. 点击转到###项目名称###(不安全)"
  5. 点击允许"按钮.

  • 单击确定".

  • Click "OK".

    复制Web应用程序的URL.就像 https://script.google.com/macros/s/###/exec .

    Copy the URL of Web Apps. It's like https://script.google.com/macros/s/###/exec.

    • 修改Google Apps脚本后,请重新部署为新版本.这样,修改后的脚本将反映到Web Apps.请注意这一点.

    ,请将上述脚本的 https://script.google.com/macros/s/###/exec 的URL设置为 url .并请重新部署Web Apps.这样,最新脚本将反映到Web应用程序中.所以请注意这一点.

    Please set the URL of https://script.google.com/macros/s/###/exec to url of above script. And please redeploy Web Apps. By this, the latest script is reflected to the Web Apps. So please be careful this.

    4.测试此替代方法.

    请点击分配给 lockSheet 的按钮.这样,用于锁定工作表的脚本由所有者运行.

    4. Test this workaround.

    Please click the button assigned with lockSheet. By this, the script for locking sheets are run by the owner.

    • 修改Google Apps脚本后,请重新部署为新版本.这样,修改后的脚本将反映到Web Apps.请注意这一点.
    • 请在启用V8的情况下使用此脚本.