如何防止任何匿名編輯器在作業簿中添加新作業表。我希望允許他們只編輯一張作業表,但一些編輯器通過插入不需要的作業表錯誤地弄亂了作業簿。提前致謝。我嘗試了下面這個鏈接中的腳本,但它似乎不起作用。
防止用戶在共享的 Google 電子表格中創建新作業表
// Deletes any tab named "SheetN" where N is a number
function DeleteNewSheets() {
var newSheetName = /^Sheet[\d] $/
var ssdoc = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ssdoc.getSheets();
// is the change made by the owner ?
if (Session.getActiveUser().getEmail() == ssdoc.getOwner().getEmail()) {
return;
}
// if not the owner, delete all unauthorised sheets
for (var i = 0; i < sheets.length; i ) {
if (newSheetName.test(sheets[i].getName())) {
ssdoc.deleteSheet(sheets[i])
}
}
}
我用上面的代碼創建了這個電子表格https://docs.google.com/spreadsheets/d/1EdF8I0tyfQagfw1cxHCWgsr2umXi6-vbu7GvM8SJQSM/edit#gid=0并設定了觸發器,但任何人仍然可以創建一個新作業表。
uj5u.com熱心網友回復:
我相信你現在的情況和目標如下。
- Google 電子表格中有一個表格。
- 您不想讓匿名用戶插入新作業表。
問題和解決方法:
遺憾的是,在現階段,沒有任何方法可以清楚地檢測匿名用戶的編輯。在您的腳本中,我認為該腳本可以用于特殊允許的用戶。在這種情況下,不能包括匿名用戶。我認為這可能是您的問題的原因。因此,為了實作您的目標,需要準備一個解決方法。在這個答案中,我想提出一個解決方法。
當檢測到作業表插入時,可以使用 OnChange 觸發器。但是,用戶的識別有點困難。當一個函式installedOnChange(e)被 OnChange 觸發器執行時,可以獲得以下條件。并且,為了檢查活躍用戶,Session.getActiveUser().getEmail()并且Session.getEffectiveUser().getEmail()被使用。
當所有者插入新作業表時,
e中installedOnChange(e)擁有的財產"user":{"email":"### owner's email ###","nickname":"### owner name ###"}。Session.getActiveUser().getEmail()并Session.getEffectiveUser().getEmail()回傳所有者的電子郵件。
當特別允許的用戶插入新作業表時,
e中installedOnChange(e)擁有的財產"user":{"email":"","nickname":""}。在這種情況下,不會回傳電子郵件地址和姓名。Session.getActiveUser().getEmail()回傳空,并Session.getEffectiveUser().getEmail()回傳所有者的電子郵件。
當匿名用戶插入新作業表時,
e中installedOnChange(e)擁有的財產"user":{"email":"### owner's email ###","nickname":"### owner name ###"}。Session.getActiveUser().getEmail()并Session.getEffectiveUser().getEmail()回傳所有者的電子郵件。- 在這種情況下,情況與所有者相同。但是,為了識別這一點,這里使用了簡單的觸發器。因為匿名用戶不能使用簡單觸發器。例如,當匿名用戶編輯單元格時,不運行簡單觸發器。使用這種情況。
當這些條件反映在示例腳本中時,將變為如下所示。
用法:
1. 準備示例腳本。
請將以下腳本復制并粘貼到電子表格的腳本編輯器中。并且,請直接onOpen使用腳本編輯器運行函式。這樣,初始作業表名稱存盤在 PropertiesService 中。而且,當電子表格打開時,onOpen運行。這樣,可以保存初始條件。
function onOpen() {
PropertiesService.getScriptProperties().setProperty("sheetName", JSON.stringify(SpreadsheetApp.getActiveSpreadsheet().getSheets().map(s => s.getSheetName())));
}
function onSelectionChange(e) {
CacheService.getScriptCache().put("simpleTrigger", JSON.stringify(e), 30);
}
function deleteSheet(e) {
if (e.changeType != "INSERT_GRID") return;
const sheetNames = JSON.parse(PropertiesService.getScriptProperties().getProperty("sheetName"));
e.source.getSheets().forEach(s => {
if (!sheetNames.includes(s.getSheetName())) e.source.deleteSheet(s);
});
}
function installedOnChange(e) {
const lock = LockService.getDocumentLock();
if (lock.tryLock(350000)) {
try {
Utilities.sleep(3000); // Please increase this wait time when the identification is not correct.
const c = CacheService.getScriptCache();
const simpleTrigger = c.get("simpleTrigger");
const activeUser = Session.getActiveUser().getEmail();
const effectiveUser = Session.getEffectiveUser().getEmail();
if (activeUser && effectiveUser && simpleTrigger) {
// Operation by owner.
// do something.
PropertiesService.getScriptProperties().setProperty("sheetName", JSON.stringify(SpreadsheetApp.getActiveSpreadsheet().getSheets().map(s => s.getSheetName())));
} else if (!activeUser && effectiveUser && simpleTrigger) {
// Operation by permitted user.
// do something.
deleteSheet(e); // If you want to make the permitted user not insert new sheet, please use this line.
} else {
// Operation by anonymous user.
// do something.
deleteSheet(e);
}
c.remove("simpleTrigger");
} catch (e) {
throw new Error(JSON.stringify(e));
} finally {
lock.releaseLock();
}
} else {
throw new Error("timeout");
}
}
In this sample script, the owner, the special permitted user, and the anonymous user are identified. And, the owner can insert a new sheet. But, when the special permitted user and the anonymous user insert a new sheet, the inserted sheet is deleted. By this, as a workaround, your goal might be able to be achieved.
In this script,
onSelectionChangeis used as a simple trigger for detecting the anonymous user.
3. Install OnChange trigger as an installable trigger.
Please install a trigger to the function installedOnChange as the OnChange installable trigger. Ref
3. Testing.
In order to test this script, please insert a new sheet by the special permitted user and the anonymous users. By this, the inserted sheet is deleted. And, when the owner inserts a new sheet, the inserted sheet is not deleted.
Note:
在這個示例腳本中,為了檢查是否執行了簡單觸發器,
Utilities.sleep(3000)使用了。所以,識別用戶的時間有點長。我認為這可能是一個限制。例如,如果您不需要識別插入新作業表的用戶,您也可以使用以下簡單腳本。在您使用此腳本之前,請安裝 OnChange 觸發器
installedOnChange并onOpen使用腳本編輯器運行。在此示例腳本中,所有用戶都無法插入新作業表。function onOpen() { PropertiesService.getScriptProperties().setProperty("sheetName", JSON.stringify(SpreadsheetApp.getActiveSpreadsheet().getSheets().map(s => s.getSheetName()))); } function installedOnChange(e) { const lock = LockService.getDocumentLock(); if (lock.tryLock(350000)) { try { if (e.changeType != "INSERT_GRID") return; const sheetNames = JSON.parse(PropertiesService.getScriptProperties().getProperty("sheetName")); e.source.getSheets().forEach(s => { if (!sheetNames.includes(s.getSheetName())) e.source.deleteSheet(s); }); } catch (e) { throw new Error(JSON.stringify(e)); } finally { lock.releaseLock(); } } else { throw new Error("timeout"); } }
參考:
- 可安裝的觸發器
- 簡單觸發器
- 獲取活動用戶()
- getEffectiveUser()
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/403103.html
標籤:
