it-swarm.com.de

Bestimmen der letzten Zeile in einer einzelnen Spalte

Ich habe ein Blatt mit Daten in den Spalten A bis H.

Ich muss die letzte Zeile in der Spalte A ermitteln, die Daten enthält (es ist alles zusammenhängend - keine Lücken in den Daten/Zeilen).

Es gibt auch Daten in den anderen Spalten, die more Datenzeilen als Spalte A enthalten. Daher muss ich nur die Spalte A isolieren. (Und/oder nur ein Bereich innerhalb von col A). 

Ich kann dies auf Tabellenkalkulationsebene mit tun 

=COUNTA(A2:A100)

Bei all meinen Recherchen nach einer Google Apps Script-Lösung sehe ich anscheinend nur die Anforderung, mehrere Funktionen auszuführen, die Dutzende von Codezeilen umfassen - einschließlich zahlreicher i++ -Dinge ... Verrechnung direkt von A1.

Gibt es möglicherweise eine spaltenspezifische Möglichkeit, diese Methode zu ändern?

var aLast = ss.getDataRange().getNumRows();

Wenn ein verschlungener Prozess erforderlich ist, dann soll es so sein. Es fällt mir jedoch schwer, sich eine einfachere Lösung vorzustellen (und noch schwieriger zu finden!).

Interessiert es mich jemand aufzuklären (oder meine Blase zu knallen)?

40
5th4x4

Wie wäre es mit einem JavaScript-Trick?

var Avals = ss.getRange("A1:A").getValues();
var Alast = Avals.filter(String).length;

Ich habe mir diese Idee aus dieser Antwort entlehnt. Die Array.filter() -Methode arbeitet mit dem Avals-Array, das alle Zellen in Spalte A enthält. Durch Filtern des Konstruktors einer nativen Funktion erhalten wir nur Elemente, die nicht Null sind.

Dies funktioniert nur für eine einzelne Spalte. Wenn der Bereich mehrere Spalten enthält, enthält das Ergebnis von filter() Zellen aus allen Spalten und liegt somit außerhalb der besetzten Dimensionen des Bereichs.

106
Mogsdad

Obwohl es keine geradlinige Formel gibt, die ich mir vorstellen kann, sind keine Dutzenden von Codezeilen erforderlich, um die letzte Zeile in Spalte A herauszufinden. Versuchen Sie diese einfache Funktion. Verwenden Sie es in einer Zelle wie üblich, 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 ;
    }
  }
}
11
Srik

Sie können dies tun, indem Sie in umgekehrter Reihenfolge vorgehen. Von der letzten Zeile der Kalkulationstabelle ausgehend, bis Sie einen Wert erhalten. Dies funktioniert in allen Fällen, auch wenn Sie einige leere Zeilen dazwischen haben . 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;
}
4
Akash Garg

Dies wird die letzte Zeile in einem Blatt erhalten, vorausgesetzt, es basiert auf Spalte 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();
  }              
}

Dies korrigiert die teilweise korrekte Antwort von @ mrityunjay-pandey.

Um diese Antwort um die letzte Zeile und Spalte zu erweitern, 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)];
}
3
Al Johri

Bei sehr großen Tabellenkalkulationen 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();

};
1
Luciano Pivi

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. Dies hat den Vorteil, dass Sie nicht zusammenhängende Spalten haben und trotzdem die letzte Zeile kennen (vorausgesetzt, Sie durchlaufen die gesamte Spalte).

0
jello195

Ich hoffe, es ist nie zu spät, eine alternative Antwort zu posten. Hier ist ein Ausschnitt meiner letzten Zelle. Ich interessiere mich hauptsächlich für Geschwindigkeit. Bei 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, bei der (durchschnittlich) 0,53 Sekunden für dieselben Daten benötigt werden. Beide Arrays wurden vor dem Funktionsaufruf vorgeladen. Es nutzt 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 Hops erforderlich sind, um das Ergebnis zurückzugeben.

Ich habe die Anmeldeanrufe zurückgelassen, damit Sie sie zuerst in der Konsole testen und ihre Funktionsweise überprüfen 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.
 */
0
DeeKay789

Ich habe die Funktionen getLastRow/getLastColumn neu geschrieben, um einen Zeilenindex oder einen 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;
    }
  }
}
0
Ashton Fei

Update von der Mogsdad-Lösung,

var Avals = ss.getRange("A1:A").getValues();
var Alast = Avals.filter(function(r){return r[0].length>0});
0
Tin Trang

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:

enter image description here

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();
  } 
}

So erhalten Sie die Anzahl der Spalten oder den Index der letzten Spalte:

var numColumns = sheet.getLastColumn()

So erhalten Sie die Zeilenanzahl oder den Index der letzten Zeile:

var numRows = sheet.getLastRow()

woher

var sheet = SpreadsheetApp.getActiveSheet()
0
Ashish Verma
var Direction=SpreadsheetApp.Direction;
var aLast =ss.getRange("A"+(ss.getLastRow()+1)).getNextDataCell(Direction.UP).getRow();
0

Dies kann ein anderer Weg sein, um lastrow zu umgehen. Möglicherweise müssen Sie mit dem Code herumspielen, um Ihre Anforderungen zu erfüllen 

    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);
};
0
Tariq Khalaf

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).

0
Simon Birt