Google 工作表范围以允许不同数量的复选框

Google Sheets range(s) to allow varying numbers of checkboxes

我有一个 sheet,我需要在其中限制一个范围内允许的复选框数量。像这样

H219 到 H225 只允许选中一个复选框。

H228:H335 允许三个复选框。

H340:H347 允许两个复选框。

这个脚本在我使用一次时有效,但是当我多次添加它并更改范围时它似乎停止工作。

function onEdit(e) {
  const sh=e.range.getSheet();
  if(sh.getName()=='GOALS') {
    const mcpr=1;
    const mcpc=2;
    const arrayrange='h219:h225';
    const arg=sh.getRange(arrayrange);
    const avs=arg.getValues();
    const ulr=arg.getRow();
    const ulc=arg.getColumn();
    const lrr=ulr+arg.getHeight()-1;
    const lrc=ulc+arg.getWidth()-1;   
    if(e.range.columnStart<=lrc && e.range.rowStart<=lrr && e.value=="TRUE") {
      let rc=avs[e.range.rowStart-ulr].filter(function(e){return e;}).reduce(function(a,v){ if(v){return a+1;} },0);
      if(rc>mcpr){e.range.setValue("FALSE");e.source.toast('Sorry maximum checks per row is ' + mcpr);};
      let cc=avs.map(function(r,i){return r[e.range.columnStart-ulc];}).filter(function(e){return e}).reduce(function(a,v){if(v){return a+1;}},0);
      if(cc>mcpc){e.range.setValue('FALSE');e.source.toast('Sorry maximum checks per column is ' + mcpc);};          
    }
  }
}

//

function onEdit(e) {
  const sh=e.range.getSheet();
  if(sh.getName()=='GOALS') {
    const mcpr=1;
    const mcpc=3;
    const arrayrange='h236:h244';
    const arg=sh.getRange(arrayrange);
    const avs=arg.getValues();
    const ulr=arg.getRow();
    const ulc=arg.getColumn();
    const lrr=ulr+arg.getHeight()-1;
    const lrc=ulc+arg.getWidth()-1;   
    if(e.range.columnStart<=lrc && e.range.rowStart<=lrr && e.value=="TRUE") {
      let rc=avs[e.range.rowStart-ulr].filter(function(e){return e;}).reduce(function(a,v){ if(v){return a+1;} },0);
      if(rc>mcpr){e.range.setValue("FALSE");e.source.toast('Sorry maximum checks per row is ' + mcpr);};
      let cc=avs.map(function(r,i){return r[e.range.columnStart-ulc];}).filter(function(e){return e}).reduce(function(a,v){if(v){return a+1;}},0);
      if(cc>mcpc){e.range.setValue('FALSE');e.source.toast('Sorry maximum checks per column is ' + mcpc);};          
    }
  }
}

非常感谢,我进行了广泛的搜索,这是我能找到的最好的脚本,我只需要它在同一个 sheet 内的大约 6 个地方工作,每个范围允许一个不同数量的复选框。

我相信你的现状和目标如下。

  • 您有一个 Google 电子表格,复选框已放入单元格 H219:H225H228:H335H340:H347
  • 您想限制在每个范围内选中复选框的数量。
  • 例如H219:H225H228:H335H340:H347分别有1、3、2的限制。
  • 您想使用 Google Apps 脚本实现此目的。

在这种情况下,为了实现您的目标,我想提出一个使用包含范围和限制的数组的示例脚本。该脚本由 OnEdit 简单触发器运行。

示例脚本:

请将以下脚本复制粘贴到Google电子表格的脚本编辑器中,设置objsheetName的变量,并保存。当您使用此脚本时,请勾选 H219:H225H228:H335H340:H347 范围内的复选框。至此,脚本通过 OnEdit 的简单触发器 运行。

function onEdit(e) {
  // Please set the ranges and limitations.
  const obj = [
    {range: "H219:H225", limit: 1},
    {range: "H228:H335", limit: 3},
    {range: "H340:H347", limit: 2},
  ];
  const sheetName = "Sheet1"; // Please set the sheet name of the sheet including the checkboxes.
  
  const range = e.range;
  const editedColumn = range.getColumn();
  const editedRow = range.getRow();
  const sheet = range.getSheet();
  if (sheet.getSheetName() != sheetName) return;
  obj.forEach(({range}, i) => {
    const temp = sheet.getRange(range);
    const startRow = temp.getRow();
    const startColumn = temp.getColumn();
    obj[i].startRow = startRow;
    obj[i].endRow = startRow + temp.getNumRows() - 1;
    obj[i].startColumn = startColumn;
    obj[i].endColumn = startColumn + temp.getNumColumns() - 1;
  });
  for (let i = 0; i < obj.length; i++) {
    if (editedRow >= obj[i].startRow && editedRow <= obj[i].endRow && editedColumn >= obj[i].startColumn && editedColumn <= obj[i].endColumn) {
      const n = sheet.getRange(obj[i].range).getValues().filter(([h]) => h === true).length;
      if (n == obj[i].limit + 1) {
        range.uncheck();
        // Browser.msgBox("Number of checked checboxes are over the limitation."); // If you want to open the dialog, you canm use this.
      } else if (n > obj[i].limit + 1) {
        Browser.msgBox("Checed checkboxes of existing checkboxes have already been over the limitation number of " + obj[i].limit);
      }
      break;
    }
  }
}

结果:

使用上面的脚本,得到如下结果。

注:

  • 此示例脚本是 运行 由 OnEdit 简单触发器创建的。所以当你直接用脚本编辑器运行脚本时,就会出现错误。请注意这一点。

参考文献:

我想知道你是否可以做这样的事情: 您可以为每个范围添加一个新部分 trow 是顶行,brow 是底行,lcol 是左列,rcol 是右列,它们是数组

function onEdit(e) {
  const sh = e.range.getSheet();
  const trow = [236];
  const brow = [244];
  const lcol = [8];
  const rcol = [8];
  const mcpr = [1];
  const mcpc = [3];

  if (sh.getName() == 'GOALS' && e.range.columnStart >= lcol[0] && e.range.columnStart <= rcol[0] && e.range.rowStart >= trow[0] && e.range.rowStart <= brow[0] && e.value == 'TRUE') {
    let vs = sh.getRange(trow[0], lcol[0], brow[0] - trow[0] + 1, rcol[0] - lcol[0] + 1).getValues();
    let rc = vs[e.range.rowStart - trow[0]].filter(e =>return e).reduce((a, v) => { if (v) return (a + 1); }, 0);
    if (rc > mcpr[0]) { e.range.setValue("FALSE"); e.source.toast('Sorry maximum checks per row is ' + mcpr[0]); };
    let cc = vs.map((r, i) => { return r[e.range.columnStart - lcol[0]] }).filter(e =>return e;).reduce((a, v) => { if (v) return a + 1; });
    if (cc > mcpc[0]) { e.range.setValue('FALSE'); e.source.toast('Sorry maximum checks per column is ' + mcpc[0]) };

  if (sh.getName() == 'GOALS' && e.range.columnStart >= lcol[1] && e.range.columnStart <= rcol[1] && e.range.rowStart >= trow[1] && e.range.rowStart <= brow[1] && e.value == 'TRUE') {
    let vs = sh.getRange(trow[1], lcol[1], brow[1] - trow[1] + 1, rcol[1] - lcol[1] + 1).getValues();
    let rc = vs[e.range.rowStart - trow[1]].filter(e =>return e).reduce((a, v) => { if (v) return (a + 1); }, 0);
    if (rc > mcpr[1]) { e.range.setValue("FALSE"); e.source.toast('Sorry maximum checks per row is ' + mcpr[1]); };
    let cc = vs.map((r, i) => { return r[e.range.columnStart - lcol[1]] }).filter(e =>return e;).reduce((a, v) => { if (v) return a + 1; });
    if (cc > mcpc[1]) { e.range.setValue('FALSE'); e.source.toast('Sorry maximum checks per column is ' + mcpc[1]) };
    }
  }
}