我的电子表格中有很多工作表(sheet1,sheet2,sheet3 ...),我想将它们全部添加到数组中,也许基于任何调用范围?现在,我手动添加它们,如下所示:
=query(
{
INDIRECT("sheet1!$A$3:$V");
INDIRECT("sheet2!$A$3:$V");
INDIRECT("sheet3!$A$3:$V") };
"SELECT Col2, Col3, Col4, ...[etc]")
我要创建任何“设置”工作表,并将所有应放在数组中的工作表放在此处,如下所示:
=query(
{
get_all_sheets_names_from('settings!A1:A100'); // something like this
};
"SELECT Col2, Col3, Col4, ...[etc]")
有可能吗?
答案 0 :(得分:2)
我认为不可能在查询参数中使用“ INDIRECT”,因为“ INDIRECT”返回一个单元格引用和参数{(); ()}是固定对象。
出于相同的原因,也无法对完整查询使用“间接”查询:查询不会在单元格上返回引用。
原理:case1:在G列的第三行(第三个来源)中查看,如果为空,则测试案例2,否则将公式应用于三个来源。
情况2:如果第二个来源为空,则转到情况1,否则将公式应用于两个来源
情况1:如果为空,则显示“无来源”,否则将公式应用于1个来源
请注意1 用 ISBLANK (eng)代替ESTVIDE (fr)!
注意2:您可以使用(G2 =“ source1”和G3 =“ source2)进行测试,
但可与G2 =“ source3”和G3 =“ source1”
=SI(ESTVIDE($G$4); SI(ESTVIDE($G$3); SI(ESTVIDE($G$1); "no source(s)";query({((INDIRECT("'"&G2&"'!A1:A5")))};"SELECT Col1")) ;query({(INDIRECT("'"&G2&"'!A1:A5"));(INDIRECT("'"&G3&"'!A1:A5"))};"SELECT Col1")) ;query({(INDIRECT("'"&G2&"'!A1:A5"));(INDIRECT("'"&G3&"'!A1:A5"));(INDIRECT("'"&G4&"'!A1:A5"))};"SELECT Col1"))
https://docs.google.com/spreadsheets/d/1sCwwFjpYKKzzAvVwmbMUWcmHSc1wY52XnHlFdT00A3U/edit?usp=sharing
当然,这是一个最多包含3个来源的公式! 它将有更多资源,而且非常庞大……
宏是唯一的解决方案?
附加此脚本,
它从G2:G30获取值源值(您还需要更多...放入G100 ..)
它创建公式并将其放在H2上
它读取每个源中的最大50值(请参见源代码中的A1:A50)
并不难理解,
注意:使用GSheet管理宏是另一个问题,如果您需要建议,请发表评论。
链接到活动表: https://docs.google.com/spreadsheets/d/14XaR-UsADUpCUCVWqeg0zCbfGy3CCvnwVxUhozjYocc/edit?usp=sharing
function formula6() {
var spreadsheet = SpreadsheetApp.getActive();
var values=spreadsheet.getRange('G2:G30').getValues();
var acSources="{";
for (var i = 0; (i < values.length) && (values[i]!=""); i++) {
if (i>0) { acSources+=";" }
acSources=acSources+'INDIRECT("'+values[i]+'!A1:A50")';
}
acSources=acSources+"}";
var formula='query('+acSources+';"SELECT Col1")';
spreadsheet.getRange('H2').activate();
spreadsheet.getCurrentCell().setFormula('='+formula);
};
答案 1 :(得分:1)
将INDIRECT
函数粘贴到Google表格中的家伙完全无法理解它的潜力,因此他们不遗余力地对其进行了改进,并涵盖了在这个数组时代至关重要的显而易见的逻辑。 / p>
换句话说,INDIRECT
不能摄取多个数组:
=INDIRECT("Sheet1!A:B"; "Sheet2!A:B")
也不会将数组化的字符串转换为活动引用,这意味着任何串联尝试都将是徒劳的:
=INDIRECT(MasterSheet!A1:A10)
————————————————————————————————————————————————————————————————————————————————————
=INDIRECT("{Sheet1!A:B; Sheet2!A:B}")
————————————————————————————————————————————————————————————————————————————————————
={INDIRECT("Sheet1!A:B"; "Sheet2!A:B")}
————————————————————————————————————————————————————————————————————————————————————
=INDIRECT("{INDIRECT("Sheet1!A:B"); INDIRECT("Sheet2!A:B")}")
唯一可能的方法是在每个范围的每个末端使用INDIRECT
,例如:
={INDIRECT("Sheet1!A:B"); INDIRECT("Sheet2!A:B")}
这意味着您最好的办法是预编程这样的数组,如果只有部分工作表/选项卡存在(让我们假设从一个工作表仅创建2个工作表的情况)总共4个):
=QUERY(
{IFERROR(INDIRECT("Sheet1!A1:B5"), {"",""});
IFERROR(INDIRECT("Sheet2!A1:B5"), {"",""});
IFERROR(INDIRECT("Sheet3!A1:B5"), {"",""});
IFERROR(INDIRECT("Sheet4!A1:B5"), {"",""})},
"where Col1 is not null", 0)
因此,即使工作表名称是可预测的(并非总是如此),这样预编程100多个工作表也会很痛苦(即使有各种偷偷摸摸的方法如何在30秒内编写这样的公式)
一种替代方法是使用脚本转换字符串并将其作为公式注入
A1是创建类似于真实公式的字符串的公式:
=ARRAYFORMULA("=QUERY({"&TEXTJOIN("; "; 1;
FILTER(SNAME(1); SNAME(1)<>SNAME(0))&"!A1:A20")&"}; ""where Col1 is not null""; 0)")
然后该脚本将从A1单元格中获取字符串,并将其作为有效公式粘贴到A2单元格中:
function onEdit() {
var sheet = SpreadsheetApp.getActive().getSheetByName('query'); // MASTER SHEET NAME
var src = sheet.getRange("A1"); // COPY STRING FROM
var str = src.getValue();
var cell = sheet.getRange("A2"); // PASTE AS FORMULA INTO
cell.setFormula(str);
}
function SNAME(option) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet()
var thisSheet = sheet.getName();
if(option === 0){ // ACTIVE SHEET NAME =SNAME(0)
return thisSheet;
}else if(option === 1){ // ALL SHEET NAMES =SNAME(1)
var sheetList = [];
ss.getSheets().forEach(function(val){
sheetList.push(val.getName())
});
return sheetList;
}else if(option === 2){ // SPREADSHEET NAME =SNAME(2)
return ss.getName();
}else{
return "#N/A"; // ERROR MESSAGE
};
}
当然,可以将脚本更改为onOpen触发器,或者使用自定义菜单或通过按钮触发的自定义名称(但是无法直接将自定义函数用作公式)
这将满足您的所有需要,即在添加新工作表时不添加参考即可编辑公式。唯一的缺点是要重新计算工作表名称脚本...为此,您需要拆除A1公式,例如,在前导'
之前按回车键之前添加=
,然后将其删除以修复公式< / p>