2

In Google Apps Script there is a method getNamedRanges() on Spreadsheets and Sheets which returns a LIST of Named Ranges. But there is no getNamedRange("Name") which returns a SINGLE named range.

This seems odd to me.

To get round this, I'm using this convoluted process:

function testing()
{
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var nameOfNamedRange = "NameOfMyNamedRange";

  var namedRanges = ss.getNamedRanges();

  /* ###### THIS IS WHAT I HAVE TO DO ######### */
  for (i = 0; i<namedRanges.length; ++i)
  { var nRange = namedRanges[i];
    if ( nRange.getName() == nameOfNamedRange )
      {
        /* Process nRange
        doSomething(nRange);
        */
        Logger.log(nRange.getName());
      }
  }

/* ############ THIS IS WHAT I'D LIKE TO DO (or something similar) ##########
    var nRange = ss.getNamedRange("NameOfMyNamedRange") // ...Range   not ...Ranges

*/
}

Is there an easier way to do this? I can't help thinking I'm missing something obvious.

Rubén
  • 34,714
  • 9
  • 70
  • 166

3 Answers3

1

For example, how about using the method of getRangeByName()?

Modified script:

var ss = SpreadsheetApp.getActiveSpreadsheet();
var nameOfNamedRange = "NameOfMyNamedRange";
var nRange = ss.getRangeByName(nameOfNamedRange); // Added

Reference:

Edit:

When you want to retrieve a single named range, how about the following sample script, because there are no methods for directly retrieve the single one? The name of named range is only one in the Spreadsheet. This can be used. Please think of this as just one of several answers.

var ss = SpreadsheetApp.getActiveSpreadsheet();
var nameOfNamedRange = "NameOfMyNamedRange";
var nRange = ss.getNamedRanges().filter(function(e) {return e.getName() === nameOfNamedRange})[0]; // Added
Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • Sadly, not. The hint is in the name of the method getRange..... It returns a Range, not a Named Range. Seems to me that getNamedRange(...) is simply missing. – Alex Goodall Feb 02 '19 at 10:53
  • @Alex Goodall I'm sorry for the inconvenience. I updated my answer. Could you please confirm it? – Tanaike Feb 03 '19 at 00:16
  • 1
    That works very neatly. Much more compact than my clunky method. Thanks @Tanaike. – Alex Goodall Feb 03 '19 at 12:24
1

Unfortunately there is no function to return a single NamedRange instance. But you can clean up your current work-around and wrap it up into a utility function as follows:

(function(scope){
    const Utils = scope.Utils || (scope.Utils = {});

    /**
     * Filter function
     */
    function filterByName(namedRange) {
        return this.name === namedRange.getName();
    }

    /**
     * Gets named range by name.
     *
     * @param {Spreadsheet|Sheet} context - An instance of Spreadsheet or Sheet.
     * @param {String}               name - The name of a NamedRange.
     *
     * @return {NamedRange} A NamedRange or null if not found.
     */
    function getNamedRangeByName(context, name) {
        if (!context || !context.getNamedRanges) {
            throw new Error("Invalid context object; must implement getNamedRanges()");
        }

        var filtered = context.getNamedRanges().filter(filterByName.bind({name:name}));

        return filtered.length ? filtered[0] : null;
    }

    Utils.getNamedRangeByName = getNamedRangeByName;
})(this);

Just add the above script to your project and then call it as follows:

var ss = SpreadsheetApp.getActive();
var nameOfNamedRange = "[NAME_OF_NAMED_RANGE]";

var namedRange = Utils.getNamedRangeByName(ss, nameOfNamedRange);
TheAddonDepot
  • 8,408
  • 2
  • 20
  • 30
  • Thanks for this, Dimu Designs. I've come back to doing some programming after MANY decades - and using Javascript for the first time. So I very much appreciate the professionalism of your solution - there's a lot there for me to learn from. However, @Tanaike's solution still best fits my immediate needs. – Alex Goodall Feb 04 '19 at 12:50
0

Actually there is a way to get a named range. Let say I have a named range A1:B3 called "Test".

var values = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("Test").getValues();

Will return the values in A1:B3. Or more simply.

  var values = SpreadsheetApp.getActiveSpreadsheet().getRange("Test").getValues();

If the objective is to change the name try this.

var spread = SpreadsheetApp.getActiveSpreadsheet();
var range = spread.getRange("Test");
spread.setNamedRange("Other",range);
TheWizEd
  • 7,517
  • 2
  • 11
  • 19
  • 1
    There are certain range names that cause problems. AFAIK the official docs doesn't mention any limitation. – Rubén Feb 02 '19 at 16:35
  • Again, that returns a Range, not a Named Range. It's fine for getting the values, but not for changing the name, or moving the Named Range to a different sheet, for example. – Alex Goodall Feb 03 '19 at 12:26