簡體   English   中英

Google Sheet App Script 保護范圍並允許基於電子郵件的編輯,但從編輯權限中排除少數列

[英]Google Sheet App Script Protect Range & Allow Editors Based on Email But Exclude Few Columns From Edit Rights

我正在使用下面的腳本來保護打開工作表時直到最后一行的數據。 該腳本將在范圍上添加保護,並允許代碼中指定的工作表所有者和電子郵件 ID 編輯受保護的范圍。 該腳本執行其工作,但是,我想在腳本下面進行更新。

例如,工作表中有 5 列,數據到第 1 行。 100,因此在打開工作表時,腳本將保護所有列直到第 1 行。 100,只有工作表所有者和指定的電子郵件 ID 將被允許編輯這個受保護的范圍。 我想要對 Col A 和 Col D 進行永久保護,因此在這種情況下,腳本中涵蓋的特定電子郵件 ID 將可以訪問受保護的范圍,但不包括 A 列和 D 列。

function installedOnOpen(e) {
const editors = ["###"]; // Added: Please set the email addresses you want to give 
the permission as the editor.

const sheetNames = ["Sheet1"]; // Please set the sheet names you want to protect.
const sheets = e.source.getSheets().filter(s => 
sheetNames.includes(s.getSheetName()));
if (sheets.length == 0) return;
sheets.forEach(s => {
const p = s.getProtections(SpreadsheetApp.ProtectionType.RANGE);
if (p.length > 0) {
  p.forEach(pp => pp.remove());
}
const lastRow = s.getLastRow();
if (lastRow != 0) {
  const newProtect = s.getRange(1, 1, lastRow, s.getMaxColumns()).protect();
  newProtect.removeEditors(newProtect.getEditors());
  newProtect.addEditors(editors); // Added
  if (newProtect.canDomainEdit()) newProtect.setDomainEdit(false);
}
});
}

上述任何幫助將不勝感激。

我相信你的目標如下。

  • 您想保護從第一行到最后一行的行。 在這種情況下,您希望將編輯權限授予特定用戶。 而且,對於特定列,您不想讓所有用戶都進行編輯。
  • 補充: I want these columns to be protected in full ie entire column should be protected.

在這種情況下,下面的修改腳本怎么樣?

修改腳本1:

請在函數中安裝 OnOpen 觸發器。 當您重新打開電子表格時,腳本會自動運行。

function installedOnOpen(e) {
  const editors = ["###"]; // Added: Please set the email addresses you want to give the permission as the editor.
  const permanentProtectedColumns = [1, 4]; // Added: Please set the permanent protected columns.

  const sheetNames = ["Sheet1"]; // Please set the sheet names you want to protect.
  const sheets = e.source.getSheets().filter(s => sheetNames.includes(s.getSheetName()));
  if (sheets.length == 0) return;
  sheets.forEach(s => {
    const p = s.getProtections(SpreadsheetApp.ProtectionType.RANGE);
    if (p.length > 0) {
      p.forEach(pp => pp.remove());
    }
    const lastRow = s.getLastRow();
    if (lastRow != 0) {
      const newProtect = s.getRange(1, 1, lastRow, s.getMaxColumns()).protect();
      newProtect.removeEditors(newProtect.getEditors());
      newProtect.addEditors(editors);
      if (newProtect.canDomainEdit()) newProtect.setDomainEdit(false);

      // I added below script.
      const maxRow = s.getMaxRows();
      permanentProtectedColumns.forEach(r => {
        const pp = s.getRange(1, r, maxRow).protect();
        pp.removeEditors(pp.getEditors());
        if (pp.canDomainEdit()) pp.setDomainEdit(false);
      });
    }
  });
}
  • 運行此腳本時,第一行到最后一行受到保護。 在這種情況下,所有者和特定用戶可以編輯受保護的范圍。 但是, const permanentProtectedColumns = [1, 4];的列 (在這種情況下,列“A”和“D”)只能由所有者編輯。

修改腳本2:

我認為可以使用上面修改的腳本。 但是,在您的情況下,流程成本可能會有點高。 那么,如果您想降低流程成本,使用 Sheets API 怎么樣?

在這種情況下, 請在 Advanced Google services 中啟用 Sheets API

function installedOnOpen(e) {
  const editors = ["###"]; // Added: Please set the email addresses you want to give the permission as the editor.
  const permanentProtectedColumns = [1, 4]; // Added: Please set the permanent protected columns.
  const sheetNames = ["Sheet1"]; // Please set the sheet names you want to protect.

  const sheets = e.source.getSheets().filter(s => sheetNames.includes(s.getSheetName()));
  if (sheets.length == 0) return;
  const id = e.source.getId();
  const obj = Sheets.Spreadsheets.get(id, { ranges: sheets.map(s => s.getSheetName()), fields: "sheets(protectedRanges)" }).sheets;
  const protectedIds = obj.flatMap(({ protectedRanges }) => protectedRanges ? protectedRanges.map(({ protectedRangeId }) => protectedRangeId) : []);
  const requests1 = [];
  if (protectedIds.length > 0) {
    protectedIds.forEach(s => requests1.push({ deleteProtectedRange: { protectedRangeId: s } }));
  }
  const owner = Session.getEffectiveUser().getEmail();
  const requests2 = sheets.map(s => {
    const sheetId = s.getSheetId();
    const lastRow = s.getLastRow();
    const maxCol = s.getMaxColumns();
    return { addProtectedRange: { protectedRange: { range: { sheetId, startRowIndex: 0, endRowIndex: lastRow, startColumnIndex: 0, endColumnIndex: maxCol }, editors: { domainUsersCanEdit: false, users: [owner, ...editors] } } } };
  });
  const requests3 = sheets.flatMap(s => {
    const sheetId = s.getSheetId();
    const maxRow = s.getMaxRows();
    return permanentProtectedColumns.map(t => ({ addProtectedRange: { protectedRange: { range: { sheetId, startRowIndex: 0, endRowIndex: maxRow, startColumnIndex: t - 1, endColumnIndex: t }, editors: { domainUsersCanEdit: false, users: [owner] } } } }));
  });
  Sheets.Spreadsheets.batchUpdate({ requests: [...requests1, ...requests2, ...requests3] }, id);
}
  • 在此示例腳本中,獲得與上述腳本相同的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM