在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, \"where A contains '1ST'\")<>\"\", 1, ),\"\")");
var cell1c = sheet.getRange("A26");
cell1c.setFormula("=iferror(IF(QUERY('.NCF'!A26, \"where A contains '1ST'\")<>\"\", 1, ),\"\")");
var cell1d = sheet.getRange("A38");
cell1d.setFormula("=iferror(IF(QUERY('.NCF'!A38, \"where A contains '1ST'\")<>\"\", 1, ),\"\")");
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,query('.NCF'!A:A,\"Select A where A contains '( G54.1P'\"),\"\"),\"\")");
var cell2c = sheet.getRange("B26");
cell2a.setFormula("=iferror(if(A26=3,query('.NCF'!A:A,\"Select A where A contains '( G54.1P'\"),\"\"),\"\")");
var cell2d = sheet.getRange("B38");
cell2a.setFormula("=iferror(if(A38=4,query('.NCF'!A:A,\"Select A where A contains '( G54.1P'\"),\"\"),\"\")");
}
答案 0 :(得分:2)
在行号和列字母上使用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。
答案 1 :(得分:1)
这是我的解决方案,基于与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'\")<>\"\", 1, ),\"\")`)
)
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语句。
答案 2 :(得分:1)
或者,您可以使用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, 14, 26, 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}, \"where A contains '1ST'\")<>\"\", 1, ),\"\")`;
row[1] = `iferror(if(A${ri + 1}=${formulaIdx++},query('.NCF'!A:A,\"Select A where A contains '( G54.1P'\"),\"\"),\"\")`;
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, ri) => r.forEach((c, 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, 0, ...cols);
});
return this;
},
insertRows(rowIndex, numRows) {
const rows = new Array(numRows).fill("").map(() => [{
value: "",
formula: ""
}]);
grid.splice(rowIndex, 0, ...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, 0, 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 [, , , , , 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, 14, 26, 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}, \"where A contains '1ST'\")<>\"\", 1, ),\"\")`;
row[1] = `iferror(if(A${ri + 1}=${formulaIdx++},query('.NCF'!A:A,\"Select A where A contains '( G54.1P'\"),\"\"),\"\")`;
return row;
});
rng.setValues(newVals);
console.log(rng.getValues());
}
onEdit();
注释
getFormulas
)并与值混合使用(请参阅mixed
变量的初始化方式)。