just two questions :
I have a spreadsheet file editable by multiple user. but I'm afraid it will be annoying: first question: does an onOpen script run when a user opens a file while another user is editing it? (because my onOpen script resets some cells, so it could be annoying). So second question: is it possible to simply warn the user, when he tries to open the file, that it is already opened by another user and deny him access?
Thank you for your answers (I already search some answers whithout success)
Loïc
You can also consider using Properties Service which stores simple data in key-value pairs scoped to one script (Script Properties), one user of a script (User Properties), or one document (Document Properties).
I decided to use this Properties Service because your main concern is to prevent the execution of onOpen() which modifies some cells when there is someone already using the file. It is somewhat different with Lock Service, since lock service prevents simultaneous/concurrent execution of a code block.
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);
}
When the file was opened, it will create a custom menu for file lock/unlock. Then check if there is an existing key in the script properties.
If key exist, it will not implement the procedure for setting cell values and will show an alert message. If key doesn't exist, then it will execute the procedure and will ask the current user to lock the file.
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.
You can modify the alert messages based on your preference. This is just a guide on how you could use Properties Service in your goals.