tl;dr - How can I pull the first two characters from a column and have a second column declare whether those characters are a numerical value (no text)?
sub-question: why doesn't IF(ISNUMBER(LEFT(C2,2)), "yes", "no") do what I just said?
--
I'm a Starfleet HR Officer, and our database is a MESS. For a while there, the Vulcans were running our Humanoid Resources, and now our officer and crew tracking numbers have been...VULCANED.
Starfleet Humanoid Resources Google Sheet
In that sample sheet, we have a Starfleet ID and a Vulcan High Command ID for each member of the bridge crew of the USS Enterprise (NCC-1701). That would be great, except that some of the Officers have both their SFID and their VHCID, and some have VHCID in both fields. I need to be able to flag one of the two kinds of IDs in the Starfleet ID column - the VHCID looks simpler.
I want to call something like IF(ISNUMBER(LEFT(C2,2)), "VHCID", "SFID"), since ALL the VHCIDs start with two digits. But, as you can see, the sheet throws an SFID for all the LEFT output, even though, when I pull the two digits out, they are clearly numbers in some cases.
Anyone boldly gone here before?
adding a +0 after the Left() method will try and convert the result in to a number.
=IF(ISNUMBER(LEFT(B2,2)+0),"VHCID","SFID")
Seems to give the expected results.
As the comment points out, both Google Sheets and Excel has a function to convert the string to a text, called Value(). I had no idea that function existed in Excel, so thank you for sharing. The formula using the Value() function would look something like:
=IF(ISNUMBER(VALUE(LEFT(B2,2))),"VHCID","SFID")
Answer to your edit:
The function Left() is expecting a string and returns a string. The function IsNumber() just checks to see if the input is a number. Since the Left() function returns a string, it will always evaluate to false in the IsNumber() function.
To get around that, you can add 0 to the Left() function, which will convert the string to a number automagically (basically it will try to force the string to be a numeric to handle the mathematical operation). If the result of the Left() function is something like "42", then adding 0 makes it 42, which resolves to 'true' in the IsNumber() function. If your Left() function results in "Text", then the conversion fails, "Text" + 0 = "Text" and the IsNumber() function resolves to false.
TLDR: "42" and 42 are completely different things, adding 0 (or using the Value() function) fixes that.
Related
I have one spreadheet that includes name, id and amount of numbers data in it and i want to make the report in other spreadsheet.
i want to count the name column that is not blank, so i type this
=COUNTIF(importrange("gsheet link","Payroll 16-31 Jan!B3:B"),"<>")
but the result is "1" in fact that there are 3670 names on the column
=COUNTIF(importrange("gsheet link","Payroll 16-31 Jan!B3:B"),"<>"&"")
but still not working
can someone help?
I want to get the exact calculation of those data
Two things: have you connected the spreadsheets? If not, use IMPORTRANGE outside COUNTIF, something like =importrange("gsheet link","A1") . Accept the permissions and see if COUNTIF now does it right
If it doesn't, try with COUNTA that is specifically defined for counting non blank cells:. =COUNTA(importrange("gsheet link","Payroll 16-31 Jan!B3:B"))
I need to find the last numerical value in a column. I was using this formula to get the last value in column G, but I made some changes and it no longer works: =INDEX(G:G, COUNTA(G:G), 1). My column now looks like this:
645
2345
4674.2345
123.1
"-"
"-"
"-"
...and the formula returns "-". I want it to return 123.1. How can I do this?
There are many ways to go about this. Here is one of them:
=QUERY(FILTER({G:G,ROW(G:G)},ISNUMBER(G:G)),"Select Col1 ORDER BY Col2 Desc LIMIT 1")
FILTER creates a virtual array of only numeric values in G in the first column and the row of those numeric values in the second column.
QUERY returns flips the order by row number and returns only the new top value from the first column (which winds up being your last numeric value in the original range).
However, if your numeric values start at G1, and if there are only numeric values up to where you start adding hyphens in cells, you could just alter your original formula like this:
=INDEX(G:G,COUNT(G:G))
This would work because COUNT only counts numeric values while COUNTA counts all non-null values (including errors BTW).
Not to take anything away from the accepted answer, but I've been working on this a bit lately in relation to this for the never-ending last row discussion and thought I'd share some potential similar solutions. These ideas are inspired by a pattern of google sheet array questions that seem to be coming up more often. I am also intentionally using different ways to do the same thing just to give people some ideas (i.e. left and Regex).
Last Row that is...
Number: =max(filter(row(G:G),isnumber(G:G)))
Text: =max(filter(row(G:G),isText(G:G)))
An error: =max(filter(row(G:G),iserror(G:G)))
Under 0 : =max(filter(row(G:G),G:G<0))
Also exists in column D: =max(filter(row(G:G),ISNUMBER(match(G:G,D:D,0))))
Not Blank: =max(filter(row(A:A),NOT(ISBLANK(A:A))))
Starts with ab: =max(filter(row(G:G),left(G:G,2)="ab"))
Contains the character !: =max(filter(row(G:G),isnumber(Find("!",G:G))))
Starts with a number: =max(filter(row(G:G),REGEXMATCH(G:G,"^\d")))
Only contains letters: =max(filter(row(G:G),REGEXMATCH(G:G,"^[a-zA-Z]+$")
Last four digits are upper case: =Max(filter(row(G:G),REGEXMATCH(G:G,"[A-Z]{4}$")))
To get the actual value (which I realize was the actual question), just wrap an index function around the Max function. So for this question, a solution could be :
=Index(G:G,max(filter(row(G:G),isnumber(G:G))))
i've the following formula the problem i've is, this isn't working as it should be.
=SUMIFS(E9:14,$I$16:$I,FALSE(),$H$16:$H,G8)
E9:E14 is the part which should be summed up when the checkbox in I16:I = FALSE and if the name matches in H16:H from G8. My problem is I am getting this error
The array arguments of "SUMIFS" vary in size
My question would be, how do I get this exact formula to work? Exactly these areas have to be covered and cannot be changed, otherwise everything else is broken.
EDIT: Added example spreadsheet
https://docs.google.com/spreadsheets/d/1DdTSZAfGTpoeun3k2qqkDMG1jnaUaSz6wgSf2heIIDI/edit?usp=sharing
You need to adjust your ranges. Here's how =SUMIFS() works and then you'll see why you need to adjust the function.
=SUMIFS() looks for ranges and then applies the logic. So when you are telling the function to summarise E9:E14 it interprets it as:
SUM(E9,E10,E11,E12,E13,E14)
provided the following conditions. The conditions will tell the function whether to include each of the components (i.e. E9,...,E14).
Whether a condition is met or not is decided using a simple boolean (true/false) array. This could for example be I9:I14=FALSE which is interpreted as the array
{IF(I9=FALSE),IF(I10=FALSE),...,IF(I14=FALSE)}
resulting in an array similar to this:
{TRUE,TRUE,FALSE,FALSE,FALSE,TRUE}
(assuming the conditions I9, I10 and I14 are met but not the other three. The same is done for the second condition (the values in column H being equal to the value in G8, resulting in another array similar to this:
{TRUE,FALSE,FALSE,TRUE,FALSE,TRUE}
(assuming that only the values in H9, H12 and H14 are equal to G8.
When the function compares the two condition arrays and returns an aggregate array similar to this:
{TRUE,FALSE,FALSE,FALSE,FALSE,TRUE}
because only for the first and the last value the conditions are met. Therefore the =SUM function becomes like this:
SUM(E9,FALSE,FALSE,FALSE,FALSE,E14)
where FALSE = 0 so it returns
=SUM(E9,E14)
Here's where you get into trouble
You try to pass the function conditional arrays that are of a different size to the sum array (E9:E14), in effect asking it to compare apples and the age of your neighbour. What you need to do is to create the calculation you have in column E in a new column in rows 24 down and use that as the sum range in =SUMIFS().
I have a column XXX like this :
XXX
A
Aruin
Avolyn
B
Batracia
Buna
...
I would like to count a cell only if the string in the cell has a length > 1.
How to do that?
I'm trying :
COUNTIF(XXX1:XXX30, LEN(...) > 1)
But what should I write instead of ... ?
Thank you in advance.
For ranges that contain strings, I have used a formula like below, which counts any value that starts with one character (the ?) followed by 0 or more characters (the *). I haven't tested on ranges that contain numbers.
=COUNTIF(range,"=?*")
To do this in one cell, without needing to create a separate column or use arrayformula{}, you can use sumproduct.
=SUMPRODUCT(LEN(XXX1:XXX30)>1)
If you have an array of True/False values then you can use -- to force them to be converted to numeric values like this:
=SUMPRODUCT(--(LEN(XXX1:XXX30)>1))
Credit to #greg who posted this in the comments - I think it is arguably the best answer and should be displayed as such. Sumproduct is a powerful function that can often to be used to get around shortcomings in countif type formulae.
Create another list using an =ARRAYFORMULA(len(XXX1:XXX30)>1) and then do a COUNTIF based on that new list: =countif(XXY1:XXY30,true()).
A simple formula that works for my needs is =ROWS(FILTER(range,LEN(range)>X))
The Google Sheets criteria syntax seems inconsistent, because the expression that works fine with FILTER() gives an erroneous zero result with COUNTIF().
Here's a demo worksheet
Another approach is to use the QUERY function.
This way you can write a simple SQL like statement to achieve this.
For example:
=QUERY(XXX1:XXX30,"SELECT COUNT(X) WHERE X MATCHES '.{1,}'")
To explain the MATCHES criteria:
It is a regex that matches every cell that contains 1 or more characters.
The . operator matches any character.
The {1,} qualifies that you only want to match cells that have at 1 or more characters in them.
Here is a link to another SO question that describes this method.
This seems to be a simple problem that I cannot get around. I have the following formula (works fine).
=MEDIAN(FILTER('Filtered-Data'!$D$4:$D,'Filtered-Data'!$C$4:$C=B3))
What I want is to use ArrayFormula to get a column wise result for the range B3:B instead of just B3
Can this be done?
First idea was to use Google QUERY function, however it does not support standard SQL SELECT ... WHERE... IN (valA,valB...) clause. However thing you want is achievable with ARRAYFORMULA. The trick is to match appropriately two columns, handle errors, and apply appropriate filtering (multiline for readability):
=MEDIAN(FILTER(Filtered-Data'!$D$4:$D,
ARRAYFORMULA(IF(IFERROR(MATCH
(Filtered-Data'!$D$4:$D,'Filtered-Data'!$C$4:$C=B3:B,0),0)>0,TRUE,FALSE))))
Explanation:
ARRAYFORMULA(MATCH(col1,col2,0)) finds in array first row containing value matching criteria, 0/1 determines whether matching starts from top or bottom. For standalone use, MATCH stops after producing first result. Applying ARRAYFORMULA on MATCH gets us close to what we want - it produces an array of results. However, if item is not matched, error is returned, so you get something like below, in a column:
N/A
2
3
1
3
2
N/A
N/A
N/A
1
3
These N/A stuff will do us no good, since we always want some kind of row number. Here comes IFERROR, which replaces all N\A with good ol' "0": IFERROR(MATCH(col1,col2,0),0)
Google Spreadsheet never counts rows from "0" (it starts from "1", only offsets are zero-based), so this is pretty safe unless your data contains "0" - than change it to anything else safe for your case.
Since FILTER expects in filtering_criteria single column array of booleans or expression that evaluates to array of booleans (https://support.google.com/drive/table/25273?hl=en ) we need to make sure ARRAYFORMULA produces such array of booleans. IF comes in handy - always produces either TRUE or FALSE: IF(IFERROR(MATCH(col1,col2,0)>0,TRUE,FALSE)
Now re-apply ARRAYFORMULA on that stuff, to work on array & render an array result instead of single result: ARRAYFORMULA(IF(IFERROR(MATCH(col1,col2,0)>0,TRUE,FALSE)) and put it inside FILTER... voila, it works.
For reference see: http://productforums.google.com/forum/#!topic/docs/PpnZinkLzQs