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:H225
、H228:H335
和 H340:H347
。
- 您想限制在每个范围内选中复选框的数量。
- 例如
H219:H225
、H228:H335
、H340:H347
分别有1、3、2的限制。
- 您想使用 Google Apps 脚本实现此目的。
在这种情况下,为了实现您的目标,我想提出一个使用包含范围和限制的数组的示例脚本。该脚本由 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 简单触发器创建的。所以当你直接用脚本编辑器运行脚本时,就会出现错误。请注意这一点。
参考文献:
我想知道你是否可以做这样的事情:
您可以为每个范围添加一个新部分 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]) };
}
}
}
我有一个 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:H225
、H228:H335
和H340:H347
。 - 您想限制在每个范围内选中复选框的数量。
- 例如
H219:H225
、H228:H335
、H340:H347
分别有1、3、2的限制。 - 您想使用 Google Apps 脚本实现此目的。
在这种情况下,为了实现您的目标,我想提出一个使用包含范围和限制的数组的示例脚本。该脚本由 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 简单触发器创建的。所以当你直接用脚本编辑器运行脚本时,就会出现错误。请注意这一点。
参考文献:
我想知道你是否可以做这样的事情: 您可以为每个范围添加一个新部分 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]) };
}
}
}