I make some named range on my Google sheet like
order_id: A2:A1000
New rows are added to this sheet via Zapier. After a while, I found the named range has become
order_id:A2:A1035
How to prevent this behavior and make the range stays A2:A1000?
solution to this kind of depends on it's purpose and how you're using the named range downstream (in appScript?, just formulas?)
seems like the way to do this is to make the named range:
order_id: A2
then, in your code, use
sheet.getRange('order_id').offset(0,0,1000)
maybe?
I have been checking the documentation for Named ranges, it does not mention anything about that behavior.
I have been testing and I noticed the named range will expand when the rows are added within the range selected, not outside of it. I'd say the behavior is expected to avoid leaving data outside of the range accidentally.
If you are a Google Workspace customer you can try submitting a Feature Idea since I do not see a way to leave the named range locked.
Related
I am very fresh with Excel and still learning the basics. I came upon an issue I really need help with and couldn't find suitable solution online.
I have a column I keep on constantly updating with Bulk data THE COLUMN.
I'd like to see the most common entry and the least common entry for a specific time using this formula:
=INDEX('Data Input'!F433:F610,MODE(MATCH('Data Input'!F433:F610,'Data Input'!F433:F610,0)))
But once I try it, it constantly tells me:
Did not find value '' in MATCH evaluation.
I've tried with shorter ranges and It did work, so I guess once it runs through empty cell - it breaks. How can I modify this formula to function properly and print what I need?
And side question, is is possible to implement a calendar bar and choose between dates?
You can insert a clause to exclude blanks (assuming they are not to be considered a legitimate return):
=INDEX('Data Input'!F433:F610,MODE(IF('Data Input'!F433:F610<>"",MATCH('Data Input'!F433:F610,'Data Input'!F433:F610,{0,0}))))
Note that I have used
{0,0}
for MATCH's match_type parameter so that the formula will not error should there be more than one entry within your range which shares the highest frequency. In such cases, the above formula will return that which occurs first in your list.
I have this formula in a cell in a 'Summary' sheet which is waiting for a new sheet to be created with its name being a date:
=IFERROR(VLOOKUP($A3, INDIRECT("'"&TEXT(BN$2,"m/d/yyyy")&"'!$E$6:$o$100"), 11, false), "")
However, when I add the new sheet with the name that would match, then it doesn't automatically recalculate and pull in the values from the new sheet.
The weird thing is if I add a column to the left of this column that has the formula shown above, then it recalculates ... and all is well. Another weird thing is if I add a column far enough away from the column in question then it doesn't recalculate in the same way that it does when I add a column near the column in question (hmmmm....).
What is going on here? And how can I work around it? Seems Google has some major bugs around this area or something ...
This is due to INDIRECT.
A partial workaround:
=IFERROR(INDIRECT("'"&C9&"'!A1"),RAND())
Use this instead of just INDIRECT in your formula. It still won't update on opening and closing. But it'll update, Whenever there's a edit anywhere in the sheet (making this a double volatile combo with RAND()).
Also, Try turning on recalculations every 6 hours or so in spreadsheet settings.
PS: Your Spreadsheet might burn🔥🔥 due to the heavy volatility.
Sorry for the late response, but I believe I have a solution that works a little better. I was experiencing the same problem with formulas involving almost exactly the same set of formulas.
Basically, just add in a check to see if now() equals an impossible time (0), and when it fails (every time), have it execute the formula that won't update on its own.
=IF(NOW()=0,"",
IFERROR(VLOOKUP($A3, INDIRECT("'"&TEXT(BN$2,"m/d/yyyy")&"'!$E$6:$o$100"), 11, false), "")
)
based on idea similar to TheMaster I defined a named range refresh and refered to it in the else portion of the IFERROR formula.
Whenever I create a new sheet, rename an existing one, or feel the need to make sure all indirects are updated I simply edit the content of refresh, and put it back to blank.
=arrayformula(iferror(indirect(B11&"!D42:H42");refresh))
I used Berteh's idea, but found that putting the refresh range within the else portion of the iferror removed the benefit of having a way to have a blank cell if there is no value, or what ever else you'd want to use the else for.
So, to maintain that, I put this together which seems gets us the benefit of preserving the benefit of using iferror and forcing the indirect to update.
=IF(refresh!$A$1=1,IFERROR(VLOOKUP($B68,INDIRECT(D$66&"A1:aa2000"),8,0),""))
Updating the value of the refresh range will force a recalculation (I change the value of cell A1 from 1 to a 0 and then back to 1). I've implemented this on multiple rows across multiple sheets and not found this to blow up the Google Sheet.
In column B are listed IDs of Google Sheets. In column C are listed cells, from which I want to import data.
Screenshot of the table
In column D is shown the result of using IMPORTRANGE() by simply dragging it. e.g. for D1 it looks like:
=IMPORTRANGE(B1;C1)
for D2:
=IMPORTRANGE(B2;C2)
and so on.
In column E I want to display the same result but using ARRAYFORMULA that looks like:
=ARRAYFORMULA(IMPORTRANGE(B2:B4,C2:C4))
but the function displays only the data from the first spreadsheet.
People complain about this permissions issue a lot, but it's not hard to solve. What I do is have a sheet which I name "Splash sheet" into which I paste the URLs of the documents I wish to link. To its right is a column headed "permit to connect" which contains IMPORTRANGE formulas importing a single cell from each sheet -- usually a cell containing a confirmation code, number or document name -- on a sheet also named "Splash Sheet." For example,
=IF(B3="enter URL",,CONCATENATE(IMPORTRANGE(B3,"Splash sheet!A1")," ",IMPORTRANGE(B3,"Splash sheet!B1")))
So, when you first connect a spreadsheet via its URL, you get those messages telling you you need to connect, you click the Permit Access, the confirmation code/number/document name appears in the second column, and voilá, your sheets are connected forevermore! Now all your other IMPORTRANGEs referencing that URL will work, and you can use IMPORTRANGE formulas that reference the URL-containing cells on the "splash sheet."
As for the OP's original question, I came here seeking an answer to the same problem, and after more research have realized that we are attempting the impossible here. No way to do this an ARRAYFORMULA. No way around writing formulas that reference every single cell a document's URL may go into.
Problem is you can't make arrays of arrays in spreadsheets; that would involve multiple dimensions, and the medium is inherently two-dimensional. This is what people use databases for.
ARRAYFORMULA doesn't work when importing data (I think it relates to permissions). You could use something like this, =IFERROR(IMPORTRANGE(B5:B7;C5:C7)) and pre-fill the column first, but still there would be the permissions issue. Each new imported sheet needs it's permissions granted by a user.
TLDR: If I understand your intention correctly when you say you would like to see
=ARRAYFORMULA(IMPORTRANGE(B2:B4,C2:C4)), I believe you can make that
happen using the following.
=ARRAYFORMULA(IMPORTRANGE(
INDIRECT(ADDRESS(ROW(B2:B4), COLUMN(B2:B4)),
INDIRECT(ADDRESS(ROW(C2:C4), COLUMN(C2:C4))
)
Breakdown
Use IMPORTRANGE with INDIRECT to create ranges inside ARRAYFORMULA
Call INDIRECT with the ADDRESS function
Call ADDRESS with the ROW and COLUMN functions since they take ranges via ARRAYFORMULA
using IMPORTRANGE with INDIRECT
IMPORTRANGE's two parameters are the spreadsheet url stored in B2:B4 for this example and the range (e.g. sheet!A1:B2) stored in C2:C4.
Since IMPORTRANGE doesn't take a range reference directly as you mentioned, you'll need to build it for each row with ARRAYFORMULA using the INDIRECT function.
INDIRECT can be used to compose a cell reference using A1 notation, for instance
=IMPORTRANGE(INDIRECT("B" & 2), INDIRECT("C" & 2))
will produce the same result as
=IMPORTRANGE(B2, C2)
Since this produces the same result, we now just have to find a way to make INDIRECT work with ARRAYFORMULA
Use ADDRESS to build the parameters for INDIRECT
Next you want to use ADDRESS to build the A1 reference for INDIRECT. For the current purposes, ADDRESS takes a numerical value for row and column as parameters
=INDIRECT(ADDRESS(2,2))
will produce the same result as
=INDIRECT("B" & 2)
Since these two are interchangeable, now we just need to find a way to get the numerical row and column values out of ARRAYFORMULA.
Call ADDRESS using the ROW and COLUMN functions
From there, you can get the row and column indexes from standard A1 notation using the ROW and COLUMN functions. While this may seem like we're pointlessly going in circles, the difference now is that ROW and COLUMN perform as expected with the ranges provided by ARRAYFORMULA. So given that ADDRESS will return $B$2 using using either method below
=ADDRESS(2,2)
or
=ADDRESS(ROW(B2),COLUMN(B2))
we now know that
=ARRAYFORMULA(ADDRESS(ROW(B2:B4),COLUMN(B2:B4)))
will produce the following array of addresses
{ $B$2; $B$3; $B$4 }
Final Assembly
So when we put this all together, we get
=ARRAYFORMULA(IMPORTRANGE(
INDIRECT(ADDRESS(ROW(B2:B4), COLUMN(B2:B4)),
INDIRECT(ADDRESS(ROW(C2:C4), COLUMN(C2:C4))
)
where INDIRECT(ADDRESS(ROW(B2:B4), COLUMN(B2:B4)) is more or less interchangeable with what you might expect from B2:B4 inside ARRAYFORMULA and represents the url parameter
and INDIRECT(ADDRESS(ROW(C2:C4), COLUMN(C2:C4)) is roughly interchangeable with what you might expect from C2:C4 inside ARRAYFORMULA and represents the range parameter.
Suggestions on organization
I recommend using the indentation (Alt +Enter to create a new line ) above along with your indentation of choice to keep it easier to read. In the end it's just a bit more syntactic sugar and if spaces are used well it shouldn't be much harder to understand and make changes to 6 months later.
RE: Permissions - as mentioned by Atiq Zabinski, just placing a simple
IMPORTRANGE("http:/xxxx", "A1") somewhere on the sheet will provide a
means to know if the sheet is connected or not and the error message
should give you a context menu for connecting the sheet. You'll might
want to stay away from error handling in these scenarios as it will
slow down the process of connecting the sheets.
I have found that any time a #REF! error exists, google sheets permanently replaces the incorrect reference in the formula to #REF!. Even if it was just a typo where one letter was off and all that it would have taken to fix it was to delete that extra character.. huge time waster, and also has made me lose quite a bit of work when I can't remember which reference went where in a complicated formula.
Anyone know of a fix?
Even though formulas display the name, Named Ranges used in formulas actually refer to the Named Range objects and not the names themselves. When you delete a named range you are deleting the object that the formula refers to. Creating a new named range with the same name is not the same object used in the formula. To change the range that the Named Range refers to one should modify the Named Range object instead of deleting it and creating a new one.
setRange(range)
Sets/updates the range for this named range.
https://developers.google.com/apps-script/reference/spreadsheet/named-range#setrangerange
The reference being replaced is by design. a suggestion has been submitted to Google to only put #REF! As the outputted value, instead of modifying the existing formula.
I love the idea of named ranges for making formulas less obscure. However I have yet to find an easy way to actually use them.
E.g. when entering a sum, I normally do
=sum(
then mouse to the blob of stuff I want
then type )
If I want to use a named range, I have to type in the full name manually.
I've tried having the named range sidebar open and clicking on that. Still fills it in column row syntax.
EDIT: New Sheets allows you to click on a range name and it is stored in the formula as a range name.
I've also tried starting to type the name of the range, in hopes that it would try to guess ahead. No joy there either.
Is there a way to automate the use of named ranges? E.g. a script that looks for ranges in your sheet, and compares them to the list of named ranges, and substitutes the named range for the column row syntax?
I don't believe it would be possible, AFAIK, to have the Autocomplete work with named-ranges in that way. To do so, according to GAS documentation one would have to declare a function for each named-range that merely returns its own range, and then call that when wanting to use that range in a function. I believe that GAS prevents the automation of JavaScript code generating other code, so these 'identity' functions would have to be written by hand, somewhat defeating the purpose of adding convenience. I cannot find a link that backs this assumption up, so I apologize for the anecdotal evidence merely based on my experience.
Using the name of namedRanges to conjure up its range is, as of this writing, already baked into Spreadsheets functionality (which I found out at this very moment), so you won't have to have it fill in the A1 range syntax if you'd prefer to use the name itself.
Hope this helps. Cheers!