Menu actions and sidebar handoffs usually care about the row you're on, not the whole grid. getActiveRowAsObject reads the header row plus the active row into { header: value } (plus _row). Different from rowsToObjects (bulk) and appendObjectAsRow (write path).
What you'll need
- A sheet with a header row (default row 1)
- The user selection on a data row (not the header)
- Exact header strings as object keys (trimmed)
How to use this snippet
function getActiveRowAsObject(sheet, headerRow) {
sheet = sheet || SpreadsheetApp.getActiveSheet();
headerRow = headerRow || 1;
var row = sheet.getActiveRange().getRow();
if (row <= headerRow) {
throw new Error('getActiveRowAsObject: active row is in the header');
}
var lastCol = sheet.getLastColumn();
if (lastCol < 1) return {};
var headers = sheet.getRange(headerRow, 1, 1, lastCol).getValues()[0];
var values = sheet.getRange(row, 1, 1, lastCol).getValues()[0];
var obj = { _row: row };
for (var i = 0; i < headers.length; i++) {
var key = String(headers[i] == null ? '' : headers[i]).trim();
if (!key) continue;
obj[key] = values[i];
}
return obj;
}
Example
function menuPushActiveLead() {
var lead = getActiveRowAsObject();
if (!lead.email) {
SpreadsheetApp.getUi().alert('Select a row with an email');
return;
}
// hand off to your API / sidebar
pushLead_(lead);
SpreadsheetApp.getActiveSpreadsheet().toast(
'Pushed row ' + lead._row + ' (' + lead.email + ')',
'Leads',
4
);
}
Tips:
_rowis the 1-based sheet row — handy for writing status back without another lookup.- Blank header cells are skipped; duplicate headers overwrite earlier keys — fix the sheet.
- For bulk imports, use
rowsToObjectson a blockgetValuesinstead of calling this in a loop.
Happy Coding!
