Check if Cells contain value exactly one time - excel

I have five cells in Excel filled with ones and zeros and now I want to check if in those five cells there is zero exactly one time?
Example:
(11110) true
(11100) false
I need a regular Excel function without VB please.

Assuming the value is in cell A1, use this formula:
This is an array formula and must be confirmed with Ctrl+Shift+Enter.
=1=SUM(--(MID(A1,ROW(OFFSET($A$1,,,LEN(A1))),1)="0"))
Now copy the formula to point at the four other cells.
That's it.
Here is how it works...
Let's say that the value of cell A1 is 11101111
So, that's a total of eight characters. We can see that seven of them are 1s and one is a 0.
But how do we get Excel to see the same thing?
At the heart of the formula is the MID() function. We use it to break apart the value into eight separate characters.
Under normal usage, the MID() function just returns one substring of text from a larger string. You provide it the start position within the larger text and how long of a substring you want and it returns that substring.
For example: =MID(A1,3,3) would return 101 when referencing our A1.
And if we changed that to: =MID(A1,4,1) we would get 0.
But how can we have the MID() function completely decompose the value in A1 into discreet, single-character substrings. Remember that MID() normally just returns one substring. But in our case we want it to return eight substrings.
This is where the array-formula comes in. Remember that the 2nd parameter for MID() is the start position of the substring we want back. If we pass to that 2nd parameter an array of numbers instead of one single number, then MID() will perform its function once for each value in the array.
One way of specifying arrays in Excel is to use and array constant. So we could change our MID() example to this:
=MID(A1,{1;2;3;4;5;6;7;8},1)
And the result would look like this: {"1";"1";"1";"0";"1";"1";"1";"1"}.
Now if you just enter the above formula in a single cell, you will only see the first element, which is a one. But if you selected a range of eight vertical cells and then clicked on the Formula Bar at the top of the worksheet and entered the formula and then confirmed the array-way with Ctrl+Shift+Enter
... you would see these eight different values appear in the selected range.
Another way to see the full results, even from one cell, is to select the full formula inside the Formula Bar and then press the F9 key on the keyboard. The formula will be replaced with the results in the Formula Bar. You can use this technique to evaluate the formula or discreet parts of a larger formula. If you press Enter the results will stay in the Formula Bar. If you want the formula instead, press Esc.
The problem with using the array constant is that it only works correctly when the text in cell A1 is exactly eight characters long or less. If we want to handle longer text, then we need an array constant with more values. One way to side-step this issue is to use a formula to create an array on the fly that when evaluated would look like our array constant. We would design this formula to have precisely the same number of incrementing elements as there are characters in the text in cell A1.
That is precisely what this construct in the middle of our formula does:
ROW(OFFSET($A$1,,,LEN(A1))
Recall that when the MID() function is finished we are left with this array of results: {"1";"1";"1";"0";"1";"1";"1";"1"}
Now we apply a logical test to each element, asking is each of these equal to 0?
Here is how that would look:
{"1";"1";"1";"0";"1";"1";"1";"1"}=0
A new array result is returned that looks like this:
{FALSE;FALSE;FALSE;TRUE;FALSE;FALSE;FALSE;FALSE}
Notice that only the 4th element is TRUE, which of course is exactly right.
So that's progress.
Now we want to count how many elements are TRUE. We know the answer is one. But how can Excel figure this out?
It would be nice if our array were of numbers rather than these Boolean TRUE and FALSE values. An easy way to convert the array of Booleans to numbers is to use two minus signs in front of the array. When a TRUE value is turned negative it becomes a number; it becomes -1. When we hit it with the 2nd minus sign, that -1 becomes +1. And of course FALSE becomes 0.
So doing that would look like this:
--({FALSE;FALSE;FALSE;TRUE;FALSE;FALSE;FALSE;FALSE}=0)
And the result would look like this:
{0;0;0;1;0;0;0;0}
Notice that the array is now composed of numbers. When we first looked at the results from the MID() function, it looked like this: {"1";"1";"1";"0";"1";"1";"1";"1"} and those are not numbers; they are text. Notice all the quotation marks.
If you are following closely you may be wondering why we could not have used the two minus signs directly on the output from the MID() function to convert those text numbers into real numbers. Well, in truth we could have. But we want an array where the 1s represent the source zeroes and the 0s represent the source 1s. In other words, we want the inverse. Taking these extra steps gives us that.
We can now use SUM() on the array.
=SUM{0;0;0;1;0;0;0;0})
Since it is only summing 1s and 0s and the 1s represent the original source zeros, the result is the count of the source zeroes.
We perform one final test to see if the result is equal to one, because you want to know if the value in cell A1 has one and only one zero in it:
=1=SUM{0;0;0;1;0;0;0;0})
The result is TRUE.

Related

Excel Spreadsheet: Removing all data from cells in a square bracket

I have the following data in an excel spreadsheet.
The first data entry in each cell is contained within square brackets and contains the student's first attempt at a test. The second percentage is their final score.
I have been trying to find a formula that will easily remove all the brackets and data to leave only the final percentage in the cells. I want to do this so that I can then find the average of all the scores, and currently due to the data in the square brackets, I cannot use a formula.
What I've tried:
Data > Text to Columns > Tried to cut off at the 0, but I was either doing it wrong, or it didn't work.
I also looked at extracting (removing) the first four characters, but wasn't clear how to replace that with the final percentage result in the same cell itself.
Rethink your logic. A formula cannot remove content from a cell. For that you need a VBA macro.
However, you can write a formula that ignores cell content.
So, if myRange is the range over which you want to average. Perhaps D2:O2?
=AVERAGE(--MID(myRange,FIND("]",myRange)+1,99))
We FIND the location of the closing bracket, and add 1 to that for the possible start of our desired number.
MID will return that number as a string, so the double unary -- converts it to a real number.
Then AVERAGE.
This is an array formula and, in earlier versions of Excel, may need to be entered with ctrl+shift+enter.

How to simplify multiple COUNTIFS in excel with non-consecutive ranges

I have a spreadsheet...
A you can see, the cell F2 has a formula with multiple COUNTSIF, basicly checks the cells F14, F33, F62 y there is a Pass there, and if there is one will give you a % completion. My question is that I have to add around 20-30 COUNTIFS to that formula, is there a way to simplify it.
=(COUNTIF(F14,"Pass")+COUNTIF(F33,"Pass")+COUNTIF(F62,"Pass")+COUNTIF(F75,"Pass")+COUNTIF(F88,"Pass")+COUNTIF(F105,"Pass"))/(COUNTIFS(F14,"<>na")+COUNTIFS(F33,"<>na")+COUNTIFS(F62,"<>na")++COUNTIFS(F75,"<>na")++COUNTIFS(F88,"<>na")+COUNTIFS(F105,"<>na"))
This is not the final formula, still missing around 20 entries. If you're wondering why not do a simple F15:FXX, because i just need the cells that have a test case name, like F14, F33, etc.
For the first part of your formula, you can use the INDEX function to return a non-contiguous set of values, which you can test.
For example, the equivalent for the first part would be:
=SUM(N(INDEX($F:$F,IF(1,N({14,33,62,75,88,105})))="Pass"))
The IF(1,N({…})) part is how you specify which cells (rows) in Column F to return.
Without knowing more about your data, not sure about handling the percentage issue.
Your posted formula would not calculate a percentage, as it is only dividing the SUM by whether or not F14<>"na" is true, and then adding one for the <>"na" factor for the rest
In earlier versions of Excel, you may need to confirm this array formula, hold down ctrl + shift while hitting enter. If you do this correctly, Excel will place braces {...} around the formula seen in the formula bar.
If you want to return the percent "pass" in your list of cells, merely divide the SUM by the number of cells. You can either hard-code that number, or compute it with something like:
COLUMNS({14,33,62,75,88,105})
Or all together:
=SUM(N(INDEX($F:$F,IF(1,N({14,33,62,75,88,105})))="Pass"))/6
or
=SUM(N(INDEX($F:$F,IF(1,N({14,33,62,75,88,105})))="Pass"))/COLUMNS({14,33,62,75,88,105})

How to contain formulas within a formula?

I am trying to have formula return with a cell population with the first six characters of the look up cell given that the first two characters are 10.
See below for example.
=IF((LEFT(A3,2)=10), LEFT(A3,6), "")
As of right now, I keep getting a blank return no matter the look up cell's information.
This works for me:
=IF(LEFT(A3,2)="10",LEFT(A3,6),"")
LEFT returns a text string so you need ". You also don't need the double brackets.
You can aslo force the result of left() to be numerical,
=IF(LEFT(A3,2)*1=10,LEFT(A3,6),"")
I used *1, but +0 can work.
see
This can be convenient if you want to have the values like 10 or 15 etc in separate cells so you can just drag down.
See
You could use a cell to tell left() how many characters to collect or use the len() function.

Excel Find the max length of characters after decimal in a given column

I'm trying to find a way to get the max number of characters after the decimal place in a given column. For example
I found this to get the max length in a column (using ctrl+shift+enter):
=MAX(LEN(A1:A5))
And this formula to get the number of characters after the decimal for a single cell:
=LEN(A1)-FIND(".",A1)
But I need to combine the two into a single formula so that I don't need another column of data. Is this possible without VBA?
Edit, one example I might encounter would be 99.999 vs 100.12 that I'd need to differentiate between and result in a length of 3 characters after the decimal.
If any of your data is the result of formulas, you may have some surprising results and need to use VBA. Otherwise, so long as the format is General, you can use
=MAX(LEN(A1:A5)-FIND(".",A1:A5&"."),0)
confirmed by holding down ctrl+shift while hitting enter
You can use Array Formulas in conjunction with some of your original suggestions to accomplish this. The formula in the example you provided would be:
{=MAX(IFERROR(LEN(B1:B3)-FIND(".",B1:B3),0))}
Some notes:
The "IFERROR" function is used to return a 0 to the MAX function if the "." is not found in the string
Array formulas can be entered into excel by entering the text "=MAX(IFERROR(LEN(B1:B3)-FIND(".",B1:B3),0))" into the formula bar and pressing ctrl+shift+enter (at which point the curly brackets will appear)
Applying this formula should yeild the following results for your sample inputs:
Sample Results

Excel Search returns #Value, but embedded in "Lookup" it works - why?

This links to question 12299700 - I want to understand why SEARCH returns #Value when used alone but works when embedded into LOOKUP, and how I can make it work alone:
In Cell A1 I have a string of text: "This is some sample text"
In Cells D1:D4 I have words: "text, sample1, sample2, string" (all in separate cells)
I want to see if my string contains any of the words in my range - I don't need the matching word/s returned.
Using the Search function in any empty cell in Row 1 =SEARCH($D$1:$D$4,A1), returns 22. Good!
Using this in any other row returns #VALUE. Why?
If I keep my formula in Row 1, but move my range of words down to D2:D5, I get #Value. Why?
How can I make SEARCH work for my cell and ranges, in any cell?
(From the answer to question 12299700 I know I can use this formula to return the matched text, in any cell of the spreadsheet: =LOOKUP(2^15,SEARCH($D$1:$D$4,A1),$D$1:$D$4) - this includes a term that gives #VALUE on its own ... intriguing).
First question asked on Stackoverflow - feedback appreciated.
The function SEARCH returns #VALUE if the searched string was not found within the text. The function SEARCH expect only one searched string. It is not a array function itself. So if it gets a range as searched string, it uses only one of these range values as searched string. Which one it is, depends on the position of the formula.
Within LOOKUP the case is completely different. LOOKUP is an array formula itself. It gets the SEARCH($D$1:$D$4,$A$1) as { SEARCH($D$1,$A$1), SEARCH($D$2,$A$1), SEARCH($D$3,$A$1), SEARCH($D$4,$A$1) } which results in a array like { #VALUE, 21, #VALUE, 21 } depending of if SEARCH finds the string or not. That LOOKUP even works with such an array is strange. Normally it needs a sorted array. But it works and gets the last value which is lower or equal than the searched value.
If you need to use SEARCH like an array formula outside a native array formula, then you have to create this array context by entering the formula with [CTRL]+[SHIFT]+[ENTER] instead of only [ENTER]. The formula gets then curly braces around it.
In my example I have created such a formula in Cell E10.
If you are interested in how formulas work, you should often click fx and look how the single parameters comes through. And you should often use Evaluate Formula on the Formulas tab, in the Formula Auditing group.
What happens is that SEARCH is being used in an array form and is outputting in a linear form (non-array).
So, what happens in row 1 is that you're actually doing:
=SEARCH($D$1,A1)
Because evaluating a linear formula with an array tends to take the value from the array in the same row/column depending on the situation. So that means the above is looking for text in A1 which can be found.
On the second row, you will get:
=SEARCH($D$2,A1)
Which means it is searching for sample1 from A1 and since it cannot be found, you get #VALUE!.
To evaluate an array formula as an array, you will have to use Ctrl+Shift+Enter instead of pushing Enter after typing in the formula. Now the problem is that the formula above will return the same thing if you use only 1 cell...
If you want to see if your string contains any of the words in your range (and it's not important to know what word was found), then you will have to use another function along with SEARCH, for example, SUM and ISNUMBER and evaluating it as an array formula:
=SUM(ISNUMBER(SEARCH($D$1:$D$4,A1)))
And if you get a number above 0, you know there's at least 1 word in the text. Maybe to make the output more explicit:
=IF(SUM(ISNUMBER(SEARCH($D$1:$D$4,A1)))>0, "Word(s) found!", "No words found...")
If you want to know what word was found, you will have to use it as a normal formula and drag it down:
The reason why it works in VLOOKUP is that this function actually expects an array as the second parameter and since SEARCH is returning an array, well, that works out just well.
Also, you can view how functions work by clicking on the cell with the function, then do to 'Formulas' in the menu bar and clicking on 'Evaluate formula':
From there you can see if something is being evaluated as a linear or array formula and see how cell references are being substituted with the actual values.

Resources