How to Automatically Navigate to the First Empty Row in a Google Sheet using Google Apps Script

Google Sheets onOpen activate next empty row

Google Sheets, Google Apps Script: SpreadsheetApp, PropertiesService, Binary Search, onOpen, Button

Ever had to open a huge data entry spreadsheet an all you want to do is enter your data and move onto another task? Instead, you have to waste precious time navigating all the way down to the bottom of the page to add your data.

Boo!!!

Wouldn’t it be cool to just jump down to the first empty row and get clicky-clacking away?

Behold, dear biped! This friendly coding goat has a little gift for you.

In this tutorial, we are going to tackle two ways to automatically move down to the first available empty cell. One will be super easy and the other slightly more tricky, fun and versatile (You can thank one of the Google Apps Script outreach gurus for the inspiration for this one).

We’ll show you how to set up this little code so it can be run via a button at the top of your page or when you open the Google Sheet workbook each time.

Note! As always feel free to read the entire tutorial or take what you need. There is a quick start guide for those people who just want to copy and paste into their own projects and a deep dive for those who want to understand the code. 

Contents

Scenario 1: The Super Easy Way

Let’s say we have a simple data set that the user needs to enter a new row of data each time the open the Google Sheet workbook.

Something like this:

Sample File - Google Sheets first empty cell at end of data

In the image above, each time the physicist publishes a study they enter their name, the day’s date the Semester and then drag down column’s D and E to get the running totals for overall published papers and total published papers by semester.

Each time the users open the Active Cell Last Row Google Sheet file they would have to scroll all the way down to the bottom to do this. Considering how prolific these authors appear to be, this could take some time to navigate to the bottom to enter their data. Time that could be spent on more SCIENCE!!!

Let’s give these heroes of the cosmos a hand with a simple code snippet.

Top

The Code

Super simple, right?

Top

Quick Use

To use this on your own project all you have to do is change the sheet name in line 10 to your own sheet tab name. Just make sure it’s in single or double inverted commas. For example:

'Sheet1'

Click here for a beginner’s guide on how to add your code to your Google Sheet.

Unfortunately, this short-sweet code has a number of limitations that we will cover in our second Scenario.

Top

Code Breakdown

When the jumpToFirstEmptyBasic() function is run on line 8, it first grabs the active spreadsheet using Google Apps Scripts SpreadsheetApp Class. In our case, this is the spreadsheet we opened and added our code to in the script editor:

Active Cell Last Row

On line 10, we then grab our desired sheet tab inside our Google Sheet workbook. For our example, the sheet tab we are looking or is “AstroPhizzz”.

AstroPhizzz Google Sheet Tab

It’s this line that you should change to update your own project.

Next, we want to get the last row that contains data in it in our sheet. Google Apps Script has a handy method for this, getLastRow().

In our example, this will give us row 416.

Google Apps Script getLastRow example2

We will want our users to start one row below the last row of data. They will probably want to start by entering their name too.

Our goal is for the user’s Google Sheet to navigate to where they need to enter their data. In other words, we want to make the first empty cell the active cell for the user.

Line 14 achieves this by first grabbing the sheet. It then gets the range within the sheet we want to make active. we do this with the getRange method.

The getRange method can take either A1 notation like, B7 or C2:G10, or it can take a number value. For example for a single cell range  it would take the row and then the column:

sheet.getRange(row number, column number)

When numbering the columns simply remember that column A is 1, column B is 2 etc.

Back to our code, and our row will be our lastRow variable plus one to get us to our first empty cell. We want to start in column A, so our column will be 1.

The last part of the code in line 14 makes the cell active with the activate() method. You can tell by the blue emphasis around the cell when you run the code.

sheet.getRange(lastRow+1,1).activate();

That’s all there is to it. Let’s see how we implement it to run when the Google Sheet workbook is opened or via a button.

Top

Running the Code when the Google Sheet Workbook Opens

Google Apps Script has a convenient trigger function that can run code when your Google Sheet workbook opens, onOpen().

To run our jumpToFirstEmptyBasic() function when the Google Sheet file opens simply add it to the onOpen() trigger function like this:

Google Sheets onOpen activate next empty row

Top

Running the Code When a Button is Clicked

Perhaps you prefer to have a simple button at the top of the Google Sheet, say on row 1, to quickly get you to the bottom. Like this:

Google Sheets Button to bottom of data

You can create a simple button by going to Insert > Drawing. Then using the shapes and text box in the drawing app create a button. Save and close the drawing.

Next, right-click the new button and some eclipses will appear in the top right of the image. Click them and select Assign a script and add your function to it.

You can get more details on this by following this tutorial:

Google Apps Script: How to Connect a Button to a Function in Google Sheets

Google Sheets on button click activate next empty row

Top

Scenario 2: The more difficult, but more useable way

Scenario 1 is fine an all, but what if our data input spreadsheet is a little more complicated? What if we decide to automate some of the processes for our users and drag down the Semester Count and Total Submissions. We also want to provide the semester for the user with a formula that is hidden until the date is entered.

The problem is that if we use the code back in scenario 1, it will take us all the way down to the last cell we dragged column C, D and E data to. In our example, it will take me to A:1000, which is not where it is meant to be.

Top

The Code

Note! You can pop out the code so that you can follow along with the quick use guide and code breakdown. 

Google Sheets on button click activate next empty row with other cols

Top

Quick Use

To set this up in your own project, simply copy and paste in the code into your Google Apps Script Editor.

Next change variable col on line 9 to the column you want to use as your reference. For example:

var col = "D";

Then change the Google Sheet tab name to the Sheet tab you wish to reference on line 12. For example:

var sheet = ss.getSheetByName("YourSheetName");

You can then either connect it to your onOpen trigger function or a button (see above).

Looking to learn more about Google Apps Scripts in a more structured format? Udemy has some great courses that can get your from the basics to a real Google Apps Script pro!

Got a more specific problem you need help with, but don’t have the time to develop the skills? Fiverr’s your best bet to find a skilled Google Apps Script professional to solve your problem quickly and cheaply. *

*The above affiliate links have been carefully researched to get you to what you specifically need. If you decide to click on one of these links it will cost you just the same as going to the site. If you decide to sign up, I just get a little pocket money to help pay for the costs of running this website.

Top

Code Breakdown

Hey! You made it to the fun stuff!

Before we go step-by-step through the code, let me explain a couple of things we needed to consider first.

We are going to iterate through a selected column to find the first empty cell. We also want to do it fast.

To do this we are going to use two tools:

  1. PropertiesService: We will use this Google Apps Script Class to store the empty row of the previous time we ran our code. This will allow us to reduce the range of rows we need to iterate through each time to find the first empty cell.
  2. Binary Search: Binary search will exponentially decrease our iteration time. It works by looking at the midpoint of our range of rows. If the primary condition is not met, it will halve the top or bottom half depending on another set of rules. It will then check the primary condition again. It will continue to do this until it finds the primary condition. More on this when we get there.

Top

Getting the Data

On line 9 we first set what column we are going to use as our iterator. For us, this is column A.

var col = "A";//<< Add your selected reference column

Next, on 11 and 12 we first grab our active Google Sheet workbook with the ss variable using the SpreadsheetApp class. We then call our target sheet tab. In our example, this is our “AstroPhizz” Sheet using the getSheetByName method.

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("AstroPhizzz");//<<Add your sheet data

So now we want to be able to save the end location from the last time we ran our search so that we are not iterating through all the rows from the top of the sheet again.

Top

PropertiesService

We can store data, like an object, in key-value pairs (e.g. "GOAT":"Yagi") using Google Apps Script’s PropertiesService class. This means that even if we close our Google Sheet workbook, we will still have a record the row from the last time we ran our code.

On line 15, we get the document properties from the Properties Service. Document properties are available to all users that will access the assigned document.

We then assign the variable startRow to the last row we saved in our document properties. The row value was saved under the key 'LAST_ROW'.  We use getProperty to call that value.

Note! All Properties Service values are stored as strings. You will need to convert things like numbers from their string state before use. 

var docProperties = PropertiesService.getDocumentProperties();
var startRow = docProperties.getProperty('LAST_ROW');

Next, we want to check to see if we actually have a value in the LAST_ROW key. If it is the first time we run our code, then we won’t have a value and will return null. If this is the case, then we want to assign startRow to 1 so it can start from the top of the page.

 if(startRow === null){
    startRow = "1";
  }
Time to get all the values in column A using the getRange method for our sheet (Line 24). The getRange method can take a number of different parameters. This time around we are going to use A1 notation as our parameter format.  We’ll join our col variable to the startRow variable to get our starting range. We’ll then join that to the col variable again and then get the last row of our sheet.
var range = sheet.getRange(col+startRow+":"+col+sheet.getLastRow());
Let’s say our startRow is row 400 and the last row – where we have dragged down all our other formulas in the other columns  – is 1,000, the getRange  might look like this:
var range = sheet.getRange("A400:A1000");
Once we have the range we can then get the values as a 2d array (line 25).
var rangeVals = range.getValues();
The array would look a little like this:

Top

Running some verification

Before we get cracking with our binary search it would be beneficial to run some checks on the data first.

Top

Check if data has been deleted

If users have been deleted from our dataset since the last time we ran our function, then the start row saved in the Properties Service will be greater than the first empty row. We need to check for this.

We can do this by seeing if our first value in our rangeVals is blank. If this is true, we can reset our Properties Service property with setProperty to row 1 again. We then call our function again recursively.

Lines 27 to 32 take care of this.

Note that the setproperty method takes the key value, in our case 'LAST_ROW' and then the new value as a string. We will want to set this to '1'.

Top

Check if the range contains all values and no empty cells

Alternatively, if the range only contains cell values in each row of data and there are no empty cells, then the first row will be the sum of the startRow function plus the length of the rangeVals.

If we check the last value of our rangeVals to see if it is not equal to blank, then we know that the entire range contains values (Line 34).

We then get our row by adding the rangeVals to the startRow (Line 36).

Next, we add col to our row and set it to Activate.  The sheet will then travel to that cell for the user to add their data.

Finally, we need to update our LAST_ROW value in our Properties  Service with our new row.

Top

Binary Search

For the binary search, I shamelessly hacked the example from GeeksforGeeks. Of course, it needed quite a bit of modification to get where I wanted.

The row we want to find is the first empty cell below the last entered data. The condition we need to meet then is that if the current row item is equal to empty (“”) and the previous row item is not equal to empty, then this is the first empty cell.

If this condition is not met, then we ask if the current row and previous row are both equally empty then we want to look at the halfway point above the currently assigned middle.

Alternatively, if the current and previous row item both contain values then we want to look at the halfway point below the currently assigned middle.

If the primary condition is not met then the loop continues halving away at the data until it finds it.

Let’s go through the steps.

On line 42, we set the start and end variables. The end variable is the length of the rangeVals-1.

Line 44 commences the while loop continuing the loop if the start is less than or equal to the end.

Next, on line 45, we assign the middle point with the mid variable. To do this, we add the start to the end and divide by two. We then use math.floor to round down. math.floor is used here so as not to exceed the length limit of the array.

We then set our primary condition on line 47. If the current row value is empty and the previous row value is not empty, then we want to activate that cell and update our LAST_ROW value in Properties Service.

On line 49, we get our last empty cell range. We add the col to the sum of the startRow and the mid variable. The cell is then activated.

Line 50, then sets the new LAST_ROW value.

Lastly, we break the loop. Job’s done.

Our first failure condition is when both the current and previous rows value are both equal empty (Line 53). If this is the case, then our desired cell is somewhere above the midpoint. We can then reset our end value to the mid minus one. The loop is then repeated.

Alternatively, if both the current and previous rows contain a value, our desired value is below the midpoint. We then reset our start value to the mid plus one and repeat our loop.

Done the jumpToFirstEmpty() function is complete.

Top

Conclusion

Both the easy scenario 1 function and the more complex scenario functions have their uses. However, jumpttoFirstEmpty() is designed to meet scenario 1’s conditions too. It is certainly more versatile, particularly in more complex data entry Google Sheet environments.

jumpToFirstEmpty does, however, have its limitations. Imagine if your data is a bit patchy and there are a few empty cells somewhere in the middle of your data. In this case, the binary search may display a false positive and activate an empty cell in the middle of your data. How would you resolve this?

Have a look at the tutorial below and see if you can combine what you learnt here with that tutorial to fix this issue.

Google Apps Script: Get the last row of a data range when other columns have content like hidden formulas and check boxes

So what did you use this on? I would love to hear in the comments below. It’s always interesting to see how these code snippets are applied to other projects.

Happy coding!

~Yagi

Top

8 thoughts on “How to Automatically Navigate to the First Empty Row in a Google Sheet using Google Apps Script”

  1. I found this very helpful – thank you.

    Do you know how I would go to the last empty row in column B with a particular value in column A?

    For example if column A is Class A, Class B or Class C and column B is student name and I want to jump to the next empty space for a student in Class B.

    Thanks
    Ger

  2. Hello

    Thanks so much for the code and for the in depth explanation.

    I have used the code in a sheet. One question I have is, can it be changed so that it can search for the first empty cell in any sheet in the workbook? I need to find the empty cell in two different sheets at different times. This code only works on the sheet I’ve named.

    I have attempted to edit, however, am such a novice at script that I can’t seem to get it to work.

    Any further help is greatly appreciated.

    B

  3. Why can’t there be a keyboard shortcut or like in Excel you can hit End then the down arrow & that moves you down to the next empty cell. All this code seems too much if you ask me

Leave a Reply