英文:
How to get an array of selected row numbers, agnostic of whether the selection is one row, multiple rows, or multiple non-contiguous rows?
问题
我只需要知道在函数运行时用户选择了哪些行。他们可能选择一个单元格,也可能拖动选择多个单元格,或者按住Ctrl键点击多个不相邻的单元格。
但是,无论是谁设计了Google Apps Script,似乎都决定我们没有一种一致的方法来实现这一点。
getActiveRangeList()
> 返回
> RangeList — 活动范围的列表。
>如果只选择了一个范围,这将表现为getActiveRange()的调用。
getActiveRange()
> 返回
> Range — 活动范围。
Range 对象具有以下方法:
> getRow() — 返回一个整数。
> getLastRow() — 返回一个整数。
> getNumRows() — 返回一个整数。
RangeList 对象具有以下方法:
> getRanges() — 返回包含每个单独范围的数组。
我花了几个小时阅读了几十篇关于范围的文章、论文和Stack Overflow的问题,显然没有一个人找到了如何做这个简单的事情的方法。
英文:
I just need to know which rows are in a user's selection when the function is run. They might select one cell, they might drag a selection across multiple cells, or they might ctrl+click multiple cells that aren't next to each other.
But whoever designed Google Apps Script seems to have decided that we're not going to have a consistent way of doing that.
getActiveRangeList()
> Return
> RangeList — The list of active ranges.
>If there is a single range selected, this behaves as a getActiveRange() call.
getActiveRange()
> Return
> Range — The active range.
Range objects have
> getRow() — Returns an integer.
> getLastRow() — Returns an integer.
> getNumRows() — Returns an integer.
RangeList objects have
> getRanges() — Returns an array containing each individual range.
I've spent hours reading dozens of articles, essays, and Stack Overflow questions about ranges, and apparently not a single one of them has figured out how to do this simple thing.
答案1
得分: 1
文档是错误的。
如果只有一个范围,getActiveRangeList()
不会像 getActiveRange()
一样运行。
getActiveRangeList().getRanges()
返回一个包含所有范围的数组。如果只有一个范围,那么数组中只有一个范围。
getActiveRange().getRanges()
会因为在这种情况下 getRanges()
不存在而导致错误。
因此,我们可以只使用 getActiveRangeList()
来处理所有可能的情况。
function rowChecker()
{
var active = SpreadsheetApp.getActiveRangeList().getRanges();
for(var n = 0; n < active.length; n++)
{
Logger.log(active[n].getRow());
Logger.log(active[n].getLastRow());
}
}
范围被找到的顺序似乎取决于它们被创建的顺序。例如:如果我从底部框开始创建最后一个图像,然后是顶部框,然后是中间两个框,输出结果是:
//4
//4
//1
//1
//2
//3
为了得到包含有选定内容的行的最终数组,我们可以修改上面的代码。
function rowChecker()
{
var rows = [];
var active = SpreadsheetApp.getActiveRangeList().getRanges();
for(var n = 0; n < active.length; n++)
{
for(var r = active[n].getRow(); r <= active[n].getLastRow(); r++)
{
if(!rows.includes(r))
{
rows.push(r);
}
}
}
Logger.log(rows);
}
请注意:如果不使用 if(!rows.includes(r))
,根据用户选择框的顺序,可能会得到类似以下的结果。
//1
//3
//4
//3
//4
英文:
The documentation was wrong.
getActiveRangeList()
does not "behave like getActiveRange()
" if there is only one range.
getActiveRangeList().getRanges()
returns an array containing all ranges. If there's only one, then the array has only one range in it.
getActiveRange().getRanges()
crashes with an error because getRanges()
doesn't exist in this case.
Therefore, we can just use getActiveRangeList()
to cover all possible scenarios.
function rowChecker()
{
var active = SpreadsheetApp.getActiveRangeList().getRanges();
for(var n = 0; n < active.length; n++)
{
Logger.log(active[n].getRow());
Logger.log(active[n].getLastRow());
}
}
//3
//3
//1
//3
//1
//1
//3
//4
//1
//1
//2
//3
//4
//4
The order the ranges are found seems to depend on the order they were created. For example: If I create that last image starting with the bottom box, then the top box, then the middle two, the output is:
//4
//4
//1
//1
//2
//3
To get our final array of rows that have a selection in them, we can just modify the code above.
function rowChecker()
{
var rows = [];
var active = SpreadsheetApp.getActiveRangeList().getRanges();
for(var n = 0; n < active.length; n++)
{
for(var r = active[n].getRow(); r <= active[n].getLastRow(); r++)
{
if(!rows.includes(r))
{
rows.push(r);
}
}
}
Logger.log(rows);
}
//1
//3
//4
Be careful: If you don't use that if(!rows.includes(r))
, you could wind up with something like this, depending on what order the user selects those boxes.
//1
//3
//4
//3
//4
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论