excel number format - varying decimal digits - excel

I'm trying to set a special cell number format with theses rules:
display percentage
display at max 3 digits (decimal + integer part)
So I can display 100% or 99.3% or 1.27%
but not 100.9% or 100.27% or 99.27%.
Of course, I can have negative number (-27.3%) and it does not affect my rules.
I've try with the cell formating option without success:
[<1]0.00%;[<10]0.0%;0%
Because it seemed that excel (2010) does not support more than 2 conditions in cell formating (and so I can't expand it to manage negative number...)
It there anyway to do what I want?
Thanks

I have a rather primitive solution by implementing a function in VBA:
Function formatStr(myVal As Double) As String
' the smaller the number, the more digits are to be shown
Dim retStr As String
Dim absVal As Double
absVal = Abs(myVal)
If absVal >= 100 Then
retStr = "0"
ElseIf absVal >= 10 Then retStr = "0.0"
ElseIf absVal >= 1 Then retStr = "0.00"
Else ' number is between -1 and 1
retStr = ".000"
End If
formatStr = retStr
End Function
...which can be used then in a VBA statement like this :
myVal = 0.5555: ActiveSheet.Cells(27, 4).Value = Format(myVal, formatStr(myVal))
if you want to use that in a sheets cell you need another little function
Function FormatAlignDigits(myVal As Double) As Double
FormatAlignDigits = Format(myVal, formatStr(myVal))
End Function
=> you may enter =FormatAlignDigits(B27) in the cell where you want the result. B27 is the cell with the source data in this example.
My test results:
100.3 => 100
100.5 => 101
10.53 => 10.5
10.55 => 10.6
1.553 => 1.55
1.555 => 1.56
0.5553 => 0.555
0.5555 => 0.556
-0.5555 => -0.556
-0.5553 => -0.555
-1.555 => -1.56
-1.553 => -1.55
-10.55 => -10.6
-10.53 => -10.5
-100.5 => -101
-100.3 => -100
I'm sure there can be a more fancy solution, e.g. with a parameter for function 'formatStr' that tells at which power the number of digits is down to 0 (here: power = 2; meaning if the value is >= 100).
For me this primitive thing works just fine.

Under the Home tab in the Ribbon select Conditional Formatting:
and then select either New Rule or Manage Rules (with the latter you can then select New Rule, but also have an overview of all current rules)
Then select Use a formula to determine which cells to format and enter the formula with reference to the cell itself (in my case cell A1 was selected, take the $ signs out to allow it to be applied to other cells themselves as well!):
Now Click Format... and select the required Number format as percentage with the number of decimal places as you want it.
Repeat this for all the cases you want to distinguish.
As values can be negative I use ABS() to always test for the rule on the absolute value of the cell.
Note you can either make all rules apply for a 2 side limited value range (in my example I have the minimum of 0.1 and the maximum of 1 (10% and 100% respectively). Alternatively you can only determine the minimum OR maximum and tick the box for Stof If True at the right end for all your rules involved.

I've recently solved this issue but configuring up to 6 decimals. The request is as follows:
We want to display a number same way as entered by the user but
allowing no more than 6 decimals:
1 -> 1
1,1 -> 1,1
1,12 -> 1,12
...
1,123456 -> 1,123456
1,1234567 -> 1,123457 (Round from this point)
This can be solved using conditional formatting and one rule per decimal starting from integers. An integer is a number without decimals, so X MOD 1 = 0. We can apply this logic multiplying the number by 10^N being N the number of decimals we want. Besides, we want to stop applying rules when we have detected the number of decimals in the cell value, so be sure you mark "Stop if True" flag and that the order of the rules is from the most restrictive one (the integer) to the less restrictive (the one that stands for the maximum number of decimals allowed).
Summarizing, you have to configure the following way (in the sample I'm doing for B column):
INTEGER: =MOD(B2;1)=0
ONE DECIMAL: =MOD(B2*10;1)=0
TWO DECIMALS: =MOD(B2*100;1)=0
...
SIX DECIMALS: =MOD(B2*1000000;1)=0
Also set the default format of the cell to be a number with the maximum number of supported decimals:
And finally the working results on Excel:

Related

How do I replicate the Excel Percentage format in ClosedXML

I have a column of fractional numbers between 0 and 1. In Excel, if I use the Format Cells option and select Percentage the displayed values are between 0% and 100% as expected.
Is there any way in Closed XML to set this Percentage format such that it both multiplies by 100 and appends the % symbol before display? All the suggestions I have found use the NumberFormat that simply appends a % to the number between 0 and 1. I don't really want to multiply the value by 100 before I add it to the cell as it will affect other computations.
ws.Column(iC+1).Style.NumberFormat.Format = "0.000\%";
Just don't escape the % character:
ws.Column(iC+1).Style.NumberFormat.Format = "0.000%";

Formula to search 3 words "text" in any sequence in different cell

Please take a look at the attached image. I have a long list of items and I've created a common keywords to search in that list. I'm using this formula:
=INDEX(A:A,MATCH((("*"&B2&"*")&("*"&C2&"*")&("*"&D2&"*")&("*"&E2&"*")&("*"&F2&"*")),A:A,0))
The problem that the search is going through the same sequence that I entered.
It gives error if the sequence of the words in the cell is different than the sequence in my formula which make sense.
Is there a way I can search for 3 or more words that are existing in any cell in any sequence?
I am open to using VBA if necessary.
My search results:
Here is the user defined function:
Public Function indexMX(rng As Range, pat1 As Range, pat2 As Range, pat3 As Range, pat4 As Range, pat5 As Range) As Variant
Dim r As Range, rngx As Range, s(1 To 5) As String, Kount As Long, j As Long
s(1) = pat1.Value
s(2) = pat2.Value
s(3) = pat3.Value
s(4) = pat4.Value
s(5) = pat5.Value
Set rngx = Intersect(rng, rng.Parent.UsedRange)
For Each r In rngx
v = r.Value
Kount = 0
For j = 1 To 5
If InStr(1, v, s(j)) > 0 Or s(j) = "" Then Kount = Kount + 1
Next j
If Kount = 5 Then
indexMX = v
Exit Function
End If
Next r
indexMX = "no luck"
End Function
Here is an example of its usage:
As you see, we give the UDF() the address of the column and the addresses of the five keywords and the UDF() finds the first item containing all five words.
If a keyword is blank, it is not used. (so if you want to search for only two keywords, leave the other three blank). If no matches are found the phrase no luck is returned.
User Defined Functions (UDFs) are very easy to install and use:
ALT-F11 brings up the VBE window
ALT-I
ALT-M opens a fresh module
paste the stuff in and close the VBE window
If you save the workbook, the UDF will be saved with it.
If you are using a version of Excel later then 2003, you must save
the file as .xlsm rather than .xlsx
To remove the UDF:
bring up the VBE window as above
clear the code out
close the VBE window
To use the UDF from Excel:
=myfunction(A1)
To learn more about macros in general, see:
http://www.mvps.org/dmcritchie/excel/getstarted.htm
and
http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx
and for specifics on UDFs, see:
http://www.cpearson.com/excel/WritingFunctionsInVBA.aspx
Macros must be enabled for this to work!
EDIT#1:
to remove case sensitivity, replace:
If InStr(1, v, s(j)) > 0 Or s(j) = "" Then Kount = Kount + 1
with:
If InStr(1, LCase(v), LCase(s(j))) > 0 Or s(j) = "" Then Kount = Kount + 1
Yes, it is possible for a single cell to return three matching words from a different cell. The answer in this example uses a formula to return 6 matches. VBA and special array functions are not used.
This is the formula:
=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUMPRODUCT((IFERROR(SEARCH(FIRST,TARGET),0)>0)*100000+(IFERROR(SEARCH(SECOND,TARGET),0)>0)*20000+(IFERROR(SEARCH(THIRD,TARGET),0)>0)*3000+(IFERROR(SEARCH(FOURTH,TARGET),0)>0)*400+(IFERROR(SEARCH(FIFTH,TARGET),0)>0)*50+(IFERROR(SEARCH(SIXTH,TARGET),0)>0)*6),"1",FIRST&DELIM),"2",SECOND&DELIM),"3",THIRD&DELIM),"4",FOURTH&DELIM),"5",FIFTH&DELIM),"6",SIXTH&DELIM),"0","")
Did you notice the named ranges? FIRST, SECOND, THIRD, etc are individual cells and each one holds a word. We are trying to find those words inside TARGET. If we find the words, then we will write them in this cell holding this formula and each word will be separated by DELIM
The ranges are optional. In the picture below, you'll see cell A2 contains the word "named". This is the first of the six words we're tying to find and it can be expressed as FIRST = "A2" = "named" Inside the formula you'll see that FIRST appears twice. You could replace it with "named" and the cell A2 would become blank but the functionality of the formula would not change.
Even TARGET is optional. It could be written as E1 or typed out word for word.
I don't know why anyone would do that... but it is possible.
DELIM is at cell B2, it is a double space
Now to explain how it works
SEARCH(search for what?, search where?) This is responsible for determining if a match exists or not. If you understand what the named ranges then you've already figured out the syntax is. The location of first letter that of match in TARGET is returned. In this formula it is always 1 If it is not found then the number is 0
IFERROR(value,value) tries to perform the operation. If successful then the result is displayed. If there's an error the second result is displayed. Every IFERROR in this formula is practically the same: IFERROR(SEARCH(FIRST,TARGET),0) It searches inside TARGET trying to find the FIRST word. Result if found is 1 and if not found is 0
It gets a little more complicated from here so lets recap. We're calling SEARCH 6 times. Once for each word we want to find and we're always looking in TARGET. Result will be a 1 if match is found or a 0 if not. Ironically, us humans can put it together and see the match but the formula can't determine which words have been matched without more information
SUMPRODUCT takes the sum (addition) of the product (multiplication) of two or more arrays.
multiply two arrays to get the product
a, b, c * e, f, g = ae, bf, cg
takethe sum of the product to get the SUMPRODUCT
ae + bf + cg`
This is easiest when thought of a price and quantity. If one array is the price of a group of items and the other is quantity of the same group of items, then multiplying the two arrays will create a new array where each element is the cost to buy all items of that type in the group the total, and adding all those numbers give you the total cost you'd pay for all of the items
Here we multiply two arrays:
Qty Price
12.0 0.3
70.0 0.1
20.0 0.4
Multiply them to get the product:
Qty Price Total
12.0 0.3 3.8
70.0 0.1 7.0
20.0 0.4 8.0
Take the sum of the product:
Qty Price Total
12.0 0.3 3.8
70.0 0.1 7.0
20.0 0.4 8.0
18.8 SUMPRODUCT
Lets look at part of the formula:
SUMPRODUCT((IFERROR(SEARCH(FIRST,TARGET),0)>0)*100000+IFERROR(SEARCH(SECOND,TARGET),0)>0)*20000+...
It is easy to see this segment is looking for two words. We know SUMPRODUCT want's to multiply and add arrays. If you're thinking (IFERROR(SEARCH(FIRST,TARGET),0)>0) is an array, you'd be right! It's not an array in the technical sense of the word, but it does evaluate into a single value which can thought of as a 1x1 array, or, a cell. The sharp eyed and quick witted, may have noticed there is something on this array we have mentioned. It's the inequality at the end! Many of you know that you can take numerical values and turn them into boolean by testing them with an inequality. So lets evaluate.... SEARCH for FIRST inside TARGET = 1 because FIRST = "named" which is inside TARGET waaaaaaay in the back and because it wasn't an error we get to keep the 1. Next we do the inequality 1 > 0 = TRUE One is greater than zero and evaluates to TRUE
This is what we have right now
SUMPRODUCT((TRUE*100000+IFERROR(SEARCH(SECOND,TARGET),0)>0)*20000+....
Can you identify the arrays now? We know TRUE is an array, a 1x1. You know the IFERROR bit all the way to the inequality is also an array. Lets evaluate that IFERROR .... Mathematically we should still be working from left to right but trust me, we're ok if we let it slide this once.
IFERROR(SEARCH(SECOND,TARGET),0)>0) SECOND = "array" = 1 = TRUE
Did you follow my short hand? It's ok if you didn't just back up and practice on FIRST until you understand.
Plugging in the value gives us something like this
SUMPRODUCT(TRUE*100000+TRUE*20000+...
SUMPRODUCT is the SUM(addition) of the PRODUCT(multiplication)
So we're adding the stuff we multiply
SUMPRODUCT = (TRUE * 100000) + (TRUE * 20000)
Remember how easy it was to go from 1 > 0 to TRUE. We're "getting all up into that boolean TRUE that" equals 1 Here's a fun fact, -1 is also equal to TRUE. If you've ever seen a formula with a double negative in it like this STUFF(--(MORESTUFF( that's just some Excel wizard person making sure they get a +1 instead of a -1 ... ok, so lets get back on track and evalute
SUMPRODCUT = 1 * 100000 + 1 * 20000+....
SUMPRODCUT = 100000 + 20000+....
SUMPRODCUT = 120000+.....
I know you've been asking about those numbers. One hundred thousand? What's one hundred thousand for? I've been purposefully ignoring until it became convenient to talk about it. And now it's convenient. Go look at the whoooole formula and you'll find a pattern. Those numbers are in a decreasing sequence. Anyone who's ever done bitwise logic can see where this is going.I'm running short on time so I'll cut to the chase. Assume a hypothetical situation where every word was matched. You'd end up with
SUMPRODUCT = 100000 + 20000 + 3000 + 400 + 50 + 6
SUMPRODCUT = 123456
123456 are you pulling my leg? No, I am not. We're almost done so if you're still with me then you're gonna drive it home.
We have a large group of SUBSTITUTE teachers at the front of the line and we gotta get rid of them.
We also have this to contend with :"1",FIRST&DELIM),"2",SECOND&DELIM),"3",THIRD&DELIM),"4",FOURTH&DELIM),"5",FIFTH&DELIM),"6",SIXTH&DELIM),"0","")
Thankfully for us, they are part of the same problem. We worked our way from the middle out.
SUBSTITUTE(SUBSTITUTE(text, old text, new text)
SUBSTITUTE(SUBSTITUTE("123456","1", FIRST & DELIM),"2",SECOND & DELIM)....
Remember at top DELIM was pointing to a cell holding a double space. Each DELIM can be replaced with " " or any other delimiter you want.
SUBSTITUTE(SUBSTITUTE("123456","1", "named" & " "),"2",SECOND & DELIM)...
SUBSTITUTE("named 23456","2",SECOND & DELIM)...
SUBSTITUTE("named 23456","2","array"& " ")...
("named array 3456")... and so on.
Any questions?
Ok, class is dismissed!

Excel VBA / math: count how many groups of n are in a range of numbers

I'm having a bit of a brain freeze, I thought this would be simple but it's not coming to me. I need an equation to calculate the number of groups of 10 in a variable range of variable data. Here's a small example, the real thing has hundreds of numbers with a variable min and max:
Number Rounded number to nearest 10
303.9 300
285 290 - min
443 440
446.8 450
461.1 460 - max
428.83 430
428.545 430
445.835 450
427.215 430
429.97 430
Unique groups of 10
300
290
440
450
460
430
Answer = 6 groups
I don't want to use pivot tables or group functions, I'd rather keep it solely in VBA. Also I don't want to work out the rounded values first and then count the distinct ones because I'd like to use the number to dimension an array, which I'll then populate in a loop. Is there a clever bit of math that can give answer?
I'm not aware of any clever math to do this. You could do this with worksheet formulas:
=SUM(--(FREQUENCY(ROUND(r,dec_places),ROUND(r,dec_places))>0))
where r is the data range and dec_places is the amount of rounding (since you're rounding to the nearest 10s, dec_places = -1).
You could implement this in VBA with something like:
Function CountUniqueRounded(r As Range, dec_places As Double) As Long
' Implement this worksheet formula
' =SUM(--(FREQUENCY(ROUND(r,dec_places),ROUND(r,dec_places))>0))
Dim rAddr As String
Dim rFormula As String
Dim c As Long
' Build up the formula string
rAddr = r.Parent.Name & "!" & r.Address
rFormula = "ROUND(" & rAddr & "," & CStr(dec_places) & ")"
rFormula = "=SUM(--(FREQUENCY(" & rFormula & "," & rFormula & ")>0))"
' Debug.Print rFormula
c = Application.Evaluate(rFormula)
CountUniqueRounded = c
End Function
Hope this helps
I have an Array Formula solution which does not require VBA. Array Formulas take single function which would normally apply only to a single cell, and perform that function over a range of cells, returning an Array of different results (1 for each cell). That Array of results is then collapsed into a single number to give your answer.
Assuming your data is in column A, and goes for less than 1000 rows, this will work:
=SUM(IFERROR(MATCH(10*(ROW(A1:A1000)),ROUND(A1:A1000,-1),0)*0+1,0))
Note that to confirm an Array Formula, you need to press CTRL + SHIFT + ENTER, isntead of just ENTER.
What it does is multiplies 10 by each row from A1 to A1000, and then checks to see if that result can be found when rounding each cell present in A1 to A1000. That is, it checks 10, 20, etc. up to 1000, and tries to find it in a range of your rounded values. Whenever it finds a value, it multiplies the row it was found on by 0, and adds 1. Whenever it doesn't find a value (ie: returns an error), it shows 0. The sum of all matches gives you the number of times each rounded number from 10 - 1000 is found.
Caveat - this will not work if you have numbers > 1000; if such numbers would occur you can easily change all instances of 1,000 to 10,000. Likewise if your data sometimes extends further than row 1000, you will need to increase all instances of 1000 to an appropriate number. If data would vary wildly and you can't estimate size / max limit, then there are ways to automate this, but as the formula is already somewhat complex, I left that as a manual process.

How to get excel to display a certain number of significant figures?

I am using excel and i want to display a value to a certain number of significant figures.
I tried using the following equation
=ROUND(value,sigfigs-1-INT(LOG10(ABS(value))))
with value replaced by the number I am using and sigfigs replaced with the number of significant figures I want.
This formula works sometimes, but other times it doesn't.
For instance, the value 18.036, will change to 18, which has 2 significant figures. The way around this is to change the source formatting to retain 1 decimal place. But that can introduce an extra significant figure. For instance, if the result was 182 and then the decimal place made it change to 182.0, now I would have 4 sig figs instead of 3.
How do I get excel to set the number of sig figs for me so I don't have to figure it out manually?
The formula (A2 contains the value and B2 sigfigs)
=ROUND(A2/10^(INT(LOG10(A2))+1),B2)*10^(INT(LOG10(A2))+1)
may give you the number you want, say, in C2. But if the last digit is zero, then it will not be shown with a General format. You have then to apply a number format specific for that combination (value,sigfigs), and that is via VBA. The following should work. You have to pass three parameters (val,sigd,trg), trg is the target cell to format, where you already have the number you want.
Sub fmt(val As Range, sigd As Range, trg As Range)
Dim fmtstr As String, fmtstrfrac As String
Dim nint As Integer, nfrac As Integer
nint = Int(Log(val) / Log(10)) + 1
nfrac = sigd - nint
If (sigd - nint) > 0 Then
'fmtstrfrac = "." & WorksheetFunction.Rept("0", nfrac)
fmtstrfrac = "." & String(nfrac, "0")
Else
fmtstrfrac = ""
End If
'fmtstr = WorksheetFunction.Rept("0", nint) & fmtstrfrac
fmtstr = String(nint, "0") & fmtstrfrac
trg.NumberFormat = fmtstr
End Sub
If you don't mind having a string instead of a number, then you can get the format string (in, say, D2) as
=REPT("0",INT(LOG10(A2))+1)&IF(B2-(INT(LOG10(A2))+1)>0,"."&REPT("0",B2-(INT(LOG10(A2))+1)),"")
(this replicates the VBA code) and then use (in, say, E2)
=TEXT(C2,D2).
where cell C2 still has the formula above. You may use cell E2 for visualization purposes, and the number obtained in C2 for other math, if needed.
WARNING: crazy-long excel formula ahead
I was also looking to work with significant figures and I was unable to use VBA as the spreadsheets can't support them. I went to this question/answer and many other sites but all the answers don't seem to deal with all numbers all the time. I was interested in the accepted answer and it got close but as soon as my numbers were < 0.1 I got a #value! error. I'm sure I could have fixed it but I was already down a path and just pressed on.
Problem:
I needed to report a variable number of significant figures in positive and negative mode with numbers from 10^-5 to 10^5. Also, according to the client (and to purple math), if a value of 100 was supplied and was accurate to +/- 1 and we wish to present with 3 sig figs the answer should be '100.' so I included that as well.
Solution:
My solution is for an excel formula that returns the text value with required significant figures for positive and negative numbers.
It's long, but appears to generate the correct results according to my testing (outlined below) regardless of number and significant figures requested. I'm sure it can be simplified but that isn't currently in scope. If anyone wants to suggest a simplification, please leave me a comment!
=TEXT(IF(A1<0,"-","")&LEFT(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00"),sigfigs+1)*10^FLOOR(LOG10(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00")),1),(""&(IF(OR(AND(FLOOR(LOG10(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00")),1)+1=sigfigs,RIGHT(LEFT(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00"),sigfigs+1)*10^FLOOR(LOG10(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00")),1),1)="0"),LOG10(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00"))<=sigfigs-1),"0.","#")&REPT("0",IF(sigfigs-1-(FLOOR(LOG10(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00")),1))>0,sigfigs-1-(FLOOR(LOG10(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00")),1)),0)))))
Note: I have a named range called "sigfigs" and my numbers start in cell A1
Test Results:
I've tested it against the wikipedia list of examples and my own examples so far in positive and negative. I've also tested with a few values that gave me issues early on and all seem to produce the correct results.
I've also tested with a few values that gave me issues early on and all seem to produce the correct results now.
3 Sig Figs Test
99.99 -> 100.
99.9 -> 99.9
100 -> 100.
101 -> 101
Notes:
Treating Negative Numbers
To Treat Negative Numbers, I have included a concatenation with a negative sign if less than 0 and use the absolute value for all other work.
Method of construction:
It was initially divided into about 6 columns in excel that performed the various steps and at the end I merged all of the steps into one formula above.
Use scientific notation, say if you have 180000 and you need 4 sigfigs the only way is to type as 1.800x10^5
I added to your formula so it also automatically displays the correct number of decimal places. In the formula below, replace the digit "2" with the number of decimal places that you want, which means you would need to make four replacements. Here is the updated formula:
=TEXT(ROUND(A1,2-1-INT(LOG10(ABS(A1)))),"0"&IF(INT(LOG10(ABS(ROUND(A1,2-1-INT(LOG10(ABS(A1)))))))<1,"."&REPT("0",2-1-INT(LOG10(ABS(ROUND(A1,2-1-INT(LOG10(ABS(A1)))))))),""))
For example, if cell A1 had the value =1/3000, which is 0.000333333.., the above formula as-written outputs 0.00033.
This is an old question, but I've modified sancho.s' VBA code so that it's a function that takes two arguments: 1) the number you want to display with appropriate sig figs (val), and 2) the number of sig figs (sigd). You can save this as an add-in function in excel for use as a normal function:
Public Function sigFig(val As Range, sigd As Range)
Dim nint As Integer
Dim nfrac As Integer
Dim raisedPower As Double
Dim roundVal As Double
Dim fmtstr As String
Dim fmtstrfrac As String
nint = Int(Log(val) / Log(10)) + 1
nfrac = sigd - nint
raisedPower = 10 ^ (nint)
roundVal = Round(val / raisedPower, sigd) * raisedPower
If (sigd - nint) > 0 Then
fmtstrfrac = "." & String(nfrac, "0")
Else
fmtstrfrac = ""
End If
If nint <= 0 Then
fmtstr = String(1, "0") & fmtstrfrac
Else
fmtstr = String(nint, "0") & fmtstrfrac
End If
sigFig = Format(roundVal, fmtstr)
End Function
It seems to work in all the use cases I've tried so far.
Rounding to significant digits is one thing... addressed above. Formatting to a specific number of digits is another... and I'll post it here for those of you trying to do what I was and ended up here (as I will likely do again in the future)...
Example to display four digits:
.
Use Home > Styles > Conditional Formatting
New Rule > Format only cells that contain
Cell Value > between > -10 > 10 > Format Number 3 decimal places
New Rule > Format only cells that contain
Cell Value > between > -100 > 100 > Format Number 2 decimal places
New Rule > Format only cells that contain
Cell Value > between > -1000 > 1000 > Format Number 1 decimal place
New Rule > Format only cells that contain
Cell Value > not between > -1000 > 1000 > Format Number 0 decimal places
.
Be sure these are in this order and check all of the "Stop If True" boxes.
The formula below works fine. The number of significant figures is set in the first text formula. 0.00 and 4 for 3sf, 0.0 and 3 for 2sf, 0.0000 and 6 for 5sf, etc.
=(LEFT((TEXT(A1,"0.00E+000")),4))*POWER(10,
(RIGHT((TEXT(A1,"0.00E+000")),4)))
The formula is valid for E+/-999, if you have a number beyond this increase the number of the last three zeros, and change the second 4 to the number of zeros +1.
Note that the values displayed are rounded to the significant figures, and should by used for display/output only. If you are doing further calcs, use the original value in A1 to avoid propagating minor errors.
As a very simple display measure, without having to use the rounding function, you can simply change the format of the number and remove 3 significant figures by adding a decimal point after the number.
I.e. #,###. would show the numbers in thousands. #,###.. shows the numbers in millions.
Hope this helps
You could try custom formatting instead.
Here's a crash course: https://support.office.com/en-nz/article/Create-a-custom-number-format-78f2a361-936b-4c03-8772-09fab54be7f4?ui=en-US&rs=en-NZ&ad=NZ.
For three significant figures, I type this in the custom type box:
[>100]##.0;[<=100]#,##0
You could try
=ROUND(value,sigfigs-(1+INT(LOG10(ABS(value)))))
value :: The number you wish to round.
sigfigs :: The number of significant figures you want to round to.

SI-prefixes for number format in MS Excel

Does anybody know if it is possible to show numbers in MS Excel with SI-prefixes?
I'd like to have
... 1 n, 1 µ, 1 m, 1, 1 k, 1M, 1 G, ...
instead of scientific format
... 1E-09, 1E-06, 1E-03, 1, 1E+03, 1E+06. 1E+09, ...
Perhaps adding an unit like V (volts), F (farad) etc.
I would be perfect, if the cell would still contain the number and not a string, so it can easily be changed to another format (back to scientific or whatever)
You can do something like this, which I got from Millions & Thousands Custom Number Formatting :
[>=1000000] #,##0.0,," MΩ";[<1000000] #,##0.0," kΩ";General
400 renders as 0.4 kΩ (probably not what you want)
4000 renders as 4.0 kΩ
40e3 renders as 40.0 kΩ
40e6 renders as 40.0 MΩ
but you can probably add more clauses to cover other ranges. Nevermind, you can't.
You can also use LOG and CHOOSE to keep it in a single formula and reasonably compact.
=ROUND(
E10 / (1000 ^ INT(LOG(ABS(E10),1000)) )
,0
) & CHOOSE(
INT(LOG(ABS(E10),1000)) + 6
,"f","p","n","µ","m","","k","M","G","T","P"
)
In this formula:
E10 (referred to 3 times) is the cell containing the raw value.
ROUND formats number for display, here rounding to no decimals (0).
INT(LOG(ABS(E10),1000)) is the prefix index -5 through +5.
CHOOSE is the prefix to use (needs positive index, hence + 6).
No solution will work better than scientific notation.
If you use custom number formats, then you would have to enter them manually (or with VBA) such that they will mask the actual content of the cell.
For instance, if you want to display the following format pairs:
1 n 1E-09
1 µ 1E-06
1 m 1E-03
1 1
1 k 1E+03
1 M 1E+06
1 G 1E+09
If you have 0.001, you would have to set the format as "1 m" -- this will mask the number, so if you have 0.002 you would have to set it as "2 m" -- if you changed it to 0.004 it would still display 2 m as a result. This obviously isn't ideal.
You could set it up as a two-column sheet, where you have the values in the left, and use a formula to display with units on the right, but then you end up not being able to do math with the formatted values.
So basically, the answer is "no", it isn't possible.
You could theoretically write a VBA script that will automatically change the visible contents according to the cell contents whenever a number is changed, but the script would be bulky and would cause serious trouble to whoever you sent to if they had macros off. It would also require all sorts of corner cases depending on if you wanted numbers formatted 'normally' in certain cells. So while it may be theoretically possible, it is practically impossible
It is possible, though bulky using a conversion table and the match and index functions.
From a conversion table like this (2 columns):
1.E+15 P
1.E+12 T
1.E+09 G
1.E+06 M
1.E+03 k
1.E+00
1.E-03 m
1.E-06 µ
1.E-09 n
1.E-12 p
1.E-15 f
You could then perform the following translation
3.68437E+11 --> 368.44 G
If you have the conversion table in columns A and B
and the unformatted number in cell G1
H1
=G1/INDEX(A:A,MATCH(G1,$A:$A,-1)+1)
I1
=INDEX($B:$B,MATCH(G1,$A:$A,-1)+1)
Then the proper numerals will display in column H with the suffix/prefix in column I.
It is still ponderous, and should only be used for final output since calculations from the modified numbers will have to include a reverse translation.
There's no way I know of to do this as a number format (where you can then use the formatted number as you would any other numeric value for subsequent calculation), but for simply presenting the number using SI prefixes, here's the formula I use. It takes the formula in the specified cell (usually next to it, in this case E28), scales the number, rounds to the specified number of significant figures (in this case 3), appends the appropriate SI prefix, and then appends the specified unit (in this case 'F' for Farads). The advantage here is that the formula is self-contained and doesn't require any external reference tables. This formula works for femto (10^-15) through Tera (10^12), but can easily be expanded for additional prefixes
=CONCAT(
ROUND(
IF(E28>1E12, E28/1E12,
IF(E28>1E9, E28/1E9,
IF(E28>1E6, E28/1E6,
IF(E28>1E3, E28/1E3,
IF(E28>1, E28,
IF(E28>1E-3, E28*1E3,
IF(E28>1E-6, E28*1E6,
IF(E28>1E-9, E28*1E9,
IF(E28>1E-12, E28*1E12,
E28*1E15
) ) ) ) ) ) ) ) ),
3 +N("This is the number of significant digits to round to")
-(1+INT(LOG10(ABS(
IF(E28>1E12, E28/1E12,
IF(E28>1E9, E28/1E9,
IF(E28>1E6, E28/1E6,
IF(E28>1E3, E28/1E3,
IF(E28>1, E28,
IF(E28>1E-3, E28*1E3,
IF(E28>1E-6, E28*1E6,
IF(E28>1E-9, E28*1E9,
IF(E28>1E-12, E28*1E12,
E28*1E15
) ) ) ) ) ) ) ) ) ))))
),
IF(E28>1E12, "T",
IF(E28>1E9, "G",
IF(E28>1E6, "M",
IF(E28>1E3, "k",
IF(E28>1, "",
IF(E28>1E-3, "m",
IF(E28>1E-6, "µ",
IF(E28>1E-9, "n",
IF(E28>1E-12, "p",
"f"
) ) ) ) ) ) ) ) ),
"F" +N("This is the unit symbol that will be appended to the end")
)
If you want to round to a fixed number of decimal figures as opposed to significant figures, the formula is a little simpler:
=CONCAT(
ROUND(
IF(E28>1E12, E28/1E12,
IF(E28>1E9, E28/1E9,
IF(E28>1E6, E28/1E6,
IF(E28>1E3, E28/1E3,
IF(E28>1, E28,
IF(E28>1E-3, E28*1E3,
IF(E28>1E-6, E28*1E6,
IF(E28>1E-9, E28*1E9,
IF(E28>1E-12, E28*1E12,
E28*1E15
) ) ) ) ) ) ) ) ),
3 +N("This is the number of decimal digits to round to")
),
IF(E28>1E12, "T",
IF(E28>1E9, "G",
IF(E28>1E6, "M",
IF(E28>1E3, "k",
IF(E28>1, "",
IF(E28>1E-3, "m",
IF(E28>1E-6, "µ",
IF(E28>1E-9, "n",
IF(E28>1E-12, "p",
"f"
) ) ) ) ) ) ) ) ),
"F" +N("This is the unit symbol that will be appended to the end")
)
Note that I've written all of the scaling constants in exponential notation, Excel will change these to plain numbers when you enter the formula. By using a relative cell reference, it's pretty easy to copy and paste the formula around where you need it.
The formula could be condensed into a single block of IF/CONCAT/ROUND statements, but arranging it as I've done here separates out the rounding constant into a single point in the formula, making it easier to change.
Just select the cell or range of cells you want to contain the given symbol. Right click on the cell and select FORMAT CELLS. Select the NUMBER format on the left, enter decimal places, etc on the right. Now go all the way down the list of your format options on the left and select CUSTOM. (IMPORTANT: Do NOT select ANY custom format options on the right.) Left click in the box just below TYPE: and above the list of custom format options. (This box displays your current selected format. {0.00 if you selected the default number format} You want to keep this formatting AND add additional formatting.) Click to the right of 0.00 and type the following: " μ" Click OKAY and you may enter your data as normal. Formatting cells has no impact on the values you enter. You can perform all functions as normal. I am attaching a pic where I used the same instructions to apply litters and the greek MU notation to values and performed some basic calculations without impeding Excel's ability to function.Special Notation in Excel
This is a limited answer for Google Sheets, using actual number formats instead of expressions that output text.
Spinning off from endolith's answer, I settled on this:
[>=1E6] #,##0.0,,"M";[>1E3] #,##0.0,"K";0.#####################
It works on numbers from 1 to <1E16, though can't be expanded to units above M. Doesn't work for negative numbers or fractional numbers. It is limited by the number of conditional sections Google Sheets is able to parse.
Docs: https://developers.google.com/sheets/api/guides/formats#number_format_patterns
' Hans Wolfgang Schulze 20190921, cause I always need this and need to write it again cause I forgot where I saved it.
' Paste this into Excel's Macro Editor (F11) and use from any cell.
' Copyleft 2019. Please include original author's name in all derivative works.
'
' Note that the conversions in this code is assuming normal Base 10, and not Binary 1024. Lots of code has to change.
' Currently recognizes numbers like "-123123.123G" or "123E15" with or without actual units.
' Special case of Excel's "-" nothing equals 0.
' Assumes, if exists, that the rightmost character is the SI exponent designation - See expS below.
' Usage: =DSci("45e9k") gives "4.5E12" as an answer.
Const expS = "-qryzafpnum KMGTPEZYRQ" ' https://en.wikipedia.org/wiki/Metric_prefix
Function DSci(inputS As String) As Double
Dim which As Integer
which = InStr(expS, Right(inputS, 1))
whichUnitary = InStr(expS, " ") ' offset into expS for " " unity value
If which = 0 Then
which = InStr("----F-Nµ- k-gt-e", Right(inputS, 1)) ' try alt case and form that aren't obscure ie k=K or m!=M
End If
If which > 0 Then ' has a terminating exponential character. 1 is not found.
If which = 1 Then ' "-"
DSci = 0 ' excel nothing value (0)
Else ' convert only the left side of input
DSci = CDbl(Left(inputS, Len(inputS) - 1)) * 10# ^ ((which - whichUnitary) * 3#) ' fix for Binary K's
End If
Else
DSci = CDbl(inputS) ' convert whole string instead ' special case devide by 1.024 for each 1000 for Binary K's
End If
End Function
' Formats to SI convention 10 ^ (-30 ... +30) and recent suggested expansions
' Usage =Sci(5.531e9, "B") gives string of "5.531GB"
' Significant digits are suggested as 4, can be any positive number.
Function Sci(value As Double, optionalUnit As String, Optional significant As Integer = 4) As String
Dim mant As Double, exp As Double, rank As Integer
rankUnitary = InStr(expS, " ") ' offset into expS for " " unity value
If value = 0 Then exp = 0 Else exp = Log(value) / Log(10#) ' nDigits
mant = value / (10# ^ exp) '
While mant >= 999.9999999999 ' don't want 2000K, rather 2M. Change to 1023.9999999999# for Binary K's
exp = exp + 3#
mant = mant / 1000# ' change to 1024# for binary K's etc.
Wend
rank = Int((exp + 0.0000000000001) / 3#) ' should be >1E-300 or so? Why not? 3 != 3#? More changes for Binary K's ?
mant = mant * 10# ^ (-rank * 3# + exp) ' adjust mantussa after de-ranking. Change?? for Binary K's
If Abs(rank) >= rankUnitary Then ' outside of +/- yY bounds
expChar = "?" ' what do you call it then? Not defined.
Else
expChar = Mid(expS, rank + rankUnitary, 1) ' add SI
End If
Sci = Left(mant, Abs(significant)) ' don't allow negative numbers, pretend they are positive lengths
If Right(Sci, 1) = "." Then Sci = Left(Sci, Len(Sci) - 1) ' lop off right DP
Sci = Sci & " " & expChar & optionalUnit
End Function

Resources