【问题标题】:Hide / show specific Sheets tabs for specific users on shared file在共享文件上隐藏/显示特定用户的特定表格标签
【发布时间】:2019-10-26 12:49:44
【问题描述】:

我的谷歌文档在打开谷歌表格文件时应该会提示一个登录框,并且根据密码,它应该显示一个特定的标签。例如。对于“password1”,它应该允许用户只看到选项卡“Sheet1”,其他工作表应该被隐藏。同样,对于“password2”,它应该只允许用户查看和处理选项卡“Sheet2”。

我尝试运行以下代码,但它显示了一些错误。

function showLoginDialog() {
    var sheet3 = SpreadsheetApp.getActiveSheet('Sheet3');
    sheet3.hideSheet();
    var sheet2 = SpreadsheetApp.getActiveSheet('Sheet2');
    sheet2.hideSheet();
    var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet('Sheet1');      
    var ui = SpreadsheetApp.getUi();      
    var prompt = ui.prompt('Password','Enter Password',ui.ButtonSet.OK_CANCEL);      
    var response = prompt.getResponseText();      
    var button = prompt.getSelectedButton();  

    if(button==ui.Button.OK) {       
    if(response=='pwd3') {
            sheet3.activate();
        }//end of inner if
        if(response=='pwd2'){
            sheet2.activate();
        }
    }//end of main if
}//end of function

Google 表格文件应在打开时要求输入密码,并应根据密码显示相应的表格。

【问题讨论】:

  • 您不能有条件地对特定用户隐藏某些工作表。 UI 不是本地的,它同时适用于所有查看者。
  • 请接受答案

标签: google-apps-script google-sheets


【解决方案1】:
  • 您只想通过对话框中输入的值打开电子表格中的所有工作表之一。
  • 例如,当输入pwd2 的值时,您只想打开“Sheet2”。
  • 您希望在打开电子表格时打开对话框。

如果我的理解是正确的,那么这个修改呢?请认为这只是几个答案之一。

修改后的脚本流程如下。

  1. 在打开电子表格时,默认只打开“Sheet1”。
  2. 打开一个对话框。
  3. 输入pwd2时,只打开“Sheet2”。
  4. 输入pwd3时,只打开“Sheet3”。

如果您想在电子表格打开时打开对话框,请将 OnOpen 事件触发器安装到RunOnOpen()

如何安装 OnOpen 触发器:

  • 打开脚本编辑器。
    • 编辑 -> 当前项目的触发器。
    • 点击“添加触发器”。
    • RunOnOpen 设置为“选择要运行的函数”。
    • 为“选择事件源”设置“来自电子表格”。
    • 将“选择事件类型”设置为“打开时”。

修改脚本:

function RunOnOpen() {
  // Updated
  var openSheet = function(ss, sheets, sheet) {
    var s = ss.getSheetByName(sheet);
    s.showSheet();
    ss.setActiveSheet(s);
    for (var i = 0; i < sheets.length; i++) {
      if (sheets[i].getSheetName() != sheet) {
        sheets[i].hideSheet();
      }
    }
  };

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheets = ss.getSheets();
  openSheet(ss, sheets, "Sheet1"); // Open only "Sheet1" when this function is run.
  var ui = SpreadsheetApp.getUi();
  var prompt = ui.prompt('Password','Enter Password',ui.ButtonSet.OK_CANCEL);
  var response = prompt.getResponseText();
  var button = prompt.getSelectedButton();

  if (button == ui.Button.OK) {
    var sheet = "";
    if(response == 'pwd3') {
      openSheet(ss, sheets, "Sheet3");
    } else if(response == 'pwd2') {
      openSheet(ss, sheets, "Sheet2");
    }
  }
}

注意:

  • 在这个修改后的脚本中,当RunOnOpen() 在脚本编辑器中手动运行时,脚本可以工作。为了做到这一点,我没有使用 OnOpen 事件触发器的事件对象。

参考资料:

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

更新:

当我对该脚本进行了多次测试时,出现“Sheet1”工作表和另一个工作表打开的情况。为了避免这种情况,我更新了脚本。能否请您再次确认一下上面的脚本?

编辑:

  • 您希望通过输入每个密码让用户使用电子表格的特定工作表。
  • 您不想为用户发布脚本。
  • 您想让多个用户同时使用电子表格。

如果我对您的目标的理解是正确的,那么这个解决方法怎么样?

  • 为每个用户创建每个电子表格。
    • 这样可以实现电子表格的同时访问。
  • 使用 Web 应用程序通过输入密码打开每个电子表格。

此变通方法的流程如下。

  1. 登录 Google 的用户打开 Web 应用程序。
  2. 用户输入密码,点击“确定”。
  3. 在服务器端检查密码,返回密码对应的Spreadsheet URL。
  4. 从 URL 打开电子表格。

通过这个流程,我认为可以实现前 3 个目标。

示例脚本:

  1. 在您使用此脚本之前,请为每个工作表拆分电子表格,并检索电子表格的每个 URL。
  2. 当您使用它时,请部署具有以下条件的 Web 应用程序。如果您想知道如何部署 Web Apps,请查看this
    • 以以下身份执行应用:
    • 有权访问应用的人:任何人
    • 在此条件下,用户需要登录 Google 才能访问 Web Apps。

用户访问 Web 应用的 URL。

Google Apps 脚本:Code.gs
function doGet() {
  return HtmlService.createHtmlOutputFromFile("index");
}

function selectSpreadsheet(value) {
  var url = "";
  if (value == "pwd2") {
    url = "### URL of Spreadsheet for password of pwd2 ###";
  } else if (value == "pwd3") {
    url = "### URL of Spreadsheet for password of pwd3 ###";
  }
  return url;
}
HTML & Javascript:index.html
<input type="text" id="value" >
<input type="button" value="ok" onclick="openSpreadsheet()">

<script>
function openSpreadsheet() {
  var value = document.getElementById("value").value;
  google.script.run.withSuccessHandler((url) => {
    if (url) window.open(url,'_top');
  }).selectSpreadsheet(value);
}
</script>

注意:

  • 修改脚本后,请将项目部署为新版本。这样,最新的脚本就会反映到 Web 应用程序中。请注意这一点。
  • 我认为当每个电子表格只为每个用户共享时,安全性会很高。
  • Web Apps 的最大同时访问数为 30。Ref
  • 这是一个简单的示例脚本。因此,如果您使用它,请根据您的情况进行修改。
  • 来自TheMaster's sommentAlthough it's highly unlikely that users are able to retrieve the passwords from source code, I recommend using private functions and/or properties service for storing of passwords for a extra layer of security.

    • 作为示例,您可以通过将密码和 URL 保存到 PropertiesService 来像下面这样使用。

      function selectSpreadsheet(value) {
        return PropertiesService.getUserProperties().getProperty(value);
      }
      

参考资料:

【讨论】:

  • 感谢它完美运行,但是,当我将文件共享给另一个用户时它不起作用。此外,有没有办法隐藏代码。
  • @user3243634 感谢您的回复。对于给您带来的不便,我深表歉意。关于Moreover is there a way to hide the code.,我没有注意到这一点。关于你的目标,我是从你的回复和提问中想到的。我更新了我的答案。你能确认一下吗?如果我误解了您的目标并且这不是您想要的方向,我深表歉意。
  • @Tanaike 尽管用户不太可能从源代码中检索密码,但我建议使用private functions 和/或属性服务来存储密码以提供额外的安全保护。跨度>
  • @TheMaster 谢谢你的建议。我将它添加到我的答案中。你能确认一下吗?
【解决方案2】:

我认为这不安全,原因如下:

  • Sheets 的隐藏/可见属性是全局的,不限于单个用户。如果 user1 和 user2 几乎同时登录,则 user1 的 sheet 在 user1 登录后可见;一旦 user2 登录,user1 的工作表将对用户隐藏,而 user2 的工作表将对 user1 和 user2 可见

  • 取消隐藏工作表很容易。用户 1 可以随时取消隐藏用户 2 的工作表,前提是他具有对电子表格的编辑权限(如果您想显示登录对话框,则需要此权限)。

【讨论】:

  • 是的,这是真的。有没有办法让它也安全。基本上我需要的是一个基于用户打开工作表的身份验证系统。
  • @user Tanaike 的更新答案是安全的,我相信。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多