getRange and getValues
sheet.getRange("A1:C10").getValues() returns a 2D array (an array of rows, each row an array of cell values); sheet.getRange("A1").getValue() returns a single value. getRange also accepts numbers: getRange(row, column, numRows, numColumns). Reading a whole block once is far faster than reading cells one by one.
Syntax
sheet.getRange(a1Notation) | sheet.getRange(row, column, numRows, numColumns) then .getValue() or .getValues()| Part | What it is |
|---|---|
row, column | 1-based position of the top-left cell |
numRows, numColumns | Size of the block; default 1 each |
getValues() | 2D array; blanks are empty strings, dates are Date objects |
getDisplayValues() | Same shape but strings exactly as shown in the sheet |
Examples
const sheet = SpreadsheetApp.getActiveSheet();
const data = sheet.getRange("A1:B3").getValues();
Logger.log(data);Result: [[Name, Qty], [Pens, 12.0], [Paper, 5.0]]
data[1][0] is Pens, data[1][1] is 12.
const price = sheet.getRange(2, 3).getValue();
Logger.log(price * 2);Result: Twice the number in C2, for example 19.9
const all = sheet.getRange(2, 1, sheet.getLastRow() - 1, 4).getValues();
Logger.log(all.length);Result: Number of data rows below the header, for example 120
This is the standard way to read everything except row 1.
const shown = sheet.getRange("A2").getDisplayValue();
Logger.log(shown);Result: 11/03/2026 (the formatted text, not a Date object)
Common mistakes
- The range you requested is out of bounds: getLastRow() - 1 is 0 on a sheet with only a header, so guard with if (lastRow < 2) return.
- Logged value looks like Tue Nov 03 2026 instead of a date: date cells come back as Date objects; use getDisplayValues or Utilities.formatDate to show text.
- You read data[0] expecting a cell but get an array: getValues is always 2D, so a single column still needs data[i][0].
- A loop calls getRange(i, 1).getValue() 5,000 times and takes minutes: read the block once with getValues and loop the array.
Practice getRange and getValues
These drills check your answer on live data, free, no account needed.
- Total of a listReturn the total of an array of numbers. An empty array totals `0`. Numbers can be negative or have decimals.
- Items in stockEach item looks like `{ name, qty }`. Return the items that are in stock, meaning `qty` is greater than 0, in their original order. A negative `qty` is a back order, not stock.
- CSV text to objectsParse simple CSV text (no quoted fields) into an array of objects. The first non-blank line holds the headers. Lines end with `\n` or `\r\n`, and blank lines are skipped. Headers and values are trimmed of surrounding spaces and stay strings. A row with fewer values than headers gets `""` for the missing ones.
Questions
What is the difference between getValue and getValues?
getValue returns the top-left cell of the range as a single value. getValues returns every cell in the range as a 2D array, even if the range is one cell ([[value]]).
How do I get a whole column?
Use sheet.getRange("A2:A" + sheet.getLastRow()).getValues() or getRange(2, 1, sheet.getLastRow() - 1, 1). Reading A:A reads to the sheet's maximum rows, mostly blanks.
How do I read a sheet as objects?
Read the block, take values[0] as headers and map each row to an object: rows.map(r => Object.fromEntries(headers.map((h, i) => [h, r[i]]))).
Related
- setValue and setValuesWrite data to Google Sheets with Apps Script: setValue for one cell, setValues for a 2D array that must match the range size, and the dimension error fix.
- getLastRowFind the last used row in Google Sheets with Apps Script: getLastRow for the whole sheet, how it treats blanks and formulas, and the last row of one column.
- Loop through rowsLoop through rows in Google Sheets with Apps Script: read the data once with getValues, loop the 2D array with for, for...of or forEach, then write back.
- Performance and batchingMake Google Apps Script faster: read and write in one getValues and setValues call, avoid getRange in loops, use flush and caching, beat the 6 minute limit.