Exception: The data validation rule has more items than the limit of 500. Use the "List from a range" criteria instead - google-apps-script

I have a google sheet for Competitor backlink Audit. In previous, it was work perfectly. Last day I tried to use my sheet again and this time, it's not worked. It shows the message
Exception: The data validation rule has more items than the limit of
500.Use the "List from a range" criteria instead.
This sheet is working 4 step way.
merging various data using an app script, and it worked perfectly.
filtered merging data using various filter data.
create a data validation, and this step is not worked.
dependent on the 3rd step. So this also not worked.
I tried to fix this, but I can't figure it out.
Here is my sheet URL:
https://docs.google.com/spreadsheets/d/1T2Jsni659wK3m9ZDka875d8wIoNrxYYn55SaKsjPGrc/edit#gid=1602455067
Also, the Code is too long to share
1st URL is the main code set: https://pastebin.pl/view/4f445433
2nd URL is the helper of 1st code: https://pastebin.pl/view/99ccc65e
custom menu here

As the error message says:
You are trying to add too many options to the Dropdown.
If there are more than 500 rows in the sheet which your script tries to use as data validation options - the script will error.
Solution:
Do not use more than 500 options.
You have more values than this - try to break them down into a nested Dropdown e.g. into Main Categories and Sub categories.
Since you do not provide your script or public access to your spreadsheet, I can not give you more details, but make sure that your script does not try to assign more than 500 values for data validation.

Related

iMPORTXML is returning #NA (imported content is empty) in some cells and #REF in some cells in Google sheets

Ok. so i'm tring to import a couple of data from different urls on the same google sheet using IMPORTXML function. it works on some cells and it returns #NA (imported content is empty) on some and #REF(Array result was not expanded because it would overwrite data in H16.) on some cells. I need help right now.
This is the formula in one of the cells returning #NA imported content is empty:
=IMPORTXML(N9;"//ul[#class='important-attributes-list']/li[2]/div/div")
And this is the url i am extracting the data from:
https://www.tim.pl/koncowka-oczkowa-miedziana-km-3510-e11km-01010104100
This is the formula in one of the cells returning #REF Array result was not expanded because it would overwrite data in H16.:
=IMPORTXML(N15;"//ul[#class='important-attributes-list']/li[1]/div/a/div/span/span/span")
And this is the url it is extracting data from:
https://www.tim.pl/aparatura-elektryczna/elementy-sterowania-i-sygnalizacji/przyciski-sterownicze-kompletne/?filters%5Bmanufacturer.keyword%5D=schneider+electric&filters%5Bseria_u_dostawcy.keyword%5D=harmony&filters%5BEF000190__kolor_przycisku.keyword%5D=Czerwony&filters%5BEF001142__z_podswietleniem.keyword%5D=Tak
If you want to check ouut the spreadsheet itself, this is the link to it.
https://docs.google.com/spreadsheets/d/1Q7IV_i--1artQMzqx3O-7YGqe-_HDljCRm8bFX4tsRc/edit?usp=sharing
I do appreciate every help you can render.
#REF!
... means that the result is an array (not only one value) and there is not enough space to display the result
For instance, in G12, =IMPORTXML(N12;"//h1") the formula gives back 4 values in G12:J12, you need free places on the right hand side of G12
To get the first one, you can do =index(IMPORTXML(N12;"//h1");1;1) or join the values =textjoin(" ";;IMPORTXML(N12;"//h1"))
#N/A
... in E12 and F12 is due to the lack of ul class=breadcrumbs__list theme--light in the source of the web page, clarify whar you are looking for
in F12 you can use
=index(IMPORTXML(N12;"//a[#class='product-link-attribute__link']");2;1)
You should probably reduce the number of calls inside the urls
edit:
reduce drastically the numbers of calls, for instance, in I9, you could fetch all data at once using this global xpath
"//ul[#class='important-attributes-list']"
it will be easy then to detailed the informations inside the multi-cells result
This will solve quite 100% of your errors.

Remove characters from a cell with imported API data in Google Sheets - or format api import

I'll start by saying that my knowledge on using APIs is extremely limited. I'm impressed I've gotten as far as I have on this.
I've created a workbook in Google Sheets with imported data from the iexcloud API, which I'm using for data on stocks.
The requests have a cell reference in them so they update whenever a different symbol is selected.
So far, everything I've needed to request from it has the option to format as csv, so I can get cells with just the values.
However, this last thing I want doesn't have that option, so the whole response is wrapped in ["" ].
That really messes up what I need it for.
Here's an example
["PSA" CCI SHO ACC]
with each symbol being in its own cell.
I'm using the Peer Groups request.
A sample request:
> https://sandbox.iexapis.com/stable/stock/aapl/peers?token=Tsk_2b4c7c6fd98542f6a99f904cb7a3e721
Using Find and Replace doesn't work. I'm assuming because it's imported.
I need to use the cells with those symbols: PSA, CCI, SHO, ACC to reference in another request.
I recreated this in another Google Sheet that you can edit. The section in question in highlighted in blue
https://docs.google.com/spreadsheets/d/1BQ6FBD0S2YkDtDGZGIkDmQoKrQT4VmVDjuNsgV4mrXM/edit?usp=sharing
So I'm wondering if there's a way to have [ " ] automatically removed from any cells in that row, or if I copy and paste the values only, to have the values updated when the original cells are updated with new symbols (since I can have those characters removed in that row)
Or if there's a way I can format the response in sheets.
Any ideas?
I believe your goal as follows.
You want to achieve from ["CCI" SBAC CTL TDS RCI RCI-A-CT DTEGY] to CCI SBAC CTL TDS RCI RCI-A-CT DTEGY using the built-in functions of Google Spreadsheet.
Modified formula:
=ARRAYFORMULA(REGEXREPLACE(IMPORTDATA("https://cloud.iexapis.com/stable/stock/"&B3&"/peers?format=psv&token=###"),"[\[\]""]",""))
In this modified formula, [, ] and " are removed using REGEXREPLACE.
Please replace ### with your token at the above formula.
Result:
In this result, the values retrieved with =IMPORTDATA("https://cloud.iexapis.com/stable/stock/"&B3&"/peers?format=psv&token=###") are used. So the formula of cell "C9" is =ARRAYFORMULA(REGEXREPLACE(C6:I6,"[\[\]""]","")). But in this case, above modified formula can be used.
Note:
In this answer, I removed your token because I thought that it is your personal information.
Reference:
REGEXREPLACE

Replace INDIRECT() in data validation rule

I had a working Excel spreadsheet that used indirect() in the data validation and it worked fine. I uploaded it to sheets and converted it, now the indirect does not work.
I have found a link on the support forum that explains it does not work in Chrome but appears to work in Firefox, and the answers and workarounds seem to be for generating a secondary list... which is what I want, but in a data validation across a row.
I have knocked up a simple test sheet, hopefully public and the script editor is visible:
https://docs.google.com/spreadsheets/d/1KUgrdXKIKlk1DWvDOX9cY3B2VnRH_5h_vKuZJlqUlN8/edit?usp=sharing
Hopefully you can see what I'm after. I want the validation in C8 to be the list of items in the category based in B8; C9 based on B9 etc.
EDIT and Update
The question is about a replacement to indirect() in a data validation rule. While I did find a way round this by using indirect(), I preferred the version mentioned by Desire (to whom I have attributed the answer), but I thought I'd document my solution in case the sheet above becomes unavailable, or you cannot access it, or you just wanted a bit more detail.
So, for My Demo I have this:
In A1:C5 are my lists of data with the titles.
In the range B8:B12 I applied a data validation rule of value in range of A1:C1 - this gives the first dropdown.
In Cell E8 I put the formula =transpose(filter($A$2:$C$5, $A$1:$C$1 = B8)) and then copied this down to E12
Finally I put the following in a function and ran it in the script editor.
function runMeOnce() {
var dst = SpreadsheetApp.getActive().getSheetByName('Sheet1').getRange('C8:C12');
var rules = [];
for (var i = 8; i < 13; i++) {
var src = SpreadsheetApp.getActive().getSheetByName('Sheet1').getRange("E" + i + ":H" + i);
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(src).build();
rules.push(rule);
}
dst.setDataValidations(rules);
}
That's all there is, no more onEdit() triggering.
NOTE There is one downside I bumped into with this method though. I have this in place for 6000+ rows in my actual spreadsheet, and across multiple sheets, with some dropdowns having 50-100 items in. This solution seriously eats into the (current) 2 million cell limit.
Hope this helps someone.
Data Validation rule of the type "List of items" takes only a comma-separated list of values as its parameter, and does not evaluate any formulas you try to put there. It does not matter what the function returns, because it will not be called. If you put, say "=sqrt(A10)" in the field "List of items", that only means that the validation rule will require the string "=sqrt(A10)" to be entered in the cell.
Similarly with "List from a Range". Either what you enter parses as range notation, or it does not. The string "=getValidationRange(B8)" does not parse as range notation, hence the error. The function is never called.
The only type of validation that calls a function is "Custom formula". If you use it, then the validation can be performed as intended: for example,
=match(C8, filter(A2:C5, A1:C1 = B8), 0)
requires the content of C8 to be in the column of the table A2:C5 under the heading that matches the category in B8. However, with a custom formula you do not get a dropdown in a cell.
To get a dynamic dropdown, one can either
Use an auxiliary range
For example, enter filter(A2:C5, A1:C1 = B8) in cell F1, so that the F column is for the categories currently selected. The data validation would be "List from a Range", F1:F. This is a fine workaround for one validation rule, but takes more work when you have multiple ones.
Use a triggered script
Use a script that is triggered on edit and sets data validation rules accordingly; this is discussed in How do you do dynamic / dependent drop downs in Google Sheets? among other places.
Based on the sacrificing a goat issue, I did find a simple(ish) way around the problem that still uses indirect().
Set up the named ranges as previously using the titles in CamelCase. In my example I have CatA, CatB, and CatC - i.e. the white space needs removing.
At the end of a row (or in another sheet) transpose the chosen named range (in cell E8: =transpose(indirect(substitute(B8, " ", ""))) copy this down as far as you need.
At this point it's good to note that because we are unsing builtin functions, the speed is so much better, as can be seen by my example.
Now the painful bit. For each subcategory cell (C8, C9 etc in my example), you need to add the validation independently as a range of E8:ZZ8 (obviously ZZ8 needs reigning in a bit) and E9:ZZ9 etc. It doesn't seem to do referential so if you select all the cell in the column, they all only look at the data you specifically type in the box... I might just not have worked out R1C1 notation here, however. I tried.
This can be scripted on GAS to create the R1C1 validation function and then apply it to the range.

Retrieve Google Spreadsheet Worksheet JSON

I try to receive the JSON of a Google Spreadsheet Worksheet. It worked till some days ago. For the default worksheet it still works, but not for all other worksheets.
This is the working URL for the default worksheet: https://spreadsheets.google.com/feeds/list/1caRqAA1TyBoZ0eVZvvKheEBh9SGRmQII4qih9urY70k/od6/public/full?alt=json
And this is the URL for the worksheet that stopped working: https://spreadsheets.google.com/feeds/list/1caRqAA1TyBoZ0eVZvvKheEBh9SGRmQII4qih9urY70k/1416241220/public/full?alt=json
The error message is Invalid query parameter value for grid_id.
Only difference is the worksheet parameter (od6 vs 1416241220).
Any ideas on why that error suddenly occurs?
ChrisPeterson's note:
You can use worksheet position number (1 for the first/default worksheet, 2 for the second worksheet).
Original answer
I came across the same issue and I managed to find my way out.
It seems that they recently changed the id for each worksheet.
You can find the new ID at the following
https://spreadsheets.google.com/feeds/worksheets/YOUR_SPREADSHEET_ID/private/full
I got something like o3laxt8 between <id> tags
Ps: od6 anddefault values will always work and redirect to the first worksheet of your document.
Joe Germuska' note:
od6 doesn't work anymore
Seems to work again.
I'd like to share a concrete example because I find there are enough confusing instructions out there including the accepted answer and worksheet IDs and where to put them not being obvious.
Here's a document I published and anyone with the link can view:
https://docs.google.com/spreadsheets/d/1QDWpycJJFA-UAiSPIv-icJ4UZhbEmuN8wxxag83SE1c/edit?usp=sharing
The document has to be published correctly. There are two Publish buttons and the first one doesn't work for this task. Use the second.
The document KEY is important. Obtain the KEY from between the /d/ and the /edit in the url. In my example, the key is 1QDWpycJJFA-UAiSPIv-icJ4UZhbEmuN8wxxag83SE1c.
Second, use the following URL style, replacing KEY with your own:
https://spreadsheets.google.com/feeds/list/KEY/od6/public/values?alt=json
My example url links directly to published json:
https://spreadsheets.google.com/feeds/list/1QDWpycJJFA-UAiSPIv-icJ4UZhbEmuN8wxxag83SE1c/od6/public/values?alt=json
Finally, if the worksheet has multiple sheets (or tabs), replace od6 in the url with a number. My example has two tabs, so there are two urls corresponding to either tab. I simply replace od6 with 1 and 2 depending on the order of the sheets:
Tab 1:
https://spreadsheets.google.com/feeds/list/1QDWpycJJFA-UAiSPIv-icJ4UZhbEmuN8wxxag83SE1c/1/public/values?alt=json
Tab 2:
https://spreadsheets.google.com/feeds/list/1QDWpycJJFA-UAiSPIv-icJ4UZhbEmuN8wxxag83SE1c/2/public/values?alt=json
In the event of a worksheet where the tabs are reordered frequently, it is possible to get the ID of a given sheet and use that instead of ordered numbers. I first learned of this approach from this post or this post:
In brief, you would reform a private URL with your KEY:
https://spreadsheets.google.com/feeds/worksheets/KEY/private/full
This only works on a browser where you are logged into Google Drive on an account with permissions.
Next, you have to sift through XML to find your sheet IDs:
Replace the previous 1 and 2 with the IDs, for example:
Tab 1 (first worksheet id in a new google sheet is always od6 by default, no matter order of tabs):
https://spreadsheets.google.com/feeds/list/1QDWpycJJFA-UAiSPIv-icJ4UZhbEmuN8wxxag83SE1c/od6/public/values?alt=json
Tab 2:
https://spreadsheets.google.com/feeds/list/1QDWpycJJFA-UAiSPIv-icJ4UZhbEmuN8wxxag83SE1c/ope57yg/public/values?alt=json
You can find the new ID at the following
https://spreadsheets.google.com/feeds/worksheets/YOUR_SPREADSHEET_ID/private/full

ABOUT: Tutorial: Sending emails from a Spreadsheet

Is it possible to get this script updated? In 2009 it may have worked, but it doesn't now.
Tutorial: Sending emails from a Spreadsheet -
Quick link to Google Developers Tutorial
I can't for the life of me get my own script to work. Having a problem incrementing the rows correctly when it checks before sending, which is either leaving me sending a dozen e-mails of a single row of data or if I try to implement a while loop, I've ended up sending myself over hundreds of e-mails and google then stops me from using the function any further until the next day.
My specific script question is HERE, except I don't think I worded it correctly because no one is replying.
It seems that you forgot a couple of things in your script :
1° : var dataRange = sheet.getRange(sRow,1,1,cols); // this gets only 1 row in your sheet so it is normal that the loop doesn't work (length=1).
I'd suggest to replace the height value by the last row value (see docs to get that value) to make the loop iterate through every rows.
2° when you use .setValue(EMAIL_SENT); the value of EMAIL_SENT is not defined in your code (it is defined outside the function in the tutorial).
I'd suggest to add a statement like this : var EMAIL_SENT="EMAIL_SENT" or, more simply use the string value in your 'setValue' statement like this : .setValue("EMAIL_SENT");