1

我创建了一个 Google 电子表格来帮助我的团队跟踪下一周的日历。该电子表格有 2 个选项卡:“概览”选项卡和“详细信息”选项卡。在“详细信息”选项卡上,顶行列出了到年底的所有工作日,左列列出了团队成员的姓名。对于每一天,团队成员都会写下他们将就读的学校以及支持的描述。

“概述”选项卡与“详细信息”选项卡具有相同的结构(即顶部的日期和左侧列出的名称),但提供了每个人将在哪里的可视摘要。我编写了一个脚本,该脚本从“详细信息”选项卡中获取学校名称,并将其输入到与“概述”选项卡上正确的人/日期相对应的单元格中。然后它获取支持的描述并在“概述”选项卡上创建一个带有描述的注释。它还在“概述”选项卡上为单元格添加阴影,因此我可以看到已计划支持。因此,从“概述”选项卡中,我所要做的就是将鼠标悬停在单元格上,它会向我显示计划中的支持。

它在我自己的帐户中效果很好。但是,我已与一些团队成员共享电子表格,但它无法正常工作。我不希望我的团队能够编辑“概述”选项卡,因为我只希望他们在“详细信息”选项卡上输入他们的信息。如果我授予他们“概览”选项卡的编辑权限,那么他们可以更改注释、单元格颜色、工作表结构等(这就是我希望“概览”选项卡仅供查看的原因)。因此,我保护了“概述”选项卡,因此他们无法进行编辑。但是,由于他们无法编辑此工作表,因此当他们编辑“详细信息”选项卡时,脚本似乎不会运行并更新“概述”选项卡。我认为这是因为他们没有权限(因为工作表受到保护)。当我删除工作表保护时,脚本对他们来说运行得很好。

关于如何解决这个问题的任何想法?我真的需要保留“概述”选项卡仅查看。谢谢。

4

4 回答 4

4

如果,如您在评论中所述,您在编辑触发器上使用可安装的,则您描述的问题不应该发生,因为“当脚本由于触发器而运行时,脚本使用安装触发器的人的身份运行,而不是身份操作触发事件的用户。这是出于安全原因。例如,如果您在脚本中安装了触发器,但您的同事执行了触发事件的操作,则脚本以您的身份运行,而不是您同事的身份。有关这方面的完整信息,请参阅了解权限和脚本执行。”

在这里查看文档


编辑:抱歉,我没有看到关于这个特殊情况的问题:问题 1562 于 2012 年 7 月发布,状态为“已分类”


编辑 2:我尝试了 @tracon6 建议暂时删除保护,但它也不起作用......脚本在尝试应用保护时生成错误。

作为编辑 3

我找到了一个可行的解决方法!我们可以在写入 targetSheet 时添加一个编辑器,然后在之后立即删除它……flush在它之间使用一个 in 可以工作。

这是我用来测试的代码:

function onEditInstallable(event) {
  var sheet = event.source.getActiveSheet();
  if(sheet.getName()=='Sheet1'){return};
  var r = event.source.getActiveRange();
  var column = r.getColumn();
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var targetSheet = ss.getSheetByName("TFA");
  var targetSheet = ss.getSheetByName("Sheet1");
  var user = SpreadsheetApp.getActive().getEditors()[1];
  var permission = targetSheet.getSheetProtection();
  permission.addUser(user);
  targetSheet.setSheetProtection(permission);
  SpreadsheetApp.flush();
  targetSheet.getRange(1,column).setValue('value change on sheet 2, column  : '+column);
  SpreadsheetApp.flush();
  permission.removeUser(user)
  targetSheet.setSheetProtection(permission)
}

编辑 4:

由于似乎许多编辑者都可以访问这些表格(请参阅最后的评论),因此必须有一种方法可以知道谁在电子表格上处于活动状态。在非域环境中,使用触发函数是不可能的,因此我建议使用带有列表的小型 uiApp,用户必须从中选择,使用可安装的 onOpen 触发它,并将值存储在主函数中使用它。

Heres 是处理该方面的一段代码。

function SpecialonOpen(){
  var s = SpreadsheetApp.getActive();
  var app = UiApp.createApplication().setTitle('Please select your email in this list').setWidth(300).setHeight(300);
  var list = app.createListBox().setName('list')
  var editors = s.getEditors();
  for(var n in editors){
    list.addItem(editors[n].getEmail());
  }
  var handler = app.createServerHandler('getMail').addCallbackElement(list);
  var btn = app.createButton('select',handler);
  s.show(app.add(list).add(btn))
}

function getMail(e){
  var email = e.parameter.list;
  var editors = ScriptProperties.getProperty('currentEditors')||' ';
  if(editors.indexOf(email)==-1){
    editors+=(','+email);
  ScriptProperties.setProperty('currentEditors',editors);
  }
  var app = UiApp.getActiveApplication().close();
  var editors = ScriptProperties.getProperty('currentEditors').split(',');
  if(editors[0].length<2){editors.splice(0,1)};
  Logger.log(editors)
  return app
}

在此处输入图像描述

您还应该添加一个功能来在某个时刻重置此列表......不知道什么是最好的?也许每天都有?我会让这个给你;-)

于 2013-11-05T22:09:20.997 回答
1

概览选项卡和详细信息选项卡是否需要在同一个电子表格中?

也许您可以在只有您可以访问的电子表格中拥有“概述”选项卡,并在其他人可以访问的电子表格中拥有“详细信息”选项卡——然后您可以修改脚本以使用新的“详细信息电子表格”中的信息来更新新的“概览电子表格”。

或者,在您的脚本中,您可以关闭概览选项卡上的保护,然后运行脚本的主要部分,然后在脚本结束之前再次打开概览选项卡上的保护(请参阅https://developers.google。 com/apps-script/reference/spreadsheet/page-protection#setProtected(Boolean) )

诚然,这些选项都不像 onEdit 选项那样干净。

于 2013-11-05T22:41:28.453 回答
0

您可以尝试以下 hacky workarround:将脚本发布为具有匿名访问权限的内容服务,并使用触发器中的 urlFetch 调用它,将必要的参数传递给您的服务。这应该会导致代码在不同的上下文中执行,其中有效用户是脚本发布者而不是用户。你会慢一点。

于 2013-11-07T01:28:33.090 回答
0

为什么不使用“数据”选项卡中的选项保护“概览”表并将编辑权限设置为“仅限您”。这将保护工作表免受所有人甚至编辑的影响,使工作表对除您自己以外的所有人都处于“仅查看”模式。

于 2017-03-15T10:31:49.933 回答