首先,这是我正在讨论的两个基本电子表格:
第一页:https://docs.google.com/spreadsheets/d/1GZs_I9_beIO9xYBXatoxStRMmk9Aj3-UxPQpB9-iA-I/edit?usp=sharing
第二页:https://docs.google.com/spreadsheets/d/1R86_0SrAtyIJPAhMW0Ura-3gwOLn5l9u7Seuj2V0YCA/edit?usp=sharing
基本上我使用Google脚本来“更新”标题为“要更新的副本”的电子表格。此副本将自动复制“复制到从中提取更新”中的所有页面,删除“要更新的副本”上的当前页面,然后将复制的页面重命名为之前的页面。这意味着我对“从中提取更新的副本”所做的任何更改都将自动在其他电子表格中更新,而无需重新分发电子表格。
当在“更新页面”表单上按下按钮时,页面成功传输。更新电子表格上的更改已成功“更新”。但是,代码中首先更新的页面有错误。具有从另一张纸张获取数据的公式的任何单元格都会返回“#REF!”错误“未解析的工作表名称'在此处插入工作表名称'。”这意味着公式/单元格无法从脚本中看到新复制的工作表。我可以通过点击受此影响的任何细胞并按下输入来解决这种情况 - 基本上“刷新”细胞。但是我在一个100多个像这样的单元格的项目中这样做,我只想按一个按钮就可以做到这一点。
我应该尝试使用脚本解决此问题,还是以不同的方式更改我更新电子表格页面的方法?感谢提前帮助!
以下是我正在使用的脚本:
<code>
function Update() {
//Sets the ID of the page to update from
var ID = "1R86_0SrAtyIJPAhMW0Ura-3gwOLn5l9u7Seuj2V0YCA"
//Pulls the correct sheet using the ID
var source = SpreadsheetApp.openById(ID);
//Identifies the active spreadsheet in use to update. (The spreadsheet you pressed "Update" on)
var destination = SpreadsheetApp.getActiveSpreadsheet();
//Sheet to pull and copy to the current spreadsheet
var sheet1 = source.getSheetByName("1");
//Copying the sheet accross
sheet1.copyTo(destination);
//Identifies the old copy of the sheet
var sheet1 = destination.getSheetByName('1');
//Deletes the old copy of the sheet
destination.deleteSheet(sheet1);
//Gets the new copy of the sheet
var sheet1 = destination.getSheetByName('Copy of 1');
//Renames the new copy of the sheet
sheet1.setName("1")
//Repeating the same code with page 2
//Sheet to pull and copy to the current spreadsheet
var sheet1 = source.getSheetByName("2");
//Copying the sheet accross
sheet1.copyTo(destination);
//Identifies the old copy of the sheet
var sheet1 = destination.getSheetByName('2');
//Deletes the old copy of the sheet
destination.deleteSheet(sheet1);
//Gets the new copy of the sheet
var sheet1 = destination.getSheetByName('Copy of 2');
//Renames the new copy of the sheet
sheet1.setName("2")
//Repeating the same code
}
</code>
答案 0 :(得分:1)
这与Force formula refresh through Apps Script
有关我有完全相同的问题。我的大多数公式都是第一行或第二行中的=ArrayFormula
公式。我的解决方案遍历给定电子表格的前两行中的所有单元格,并重新评估任何公式。
如果它是一个公式(而不是重置非公式的文本值),这可能会被清理为仅修改单元格。也可以通过更改指定的范围来修改它以在整个电子表格上运行。
您可以在工作表复制到新位置后在工作表上运行此功能,也可以在所需工作表处于活动状态时调用myFunction
。
function updateFormulasTwoRows(given_sheet) {
var last_col = given_sheet.getDataRange().getLastColumn();
var range = given_sheet.getRange(1,1,2,last_col);
// contains empty strings or cell formulas
var formulas = range.getFormulas();
// contains text, formula errors, formula output
var contents = range.getValues();
// formulas[0][0].length > 1 ==> is a formula
for (var r = 0; r < range.getHeight(); r++) {
for (var c = 0; c < range.getWidth(); c++) {
var cell = range.getCell(r+1,c+1);
// clear only the contents, not notes or comments or formatting.
cell.clearContent();
if (formulas[r][c].length > 1) {
// cell was a formula, so insert the formula back in place
cell.setValue(formulas[r][c]);
} else {
// cell was not a formula, so insert the text content back in place
cell.setValue(contents[r][c]);
}
}
}
}
// run this after selecting a sheet to reevalute formulas on
function myFunction() {
var curr_sheet = SpreadsheetApp.getActiveSheet();
updateFormulasTwoRows(curr_sheet);
}
答案 1 :(得分:0)
在上面@bryan的答案的基础上,我发现下面的代码更有效,它在范围级别而不是在每个单元格上执行clearContent()
和setValue()
调用,从而节省了对后端的大量呼叫。
var updateFormulasAllRows = function updateFormulasAllRows(sheet) {
var range = sheet.getDataRange();
var formulas = range.getFormulas();
var contents = range.getValues();
var rangeWidth = range.getWidth(), rangeHeight = range.getHeight();
for (var r = 0; r < rangeHeight; r++) {
for (var c = 0; c < rangeWidth; c++) {
if (formulas[r][c].length > 1) {
contents[r][c] = formulas[r][c];
}
}
}
range.clearContent().setValues(contents);
};
作为改进建议,这还会更改代码以使其可以在电子表格的所有行上运行。