GAS 脚本:是否可以防止同时用户?
GAS Script : Is it possible to prevent simultaneous user?
只有两个问题:
我有一个可由多个用户编辑的电子表格文件。但恐怕会很烦人:
第一个问题:当用户打开文件而另一个用户正在编辑文件时,onOpen 脚本 运行 会发生吗? (因为我的 onOpen 脚本重置了一些单元格,所以它可能很烦人)。
那么第二个问题:是否可以简单地警告用户,当他试图打开文件时,它已经被另一个用户打开并拒绝他访问?
感谢您的回答(我已经搜索了一些答案但没有成功)
洛伊克
当一个用户打开文件而另一个用户正在编辑文件时,onOpen 脚本是否 运行?
是的,会 运行。根据 official documentation:
The onOpen(e) trigger runs automatically when a user opens a
spreadsheet, document, presentation, or form that they have permission
to edit.
是否可以在用户试图打开该文件时简单地警告该文件已被其他用户打开并拒绝他访问?
不,但是您可以使用 LockService which:
Prevents concurrent access to sections of code. This can be useful
when you have multiple users or processes modifying a shared resource
and want to prevent collisions.
有很多关于如何使用 LockService
的资源,解决方案取决于您的具体用例,所以我建议您查找这些资源,进行一些研究,然后就此提出具体问题如果您无法自己实施。
资源:
您还可以考虑使用 Properties Service,它将简单数据存储在键值对中,范围限定为一个脚本(脚本属性)、一个脚本用户(用户属性)或一个文档(文档属性) .
我决定使用这个 Properties Service 因为您主要关心的是防止 onOpen() 的执行,它在有人已经在使用该文件时修改了一些单元格。 锁定服务有些不同,因为锁定服务阻止simultaneous/concurrent代码块的执行。
示例实现:
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);
}
它是如何工作的?
打开文件时,将为文件 lock/unlock 创建一个自定义菜单。然后检查脚本属性中是否存在现有密钥。
如果key存在,则不会执行设置单元格值的过程,并会显示警告信息。如果key不存在,则执行程序并要求当前用户锁定文件。
I cannot lock the file automatically during onOpen() because during file open, Session.getActiveUser().getEmail() returns an empty string. You can either ask the current user to lock the file using the custom menu or create a prompt dialog and ask for the current user's email as the key value.
- 您可以lock/unlock 使用自定义菜单的文件。在文件锁定期间,它会在锁定文件之前检查是否不存在现有密钥。而在文件解锁过程中,会检查当前解锁文件的用户是否为解锁前锁定文件的同一人。
您可以根据自己的喜好修改提醒消息。这只是关于如何在您的目标中使用 Properties Service 的指南。
只有两个问题:
我有一个可由多个用户编辑的电子表格文件。但恐怕会很烦人: 第一个问题:当用户打开文件而另一个用户正在编辑文件时,onOpen 脚本 运行 会发生吗? (因为我的 onOpen 脚本重置了一些单元格,所以它可能很烦人)。 那么第二个问题:是否可以简单地警告用户,当他试图打开文件时,它已经被另一个用户打开并拒绝他访问?
感谢您的回答(我已经搜索了一些答案但没有成功)
洛伊克
当一个用户打开文件而另一个用户正在编辑文件时,onOpen 脚本是否 运行?
是的,会 运行。根据 official documentation:
The onOpen(e) trigger runs automatically when a user opens a spreadsheet, document, presentation, or form that they have permission to edit.
是否可以在用户试图打开该文件时简单地警告该文件已被其他用户打开并拒绝他访问?
不,但是您可以使用 LockService which:
Prevents concurrent access to sections of code. This can be useful when you have multiple users or processes modifying a shared resource and want to prevent collisions.
有很多关于如何使用 LockService
的资源,解决方案取决于您的具体用例,所以我建议您查找这些资源,进行一些研究,然后就此提出具体问题如果您无法自己实施。
资源:
您还可以考虑使用 Properties Service,它将简单数据存储在键值对中,范围限定为一个脚本(脚本属性)、一个脚本用户(用户属性)或一个文档(文档属性) .
我决定使用这个 Properties Service 因为您主要关心的是防止 onOpen() 的执行,它在有人已经在使用该文件时修改了一些单元格。 锁定服务有些不同,因为锁定服务阻止simultaneous/concurrent代码块的执行。
示例实现:
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);
}
它是如何工作的?
打开文件时,将为文件 lock/unlock 创建一个自定义菜单。然后检查脚本属性中是否存在现有密钥。
如果key存在,则不会执行设置单元格值的过程,并会显示警告信息。如果key不存在,则执行程序并要求当前用户锁定文件。
I cannot lock the file automatically during onOpen() because during file open, Session.getActiveUser().getEmail() returns an empty string. You can either ask the current user to lock the file using the custom menu or create a prompt dialog and ask for the current user's email as the key value.
- 您可以lock/unlock 使用自定义菜单的文件。在文件锁定期间,它会在锁定文件之前检查是否不存在现有密钥。而在文件解锁过程中,会检查当前解锁文件的用户是否为解锁前锁定文件的同一人。
您可以根据自己的喜好修改提醒消息。这只是关于如何在您的目标中使用 Properties Service 的指南。