简体   繁体   English

Google Sheet App Script 保护范围并允许基于电子邮件的编辑,但从编辑权限中排除少数列

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

I am using below script to protect data upto last row on opening the sheet.我正在使用下面的脚本来保护打开工作表时直到最后一行的数据。 The script will add protection on the range and will allow the sheet owner and email id specified in the code to edit the protected range.该脚本将在范围上添加保护,并允许代码中指定的工作表所有者和电子邮件 ID 编辑受保护的范围。 The script performs its work, however, I want to update below in the script.该脚本执行其工作,但是,我想在脚本下面进行更新。

Eg There are 5 columns in the sheet and data upto row no.例如,工作表中有 5 列,数据到第 1 行。 100, so on opening the sheet the script will protect all the columns upto row no. 100,因此在打开工作表时,脚本将保护所有列直到第 1 行。 100, only the sheet owner and the specified email id will be allowed to edit this protected range. 100,只有工作表所有者和指定的电子邮件 ID 将被允许编辑这个受保护的范围。 I want a permanent protection on Col A & Col D so in this case the specific email id covered in the script will get access to protected range but excluding column A & col D.我想要对 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);
}
});
}

Any help on above will be greatly appreciated.上述任何帮助将不胜感激。

I believe your goal is as follows.我相信你的目标如下。

  • You want to protect the rows from 1st row to the last row.您想保护从第一行到最后一行的行。 In this case, you want to give the edit permission to the specific user.在这种情况下,您希望将编辑权限授予特定用户。 And, for the specific columns, you don't want to make all users edit.而且,对于特定列,您不想让所有用户都进行编辑。
  • Added: I want these columns to be protected in full ie entire column should be protected.补充: I want these columns to be protected in full ie entire column should be protected.

In this case, how about the following modified script?在这种情况下,下面的修改脚本怎么样?

Modified script 1:修改脚本1:

Please install OnOpen trigger to the function.请在函数中安装 OnOpen 触发器。 When you reopen the Spreadsheet, the script is automatically run.当您重新打开电子表格时,脚本会自动运行。

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);
      });
    }
  });
}
  • When this script is run, the 1st row to the last row is protected.运行此脚本时,第一行到最后一行受到保护。 In this case, the owner and specific users can edit the protected ranges.在这种情况下,所有者和特定用户可以编辑受保护的范围。 But, the columns of const permanentProtectedColumns = [1, 4];但是, const permanentProtectedColumns = [1, 4];的列(in this case, columns "A" and "D") can be edited by only the owner. (在这种情况下,列“A”和“D”)只能由所有者编辑。

Modified script 2:修改脚本2:

I think that the above modified script can be used.我认为可以使用上面修改的脚本。 But, in your situation, the process cost might be high a little.但是,在您的情况下,流程成本可能会有点高。 So, if you want to reduce the process cost, how about using Sheets API as follows?那么,如果您想降低流程成本,使用 Sheets API 怎么样?

In this case, please enable Sheets API at Advanced Google services .在这种情况下, 请在 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);
}
  • In this sample script, the same result with the above script is obtained.在此示例脚本中,获得与上述脚本相同的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 App Script 编辑 Google Sheet 的 email - How to email editors of a Google Sheet using App Script Google Sheets Apps脚本处于“编辑”状态时,从受保护范围中删除编辑器的速度非常慢/未完成 - Google Sheets Apps Script On Edit Remove Editors From Protected Range Very Slow / Not Completing 基于日期保护范围的 Google Apps 脚本 - Google Apps Script to protect range based on dates 基于 email 列在工作表中对行数据进行分组的 Google App 脚本 - Google App Script to Group Row data in sheet based on email column 如何使用Google Apps脚本保护范围不受Google表格的创建者/所有者的影响? - How to protect a range from creator / owner of Google Sheet using Google Apps Script? Google App 脚本从保护中删除编辑器 - Google App script Remove Editors From Protection 谷歌脚本:编辑无法保存工作表侧边栏中的数据 - Google Script: Editors can't save data from sidebar in the sheet Google Sheet 在首次编辑后删除编辑器 - Google Sheet Remove Editors After First Edit 如何将变更事件回滚到Google工作表或仅禁止变更事件但允许用户进行编辑? - How to roll-back change events to a Google sheet or disallow only change events but allow edit rights to users? 用于剪切和粘贴从一个谷歌表到另一个谷歌表的范围的谷歌应用程序脚本 - Google app script to cut and paste a range from a google sheet to another google sheet
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM