如何使用公式或脚本将序数添加到 Google 工作表中水平非连续范围内设置的值?编辑地址功能
How To Add The Ordinal Count To Values Set In Horizontal Non-Contiguous Ranges In Google Sheets With A Formula Or A Script? EDIT ADDRESS FUNCTION
问题:
我正在尝试将每个序号引用添加到每个值上方每个单元格中的一组重复值。
值按水平和非连续顺序排列。
我在下面展示的插图示例出于测试目的很简单,但最终用途应该是数百个 values/ranges,因此最好使用脚本或我找到的公式的简化版本.
插图示例:
其他相关问题及解决方案:
我发现该问题和答案解决的是同一个问题,但针对垂直和连续值使用以下公式作为解决方案:
=COUNTIF(A:A1,A1)
=COUNTIF(A:A1,A1)&MID("thstndrdth",MIN(9,2*RIGHT(COUNTIF(A:A1,A1))*(MOD(COUNTIF(A:A1,A1)-11,100)>2)+1),2)
Calculate ordinal number of replicates
到目前为止我的公式:
=TRANSPOSE(INDIRECT($P&(SUM(Q21))&":"&$P&(SUM(Q21,I22)-1)))
=TRANSPOSE(INDIRECT($P&(SUM(Q21,I22))&":"&$P&(SUM(Q21,I22,I26)-1)))
=TRANSPOSE(INDIRECT($P&(SUM(Q21,I22,I26))&":"&$P&(SUM(Q21,I22,I26,I30)-1)))
我使用上面的公式,需要将它复制粘贴到每个水平范围的第一个单元格正上方的单元格中。
我需要引用 SUM
函数部分中的每个单元格,因为电子表格将充当模板,每次都有不同的新数据集。
因此,单元格需要 return 以某种动态方式输出(不能对其进行硬编码)。
公式问题是,随着我们达到新的范围,它需要越来越多的单元格引用。由于要添加到 SUM
函数的内联单元格不断增加,因此很难获得数百个水平范围。
它也容易出错。如果之后添加行或列,它可能会中断。
试验:
我本来没想过使用INDIRECT函数(以前从来不需要)。但我不知道其他 Google Sheet 函数能够以更简单的方式实现最终结果。
问题:
对于公式解决方案,您建议如何避免使用 SUM
函数方法来获得相同的结果?
对于公式,有什么比 INDIRECT
and/or SUM
更简单的函数更有效?
我也考虑过使用脚本来做到这一点,但我无法将整个想法放入可管理的脚本概念过程中。如果脚本更合适,您有什么建议?
非常感谢您的帮助!
样本Sheet:
编辑:
我刚刚从 Player0 的回答中找到了 ADDRESS
函数(有助于大大简化 INDIRECT 函数的行和列引用):
参考文献:
我能够创建一个脚本来显示重复的序号,但只对应一个范围。 编辑: 我已将其修改为也接受多个行范围。请参阅下面的更新答案:
脚本:
function showOrdinal(range) {
range = "A4:E12";
var values = SpreadsheetApp.getActiveSheet().getRange(range).getValues();
var output = [];
var order, subTotal;
values.forEach((x, i) => {
if(x.flat().filter(String).length) {
subTotal = values.slice(0, i + 1).flat().filter(String);
order = x.filter(String);
if (order[0] != '-') {
var row = order.map(x => {
return getNumberWithOrdinal(subTotal.filter(e => e == x).length);
})
row = [...row, ...Array(x.length - row.length)];
output.push(row);
if(output.length > 2)
output.splice(output.length - 2, 1);
}
order = [...order, ...Array(x.length - order.length)];
output.push(order)
}
else
output.push(x);
});
// console.log(output);
SpreadsheetApp.getActiveSheet().getRange(3, 21, output.length, output[0].length).setValues(output);
// return output;
}
// get ordinal number
//
function getNumberWithOrdinal(n) {
var s = ["th", "st", "nd", "rd"],
v = n % 100;
return n + (s[(v - 20) % 10] || s[v] || s[0]);
}
输出:
注:
- 要传递的范围假定第一行应该是第一个范围,而不是空白。范围的最后一行也应该包含数据的最后一行。
- 任何不相关的数据都应在第一列以
-
开头,这样就可以允许不处理它。
问题:
我正在尝试将每个序号引用添加到每个值上方每个单元格中的一组重复值。
值按水平和非连续顺序排列。
我在下面展示的插图示例出于测试目的很简单,但最终用途应该是数百个 values/ranges,因此最好使用脚本或我找到的公式的简化版本.
插图示例:
其他相关问题及解决方案:
我发现该问题和答案解决的是同一个问题,但针对垂直和连续值使用以下公式作为解决方案:
=COUNTIF(A:A1,A1)
=COUNTIF(A:A1,A1)&MID("thstndrdth",MIN(9,2*RIGHT(COUNTIF(A:A1,A1))*(MOD(COUNTIF(A:A1,A1)-11,100)>2)+1),2)
Calculate ordinal number of replicates
到目前为止我的公式:
=TRANSPOSE(INDIRECT($P&(SUM(Q21))&":"&$P&(SUM(Q21,I22)-1)))
=TRANSPOSE(INDIRECT($P&(SUM(Q21,I22))&":"&$P&(SUM(Q21,I22,I26)-1)))
=TRANSPOSE(INDIRECT($P&(SUM(Q21,I22,I26))&":"&$P&(SUM(Q21,I22,I26,I30)-1)))
我使用上面的公式,需要将它复制粘贴到每个水平范围的第一个单元格正上方的单元格中。
我需要引用 SUM
函数部分中的每个单元格,因为电子表格将充当模板,每次都有不同的新数据集。
因此,单元格需要 return 以某种动态方式输出(不能对其进行硬编码)。
公式问题是,随着我们达到新的范围,它需要越来越多的单元格引用。由于要添加到 SUM
函数的内联单元格不断增加,因此很难获得数百个水平范围。
它也容易出错。如果之后添加行或列,它可能会中断。
试验:
我本来没想过使用INDIRECT函数(以前从来不需要)。但我不知道其他 Google Sheet 函数能够以更简单的方式实现最终结果。
问题:
对于公式解决方案,您建议如何避免使用 SUM
函数方法来获得相同的结果?
对于公式,有什么比 INDIRECT
and/or SUM
更简单的函数更有效?
我也考虑过使用脚本来做到这一点,但我无法将整个想法放入可管理的脚本概念过程中。如果脚本更合适,您有什么建议?
非常感谢您的帮助!
样本Sheet:
编辑:
我刚刚从 Player0 的回答中找到了 ADDRESS
函数(有助于大大简化 INDIRECT 函数的行和列引用):
参考文献:
我能够创建一个脚本来显示重复的序号,但只对应一个范围。 编辑: 我已将其修改为也接受多个行范围。请参阅下面的更新答案:
脚本:
function showOrdinal(range) {
range = "A4:E12";
var values = SpreadsheetApp.getActiveSheet().getRange(range).getValues();
var output = [];
var order, subTotal;
values.forEach((x, i) => {
if(x.flat().filter(String).length) {
subTotal = values.slice(0, i + 1).flat().filter(String);
order = x.filter(String);
if (order[0] != '-') {
var row = order.map(x => {
return getNumberWithOrdinal(subTotal.filter(e => e == x).length);
})
row = [...row, ...Array(x.length - row.length)];
output.push(row);
if(output.length > 2)
output.splice(output.length - 2, 1);
}
order = [...order, ...Array(x.length - order.length)];
output.push(order)
}
else
output.push(x);
});
// console.log(output);
SpreadsheetApp.getActiveSheet().getRange(3, 21, output.length, output[0].length).setValues(output);
// return output;
}
// get ordinal number
//
function getNumberWithOrdinal(n) {
var s = ["th", "st", "nd", "rd"],
v = n % 100;
return n + (s[(v - 20) % 10] || s[v] || s[0]);
}
输出:
注:
- 要传递的范围假定第一行应该是第一个范围,而不是空白。范围的最后一行也应该包含数据的最后一行。
- 任何不相关的数据都应在第一列以
-
开头,这样就可以允许不处理它。