繁体   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