Ich habe ein Blatt mit Daten in Spalten A
durch H
.
Ich muss die letzte Zeile in der Spalte bestimmen A
, die Daten enthält (alles ist zusammenhängend - keine Lücken in den Daten / Zeilen).
Es gibt auch Daten in den anderen Spalten, die mehr Datenzeilen als Spalten enthalten A
, sodass ich nur die Spalte isolieren muss A
. (Und / oder nur ein Bereich innerhalb von Spalte A
).
Ich kann dies auf Tabellenkalkulationsebene mit tun
=COUNTA(A2:A100)
Bei all meinen Recherchen nach einer Google Apps Script-Lösung scheine ich jedoch nur Anforderungen zu finden, um mehrere Funktionen auszuführen, die Dutzende von Codezeilen umfassen - einschließlich vieler i++
Dinge ... Was ich durch direktes Versetzen weniger komplex machen könnte A1
.
Gibt es möglicherweise eine spaltenspezifische Möglichkeit, diese Methode zu ändern?
var aLast = ss.getDataRange().getNumRows();
Wenn ein komplizierter Prozess erforderlich ist, dann sei es so. Aber ich finde es schwierig, mir eine einfachere Lösung vorzustellen (und noch schwieriger zu finden!).
Möchte mich jemand aufklären (oder meine Blase platzen lassen)?
var Alast = Avals.filter(String).length;
Variablen?Obwohl es keine einfache Formel gibt, die ich mir vorstellen kann, sind nicht Dutzende von Codezeilen erforderlich, um die letzte Zeile in Spalte A herauszufinden. Probieren Sie diese einfache Funktion aus. Verwenden Sie es in einer Zelle wie gewohnt, wenn Sie eine andere Funktion verwenden würden
=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 ; } } }
quelle
Dadurch wird die letzte Zeile in einem Blatt basierend auf Spalte A angezeigt.
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(); } }
Dies behebt die teilweise korrekte Antwort von @ mrityunjay-pandey.
Um diese Antwort zu erweitern und die letzte Zeile und Spalte zu erhalten, können wir Folgendes verwenden:
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)]; }
quelle
var Direction=SpreadsheetApp.Direction; var aLast =ss.getRange("A"+(ss.getLastRow()+1)).getNextDataCell(Direction.UP).getRow();
Laut Dokumentation ist getNextDataCell ähnlich, um in den angegebenen Bereich zu wechseln und Strg (Befehl) + die Pfeiltaste zu drücken. Das funktioniert also, weil es zur letzten möglichen Zeile geht, eine (Pfeil nach unten) und dann Strg + NACH OBEN hinzufügt, sodass es definitiv die letzte Zeile mit etwas Inhalt erhält. Das einzige, was verbessert werden könnte, ist zu überprüfen, ob die letzte Zelle + 1 größer als die maximale Zelle ist, und eine spezifische Logik für diesen Fall zu erstellen.
quelle
getNextDataCell
ist es ähnlich, in den angegebenen Bereich zu gehen und Strg (Befehl) + die Pfeiltaste zu drücken. Das funktioniert also, weil es zur letzten möglichen Zeile geht, eine (Pfeil nach unten) und dann Strg + NACH OBEN hinzufügt, sodass es definitiv die letzte Zeile mit etwas Inhalt erhält. Das einzige, was verbessert werden könnte, ist zu überprüfen, ob die letzte Zelle + 1 größer als die maximale Zelle ist, und eine spezifische Logik für diesen Fall zu erstellen.Sie können dies in umgekehrter Reihenfolge tun. Beginnen Sie mit der letzten Zeile in der Tabelle und gehen Sie nach oben, bis Sie einen Wert erhalten. Dies funktioniert in allen Fällen auch dann, wenn dazwischen einige leere Zeilen liegen. Der Code sieht wie folgt aus:
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; }
quelle
Ich hoffe, es ist nie zu spät, eine alternative Antwort zu veröffentlichen. Hier ist ein Ausschnitt aus meiner letzten Zelle finden. Ich interessiere mich hauptsächlich für Geschwindigkeit. In einer Datenbank, die ich mit ungefähr 150.000 Zeilen verwende, dauerte diese Funktion (durchschnittlich) 0,087 Sekunden, um eine Lösung zu finden, verglichen mit der eleganten JS-Lösung von @Mogsdad, über der (durchschnittlich) 0,53 Sekunden für dieselben Daten benötigt werden. Beide Arrays wurden vor dem Funktionsaufruf vorinstalliert. Es verwendet die Rekursion, um eine binäre Suche durchzuführen. Bei mehr als 100.000 Zeilen sollten Sie feststellen, dass nicht mehr als 15 bis 20 Sprünge erforderlich sind, um das Ergebnis zurückzugeben.
Ich habe die Log-Aufrufe belassen, damit Sie sie zuerst in der Konsole testen und ihre Funktionsweise sehen können.
/* @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. */
quelle
Ich habe getDataRegion verwendet
sheet.getRange(1, 1).getDataRegion(SpreadsheetApp.Dimension.ROWS).getLastRow()
Beachten Sie, dass dies davon abhängt, dass die Daten zusammenhängend sind (gemäß der Anforderung des OP).
quelle
So ermitteln Sie die Anzahl der Spalten oder den Index der letzten Spalte:
var numColumns = sheet.getLastColumn()
So ermitteln Sie die Anzahl der Zeilen oder den Index der letzten Zeile:
var numRows = sheet.getLastRow()
wo
var sheet = SpreadsheetApp.getActiveSheet()
quelle
Für sehr große Tabellen ist diese Lösung sehr schnell:
function GoLastRow() { var spreadsheet = SpreadsheetApp.getActive(); spreadsheet.getRange('A:AC').createFilter(); var criteria = SpreadsheetApp.newFilterCriteria().whenCellNotEmpty().build(); var rg = spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(1, criteria).getRange(); var row = rg.getNextDataCell (SpreadsheetApp.Direction.DOWN); LastRow = row.getRow(); spreadsheet.getActiveSheet().getFilter().remove(); spreadsheet.getActiveSheet().getRange(LastRow+1, 1).activate(); };
quelle
Nach einer Weile beim Versuch, eine Funktion zu erstellen, um eine Ganzzahl mit der letzten Zeile in einer einzelnen Spalte zu erhalten, funktionierte dies einwandfrei:
function lastRow() { var spreadsheet = SpreadsheetApp.getActiveSheet(); spreadsheet.getRange('B1').activate(); var columnB = spreadsheet.getSelection().getNextDataRange(SpreadsheetApp.Direction.DOWN).activate(); var numRows = columnB.getLastRow(); var nextRow = numRows + 1; }
quelle
Dies kann ein anderer Weg sein, um Lastrow zu umgehen. Möglicherweise müssen Sie mit dem Code herumspielen, um Ihren Anforderungen zu entsprechen
function fill() { var spreadsheet = SpreadsheetApp.getActive(); spreadsheet.getRange('a1').activate(); var lsr = spreadsheet.getLastRow(); lsr=lsr+1; lsr="A1:A"+lsr; spreadsheet.getActiveRange().autoFill(spreadsheet.getRange(lsr), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES); };
quelle
persönlich hatte ich ein ähnliches Problem und ging mit so etwas:
function getLastRowinColumn (ws, column) { var page_lastrow = ws.getDataRange().getNumRows(); var last_row_col = 0 for (i=1; i<=page_lastrow;i++) { if (!(spread.getRange(column.concat("",i)).isBlank())) {last_row_col = i}; } return last_row_col }
Es sucht nach der Anzahl der Zeilen im ws und durchläuft jede Zelle in Ihrer Spalte. Wenn eine nicht leere Zelle gefunden wird, wird die Position dieser Zelle in der Variablen last_row_col aktualisiert. Es hat den Vorteil, dass Sie nicht zusammenhängende Spalten haben und trotzdem die letzte Zeile kennen (vorausgesetzt, Sie gehen die gesamte Spalte durch).
quelle
Ich habe versucht, 3 folgende Funktionen zu schreiben, Sie können sie für verschiedene Fälle von Ihnen testen. Dies sind die Daten, mit denen ich getestet habe:
Die Funktionen getLastRow1 und getLastRow2 geben 0 für Spalte B zurück. Die Funktion getLastRow3 gibt 1 für Spalte B zurück
Abhängig von Ihrem Fall werden Sie sie an Ihre Bedürfnisse anpassen.
function getLastRow1(sheet, column) { var data = sheet.getRange(1, column, sheet.getLastRow()).getValues(); while(typeof data[data.length-1] !== 'undefined' && data[data.length-1][0].length === 0){ data.pop(); } return data.length; } function test() { var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet6'); Logger.log('Cách 1'); Logger.log("Dòng cuối cùng của cột A là: " + getLastRow1(sh, 1)); Logger.log("Dòng cuối cùng của cột B là: " + getLastRow1(sh, 2)); Logger.log("Dòng cuối cùng của cột C là: " + getLastRow1(sh, 3)); Logger.log("Dòng cuối cùng của cột D là: " + getLastRow1(sh, 4)); Logger.log("Dòng cuối cùng của cột E là: " + getLastRow1(sh, 5)); Logger.log('Cách 2'); Logger.log("Dòng cuối cùng của cột A là: " + getLastRow2(sh, 1)); Logger.log("Dòng cuối cùng của cột B là: " + getLastRow2(sh, 2)); Logger.log("Dòng cuối cùng của cột C là: " + getLastRow2(sh, 3)); Logger.log("Dòng cuối cùng của cột D là: " + getLastRow2(sh, 4)); Logger.log("Dòng cuối cùng của cột E là: " + getLastRow2(sh, 5)); Logger.log('Cách 3'); Logger.log("Dòng cuối cùng của cột A là: " + getLastRow3(sh, 'A')); Logger.log("Dòng cuối cùng của cột B là: " + getLastRow3(sh, 'B')); Logger.log("Dòng cuối cùng của cột C là: " + getLastRow3(sh, 'C')); Logger.log("Dòng cuối cùng của cột D là: " + getLastRow3(sh, 'D')); Logger.log("Dòng cuối cùng của cột E là: " + getLastRow3(sh, 'E')); } function getLastRow2(sheet, column) { var lr = sheet.getLastRow(); var data = sheet.getRange(1, column, lr).getValues(); while(lr > 0 && sheet.getRange(lr , column).isBlank()) { lr--; } return lr; } function getLastRow3(sheet, column) { var lastRow = sheet.getLastRow(); var range = sheet.getRange(column + lastRow); if (range.getValue() !== '') { return lastRow; } else { return range.getNextDataCell(SpreadsheetApp.Direction.UP).getRow(); } }
quelle
Update von der Mogsdad-Lösung,
var Avals = ss.getRange("A1:A").getValues(); var Alast = Avals.filter(function(r){return r[0].length>0});
quelle
Mir ist klar, dass dies ein ziemlich alter Thread ist, aber es ist eines der ersten Ergebnisse bei der Suche nach diesem Problem.
Es gibt eine einfache Lösung dafür, die afaik schon immer zur Verfügung hatte ... Dies ist auch die " empfohlene " Methode, um dieselbe Aufgabe in VBA auszuführen.
var lastCell = mySheet.getRange(mySheet.getLastRow(),1).getNextDataCell( SpreadsheetApp.Direction.UP );
Dies gibt die letzte vollständige Zelle in der Spalte zurück, die Sie in getRange angegeben haben (Zeile, Spalte). Denken Sie daran, 1 hinzuzufügen, wenn Sie die erste leere Zeile verwenden möchten.
quelle
getLastRow()
wird?Das hat bei mir funktioniert:
var ss = SpreadsheetApp.openById(YourSpreadsheetID); var main_sheet = ss.getSheetByName(YourMainSheet); main_sheet.getRange('K16').activate(); // substitute your cell from where you want to count main_sheet.getCurrentCell().getNextDataCell(SpreadsheetApp.Direction.DOWN).activate(); var last_row_submissions = main_sheet.getCurrentCell().getRowIndex();
quelle
Ich habe die Funktionen getLastRow / getLastColumn umgeschrieben, um einen Zeilenindex oder Spaltenindex anzugeben.
function get_used_rows(sheet, column_index){ for (var r = sheet.getLastRow(); r--; r > 0) { if (sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getCell(r, column_index).getValue() != ""){ return r; break; } } } function get_used_cols(sheet, row_index){ for (var c = sheet.getLastColumn(); c--; c > 0) { if (sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getCell(row_index, c).getValue() != ""){ return c; break; } } }
quelle
Hier ist eine alternative Möglichkeit, dies zu lösen. Es verwendet eine
while
Schleife, berücksichtigt jedoch leere Lücken zwischen Zeilen.function getLastRow (column) { var iLastRow = ss.getActiveSheet().getMaxRows(); var aValues = ss.getActiveSheet().getRange(column + ":" + column).getValues(); var row = ""; while(row == ""){ row = aValues[iLastRow-1]; iLastRow--; } return iLastRow; }
quelle
Ich benutze
getDataRange()
gefolgt vongetNumRows()
. Die erste Funktionund die zweite Funktion
var ss = SpreadsheetApp.getActiveSpreadsheet(); var ws = ss.getActiveSheet(); var lastRow = ws.getDataRange().getNumRows();
PS Ich hoffe das funktioniert in allen Fällen.
quelle
getDataRange
Gibt ein rechteckiges Array zurück.