【发布时间】:2011-05-09 08:49:29
【问题描述】:
我有一个电子表格,其中 G 列中有一些值。一些单元格之间是空的,我需要将该列中的最后一个值获取到另一个单元格中。
类似:
=LAST(G2:G9999)
除了 LAST 不是函数。
【问题讨论】:
标签: google-apps-script google-sheets google-sheets-formula array-formulas custom-function
我有一个电子表格,其中 G 列中有一些值。一些单元格之间是空的,我需要将该列中的最后一个值获取到另一个单元格中。
类似:
=LAST(G2:G9999)
除了 LAST 不是函数。
【问题讨论】:
标签: google-apps-script google-sheets google-sheets-formula array-formulas custom-function
与caligari's answer 类似,但我们可以通过指定完整的列范围来整理它:
=INDEX(G2:G, COUNT(G2:G))
【讨论】:
FILTER()ed 范围内的第一行、最后一行或第n 行,类似于@Geta's answer。
COUNT(G2:G) 返回 0。而是使用COUNTA(G2:G),它只计算数据集中值的数量。 COUNTA 仅在与 INDEX 结合使用时才能在您的值之间没有一个空格时获得最后一个值。
COUNTA。 COUNT 只计算数值:给定时它将返回 0,例如文本单元格。
所以这个解决方案将一个字符串作为它的参数。它找出工作表中有多少行。它获取指定列中的所有值。它从末尾到开头循环遍历值,直到找到一个不是空字符串的值。最后它返回值。
脚本:
function lastValue(column) {
var lastRow = SpreadsheetApp.getActiveSheet().getMaxRows();
var values = SpreadsheetApp.getActiveSheet().getRange(column + "1:" + column + lastRow).getValues();
for (; values[lastRow - 1] == "" && lastRow > 0; lastRow--) {}
return values[lastRow - 1];
}
用法:
=lastValue("G")
编辑:
回应要求自动更新功能的评论:
我能找到的最好方法是使用上面的代码:
function onEdit(event) {
SpreadsheetApp.getActiveSheet().getRange("A1").setValue(lastValue("G"));
}
不再需要像 Usage 部分所述在单元格中使用该函数。相反,您对要更新的单元格和要跟踪的列进行硬编码。可能有一种更雄辩的方式来实现这一点(希望不是硬编码的),但这是我目前能找到的最好的方式。
请注意,如果您如前所述在单元格中使用该功能,它将在重新加载时更新。也许有一种方法可以连接到onEdit() 并强制单元格函数更新。我只是在文档中找不到它。
【讨论】:
Tools -> Scripts -> Script editor...下新建一个脚本
其实我在这里找到了一个更简单的解决方案:
http://www.google.com/support/forum/p/Google+Docs/thread?tid=20f1741a2e663bca&hl=en
看起来像这样:
=FILTER( A10:A100 , ROW(A10:A100) =MAX( FILTER( ArrayFormula(ROW(A10:A100)) , NOT(ISBLANK(A10:A100)))))
【讨论】:
ROW返回行号,所以FILTER( ROW(A10:A100), NOT(ISBLANK(A10:A100) )返回所有非空行号(不是它们的值)的数组,例如[1,2,3,7, 12、14]。然后MAX 给我们最后的行号。然后应用第二个FILTER 过滤掉行号与MAX 中的值不匹配的所有行(即最后一个非空白行的值)。
LAST() 函数目前未实现以选择范围内的最后一个单元格。但是,按照您的示例:
=LAST(G2:G9999)
我们可以通过这种方式使用 INDEX() 和 COUNT() 这两个函数来获取最后一个单元格:
=INDEX(G2:G; COUNT(G2:G))
在电子表格中有一个 live example,我发现(并解决了)同样的问题(表格Orzamentos,单元格I5)。请注意,即使引用文档中的其他工作表,它也能完美运行。
【讨论】:
COUNTA。请参阅我的 cmets 以了解 dohmoose 的答案。
:G 表示最后一个元素?这有记录吗?
=INDEX( FILTER( G2:G , NOT(ISBLANK(G2:G))) , COUNTA(G2:G) )
我已经查看并尝试了几个答案,这就是我发现的: 如果没有空格,最简单的解决方案(请参阅Dohmoose' answer)有效:
=INDEX(G2:G; COUNT(G2:G))
如果有空格,则失败。
您只需将COUNT 更改为COUNTA 即可处理一个空白(参见user3280071's answer):
=INDEX(G2:G; COUNTA(G2:G))
但是,对于某些空白组合,这将失败。 (1 blank 1 blank 1 对我来说失败了。)
以下代码有效(参见Nader's answer 和jason's comment):
=INDEX( FILTER( G2:G , NOT(ISBLANK(G2:G))) , ROWS( FILTER( G2:G , NOT(ISBLANK(G2:G)) ) ) )
但这需要考虑是否要在给定范围内使用COLUMNS 或ROWS。
但是,如果将COLUMNS 替换为COUNT,我似乎得到了LAST 的可靠、无空白的实现:
=INDEX( FILTER( G2:G , NOT(ISBLANK(G2:G))) , COUNT( FILTER( G2:G , NOT(ISBLANK(G2:G)) ) ) )
由于COUNTA 内置了过滤器,我们可以进一步简化使用
=INDEX( FILTER( G2:G , NOT(ISBLANK(G2:G))) , COUNTA(G2:G) )
这有点简单,而且是正确的。而且您不必担心是否计算行数或列数。与脚本解决方案不同,它会随着电子表格的更改自动更新。
如果要获取一行中的最后一个值,只需更改数据范围即可:
=INDEX( FILTER( A2:2 , NOT(ISBLANK(A2:2))) , COUNTA(A2:2) )
【讨论】:
为了从一列文本值中返回最后一个值,您需要使用 COUNTA,因此您需要以下公式:
=INDEX(G2:G; COUNTA(G2:G))
【讨论】:
COUNTA 结合 INDEX 将不会返回列中的最后一个值。
这个对我有用:
=INDEX(I:I;MAX((I:I<>"")*(ROW(I:I))))
【讨论】:
试试这个:
=INDIRECT("B"&arrayformula(max((B3:B<>"")*row(B3:B))))
假设您要在其中查找最后一个值的列是 B。
是的,它适用于空白。
【讨论】:
Google Apps 脚本现在似乎支持范围作为函数参数。此解决方案接受一个范围:
// Returns row number with the last non-blank value in a column, or the first row
// number if all are blank.
// Example: =rowWithLastValue(a2:a, 2)
// Arguments
// range: Spreadsheet range.
// firstRow: Row number of first row. It would be nice to pull this out of
// the range parameter, but the information is not available.
function rowWithLastValue(range, firstRow) {
// range is passed as an array of values from the indicated spreadsheet cells.
for (var i = range.length - 1; i >= 0; -- i) {
if (range[i] != "") return i + firstRow;
}
return firstRow;
}
另请参阅 Google Apps 脚本帮助论坛中的讨论:How do I force formulas to recalculate?
【讨论】:
我看了以前的答案,他们似乎工作太努力了。也许脚本支持只是简单地改进了。我认为函数是这样表达的:
function lastValue(myRange) {
lastRow = myRange.length;
for (; myRange[lastRow - 1] == "" && lastRow > 0; lastRow--)
{ /*nothing to do*/ }
return myRange[lastRow - 1];
}
然后在我的电子表格中使用:
= lastValue(E17:E999)
在函数中,我得到一个值数组,每个引用的单元格都有一个值,这只是从数组的末尾向后迭代,直到找到一个非空值或用完元素。在将数据传递给函数之前,应解释工作表引用。也不够花哨,无法处理多维度。这个问题确实要求单列中的最后一个单元格,所以它似乎很合适。如果您也用完数据,它可能会死掉。
您的里程可能会有所不同,但这对我有用。
【讨论】:
function lastRow(column){
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var lastRow = sheet.getLastRow();
var lastRowRange=sheet.getRange(column+startRow);
return lastRowRange.getValue();
}
没有硬编码。
【讨论】:
这会获取最后一个值并处理空值:
=INDEX( FILTER( H:H ; NOT(ISBLANK(H:H))) ; ROWS( FILTER( H:H ; NOT(ISBLANK(H:H)) ) ) )
【讨论】:
=INDEX( FILTER( 88:88 , NOT(ISBLANK(88:88))) , columns( FILTER( 88:88 , NOT(ISBLANK(88:88)) ) ) )
=INDEX( FILTER( indirect(row()&":"&row()) , NOT(ISBLANK(indirect(row()&":"&row())))) , columns( FILTER( indirect(row()&":"&row()) , NOT(ISBLANK(indirect(row()&":"&row()))) ) ) )
在有空格的列中,可以用
获取最后一个值=+sort(G:G,row(G:G)*(G:G<>""),)
【讨论】:
答案
$ =INDEX(G2:G; COUNT(G2:G))
在 LibreOffice 中无法正常工作。不过,只要稍加改动,就可以完美运行。
$ =INDEX(G2:G100000; COUNT(G2:G100000))
只有当真实范围小于(G2:G10000)时它总是有效的
【讨论】:
用严格的题外话回答原始问题是否可以接受:) 您可以在电子表格中编写一个公式来执行此操作。也许丑?但对电子表格的正常操作有效。
=indirect("R"&ArrayFormula(max((G:G<>"")*row(G:G)))&"C"&7)
(G:G<>"") gives an array of true false values representing non-empty/empty cells
(G:G<>"")*row(G:G) gives an array of row numbers with zeros where cell is empty
max((G:G<>"")*row(G:G)) is the last non-empty cell in G
这是对脚本领域中一系列问题的思考,这些问题可以使用数组公式可靠地传递,这些公式的优点是经常在 excel 和 openoffice 中以类似的方式工作。 p>
【讨论】:
function getDashboardSheet(spreadsheet) {
var sheetName = 'Name';
return spreadsheet.getSheetByName(sheetName);
}
var spreadsheet = SpreadsheetApp.openByUrl(SPREADSHEET_URL);
var dashboardSheet = getDashboardSheet(spreadsheet);
Logger.log('see:'+dashboardSheet.getLastRow());
【讨论】:
我正在使用@tinfini 提供的代码,并认为人们可能会从我认为稍微更优雅的解决方案中受益(请注意,当他创建原始答案时,我认为脚本的工作方式并不完全相同)。 ..
//Note that this function assumes a single column of values, it will
//not function properly if given a multi-dimensional array (if the
//cells that are captured are not in a single row).
function LastInRange(values)
{
for (index = values.length - 1; values[index] == "" && index > 0; index--) {}
return String(values[index]);
}
在使用中它看起来像这样:
=LastInRange(D2:D)
【讨论】:
关于@Jon_Schneider 的评论,如果该列有空白单元格,请使用 COUNTA()
=INDEX(G2:G; COUNT**A**(G2:G))
【讨论】:
我找到了另一种方法可能对你有帮助
=INDEX( SORT( A5:D ; 1 ; FALSE) ; 1 ) - 将返回最后一行
来自 anab 的更多信息: https://groups.google.com/forum/?fromgroups=#!topic/How-to-Documents/if0_fGVINmI
【讨论】:
发现了一个细微的变化,可以消除表格底部的空白。 =index(G2:G,COUNTIF(G2:G,""))
【讨论】:
我很惊讶以前没有人给出过这个答案。但这应该是最短的,甚至可以在 excel 中使用:
=ARRAYFORMULA(LOOKUP(2,1/(G2:G<>""),G2:G))
G2:G<>"" 创建一个由 1/true(1) 和 1/false(0) 组成的数组。由于LOOKUP 采用自上而下的方法来查找2,并且由于它永远不会找到2,所以它会到达最后一个非空白行并给出它的位置。
正如其他人可能提到的那样,另一种方法是:
=INDEX(G2:G,MAX((ISBLANK(G2:G)-1)*-ROW(G2:G))-1)
找到非空白行的MAXimum ROW并将其提供给INDEX
在零空白中断数组中,使用INDIRECT RC 符号和COUNTBLANK 是另一种选择。如果 V4:V6 被条目占用,那么,
V18:
=INDIRECT("R[-"&COUNTBLANK(V4:V17)+1&"]C",0)
会给出V6的位置。
【讨论】:
要从列中获取最后一个值,您还可以使用 MAX 函数和 IF 函数
=ARRAYFORMULA(INDIRECT("G"&MAX(IF(G:G<>"", ROW(G:G), )), 4)))
【讨论】:
对于特定列,我已经经历了太多最后一行的实现。许多解决方案都有效,但对于大型或多个数据集来说速度很慢。我的一个用例要求我检查多个电子表格中特定列的最后一行。我发现将整个列作为一个范围然后迭代它太慢了,将其中的一些加在一起会使脚本变得迟缓。
我的“hack”是这个公式:
=ROW(index(sheet!A2:A,max(row(sheet!A2:A)*(sheet!A2:A<>""))))-1
示例:将此添加到单元格 A1,以查找 A 列中的最后一行。可以添加到任何地方,只需确保根据放置公式的行来管理末尾的“-1”。您也可以将其放置为另一个列,而不是您要计数的列,并且您不需要管理 -1。您还可以从起始行开始计数,例如“C16:C” - 将从 C16 开始计数值
这个公式可靠地给了我最后一行,包括数据集中间的空白
要在我的 GS 代码中使用这个值,我只是从 A1 中读取单元格值。我知道 Google 很清楚读/写等电子表格功能很繁重(耗时),但根据我的经验(对于大型数据集),这比列计数最后一行方法快得多
为了提高效率,我在 col 中获取最后一行,然后将其保存为全局变量并在我的代码中递增以跟踪我应该更新哪些行。每次循环需要进行更新时读取单元格的效率太低了。读取一次,迭代值,A1 单元格公式(上图)将“存储”更新后的值以供下次函数运行时使用
如果这对您有帮助,请告诉我!如果我遇到任何问题,我会对此答案发表评论。
【讨论】:
=MATCH(1, ARRAYFORMULA(IF(ISBLANK(sheet!A2:A), #N/A, 0)))
MAX 需要检查每个单元格,而 MATCH 可能会在其输入范围已排序的假设下短路(如果它只有零,因为#N/A 在我观察到的比赛中不考虑错误)。我假设ARRAYFORMULA 评估是懒惰地完成的,MATCH 会进行某种二进制搜索扫描,相当早地测试行/列的最后一个条目,但我不知道这些假设是否正确。跨度>