首页 > 解决方案 > 复制文件时保持受保护范围

问题描述

我们在 Googlesheets 上有一个文件模板,它有受保护的范围。我们希望复制此文件(文件,制作副本)并为制作此文件的每个人保留受保护的范围,以便他们只能填充某些特定的单元格。问题是,每当有人制作副本时,他/她就会自动成为副本的所有者。这使得无法保护此副本的范围免受此人的侵害(所有者似乎无论如何都可以完全访问电子表格)。有人会解决这个问题吗?

标签: google-apps-scriptgoogle-sheets

解决方案


  • 您想让用户将 Google Drive 上的电子表格复制到用户的 Google Drive。
    • 您的电子表格有几个受保护的范围。
    • 您的电子表格与用户共享。
    • 用户没有与您共享的自己的文件夹。
  • 您想为用户保护电子表格的范围。即,您想从受保护范围的编辑器中删除用户。
  • 您想使用 Google Apps 脚本实现此目的。

如果我的理解是正确的,这个答案怎么样?

问题:

在上述情况下,我认为以下几点是瓶颈。

  • 当您的 Google Drive 中的电子表格被复制到用户的 Google Drive 时,它​​需要由用户的帐户运行。
  • 当电子表格由用户复制到用户的 Google Drive 时,受保护范围的所有者成为用户。因此用户可以编辑受保护的范围。并且用户不能通过用户从编辑器中删除用户。
    • 为了使用户不编辑受保护范围,需要更改电子表格的所有者,然后需要将用户从受保护范围的编辑器中删除。
  • 在这里,又出现了 2 个问题。
    1. 为了将电子表格的所有者更改为您,它需要由用户帐户运行。
    2. 为了从受保护范围的编辑器中删除用户,它需要由您的帐户运行,该帐户不是用户的帐户。

因此,为了使用脚本实现上述目标,脚本需要由用户和您运行。

解决方法:

在我的解决方法中,使用 2 个脚本和 2 个帐户,它实现了上述目标。此解决方法的重点是使用 2 个 Web 应用程序。请将此视为几种解决方法之一。此解决方法的流程如下。

解决方法流程:

在此解决方法中,使用了 Web 应用程序“A”和 Web 应用程序“B”的 2 个 Web 应用程序。

  1. 用户访问您部署的 Web 应用程序“A”。
    • 在这种情况下,Web 应用程序作为用户执行。
  2. 当 Web 应用程序“A”运行时,
    1. 您的电子表格从您的 Google Drive 复制到用户的 Google Drive。
    2. 复制的电子表格的所有者是用户。因此,将所有者从用户更改为您。
    3. 访问脚本中的 Web 应用程序“B”。
      • 在这种情况下,Web 应用程序将作为您执行。
    4. 当 Web 应用程序“B”运行时,
      1. 用户将从受保护范围的编辑器中删除。

脚本的使用:

准备:

请创建 2 个独立脚本类型的项目。

  • 一个用于 Web 应用程序“A”。
  • 另一个用于 Web 应用程序“B”。

Web 应用程序“B”的独立脚本:

首先,请部署 Web 应用程序“B”,因为在 Web 应用程序“A”的脚本中使用了 Web 应用程序“B”的 URL。请复制以下脚本并将 Web 应用程序部署为Execute the app as: **Me**Who has access to the app: **Anyone, even anonymous**. 请复制此 Web 应用程序“B”的 URL 并将其粘贴到urlWeb 应用程序“A”的脚本中。

function doGet(e) {
  var id = e.parameter.id;
  if (id) {
    var owner = Session.getActiveUser().getEmail();
    var ss = SpreadsheetApp.openById(id);
    var protectedRanges = ss.getProtections(SpreadsheetApp.ProtectionType.RANGE);
    protectedRanges.forEach(function(p) {
      var removes = p.getEditors().filter(function(e) {return e.getEmail() != owner});
      p.removeEditors(removes);
    });
  }
  return ContentService.createTextOutput("Done");
}

Web 应用程序“A”的独立脚本:

请复制以下脚本并设置 和 的srcSpreadsheetId变量url。在这种情况下,url是在 Web 应用程序“B”中检索到的 URL。然后,请将 Web 应用程序部署为Execute the app as: **User accessing the web app**Who has access to the app: **Anyone**. 请复制此 Web 应用程序“A”的 URL。此 URL 用于用户访问。

function doGet() {
  var srcSpreadsheetId = "###"; // Please set your source Spreadsheet ID.
  var url = "###"; // Please set the URL of Web Apps B.

  var srcSS = SpreadsheetApp.openById(srcSpreadsheetId);
  var dstSS = srcSS.copy(srcSS.getName());
  var file = DriveApp.getFileById(dstSS.getId()).setOwner(srcSS.getOwner().getEmail());
  var res = UrlFetchApp.fetch(url + "?id=" + file.getId(), {muteHttpExceptions: true}); // Here, run the script of Web Apps "B".
  return ContentService.createTextOutput(res.getContentText());
}

跑:

当用户使用上述脚本时,请让用户使用自己的浏览器访问Web Apps“A”的URL。当用户访问网络应用程序“A”时,会显示谷歌的登录屏幕。通过登录到谷歌,授权屏幕显示。通过授权,Web 应用程序“A”的脚本运行,Web 应用程序“B”由 Web 应用程序“A”运行。授权只需要做一次。

当用户浏览器中显示“完成”时,用户可以在根文件夹中看到复制的电子表格。

这样,您的 Google Drive 中的电子表格将被复制到用户的 Google Drive,并且电子表格的所有者被修改为您,然后,用户从受保护范围的编辑器中删除。因此用户无法编辑受保护的范围。

如何部署 Web 应用程序:

  1. 在脚本编辑器上,通过“发布”->“部署为 Web 应用程序”打开一个对话框。
  2. 为“将应用程序执行为:”选择“用户访问网络应用程序”“我”。
  3. 为“谁有权访问应用程序:”选择“任何人”“任何人,甚至匿名”。
  4. 单击“部署”按钮作为新的“项目版本”。
  5. 自动打开“需要授权”对话框。
    1. 单击“查看权限”。
    2. 选择自己的帐户。
    3. 在“此应用未验证”中单击“高级”。
    4. 点击“转到###项目名称###(不安全)”
    5. 单击“允许”按钮。
  6. 复制“当前网络应用 URL:”。
    • 就像https://script.google.com/macros/s/#####/exec
  7. 单击“确定”。

重要的:

  1. 当您修改 Web Apps 的脚本时,请将 Web Apps 重新部署为新版本。这样,最新的脚本就会反映到 Web 应用程序中。如果即使修改了脚本也没有重新部署 Web 应用程序,则不会使用最新的脚本。请注意这一点。
  2. 请确认您要制作用户副本的电子表格已与用户共享。

参考:

如果我误解了您的问题并且这不是您想要的方向,我深表歉意。


推荐阅读