简体   繁体   English

如何允许谷歌工作表中的共享用户运行访问受保护工作表的脚本

[英]How to allow shared users in google sheets to run script that accesses protected sheet

I have a google spreadsheet in which I plan to share with over 50 users who will each have their own sheet.我有一个 google 电子表格,我计划在其中与 50 多个用户共享,每个用户都有自己的工作表。 For security measures, I have some script that I would like to run which would allow a user to enter data into their sheet but prevent them from deleting that entry after.为了安全措施,我有一些我想运行的脚本,它允许用户将数据输入到他们的工作表中,但防止他们之后删除该条目。 The code works fine on my end, but when I tried to test it out by sharing it to one of the users, the script either didn't run or is not allowed to run.该代码在我的最终工作正常,但是当我尝试通过将其共享给其中一个用户来对其进行测试时,该脚本要么没有运行,要么不允许运行。

I have done my research on this matter for a while now and cannot seem to apply any of the solutions that I have seen posted on this forum and many others.我已经对这个问题进行了一段时间的研究,似乎无法应用我在这个论坛和许多其他论坛上看到的任何解决方案。 I am using an onEdit() function which, to the best of my knowledge, is a simple trigger so it shouldn't cause this kind of error.我正在使用 onEdit() 函数,据我所知,它是一个简单的触发器,因此它不会导致此类错误。 The code is as follows:代码如下:

function onEdit(event) {

var masterSheetName = "Blank" // sheet where the cells are protected from updates
  var helperSheetName = "Blank Copy" // sheet where the values are copied for later checking

  // range where edits are "write once": D18:Y157, i.e., rows 18-157 and columns 4-25
  var firstDataRow = 18; // only take into account edits on or below this row
  var lastDataRow = 157; // only take into account edits on or above this row
  var firstDataColumn = 4; // only take into account edits on or to the right of this column
  var lastDataColumn = 25; // only take into account edits on or to the left of this column

  var miscFirstDataColumnOne = 15; // only take into account edits on or to the right of this column
  var miscLastDataColumnOne = 15; // only take into account edits on or to the left of this column
  var miscFirstDataColumnTwo = 25; // only take into account edits on or to the right of this column
  var miscLastDataColumnTwo = 25; // only take into account edits on or to the right of this column
  var miscFirstDataRowTwo = 18;
  var miscLastDataRowTwo = 157;

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var masterSheet = ss.getActiveSheet();
  var masterSheetMiscOne = ss.getActiveSheet();
  if (masterSheet.getName() != masterSheetName) return;
  if (masterSheetMiscOne.getName() != masterSheetName) return;

  var masterCell = masterSheet.getActiveCell();
  var masterCellMiscOne = masterSheetMiscOne.getActiveCell();

  if (masterCell.getRow() < firstDataRow || masterCell.getColumn() < firstDataColumn ||

    masterCell.getRow() > lastDataRow || masterCell.getColumn() > lastDataColumn) return;

  var helperSheet = ss.getSheetByName(helperSheetName);
  var helperCell = helperSheet.getRange(masterCell.getA1Notation());
  var newValue = masterCell.getValue();
  var oldValue = helperCell.getValue();

  var user = SpreadsheetApp.getActive().getEditors()[1];
  var permission = helperSheet.getSheetProtection();
  permission.addUser(user);
  helperSheet.setSheetProtection(permission);
  SpreadsheetApp.flush();

  if (oldValue == "") {
    helperCell.setValue(newValue);
  } else {
    masterCell.setValue(oldValue);
    Browser.msgBox('You can not delete this value');
  }

  if ((masterCellMiscOne.getRow() < firstDataRow || masterCellMiscOne.getColumn() < miscFirstDataColumnOne || masterCellMiscOne.getRow() > lastDataRow || 

    masterCellMiscOne.getColumn() > miscLastDataColumnOne) & (masterCellMiscOne.getRow() < firstDataRow || masterCellMiscOne.getColumn() < miscLastDataColumnOne ||

      masterCellMiscOne.getRow() > lastDataRow || masterCellMiscOne.getColumn() > miscLastDataColumnTwo)) return;

var miscCellValueOne = masterCellMiscOne.getValue();

  if (miscCellValueOne !== "")  {

    Browser.msgBox('Submission Needs To Be Authorized Before Being Added.');

  }

  SpreadsheetApp.flush();
  permission.removeUser(user)
  helperSheet.setSheetProtection(permission)
}
}

Each user has a sheet which will also have a copy, (in this code the users sheet is "Blank" and the copy is "Blank Copy").每个用户都有一张工作表,其中也有一份副本(在此代码中,用户工作表为“空白”,副本为“空白副本”)。 The blank copy will be protected so they can not edit this because it will allow them to delete the data in their sheet (Blank).空白副本将受到保护,因此他们无法对其进行编辑,因为这将允许他们删除工作表(空白)中的数据。 This code does work, but I just need for it to work when I share the spreadsheet.这段代码确实有效,但我只需要在共享电子表格时它才能工作。

All help is greatly appreciated and here is a link to a copy of the spreadsheet.非常感谢所有帮助,这里是电子表格副本的链接。

https://docs.google.com/spreadsheet/ccc?key=0AhBLjhwt88kUdFZ2cG9CVFNEQy1zVHdJYlp6ZEx5Unc&usp=sharing https://docs.google.com/spreadsheet/ccc?key=0AhBLjhwt88kUdFZ2cG9CVFNEQy1zVHdJYlp6ZEx5Unc&usp=sharing

Short answer : Create a simple add-on with minimal code refactoring简短回答:使用最少的代码重构创建一个简单的附加组件

Explanation解释

... but when I tried to test it out by sharing it to one of the users, the script either didn't run or is not allowed to run. ...但是当我尝试通过将它共享给其中一个用户来测试它时,该脚本要么没有运行,要么不允许运行。

Unfortunately this would be the case as the "trigger" that you're currently using (ie the onEdit one) -不幸的是,这将是您当前使用的“触发器”(即onEdit一个)-

... cannot access services that require authorization . ... 无法访问需要授权的服务

Please refer to Simple Triggers > Restrictions .请参阅简单触发器 > 限制

Alternate solution替代解决方案

You can introduce an onInstall function and publish this code as an add-on with visibility set to Private if folks from only your domain are going to use the sheet/script.如果只有您所在域的人要使用工作表/脚本,您可以引入一个onInstall函数并将此代码作为可见性设置为Private的附加组件发布。

Hope this helps.希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM