Handling and modifying the exception returned when a Google Sheets =query() returns #N/A - exception

I have a query that runs on Google Sheets against a table where the user has separate input that can modify values in logic checks to a TRUE FALSE result on that table. It is possible that the user has a selection that returns all FALSE for a where statement within the query.
The output I get is #N/A, I want to be able to create an exception where I can identify that it's returning #N/A, and change the output to blank or "No results found".
My users are not very tech savvy, so I need it to be legible to someone without coding knowledge or experience.
Normally when I'm returned an error from a function in Google Sheets, or Excel for that matter, I use the =Iferror() function to control the output of an error exception. This does not seem to work, either because the function iferror was made with a scope that falls outside of =query, or because of some other behind the scenes structural problem.
FALSE, PIG, $5.50
FALSE, APPLE, $0.50
FALSE, CAR, $25.00
FALSE, HORSE, $20.00
I thought then maybe I could add an if() statement, and put the query in a logic statement checking for the value "N/A":
if(query(A:B,"select B where A =TRUE")="#N/A","No results found",(A:B,"select B where A = TRUE"))
This did not work. The value that was returned was "#N/A" still. So I thought maybe the value type of the exception wasn't technically a string value, so it wouldn't accept the value of a non-string #N/A to equal "#N/A", so I wrapped the first query in a concatenate() in an attempt to force it into a singular variable/cell value. I know this works in turning the query it runs into a singular string if it has results, but doing this:
if(concatenate(query(A:B,"select B where A =TRUE"))="#N/A","No results found",(A:B,"select B where A = TRUE"))
This still returns "#N/A"
I thought maybe the actual value it's throwing back is a NULL type value, and it has some clever behind the scenes shenanigans to make it display "#N/A" when the where function filters out all results. so I changed the parameter it's checking against in the if statement from "#N/A" to "" as follows:
=if(concatenate(query(lookup!Z2:AN,"select Z where AN = TRUE"))="","No results found",query(lookup!Z2:AN,"select Z where AN = TRUE"))
This still returns "#N/A"
I thought maybe the isblank() function would have some mechanism in it to find that it's blank, changing it to:
=if(ISBLANK(concatenate(query(lookup!Z2:AN,"select Z where AN = TRUE"))),"No results found",query(lookup!Z2:AN,"select Z where AN = TRUE"))
This also still returns "#N/A"
I'm at a loss. I'm expecting it to throw me the exception I'm qualifying: "No results found" but this never comes. Obviously, I don't understand the nature of how the =query() function is handling data on the back end of things. It must be doing something on a separate layer of operations or something, or have a totally different scope, but how am I supposed to figure out what that variable/process is?

Not just IFERROR?:
=iferror(query(A:B,"select B where A =TRUE"),"No results found")

Related

lua, iterating and calling all same-named-functions of n=3 tiers of tables

Say I have multiple tables in {game} like {bullets}, where {bullets} has multiple tables as found below. How would I iterate through and call all the update functions contained in {game}?
--Below is a simplified example, Assume each table in {bullets} has multiple entries not just update. And that the final code must work in cases like game={bullets,coins,whatever}, each entry being of similar nature to bullets.
game={}
game.bullets={{update=function(self) end,...}, {update=function(self) end,...},...}
for obj in all(game) do
for things in all(obj) do
things:update() end end
--I'm not sure what I"m doing wrong and whether I even need a double for-loop.
--if bullets wasn't embedded in {game} it would just be:
for obj in all(bullets) do
obj:update()
end
I've also tried:
for obj in all(game.bullets) do
obj:update()
end
*correction: this works, the problem I want solved though is to make this work if I have multiple tables like {bullets} in {game}. Thus the first attempt at double iterations which failed. So rather than repeat the above as many times as I have items in {game}, I want to type a single statement.
all() isn't a standard function in Lua. Is that a helper function you found somewhere?
Hard to tell without seeing more examples, or documentation showing how it's used, with expected return values. Seems to be an iterator, similar in nature to pairs(). Possibly something like this:
for key, value in pairs( game ) do
for obj in all( value ) do
obj :update()
end
end

Syntax Error: Comma in Query Expression of SQL Statement Access?

I've been trying to make this statement work for some time but have ultimately lost the will to live.
In essence, I am attempting to filter a report to only certain Locations (So if you want the query to only include locations "Avonmouth" and "Bedford", that's what it would include, filtering the rest out) I have done this by implementing a check box system, so you can easily add locations to the filter. Unfortunately I keep getting syntax problems with the SQL script. Its a bit of a butchery, so please forgive me, but I have included the SQL below. (CHKBE = The check box)
WHERE QryTraining IN ((IIf [Forms]![ReportDeployer]![CHKAV]<>"" ,"Avonmouth",x),(IIf [Forms]![ReportDeployer]![CHKBA]<>"" ,"Basingstoke",x),(IIf [Forms]![ReportDeployer]![CHKBT]<>"" ,"Bedford Transport",x),(IIf [Forms]![ReportDeployer]![CHKBW]<>"" ,"Bedford Warehouse",x),(IIf [Forms]![ReportDeployer]![CHKBE]<>"" ,"Belfast",x),(IIf [Forms]![ReportDeployer]![CHKCA]<>"" ,"Carluke",x),(IIf [Forms]![ReportDeployer]![CHKEX]<>"" ,"Exeter",x),(IIf [Forms]![ReportDeployer]![CHKKI]<>"" ,"Kidderminister",x),(IIf [Forms]![ReportDeployer]![CHKKN]<>"" ,
"Knowsley",x),(IIf [Forms]![ReportDeployer]![CHKTE]<>"" ,"Teva",x),(IIf [Forms]![ReportDeployer]![CHKWI]<>"" ,"Wickford",x),(IIf [Forms]![ReportDeployer]![CHKYO]<>"" ,"York",x))
Each time I attempt to run it, it throws it back with a Syntax error.
Thanks in advance, T.
Not sure this will work any better but parens are in wrong place at beginning of each IIf() and maybe need apostrophe delimiters:
WHERE QryTraining IN (IIf([Forms]![ReportDeployer]![CHKAV]<>"" ,"'Avonmouth'",x), IIf([Forms]![ReportDeployer]![CHKBA]<>"","'Basingstoke'",x), IIf([Forms]![ReportDeployer]![CHKBT]<>"","'Bedford Transport'",x), IIf([Forms]![ReportDeployer]![CHKBW]<>"","'Bedford Warehouse'",x), IIf([Forms]![ReportDeployer]![CHKBE]<>"","'Belfast'",x), IIf([Forms]![ReportDeployer]![CHKCA]<>"","'Carluke'",x), IIf([Forms]![ReportDeployer]![CHKEX]<>"","'Exeter'",x), IIf([Forms]![ReportDeployer]![CHKKI]<>"","'Kidderminister'",x), IIf([Forms]![ReportDeployer]![CHKKN]<>"","'Knowsley'",x), IIf([Forms]![ReportDeployer]![CHKTE]<>"","'Teva'",x), IIf([Forms]![ReportDeployer]![CHKWI]<>"","'Wickford'",x), IIf([Forms]![ReportDeployer]![CHKYO]<>"","'York'",x))
Probably need to use empty string or some text like "N/A" in place of the x.
A BOUND checkbox must be either True or False (Yes/No), never an empty string. An UNBOUND checkbox can be set for triple state, in which case it could return True/False/Null, again never an empty string. So I am not sure why comparison to empty string. Just test for True.
IIf([Forms]![ReportDeployer]![CHKAV], "'Avonmouth'", "")

I can't get an e-mail of a specific contact

Here is my story:
I'm writting a script that permits to see every users in an array of group (I mean, you select 2 group, it show every users in one of these two groups). It also do some other treatment. But it's OK for this part.
Everything seems to work correcly. Except for only one user.
The idea is, I have to get the e-mail of a user, to then compare users'e-mail got in a former group, to see if this user is (or not) already listed ( in order to avoid duplicate).
The user (this one only) won't use my function. I supposed it was a group, but it really is a user.. I'm pretty sure it is an option to select ( or not) in the user's preference, but which one?
PS: here is the error quote
TypeError: Fonction getEmail introuvable dans l'objet
(TypeError: getEmail function not found in object)
And here is the code I use in order to get e-mails:
for(var i in objuser){
for(var j in objuser[i])
{
objuser[i][j]=objuser[i][j].getEmail();
}
}
Objuser is a list of User Object. First dimension (I) is the group, second dimension (j), is users of the "I" group.
PROBLEM NOT SOLVED:
the reason:
I have 2 functions that do treatments. Theses Two function need an array, that another function create (which is long to execute). My code is done in such a way, if i execute consecutively these 2 treatment functions with the same array, the second to be played use an incorrect array.
So i clone it with :
var groupsUser2 = JSON.parse(JSON.stringify(groupsUser));
but, now that i dont use anymore email adresses ( i mean String), but direct Users (i mean Object), the former code don't clone correctly:
array1 : user's array (Objects)
array2 = JSON.parse(JSON.stringify(array1))
log(array1) :[blabla1#...com,blabla2#...com,blabla3#...com, .....]
log(array2) :[{},{},{}………]
SO.... Here is the new question: Is there a simple way to copy an Object's array ?
Here is the former question: What rights configuration unallow me to use the getEmail() function for a specific contact?
I need an answer just for one of these two questions, and i'll be able to correct my problem. Any idea guys???????
never use "for x in array" its bad use of javascript on an array because the array has the "length" property which is a number and not the object your loop expects.
instead use " for (i=0;...." or forEach.
Well, I was using getEmail() function in order to compare users got in one group, to others got in another group , so that i can avoid duplicates.
I was checking with IndexOf() if the user adress were in the array of the other group's users.
I don't know why , but now it works even if i don't get the e-mail of the user. So , the problem that was happening for one user can't happen anymore.
Conclusion: Problem solved. Thx mates
I thought about a solution: try .. catch, so that the email which won't be get, will be potentially duplicated because I will not be able to find the user if already displayed or not without his e-mail, but at least the script will not crash.

Is this really a possible InvalidOperationException?

I have a Linq2Sql query that looks like this:
var data = from d in dc.GAMEs
where (d.GAMEDATE + d.GAMETIME.Value.TimeOfDay) >= DateTime.Now
&& d.GAMESTAT == 'O' && d.GAMETYPE == 0 select d;
Resharper is underlining the "d.GAMETIME.Value.TimeOfDay" in blue and telling me it's a possible System.InvalidOperationException. While I get that if it were C# code, referencing Value without checking if it has a value would be such, i'm not sure if that is true of a Linq query.
The actual SQL generated looks horrendous, and makes me want to burn my eyes out, but I see nothing that looks like it could be a null reference. Can I safely ignore this?
(ignore for the moment the other issues, such as if it returns the expected results)
EDIT:
Upon further thought, I can see how the above might cause an exception in a LinqToObjects query, and possibly other kinds (XML?). So yeah, I suppose Resharper is just being safe.
When dealing with expression trees (as this LINQ to SQL query) it totally depends on the LINQ provider used (in your case LINQ to SQL). Therefore, it is (almost) impossible for Resharper to say anything useful about your query. I think it just interprets this code as normal C# delegates. I would say it is safe to ignore, but perhaps add a comment for the next developer.
Without seeing the data schema my guess is that GAMETIME is Nullable<DateTime> - i.e. maps to datetime/time field in the DB that can be null. Resharper is simply giving you a static analysis warning that you are referencing Nullable<T>.Value without checking that it has a value.
You can rewrite the query in this way:
var data = from d in dc.GAMEs
where (d.GAMEDATE + (d.GAMETIME.HasValue ? d.GAMETIME.TimeOfDay : new TimeSpan())) >= DateTime.Now
&& d.GAMESTAT == 'O' && d.GAMETYPE == 0 select d;
The above query will just use a TimeSpan of 0 when GAMETIME is NULL.
Considering that GAMEDATE is a non-nullable database field and GAMETIME is a nullable one, I recommend that you make GAMETIME non-nullable too. This way the two fields are consistent and do not need extra logic to handle NULL values.
EDIT I have just confirmed that trying to call Nullable<T>.Value does indeed throw InvalidOperationException, not NullReferenceException.
From the horse's mouth (bolding is mine):
The two fundamental members of the
Nullable structure are the HasValue
and Value properties. If the HasValue
property for a Nullable object is
true, the value of the object can be
accessed with the Value property. If
the HasValue property is false, the
value of the object is undefined and
an attempt to access the Value
property throws an
InvalidOperationException.

Why am I getting "Invalid Cast" when using Linq to SQL?

I am a bit of a newbie when it comes to Linq to SQL but I hope you can help out. I've written the following Linq to SQL statement with Extension Methods:
Cedb.ClassEvents.Where(c => c.ClassID == 1).Select(c => c).Single()
Where Cedb is the Datacontext, ClassEvents is a table (for classes and events being held at a facility) and ClassID is a unique integer key.
This query runs fine in LinqPad (without Cedb). When it returns, it says that the return type is "ClassEvent". In Intellisense in Visual studio, it tells me that the return type of this query is ClassEvent (created in my data model). However, when I try to place the results in a variable:
var classEvent = Cedc.ClassEvents.Where(c.ClassID == 1).Select(c => c).Single();
then I get an error: InvalidCastException: Specified cast is not valid. The same thing happens if I use the "ClassEvent" class in place of the var. I'm new to this but this one seems like a true slam dunk rather than a bug. Is there something about the Single method that I don't know that is leading to the error? Any help would be appreciated!
Slace - and any other interested parties. The cause of the "Invalid Cast Exception" error was a change in the underlying data model. A smallint field had been changed to bit. Thus, when the system tried to map the query results onto the "ClassEvent" data structure, the conflict between the model (which had not been updated) and the data table emerged.
Nonetheless, I do appreciate the answer!
You don't need to do both a Select and a Single, in fact, you don't even need the Where, you can get away with (see http://msdn.microsoft.com/en-us/library/bb535118.aspx):
var classEvent = Cedc.ClassEvents.Single(c => c.ClassID == 1);
I'd also recommend against using Single unless you're 100% sure that the Func<T, bool> will always return a value, as if it doesn't return a value you will have an exception thrown. Better is using SingleOrDefault and doing a null check before interaction with the object (http://msdn.microsoft.com/en-us/library/bb549274.aspx)