5

How to find the last used cell of column C ?

Example: "Sheet1" : "Col A" and "Col B" have 1200 rows. And "Col C" has only 1 row.

## ColA  ColB   ColC
##    1     1      1
##    2     2   empty
## ..    ..     ..
## 1200  1200   empty

Here are my unsuccessful tests :

Function find_last_row_other_column() {
var ws_sheet =
var ws = SpreadsheetApp.openById("Dy...spreadsheet_id...4I")
var ws_sheet = ws1.getSheetByName("Sheet1");

var lastRow = ws_sheet.getRange("C").getLastRow();
var lastRow = ws_sheet.getRange("C:C").getLastRow();
var lastRow = ws_sheet.getRange(1,3,ws_sheet.getLastRow());  1200 rows for colA! instead of row = 1 for col C.
}

Note: I can't use C1 because next time I use the function it will be C1200 or something else.

var lastRow = ws_sheet.getRange("C1").getLastRow();

I ask this because my next goal is to copy/paste the result of C1 into C2:C1200. Here is my test :

var lastRow = ws_sheet.getLastRow();
var target_range = ws_sheet.getRange(1,3,lastRow,1); //C1 until last row
var Formula_values = source_range.getValues();
target_range.setValues(Formula_values);

Thanks in advance ;)

ps: I have spend 2 hours on it. I have tried similar problems & their solutions already given on this website, but I can't happen to make them working. I am lost ! : More efficient way too look up the last row in a specific column? and Get last row of specific column function - best solution

Rubén
  • 34,714
  • 9
  • 70
  • 166
miodf
  • 524
  • 3
  • 9
  • 21
  • 1
    possible duplicate of [Selecting the last value of a column](http://stackoverflow.com/questions/4169914/selecting-the-last-value-of-a-column) – Serge insas Sep 26 '14 at 09:41
  • This is the subject of the highest score post on stackoverflow about Google apps script :http://stackoverflow.com/questions/4169914/selecting-the-last-value-of-a-column – Serge insas Sep 26 '14 at 09:41
  • Thanks Serge. Alas I don't want to know the value of the last written row of column C (like: "4654654"). But I would like to know what is the last written row of Column C ? Row number : 1 or whatever. Thanks in advance ;) – miodf Sep 26 '14 at 14:07

4 Answers4

14

As I mentioned in the comments above, this is the subject of the highest score post on StackOverFlow...

The original post returns the value of the last cell in a column but a (very) little modification makes it return the row index.

Original post :

Script:

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];
}

modified to return index of the last used cell in a column :

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 lastRow;
}
Serge insas
  • 45,904
  • 7
  • 105
  • 131
  • 1
    That is very neat! Sorry for a premature comment above. Wish I could upvote your answer more than once! – azawaza Sep 26 '14 at 16:08
  • Thanks Serge (and azawaza). It works like a charm. I was not good enough to make the changes you did. So thanks. ;) Following your link http://stackoverflow.com/questions/4169914/selecting-the-last-value-of-a-column I have added `function onEdit(event) { SpreadsheetApp.getActiveSheet().getRange("F1").setValue(lastValue("C"));// }` Thanks again. ;) – miodf Oct 02 '14 at 13:23
  • Hi again, After the above script, I also use this kill duplicate script for the first column https://developers.google.com/apps-script/articles/removing_duplicates Alas not all duplicates are deleted when the `function onEdit(event)` is running. I have also tested to add the formula in F1 `=lastValue("C")`. It works once but next time I add some more rows , it doesn't work anymore. Any idea ? Thanks in advance – miodf Oct 03 '14 at 17:03
  • Please start a new question exposing clearly what you need to do. Follow up question are not clear an not very useful for S.O users- thx – Serge insas Oct 03 '14 at 17:44
  • Dear future visitor, [check this answer](http://stackoverflow.com/questions/17632165/determining-the-last-row-in-a-single-column), IMHO is cleaner. – mTorres Sep 21 '16 at 09:53
  • This was super helpful! Thanks! – Tingo Sep 11 '18 at 01:27
  • Thanks! This is easy and simple. – k.b Apr 07 '21 at 19:14
1

Here is the function to do it:

function lastRowInColumnLetter(column) {
  var lastRow = SpreadsheetApp.getActiveSheet().getLastRow() - 1; // values[] array index
  var values = SpreadsheetApp.getActiveSheet().getRange(column + "1:" + column + (lastRow + 1)).getValues();
  while (lastRow > -1 && values[lastRow] == "") {
      lastRow--;
  }
  if (lastRow == -1) {
    return "Empty Column";
  } else {
    return lastRow + 1;
  }
}

and you invoke it as =lastRowInColumnLetter("C").

And here are 3 more useful functions in this context:

function lastValueInColumnLetter(column) {
  var lastRow = SpreadsheetApp.getActiveSheet().getLastRow() - 1; // values[] array index
  var values = SpreadsheetApp.getActiveSheet().getRange(column + "1:" + column + (lastRow + 1)).getValues();
  while (lastRow > -1 && values[lastRow] == "") {
      lastRow--;
  }
  if (lastRow == -1) {
    return "Empty Column";
  } else {
    return values[lastRow];
  }
}

function lastValueInColumnNumber(column) {
  var lastRow = SpreadsheetApp.getActiveSheet().getLastRow() - 1; // values[] array index
  var values = SpreadsheetApp.getActiveSheet().getRange(1,column,lastRow + 1).getValues();
  while (lastRow > -1 && values[lastRow] == "") {
      lastRow--;
  }
  if (lastRow == -1) {
    return "Empty Column";
  } else {
    return values[lastRow];
  }
}

function lastRowInColumnNumber(column) {
  var lastRow = SpreadsheetApp.getActiveSheet().getLastRow() - 1; // values[] array index
  var values = SpreadsheetApp.getActiveSheet().getRange(1,column,lastRow + 1).getValues();
  while (lastRow > -1 && values[lastRow] == "") {
      lastRow--;
  }
  if (lastRow == -1) {
    return "Empty Column";
  } else {
    return lastRow + 1;
  }
}

These functions properly address empty columns, and also start counting backwards from the last row with content on the active sheet getLastRow(), and not from the last row on the sheet (with or without content) getMaxRows() as in the accepted answer.

vstepaniuk
  • 667
  • 6
  • 14
1

If you don't have empty cells between your data, you can use this:

function last_Column_Row(){ 
  var ss = SpreadsheetApp.getActive(); 
  var sheet = ss.getActiveSheet();
  var Direction = SpreadsheetApp.Direction;
  var xcol = 2;//e.g. for column 2 ("B"), to obtain its last row
  var yrow = 8;//e.g. for row 8, to obtain its last column

  var lastRow =sheet.getRange(1,xcol).getNextDataCell(Direction.DOWN).getRow();//last row of column 'xcol'
  var lastCol =sheet.getRange(yrow,1).getNextDataCell(Direction.NEXT).getColumn();//last column of row 'yrow'
};

It gets the number of next empty cell-1 of a specific row or column (similar to Ctrl + 'arrow' in a sheet)

But If you have empty cells between your data, you can use this:

function last_Row_Column2()
{ 
  var ss = SpreadsheetApp.getActive(); 
  var sheet = ss.getActiveSheet();
  var Direction = SpreadsheetApp.Direction;
  var maxR =sheet.getMaxRows();
  var maxC = sheet.getMaxColumns();

  var yrow = 8;//e.g. for row 8, to obtain its last column
  var xcol = 2;//e.g. for column 2 ('B'), to obtain its last row

  var valMaxR = sheet.getRange(maxR,xcol).getValue();//for the case that the last row has the last value
  var valMaxC = sheet.getRange(yrow,maxC).getValue();//for the case that the last column has the last value

  if(valMaxR !=''){var lastRow = maxR;}//if the last row in studied column is the last row of sheet
  else{var lastRow =sheet.getRange(maxR,xcol).getNextDataCell(Direction.UP).getRow();}

  if(valMaxC !=''){var lastCol = maxC;}//if the last column in studied row is the last column of sheet(e.g.'Z')
  else{var lastCol =sheet.getRange(yrow,maxC).getNextDataCell(Direction.PREVIOUS).getColumn();}
};
0

[UPADTE} Please disregard this answer. User Serge's code instead. I was having a brain fart. His answer is magnitudes better in every way. That will teach me not to answer SO questions after you come back from a cocktail night... [/UPDATE]

The following function will log the last non-blank row number of column C. Note: if, for example, column C has a value in row 1 and row 200, with rows 2-199 blank, the function will return 200 as last non-blank row - it does not account for blank rows above last non-blank row.

function getLastNonBlankColCrow() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var lastNonBlankColCrow = 0;
  for (var i=1, lenRows=sheet.getRange("C:C").getNumRows(); i<=lenRows; i++) {
    if ( !sheet.getRange(i, 3).isBlank() ) { // 3 is 1-based index of column C
      lastNonBlankColCrow = i;
    }
  }
  Logger.log(lastNonBlankColCrow);
}
azawaza
  • 3,065
  • 1
  • 17
  • 20
  • This will be incredibly slow if the sheet has many rows... read about [best practices](https://developers.google.com/apps-script/best_practices) – Serge insas Sep 26 '14 at 15:39
  • @Sergeinsas I know the best practices very well. It may get slow(er) with a large number of rows in the sheet, but that's the only way to get the last row of a specific column while other columns in the sheet may have more or fewer populated rows. The code in the answer you posted will return the number of the last row in the sheet, disregarding is column C has fewer populated rows than that. – azawaza Sep 26 '14 at 15:55
  • 1
    Wrong ... it will return the value of the specified column ...please feel free to test before being so assertive. Column as letter parameter ("c") in this case. – Serge insas Sep 26 '14 at 15:58
  • Btw I'm actually testing about every code I post around here... sometimes I might be wrong but certainly not on such basic requirement... And I did test this one of course :-) – Serge insas Sep 26 '14 at 16:03
  • @Sergeinsas Apologies. You are indeed correct. I was actually setting up your code to test when I accidentally posted my comment. Your code also runs about 5 times faster in a sheet with 1000 rows. Upvoted. – azawaza Sep 26 '14 at 16:03
  • Thanks, no bad feelings :-) – Serge insas Sep 26 '14 at 16:07