5th*_*4x4 50 google-sheets google-apps-script
我在COLS与数据在片材A通过H.
我需要确定A包含数据的列中的最后一行(它是所有连续的 - 数据/行中没有间隙).
其他列中的数据也包含比列更多的数据行A,因此我只需要隔离列A.(和/或只是col内的范围A).
我可以在电子表格级别使用
=COUNTA(A2:A100)
Run Code Online (Sandbox Code Playgroud)
然而,在我对Google Apps脚本解决方案的所有研究中,我似乎都发现需要执行多个功能,包括几十行代码 - 包括大量的i++内容......我可以通过直接抵消来减少复杂性A1.
是否可能有特定于列的方法来修改此方法?
var aLast = ss.getDataRange().getNumRows();
Run Code Online (Sandbox Code Playgroud)
如果需要一个复杂的过程,那就这样吧.但我发现很难想象(甚至更难找到!)一个更简单的解决方案.
有人关心开导我(或弹出我的泡泡)?
Mog*_*dad 127
如何使用JavaScript技巧?
var Avals = ss.getRange("A1:A").getValues();
var Alast = Avals.filter(String).length;
Run Code Online (Sandbox Code Playgroud)
我从这个答案中借鉴了这个想法.该Array.filter()方法在Avals数组上运行,该数组包含A列中的所有单元格.通过对本机函数的构造函数进行过滤,我们只返回非null元素.
这仅适用于单个列; 如果范围包含多个列,则结果filter()将包括来自所有列的单元格,因此位于范围的填充维度之外.
Sri*_*rik 11
虽然没有直接的公式,我可以想到,它不需要几十行代码来找出A列的最后一行.试试这个简单的函数.以正常方式使用其他功能在单元格中使用它=CountColA()
function CountColA(){
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for(var i = data.length-1 ; i >=0 ; i--){
if (data[i][0] != null && data[i][0] != ''){
return i+1 ;
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 8
var Direction=SpreadsheetApp.Direction;
var aLast =ss.getRange("A"+(ss.getLastRow()+1)).getNextDataCell(Direction.UP).getRow();
Run Code Online (Sandbox Code Playgroud)
根据文档, getNextDataCell 类似于转到给定范围并按 ctrl (command) + 箭头键。所以这是有效的,因为它转到 las 可能的行,添加一个(向下箭头)然后 ctrl + UP,所以它肯定会得到包含一些内容的最后一行。唯一可以改进的是检查最后一个单元格 + 1 是否大于最大单元格,并为这种情况制定特定的逻辑。
小智 6
sheet.getRange(1, 1).getDataRegion(SpreadsheetApp.Dimension.ROWS).getLastRow()
Run Code Online (Sandbox Code Playgroud)
请注意,这依赖于连续的数据(根据 OP 的请求)。
小智 5
您可以通过相反的方式进行操作。从电子表格的最后一行开始,一直到获得一些价值为止。即使您之间有一些空行,在所有情况下都可以使用。代码如下所示:
var iLastRowWithData = lastValue('A');
function lastValue(column) {
var iLastRow = SpreadsheetApp.getActiveSheet().getMaxRows();
var aValues = SpreadsheetApp.getActiveSheet().getRange(column + "2:" + column + lastRow).getValues();
for (; aValues[iLastRow - 1] == "" && iLastRow > 0; iLastRow--) {}
return iLastRow;
}
Run Code Online (Sandbox Code Playgroud)
假设基于A列,这将获得工作表中的最后一行。
function getLastDataRow(sheet) {
var lastRow = sheet.getLastRow();
var range = sheet.getRange("A" + lastRow);
if (range.getValue() !== "") {
return lastRow;
} else {
return range.getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
}
}
Run Code Online (Sandbox Code Playgroud)
这可以修复@ mrityunjay-pandey部分正确的答案。
为了扩展此答案以获得最后一行和最后一列,我们可以使用:
function columnToLetter(column) {
var temp, letter = '';
while (column > 0) {
temp = (column - 1) % 26;
letter = String.fromCharCode(temp + 65) + letter;
column = (column - temp - 1) / 26;
}
return letter;
}
function letterToColumn(letter) {
var column = 0, length = letter.length;
for (var i = 0; i < length; i++) {
column += (letter.charCodeAt(i) - 64) * Math.pow(26, length - i - 1);
}
return column;
}
function getLastDataColumn(sheet) {
var lastCol = sheet.getLastColumn();
var range = sheet.getRange(columnToLetter(lastCol) + "1");
if (range.getValue() !== "") {
return lastCol;
} else {
return range.getNextDataCell(SpreadsheetApp.Direction.PREVIOUS).getColumn();
}
}
function getLastDataRow(sheet) {
var lastRow = sheet.getLastRow();
var range = sheet.getRange("A" + lastRow);
if (range.getValue() !== "") {
return lastRow;
} else {
return range.getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
}
}
function run() {
var sheet = SpreadsheetApp.getActiveSheet();
var [startRow, lastRow] = [2, getLastDataRow(sheet)];
var [startCol, lastCol] = [1, getLastDataColumn(sheet)];
}
Run Code Online (Sandbox Code Playgroud)
我希望发布替代答案永远不会太晚。这是我查找最后一个单元格的片段。我主要对速度感兴趣。在我使用大约 150,000 行的数据库上,与上面的@Mogsdad 优雅的 JS 解决方案相比,该函数需要(平均)0.087 秒才能找到解决方案,后者在相同数据上需要(平均)0.53 秒。两个数组都在函数调用之前预加载。它利用递归进行二分查找。对于 100,000+ 行,您应该会发现返回结果所需的时间不超过 15 到 20 跳。
我已经保留了 Log 调用,因此您可以先在控制台中对其进行测试并查看其工作情况。
/* @OnlyCurrentDoc */
function myLastRow() {
var ss=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var colArray = ss.getRange('A1:A').getDisplayValues(); // Change to relevant column label and put in Cache
var TestRow=ss.getLastRow();
var MaxRow=ss.getMaxRows();
Logger.log ('TestRow = %s',TestRow);
Logger.log ('MaxRow = %s',MaxRow);
var FoundRow=FindLastRow(TestRow,MaxRow);
Logger.log ('FoundRow = %s',FoundRow);
function FindLastRow(v_TestRow,v_MaxRow) {
/* Some housekeeping/error trapping first
* 1) Check that LastRow doesn't = Max Rows. If so then suggest to add a few lines as this
* indicates the LastRow was the end of the sheet.
* 2) Check it's not a new sheet with no data ie, LastRow = 0 and/or cell A1 is empty.
* 3) A return result of 0 = an error otherwise any positive value is a valid result.
*/
return !(colArray[0][0]) ? 1 // if first row is empty then presume it's a new empty sheet
:!!(colArray[v_TestRow][0]) ? v_TestRow // if the last row is not empty then column A was the longest
: v_MaxRow==v_TestRow ? v_TestRow // if Last=Max then consider adding a line here to extend row count, else
: searchPair(0,v_TestRow); // get on an find the last row
}
function searchPair(LowRow,HighRow){
var BinRow = ((LowRow+HighRow)/2)|0; // force an INT to avoid row ambiguity
Logger.log ('LowRow/HighRow/BinRow = %s/%s/%s',LowRow, HighRow, BinRow);
/* Check your log. You shoud find that the last row is always found in under 20 hops.
* This will be true whether your data rows are 100 or 100,000 long.
* The longest element of this script is loading the Cache (ColArray)
*/
return (!(colArray[BinRow-1][0]))^(!(colArray[BinRow][0])) ? BinRow
: (!(colArray[BinRow-1][0]))&(!(colArray[BinRow][0])) ? searchPair(LowRow,BinRow-1)
: (!!(colArray[BinRow-1][0]))|(!!(colArray[BinRow][0])) ? searchPair(BinRow+1,HighRow)
: false; // Error
}
}
/* The premise for the above logic is that the binary search is looking for a specific pairing, <Text/No text>
* on adjacent rows. You said there are no gaps so the pairing <No Text/Text> is not tested as it's irrelevant.
* If the logic finds <No Text/No Text> then it looks back up the sheet, if it finds <Text/Text> it looks further
* down the sheet. I think you'll find this is quite fast, especially on datasets > 100,000 rows.
*/
Run Code Online (Sandbox Code Playgroud)
小智 5
旧线程,但我找到了一种似乎有效的简单方法
ws.getRange("A2").getNextDataCell(SpreadsheetApp.Direction.DOWN).getLastRow()
Run Code Online (Sandbox Code Playgroud)
接受的答案以及大多数答案(如果不是全部)都有一个共同的限制,对于问题的所有者(他们有连续的数据)但对于未来的读者来说可能不是这种情况。
例如,考虑这个非常简单的场景:
接受的解决方案会给出,4而正确的答案是6。
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet1')
const lrow = sh.getLastRow();
const Avals = sh.getRange("A1:A"+lrow).getValues();
const Alast = lrow - Avals.reverse().findIndex(c=>c[0]!='');
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
88605 次 |
| 最近记录: |