Google apps script Google Sheets允许不同数量的复选框

Google apps script Google Sheets允许不同数量的复选框,google-apps-script,google-sheets,checkbox,Google Apps Script,Google Sheets,Checkbox,我有一张表格,我需要在一个范围内限制允许的复选框数量。像这样 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

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

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);};          
    }
  }
}
函数onEdit(e){
const sh=e.range.getSheet();
如果(sh.getName()=='GOALS'){
常数mcpr=1;
常数mcpc=2;
常数arrayrange='h219:h225';
常量arg=sh.getRange(arrayrange);
const avs=arg.getValues();
常量ulr=arg.getRow();
常量ulc=arg.getColumn();
常量lrr=ulr+arg.getHeight()-1;
常量lrc=ulc+arg.getWidth()-1;
if(e.range.columnStartmcpc){e.range.setValue('FALSE');e.source.toast('Sorry每个列的最大检查数为'+mcpc);};
}
}
}
//

函数onEdit(e){
const sh=e.range.getSheet();
如果(sh.getName()=='GOALS'){
常数mcpr=1;
常数mcpc=3;
常数arrayrange='h236:h244';
常量arg=sh.getRange(arrayrange);
const avs=arg.getValues();
常量ulr=arg.getRow();
常量ulc=arg.getColumn();
常量lrr=ulr+arg.getHeight()-1;
常量lrc=ulc+arg.getWidth()-1;
if(e.range.columnStartmcpc){e.range.setValue('FALSE');e.source.toast('Sorry每个列的最大检查数为'+mcpc);};
}
}
}

非常感谢,我已经搜索了很多地方,这是我能找到的最好的脚本,我只需要它在同一张表中的大约6个位置工作,每个范围允许不同数量的复选框。

我相信您当前的情况和目标如下

  • 您有一个谷歌电子表格,其中复选框放在单元格
    H219:H225
    H228:H335
    H340:H347
  • 您希望对每个范围中的复选框的选中数量进行限制
  • 例如,
    H219:H225
    H228:H335
    H340:H347
    分别具有1、3和2的限制
  • 您希望使用谷歌应用程序脚本实现这一点
在本例中,为了实现您的目标,我想提出一个使用数组的示例脚本,其中包括范围和限制。脚本由OnEdit简单触发器运行

示例脚本: 请将以下脚本复制粘贴到Google电子表格的脚本编辑器中,并设置
obj
sheetName
的变量,然后保存。使用此脚本时,请选中范围
H219:H225
H228:H335
H340: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(e){
//请设置范围和限制。
常量对象=[
{范围:“H219:H225”,限值:1},
{范围:“H228:H335”,限值:3},
{范围:“H340:H347”,限制:2},
];
const sheetName=“Sheet1”//请设置工作表的工作表名称,包括复选框。
常数范围=e范围;
const editedColumn=range.getColumn();
const editedRow=range.getRow();
const sheet=range.getSheet();
如果(sheet.getSheetName()!=sheetName)返回;
对象forEach(({range},i)=>{
常数温度=表getRange(范围);
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(设i=0;i=obj[i]。startRow&&editedRow=obj[i]。startColumn&&editedColumn h==true)。长度;
如果(n==obj[i]。极限+1){
range.uncheck();
//Browser.msgBox(“选中的复选框数超出限制”);//如果要打开对话框,可以使用此选项。
}否则,如果(n>obj[i]。限制+1){
Browser.msgBox(“现有复选框的选中复选框已超过限制数量”+obj[i].limit);
}
打破
}
}
}
结果: 使用上述脚本时,将获得以下结果

注:
  • 此示例脚本由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]) };
          }
        }
      }
      
      函数onEdit(e){
      const sh=e.range.getSheet();
      常量trow=[236];
      const-brow=[244];
      常数lcol=[8];
      常数rcol=[8];
      常数mcpr=[1];
      常数mcpc=[3];
      如果(sh.getName()=='GOALS'&&e.range.columnStart>=lcol[0]&&e.range.columnStart=trow[0]&&e.range.rowStart返回e.reduce((a,v)=>{if(v)返回(a+1);},0);
      如果(rc>mcpr[0]){e.range.setValue(“FALSE”);e.source.toast('Sorry每行的最大检查数为'+mcpr[0]);};
      让cc=vs.map((r,i)=>{return r[e.range.columnStart-lcol[0]]}).filter(e=>return e;).reduce((a,v)=>{if(v)return a+1;});
      如果(cc>mcpc[0]){e.range.setValue('FALSE');e.source.toast('Sorry,每列的最大检查数为'+mcpc[0]);
      如果(sh.getName()=='GOALS'&&e.range.columnStart>=lcol[1]&&e.range.columnStart=trow[1]&&e.range.rowStart返回e.reduce((a,v)=>{if(v)返回(a+1);},0);
      如果(rc>mcpr[1]){e.range.setValue(“FALSE”);e.source.toast('Sorry每行的最大检查数为'+mcpr[1]);};
      让cc=vs.map((r,i)=>{return r[e.range.columnStart-lcol[1]]}).filter(e=>return e;).reduce((a,v)=>{if(v)return a+1;});
      如果(cc>mcpc[1]){e.range.setValue('FALSE');e.source.toast('Sorry),则每列的最大检查数为'+m
      
      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]) };
          }
        }
      }