BUG in Excel CountIF function - excel

I am having problems with the CountIf Function in Excel.
=COUNTIF(A:A,A2)
The A column consists of these items:
0107791489614255200011140926107503100513
0107791489614255200011140926107503100457
0107791489614255200011140926107503100518
0107791489614255200011140926107503100503
0107791489614255200011140926107503100519
0107791489614255200011140926107503100444
0107791489614255200011140926107503100521
0107791489614255200011140926107503100438
0107791489614255200011140926107503100449
0107791489614255200011140926107503100443
0107791489614255200011140926107503100501
0107791489614255200011140926107503100455
the formula results to 12, even though these set of strings are not really the same at all. It counts these strings as similar strings, I am thinking this is related to its string length?
What do you guys think? I appreciate your help.

+1, A good question. Not really a bug but a feature!
This is due to Excel implicitly converting the inputs to its internal numeric type and losing precision in doing so. Excel's internal numeric type is an IEEE floating point double precision number. (Although it does clever things with formatting and error propagation so it appears to get sums like 1/3 + 1/3 + 1/3 correct).
As they are so similar they all compare as mutually equal.
One remedy would be to prefix each string with ' (single quotation) which will prevent the conversion to the numeric type. Then the COUNTIF value returns 1. (At least in my version of Excel; 2013).

Preceding the strings with a single apostrophe will not remedy the situation. COUNTIF is designed to interpret data as numerical, where possible, irrespective of the datatype of the values in question. This is sometimes helpful, sometimes (as here) not.
SUMPRODUCT does not exhibit this property:
=SUMPRODUCT(0+($A$1:$A$12=A2))
will return 1, as desired.
Regards

Related

Why does zero not equate to zero in excel

I have an index match match formula. When i specifically refresh the index match match formula, it states a result of 0 withiut any decimal points or values. Just 0. So i believe this is not a floating point issue. However, when i use an IF formula which checks if it equates to 0, it comes up with a false. Why is this so? Is there a solution?
Without having the spreadsheet, it's hard to be sure.
But as others have stated already it could well be a floating point rounding issue.
Another option is that it may be a different data type altogether. Say one of the values is an integer number 0 and the other a string "0". Can look the same in the sheet, but definitely aren't the same.
It sounds like it is not a number at all so we will need to convert it to an integer for the comparison:
=IF(INT(VALUE(A1)) = 0, ... )

VBA Compare times correctly

I am using VBA to compare two times from a spreadsheet.
Im my example the actual value form the sheet is 23:00 in two cells. I use them for an if-statement, the values both come from two different arrays from the type Variant.
if dataArr(v1) = rowArr(v2) Then
If I debug the two values it shows the two value like this
0,958333333333333 / 0,958333333333333
They seem the same but the compare in the if-statement returns false
So I subtracted the two value to see if the result is zero.
dataArr(v1) - rowArr(v2)
In this case the result is not zero but
3,33066907387547E-16
So something is wrong with the compare or the two double values that represent the time.
The only working solution I found was to convert them to string values by
CStr(dataArr(v1)) = CStr(rowArr(v2))
which returns true as it should be.
I don't really like this solution because it is not really how it should work. I also investigated what happens to the values before they end up in the compare but I could not find any mistake . Actually all the values in the dataArr are coming from the spreadsheet (ListObject.DataBodyRange.Value) and then certain values are copied to the rowArr out of the dataArr so it really should be the same value.
Any suggestions? Thanks!
If the cells are actually formatted for time instead of a string, I would make the definition of my arrays a "Date" not a "Variant".
Then you would have all the date/time related functionality in VBA at your disposal (like DateDiff() ).
Sometimes floating point inaccuracies creep in. If you want to compare then take the Absolute Value (ABS) of the subtraction and see if it is below a tolerance level, say, 1E-7 (a millionth).
Thanks to Florent B I got a solution that works!
Florent B: To compare the equality of two dates, you need to round to the precision which is 24hrs x 60min x 60 sec
So the solution is:
If Round(dataArr(v1) * 86400) = Round(rowArr(v2) * 86400) Then
It makes perfektly sense. Thanks a lot!

Is there Infinity in Spreadsheets?

I am wondering if there is any way to represent infinity (or a sufficiently high number) in MS Excel.
I am particularly looking for something like Double.POSITIVE_INFINITY or Double.MAX_VALUE in Java.
I like to use 1e99 as it gives the largest number with the fewest keystrokes but I believe the absolute maximum is actually 9.99999E+307. At that stage of the number spectrum I don't think there is much difference as far as Excel is concerned.
I think it's worth adding that, Infinity as well as other special values can be returned from a vba function (How do you get VB6 to initialize doubles with +infinity, -infinity and NaN?):
Function Infinity(Optional Recalc) As Double
On Error Resume Next
Infinity = 1/0
End Function
When entered as a cell formula a large number is shown (2^1024). You can set a conditional format to show "+Infinity" as a number format with a formula condition:
=AND(ISNUMBER(A1),A1>2^1023*(2-2^-52))
A dummy argument containing a dynamic reference can be inserted so that values are recalculated when the workbook is opened, for example:
=Infinity(IF(,) IF(,))
With LibreOffice 6 I use 1.79769313486231E+308 that seems the largest number it allows me to enter, but I miss not having an exact representation of +- infinite, also because I suspect the number above is implementation specific...
This is an other point that makes me think that spreadsheets are great for visualising, editing and simple computations on tabular data, but for doing more complex operations/modelling a real programming language is a must...

Trying to show only a certain amount of numbers

To make the sale to my customer I need to import numbers from a report into an Excel document. For example the number coming in will be 14.182392. The only reason for my guy not to buy the product is because he only wants to view 14.182 on the Excel sheet. Okay so the other catch is, the number CANNOT be rounded in any shape or form.
So what I need is a way to just show so much of number, WITHOUT ROUNDING.
Is this possible? Any ideas of how I could get around this would be fantastic.
Please try:
=TEXT(INT(A1)+VALUE(LEFT(MOD(A1,1),5)),"00.000")
Firstly =TRUNC is a better answer (much shorter). My version was connected with uncertainty in your requirement (it is odd!) and in the hope it might be easier to adjust if not exactly what you/your boss wanted.
TRUNC literally just truncates the decimals (no rounding!) to a length to suit (ie 3 if to show nn.182 given nn.182392 or say nn.182999).
LEFT may also be a better choice, but that depends upon knowing how large the integer part of your number is. =LEFT(A1,6) would display 14.189 given say 14.189999 in A1. However it would show 1.4189 given 1.4189999 in A1 (ie four decimal places).
The formula above combines text manipulation with number manipulation.:
INT takes just the integer value (here 14.)
MOD takes just the modulus – the residual that is not an integer after division, in this case by 1. So just the .182392 part. LEFT is then applied here in a similar way to as used above, but without needing to concern oneself with the length of the integer part of the source value (ie 14 or 1 etc does not matter).
VALUE then converts the result back into numeric format (string manipulation functions such as LEFT always return text format) so our abbreviated decimal string can then be added to our integer.
Finally, the TEXT part is for formatting but is hard or impossible to justify! About the only use is that it displays the result left-justified in the cell – perhaps a little warning that the number displayed is not the “true” value (eg it won’t SUM) because, as a result of a formula, it won’t be marked with a little green warning triangle.
The displayed values can use the TRUNC function like this,
=TRUNC(A1, 3)
But you must use A1 in any calculations to retain the precision of the raw value.
Easiest way I know:
=LEFT(A1; x)
where x = the amount of characters You want. Mind that the dot counts as a character as well.

Number representation by Excel

I'm building a VBA program on Excel 2007 inputing long string of numbers (UPC). Now, the program usually works fine, but sometimes the number string seems to be converted to scientific notation and I want to avoid this, since I then VLook them up.
So, I'd like to treat a textbox input as an exact string. No scientific notation, no number interpretation.
On a related side, this one really gets weird. I have two exact UPC : both yield the same value (as far as I or any text editor can tell), yet one of the value gives a successful Vlookup, the other does not.
Anybody has suggestions on this one? Thanks for your time.
Long strings that look like numbers can be a pain in Excel. If you're not doing any math on the "number", it should really be treated as text. As you've discovered, when you want to force Excel to treat something as a string, precede it with an apostrophe.
There are a couple of common problems with VLOOKUP. The one you found, extra whitespace, can be avoided by using a formula such as
=VLOOKUP(TRIM(A1),B1:C:100,2,FALSE)
The TRIM function will remove those extraneous spaces. The other common problem with VLOOKUP is that one argument is a string and the other is a number. I run into this one a lot with imported data. You can use the TEXT function to do the VLOOKUP without having to change the raw data
=VLOOKUP(TEXT(A1,"00000"),B1:C100,2,FALSE)
will convert A1 to a five digit string before it tries to look it up in column B. And, of course, if your data is a real mess, you may need
=VLOOKUP(TEXT(TRIM(A1),"00000"),B1:C100,2,FALSE)

Resources