如何解决将公式设置为多个单元格脚本-必须有更有效的方法
在Google表格中,我想将以下内容应用于A2,A14,A26和A28,并将另一个公式应用于B2,B14,B26和B28。现在,我只做以下4次。可以,但是效果不佳。我如何才能更有效地做到这一点?
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
sheets[7].setName('.NCF');
var sheet = ss.getSheets()[5];
var cell1a = sheet.getRange("A2");
cell1a.setFormula("=iferror(IF(QUERY('.NCF'!A2,\"where A contains '1ST'\")<>\"\",1,),\"\")");
var cell1b = sheet.getRange("A14");
cell1a.setFormula("=iferror(IF(QUERY('.NCF'!A14,\"\")");
var cell1c = sheet.getRange("A26");
cell1c.setFormula("=iferror(IF(QUERY('.NCF'!A26,\"\")");
var cell1d = sheet.getRange("A38");
cell1d.setFormula("=iferror(IF(QUERY('.NCF'!A38,\"\")");
var cell2a = sheet.getRange("B2");
cell2a.setFormula("=iferror(if(A2=1,query('.NCF'!A:A,\"Select A where A contains '( G54.1P'\"),\"\"),\"\")");
var cell2b = sheet.getRange("B14");
cell2a.setFormula("=iferror(if(A14=2,\"\")");
var cell2c = sheet.getRange("B26");
cell2a.setFormula("=iferror(if(A26=3,\"\")");
var cell2d = sheet.getRange("B38");
cell2a.setFormula("=iferror(if(A38=4,\"\")");
}
解决方法
-
在行号和列字母上使用Array.forEach至loop。
-
使用template literals创建要设置的公式。
function onEdit(e) {
const ss = e.source;
const sheets = ss.getSheets();
sheets[7].setName('.NCF');
const sheet = sheets[5];
let a1;
['A','B'].forEach(column =>
[2,14,26,38].forEach((row,i) =>
sheet
.getRange((a1 = column + row))
.setFormula(
column === 'A'
? `=IFERROR(IF(QUERY('.NCF'!${a1},"WHERE A CONTAINS '1ST'")<>"",1,))`
: `=IFERROR(IF(A${row}=${i +
1},QUERY('.NCF'!A:A,"SELECT A WHERE A CONTAINS '( G54.1P'"),))`
)
)
);
}
另请参阅ternary operator。
,解决方案:
这是我的解决方案,基于与TheMaster答案相同的逻辑。
function onEdit(e) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheets = ss.getSheets();
sheets[7].setName('.NCF');
const sheet = ss.getSheets()[5];
const cells1 = ['A2','A14','A26','A38'];
const cells2 = ['B2','B14','B26','B38'];
cells1.forEach(c=>
sheet.getRange(c).setFormula(`iferror(IF(QUERY('.NCF'!${c},\"where A contains '1ST'\")<>\"\",),\"\")`)
)
cells2.forEach((c,i)=>
sheet.getRange(c).setFormula(`iferror(if(${cells1[i]}=${i+1},query('.NCF'!A:A,\"Select A where A contains '( G54.1P'\"),\"\"),\"\")`)
)
}
说明:
很显然,您要使用两个单元格序列和两个公式。这就是我使用cells1
和cells2
表示要分别应用公式1和2的单元格集的原因。您要调用此表达式:每个单元格都sheet.getRange().setFormula
,这就是为什么可以使用forEach
函数的原因。最后,我使用template literals将cells
表的元素合并到字符串参数中。
我的解决方案与其他解决方案之间的主要区别在于,我的forEach语句彼此之间没有链接,并且我不使用if语句。
,或者,您可以使用setValues
批量应用这些值,以获得更好的性能。如果在值前加上=
,则与设置公式本质上相同,因此,只能使用该方法设置值的事实无关紧要。
function onEdit(e) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheets = ss.getSheets();
sheets[7].setName('.NCF');
const [,sheet] = ss.getSheets();
const rng = sheet.getDataRange();
const vals = rng.getValues();
const formulas = rng.getFormulas();
const mixed = formulas.map((r,ri) => r.map((c,ci) => c || vals[ri][ci]));
const toFormula = [2,38].map(r => r - 1);
let formulaIdx = 1;
const newVals = mixed.map((row,ri) => {
if (!toFormula.includes(ri)) {
return row;
}
row[0] = `=iferror(IF(QUERY('.NCF'!A${ri+1},\"\")`;
row[1] = `iferror(if(A${ri + 1}=${formulaIdx++},\"\")`;
return row;
});
rng.setValues(newVals);
console.log(rng.getValues());
}
带有模拟的可运行代码段:
function Range(grid) {
return {
getFormulas() {
return grid.map(row => row.map(({
formula
}) => formula));
},setFormulas(formulas) {
grid.forEach((r,ri) => r.forEach((c,ci) => {
grid[ri][ci].formula = formulas[ri][ci];
}));
return this;
},setValues(values) {
grid.forEach((r,ci) => {
grid[ri][ci].value = values[ri][ci];
}));
return this;
},getValues() {
return grid.map(row => row.map(({
value
}) => value));
}
};
}
function Sheet(spreadsheet) {
/** @type {{ value }[][]} */
const grid = [];
let sheetName = "Sheet1";
return {
activate() {
spreadsheet.setActiveSheet(this);
return this;
},insertColumns(columnIndex,numColumns) {
grid.forEach(row => {
const cols = new Array(numColumns).fill("").map(() => ({
value: "",formula: ""
}));
row.splice(columnIndex,...cols);
});
return this;
},insertRows(rowIndex,numRows) {
const rows = new Array(numRows).fill("").map(() => [{
value: "",formula: ""
}]);
grid.splice(rowIndex,...rows);
return this;
},getLastRow() {
const {
length
} = grid;
return length;
},getLastColumn() {
const lengths = grid.map(({
length
}) => length);
return Math.max(...lengths);
},getDataRange() {
return Range(grid);
},getSheetName() {
return sheetName;
},setName(name) {
sheetName = name;
return this;
}
};
}
function Spreadsheet() {
const defaultSheet = Sheet(this);
const sheets = [defaultSheet];
let active = defaultSheet;
return {
getSheets() {
return sheets;
},getActiveSheet() {
return active;
},insertSheet(sheetIndex = 0) {
const sheet = Sheet(this);
sheets.splice(sheetIndex,sheet);
return sheet.activate();
},setActiveSheet(sheet) {
active = sheet;
return sheet;
}
};
}
var SpreadsheetApp = {
getActiveSpreadsheet() {
return Spreadsheet();
}
};
function onEdit(e) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
//prepare mock//
for (let i = 0; i < 8; i++) {
const sheet = ss.insertSheet();
sheet.insertRows(0,38);
sheet.insertColumns(0,2);
const rng = sheet.getDataRange();
const formulas = rng.getFormulas();
formulas[5][2] = "=true";
rng.setFormulas(formulas);
}
//end mock preparation//
const sheets = ss.getSheets();
sheets[7].setName('.NCF');
const [,\"\")`;
return row;
});
rng.setValues(newVals);
console.log(rng.getValues());
}
onEdit();
注释
- 您必须enable V8运行时才能使用摘要。
- 请注意,如果数据范围内有公式,则需要分别获取它们(使用
getFormulas
)并与值混合使用(请参阅mixed
变量的初始化方式)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。