在 Google 脚本中反转复选框的最佳方法?
The most optimal way to invert checkboxes in Google Script?
因为 Google 脚本不支持单选按钮,我尝试创建一个解决方法。虽然我已经学习了 Python 的基础知识,但我是 Javascript/Google Sctipt 的新手。我终于让我的代码工作了,但我觉得对于这样一个简单的任务来说结果太笨拙了。如何优化?
这是工作示例:https://docs.google.com/spreadsheets/d/1bcMj3Yxewo4ZUgnhg0z46NyqJYBfxm-6ocvmEHLwtWE/edit?usp=sharing
这是我的代码:
const ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
function onEdit(e) {
var invertedRange = { // C4:D5 is the range to follow
top : 4,
bottom : 5,
left : 3,
right : 4
}
var thisRow = e.range.getRow();
var thisCol = e.range.getColumn();
// Invert the checkboxes in the range
if (thisRow <= invertedRange.bottom && thisRow >= invertedRange.top) {
if (thisCol <= invertedRange.right && thisCol >= invertedRange.left) {
var changeArray = ss.getRange(invertedRange.top, invertedRange.left, 2, 2).getValues();
var invertedArray = [];
var rPos = 0; // first row of the 2x2 matrix
var valueToAdd = true;
for (var readRow = invertedRange.top; readRow <= invertedRange.bottom; readRow = readRow + 1) {
var cPos = 0; // first column of the 2x2 matrix
var invertedPart = [];
for (var readCol = invertedRange.left; readCol <= invertedRange.right; readCol = readCol + 1) {
if (thisRow == readRow && thisCol == readCol) {
var valueToAdd = changeArray[rPos][cPos]; // do not invert the checkbox that was already manually changed by user edit
} else {
var valueToAdd = !changeArray[rPos][cPos]; // invert all other checkboxes in the range
}
var invertedPart = invertedPart.concat(valueToAdd); // create an array from a pair of checkbox values
cPos = cPos + 1;
}
invertedArray[rPos]=invertedPart; // add the pairs into an array
rPos = rPos + 1;
}
ss.getRange(invertedRange.top, invertedRange.left, 2, 2).setValues(invertedArray); // set the chackbox values
} return;
}
}
提供复选框单选组行为
此 onEdit 函数为任何范围提供单选按钮组行为。您需要通过设置 cbrg 的值和 selecting 您希望组在行或列中的方向来输入 A1 表示法中的范围。单击它会将您 select 所在行或列中的所有其他单元格设置为 true。它不支持 true 或 false 以外的验证值。
function onEdit(e) {
//e.source.toast('Entry');
const sh = e.range.getSheet();
const group = 'col';//change which direction that you wish to group in
const cbrg = "C4:D5";//specifying the range the starting column and row must be greater than one.
const rg = sh.getRange(cbrg);
const w = rg.getWidth();
const h = rg.getHeight();
const cs = rg.getColumn();
const ce = cs + w - 1;
const rs = rg.getRow();
const re = rs + h - 1;
//console.log('rs:%s,re:%s,cs:%s,ce:%s', rs, re, cs, ce);
if (sh.getName() == 'Sheet1' && e.range.columnStart > cs - 1 && e.range.columnStart < ce + 1 && e.range.rowStart > rs - 1 && e.range.rowStart < re + 1 && e.value == 'TRUE') {
if (group == 'row') {
//e.source.toast('row');
let cA = new Array(w).fill(false);
cA[e.range.columnStart - cs] = true;
sh.getRange(e.range.rowStart, cs, 1, cA.length).setValues([cA]);
}
if (group == 'col') {
//e.source.toast('col');
let idx = e.range.rowStart - rs;
let cA = [];
for (let i = 0; i < h; i++) {
if (i == idx) cA.push([true]);
else cA.push([false]);
}
sh.getRange(rs, e.range.columnStart, cA.length, 1).setValues(cA);
}
}
}
下面的执行速度稍快,只需设置顶行 (trow)、底行 (brow)、左列 (lcol)、右列 (rcol) 和单选组方向即可 'row' 或 'col'。它需要的函数调用少得多,但耗时。
function onEdit(e) {
//e.source.toast('Entry');
const sh = e.range.getSheet();
const trow=4;//top row
const brow=5;//bottom row
const lcol=3;//left column
const rcol=4;//right column
const group = 'row';//change which direction that you wish to group in
//console.log('trow:%s,brow:%s,lcol:%s,rcol:%s', trow, brow, lcol, rcol);
if (sh.getName() == 'Sheet1' && e.range.columnStart >= lcol && e.range.columnStart <= rcol && e.range.rowStart >= trow && e.range.rowStart <= brow && e.value == 'TRUE') {
if (group == 'row') {
//e.source.toast('row');
let cA = new Array(rcol-lcol+1).fill(false);
cA[e.range.columnStart - lcol] = true;
sh.getRange(e.range.rowStart, lcol, 1, cA.length).setValues([cA]);
}
if (group == 'col') {
//e.source.toast('col');
let idx = e.range.rowStart - trow;
let cA = [];
for (let i = 0; i < brow-trow+1; i++) {
if (i == idx) cA.push([true]);
else cA.push([false]);
}
sh.getRange(trow, e.range.columnStart, cA.length, 1).setValues(cA);
}
}
}
动画:
我更改了动画的范围,以便将其放入尽可能小的图像中。
因为 Google 脚本不支持单选按钮,我尝试创建一个解决方法。虽然我已经学习了 Python 的基础知识,但我是 Javascript/Google Sctipt 的新手。我终于让我的代码工作了,但我觉得对于这样一个简单的任务来说结果太笨拙了。如何优化?
这是工作示例:https://docs.google.com/spreadsheets/d/1bcMj3Yxewo4ZUgnhg0z46NyqJYBfxm-6ocvmEHLwtWE/edit?usp=sharing
这是我的代码:
const ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
function onEdit(e) {
var invertedRange = { // C4:D5 is the range to follow
top : 4,
bottom : 5,
left : 3,
right : 4
}
var thisRow = e.range.getRow();
var thisCol = e.range.getColumn();
// Invert the checkboxes in the range
if (thisRow <= invertedRange.bottom && thisRow >= invertedRange.top) {
if (thisCol <= invertedRange.right && thisCol >= invertedRange.left) {
var changeArray = ss.getRange(invertedRange.top, invertedRange.left, 2, 2).getValues();
var invertedArray = [];
var rPos = 0; // first row of the 2x2 matrix
var valueToAdd = true;
for (var readRow = invertedRange.top; readRow <= invertedRange.bottom; readRow = readRow + 1) {
var cPos = 0; // first column of the 2x2 matrix
var invertedPart = [];
for (var readCol = invertedRange.left; readCol <= invertedRange.right; readCol = readCol + 1) {
if (thisRow == readRow && thisCol == readCol) {
var valueToAdd = changeArray[rPos][cPos]; // do not invert the checkbox that was already manually changed by user edit
} else {
var valueToAdd = !changeArray[rPos][cPos]; // invert all other checkboxes in the range
}
var invertedPart = invertedPart.concat(valueToAdd); // create an array from a pair of checkbox values
cPos = cPos + 1;
}
invertedArray[rPos]=invertedPart; // add the pairs into an array
rPos = rPos + 1;
}
ss.getRange(invertedRange.top, invertedRange.left, 2, 2).setValues(invertedArray); // set the chackbox values
} return;
}
}
提供复选框单选组行为
此 onEdit 函数为任何范围提供单选按钮组行为。您需要通过设置 cbrg 的值和 selecting 您希望组在行或列中的方向来输入 A1 表示法中的范围。单击它会将您 select 所在行或列中的所有其他单元格设置为 true。它不支持 true 或 false 以外的验证值。
function onEdit(e) {
//e.source.toast('Entry');
const sh = e.range.getSheet();
const group = 'col';//change which direction that you wish to group in
const cbrg = "C4:D5";//specifying the range the starting column and row must be greater than one.
const rg = sh.getRange(cbrg);
const w = rg.getWidth();
const h = rg.getHeight();
const cs = rg.getColumn();
const ce = cs + w - 1;
const rs = rg.getRow();
const re = rs + h - 1;
//console.log('rs:%s,re:%s,cs:%s,ce:%s', rs, re, cs, ce);
if (sh.getName() == 'Sheet1' && e.range.columnStart > cs - 1 && e.range.columnStart < ce + 1 && e.range.rowStart > rs - 1 && e.range.rowStart < re + 1 && e.value == 'TRUE') {
if (group == 'row') {
//e.source.toast('row');
let cA = new Array(w).fill(false);
cA[e.range.columnStart - cs] = true;
sh.getRange(e.range.rowStart, cs, 1, cA.length).setValues([cA]);
}
if (group == 'col') {
//e.source.toast('col');
let idx = e.range.rowStart - rs;
let cA = [];
for (let i = 0; i < h; i++) {
if (i == idx) cA.push([true]);
else cA.push([false]);
}
sh.getRange(rs, e.range.columnStart, cA.length, 1).setValues(cA);
}
}
}
下面的执行速度稍快,只需设置顶行 (trow)、底行 (brow)、左列 (lcol)、右列 (rcol) 和单选组方向即可 'row' 或 'col'。它需要的函数调用少得多,但耗时。
function onEdit(e) {
//e.source.toast('Entry');
const sh = e.range.getSheet();
const trow=4;//top row
const brow=5;//bottom row
const lcol=3;//left column
const rcol=4;//right column
const group = 'row';//change which direction that you wish to group in
//console.log('trow:%s,brow:%s,lcol:%s,rcol:%s', trow, brow, lcol, rcol);
if (sh.getName() == 'Sheet1' && e.range.columnStart >= lcol && e.range.columnStart <= rcol && e.range.rowStart >= trow && e.range.rowStart <= brow && e.value == 'TRUE') {
if (group == 'row') {
//e.source.toast('row');
let cA = new Array(rcol-lcol+1).fill(false);
cA[e.range.columnStart - lcol] = true;
sh.getRange(e.range.rowStart, lcol, 1, cA.length).setValues([cA]);
}
if (group == 'col') {
//e.source.toast('col');
let idx = e.range.rowStart - trow;
let cA = [];
for (let i = 0; i < brow-trow+1; i++) {
if (i == idx) cA.push([true]);
else cA.push([false]);
}
sh.getRange(trow, e.range.columnStart, cA.length, 1).setValues(cA);
}
}
}
动画:
我更改了动画的范围,以便将其放入尽可能小的图像中。