To implement something like Excel's Structured References, try this: The following Apps Script will add a function to created Named Ranges in the format SheetName_ColumnHeader for the contiguous range (basically, a table) surrounding the cell you have selected. If the Named_Range already exists, it will overwrite it. You'd have to run it again every time the table length increases, but if your data is relatively static it does the job nicely.
function createStructuredReferences() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = SpreadsheetApp.getActiveSheet();
const re = new RegExp( '[^A-Za-z0-9]+', 'g' );
const sheet_name = sheet.getName().replace(re,'');
console.log( sheet_name );
const rng = sheet.getActiveRange().getDataRegion();
const dr_height = rng.getNumRows();
const dr_width = rng.getNumColumns();
const dr_row1 = rng.getRow();
const dr_col1 = rng.getColumn();
const headers = sheet.getRange( dr_row1, dr_col1, 1, dr_width )
const header_names = rng.getValues()[0].map( (h) => h.replace(re,'') );
console.log( header_names );
const namedRanges = sheet.getNamedRanges();
for ( let i = 0; i < dr_width; i++ ) {
let name = sheet_name + "_" + header_names[i];
let range = sheet.getRange( dr_row1 + 1, dr_col1 + i, dr_height - 1, 1 )
for ( var j = 0; j < namedRanges.length; j++ ) {
let nr = namedRanges[j];
if ( nr.getName() == name ) {
ss.removeNamedRange( name );
}
}
ss.setNamedRange( name, range );
}
};
You'll also want to add a Named Function called AT
which simulates Excel's table[@Column] behaviour.
=INDEX( range, ROW() - ROW( range ) + 1 )
Then you just called it like so: =AT([named_range])
.
Here's a file you can use as a template with both of these features built in: Structured References Template