【问题标题】:GAS Script : Is it possible to prevent simultaneous user?GAS 脚本:是否可以防止同时使用用户?
【发布时间】:2021-04-26 04:24:36
【问题描述】:

只有两个问题:

我有一个可由多个用户编辑的电子表格文件。但我担心它会很烦人: 第一个问题:当一个用户打开一个文件而另一个用户正在编辑它时,是否会运行 onOpen 脚本? (因为我的 onOpen 脚本会重置一些单元格,所以可能很烦人)。 那么第二个问题:是否可以简单地警告用户,当他试图打开文件时,它已经被另一个用户打开并拒绝他访问?

感谢您的回答(我已经搜索了一些没有成功的答案)

洛伊克

【问题讨论】:

标签: user-interface google-apps-script google-sheets editor simultaneous


【解决方案1】:

您还可以考虑使用Properties Service,它将简单数据存储在一个脚本(脚本属性)、一个脚本的一个用户(用户属性)或一个文档(文档属性)范围内的键值对中。

我决定使用这个Properties Service,因为您主要关心的是防止执行 onOpen() 当有人已经在使用该文件时修改某些单元格。与Lock Service 有所不同,因为锁定服务会阻止代码块的同时/并发执行。

示例实现:

function onOpen(e){
  var ui = SpreadsheetApp.getUi();
  // Or DocumentApp or FormApp.
  ui.createMenu('LockFile')
      .addItem('Lock', 'lock')
      .addItem('Unlock', 'unlock')
      .addToUi();

  //Check if file is locked. if not, execute the procedure
  var scriptProperties = PropertiesService.getScriptProperties();
  var keys = scriptProperties.getKeys();
  if(keys.length==0){
    //Lock the file 
    //lock(); empty Session.getActiveUser().getEmail() received when user opens the spreadsheet
    showAlert("Please lock the file first");
    
    SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('A1').setValue(Session.getActiveUser().getEmail());
    SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('B1').setValue("Test");
  }else{
    showAlert("File is currenly locked by "+scriptProperties.getProperty('user'));
  }
}

function lock(){
  var scriptProperties = PropertiesService.getScriptProperties();
  var userEmail;
  var keys = scriptProperties.getKeys();
  Logger.log(keys.length);

  if(keys.length==0){
    //Create new property with current user's email
    userEmail = Session.getActiveUser().getEmail();
    Logger.log(userEmail);
    scriptProperties.setProperties({user: userEmail});
    showAlert("File successfully locked by "+userEmail);
    
  }else{
    userEmail = scriptProperties.getProperty('user');
    showAlert("File is currenly locked by "+userEmail);
  }

}
function unlock(){
  var scriptProperties = PropertiesService.getScriptProperties();
  var userEmail = Session.getActiveUser().getEmail();
  var keys = scriptProperties.getKeys();
  Logger.log(keys.length);
  Logger.log(scriptProperties.getProperty('user'));

  if(keys.length>0){
    Logger.log(scriptProperties.getProperty('user'));
    if(scriptProperties.getProperty('user') == userEmail){
      scriptProperties.deleteAllProperties();
      showAlert("File successfully unlocked by "+userEmail);
    }else{
      showAlert("File is currenly locked by "+scriptProperties.getProperty('user'));
    }
    
  }else{
    showAlert("File is not locked");
  }
}

function reset(){
  var scriptProperties = PropertiesService.getScriptProperties();
  scriptProperties.deleteAllProperties();
  showAlert("Lock has been reset");
}

function showAlert(message) {
  var ui = SpreadsheetApp.getUi(); // Same variations.
  Logger.log(message);
  var result = ui.alert(
     'File Lock',
     message,
      ui.ButtonSet.OK);
}

它是如何工作的?

  1. 当文件被打开时,它将创建一个用于文件锁定/解锁的自定义菜单。然后检查脚本属性中是否存在现有键。

  2. 如果 key 存在,则不会执行设置单元格值的过程,并会显示警告消息。如果key不存在,则执行该过程并要求当前用户锁定文件。

我无法在 onOpen() 期间自动锁定文件,因为在文件打开期间,Session.getActiveUser().getEmail() 返回一个空字符串。您可以要求当前用户使用自定义菜单锁定文件或创建prompt dialog 并要求当前用户的电子邮件作为键值。

  1. 您可以使用自定义菜单锁定/解锁文件。在文件锁定期间,它会在锁定文件之前检查是否没有现有的密钥。在文件解锁过程中,它会检查当前解锁文件的用户是否是解锁前锁定文件的同一个人。

您可以根据自己的喜好修改警报消息。这只是关于如何在目标中使用 Properties Service 的指南。

【讨论】:

  • 好的,如果我理解得很好,该文件并没有真正被锁定,但脚本会阻止潜在用户该文件当前被其他用户编辑。对吗?
  • 是的,从技术上讲,其他用户仍然可以编辑/查看文件。根据我的理解,您只想阻止 onOpen() 在另一个用户打开文件时触发。如果要防止其他用户修改文件,可以添加 onEdit() 并检查 currentUser 电子邮件地址,如果不匹配,首先将其与 scriptproperty 键进行比较,显示警告对话框并还原修改的单元格。 onEdit() 事件触发器具有 e.oldValue,您可以使用它来恢复修改的单元格值。如果您需要有关如何防止用户修改您的文件的示例,请告诉我
【解决方案2】:

当一个用户打开一个文件而另一个用户正在编辑它时,是否会运行 onOpen 脚本?

是的,它会运行。根据official documentation

onOpen(e) 触发器在用户打开一个 他们有权使用的电子表格、文档、演示文稿或表格 编辑。

是否可以在用户尝试打开文件时简单地警告用户该文件已被其他用户打开并拒绝他访问?

不,但您可以使用LockService,其中:

防止对代码段的并发访问。这可能很有用 当您有多个用户或进程修改共享资源时 并希望防止碰撞。

有很多关于如何使用 LockService 的资源,解决方案取决于您的具体用例,所以我建议您寻找这些资源,做一些研究,然后问一个具体的问题,如果您不是可以自己实现。

资源:

How to understand LockService and implement it correctly?

【讨论】:

    猜你喜欢
    • 2019-01-07
    • 2018-09-30
    • 1970-01-01
    • 1970-01-01
    • 2021-10-27
    • 2013-08-10
    • 1970-01-01
    • 2019-07-04
    • 2011-05-31
    相关资源
    最近更新 更多