Here's what I believe is the best solution so far:
=CountIf(ArrayFormula(range<>""),TRUE)
Here's why in 3 easy steps
Step 1: Simple As Pie - Add Extra Column
The answer by eniacAvenger will yield the correct solution without worrying about edge cases as =A1<>""
seems to arrive at the correct truthy/falsy value based on how we intuitively think of blank cells, either virgin blanks or created blanks.
So imagine we have this data and we want the Count of non-blanks in B2:B6
:
<pre><code>| | <i>A</i> | <i>B</i> | <i>C</i> |
|---|-------------|-------|---------|
| <i>1</i> | <b>Description</b> | <b>Value</b> | <b>B1<>""</b> |
| <i>2</i> | Text | H | TRUE |
| <i>3</i> | Number | 1 | TRUE |
| <i>4</i> | IF -> "" | | FALSE |
| <i>5</i> | IF -> Text | h | TRUE |
| <i>6</i> | Blank | | FALSE |
</code></pre>
If we relied on Column C, we could get the count of values in B like this:
=COUNTIF(C2:C6,True)
Step 2: Use FormulaArray
to dynamically create Extra Column
However, consideRatio's comment is a valid one - if you need an extra column, you can often accomplish the same goal with an ArrayFormula
which can create a column in memory without eating up sheet space.
So if we want to create C dynamically, we can use an array formula like this:
=ArrayFormula(B2:B6<>"")
If we simply put it in C2, it would create the vertical array with a single stroke of the pen:
<pre><code>| | <i>A</i> | <i>B</i> | <i>C</i> |
|---|-------------|-------|--------------------------|
| <i>1</i> | <b>Description</b> | <b>Value</b> | <b>=ArrayFormula(B2:B6<>"")</b> |
| <i>2</i> | Text | H | TRUE |
| <i>3</i> | Number | 1 | TRUE |
| <i>4</i> | IF -> "" | | FALSE |
| <i>5</i> | IF -> Text | h | TRUE |
| <i>6</i> | Blank | | FALSE |
</code></pre>
Step 3: Count Values in Dynamic Column
But with that solved, we no longer need the column to merely display the values.
ArrayFormula
will resolve to the following range: {True,True,False,True,False}
.
CountIf
just takes in any range and in this case can count the number of True values.
So we can wrap CountIf
around the values produced by ArrayFormula
like this:
=CountIf(ArrayFormula(B2:B6<>""),TRUE)
Further Reading
The other solutions in this thread are either overly complex, or fail in particular edge cases that I've enumerated in this test sheet:
For why CountA
works the wonky way it does, see my answer here