Is there a way via Conditional Formatting (preferably no VBA, but if it's a must, then I'm open to it), to highlight a cell where the formula "idea" is different than the cell above?
I have a column of formulas, but have to manually edit a few of those. I'd like to have those manually edited formulas highlighted, so when I change the formula for the other cells, I know which cell to skip when updating that column.
For example, here's my column and formulas:
I'd like to have B5 highlighted yellow, since the formula is different.
I've tried using =FORMULATEXT($B3)<>FORMULATEXT($B2) but that doesn't work, since it's looking at the literal formula text...in which has they're always different. (=FORMULATEXT(B3)=FORMULATEXT(B2) will always be FALSE since the formula is technically changing, despite it being the same "idea").
I could also perhaps use =LEN($B3)<>LEN($B2) but that would have a false positive when the row changes from 9to 10, and again from 99 to 100...
The other option would, of course, just be to work in an IF()statement to clarify why I'm doing a different formula, i.e. =IF(ROW()=5,A5+A4+A2+A1,A5+A4) and use that...but there's no real logic for why I have to edit manually I could work in - which is why I'd just like a nice visual reminder on those random cells that the formula isn't like the others.
Edit: Quick note that the above formulas are way simplified. My actual ones are a little complex. I'm looking for a general answer to this too. Just thinking for my purposes, I could maybe do a check that if the formula has more than two + in it, highlight the cell. ...but I'm interested in a general way to solve this type of issue that could apply more broadly.
Here's another option for UDF:
Function findDifferent(Rng As Range) As Boolean
findDifferent = Not (Rng.FormulaR1C1 = Rng.Offset(-1).FormulaR1C1 Or Rng.FormulaR1C1 = Rng.Offset(1).FormulaR1C1)
End Function
Here's a quick VB aided solution I came up with. If I add a comment to the special cells (which I do to explain the formula/why it's different), I can check for a comment then highlight it.
Add this function to the workbook:
Function has_Comment(cel As Range) As Boolean
has_Comment = False
If cel.Comment.Text <> "" Then
has_Comment = True
End If
End Function
Then a simple Conditional Formatting formula of:
=has_comment(B2)
That works, and is relatively simple.
Edit: I found also you can do this, which doesn't rely on a comment. Just points out an Inconsistency Error.
Function has_inconsistency(cel As Range) As Boolean
has_inconsistency = False
If cel.Errors.Item(xlInconsistentFormula).Value = True Then
has_inconsistency = True
End If
End Function
Related
How can I change formatting of the cell that uses vba function from the code of that function?
Example I tried:
made vba module (see code below)
put in excel sheet in some cell "=test()"
function "works" - it changes cell value and shows 2 popup windows. But formatting stays the same
Function test()
MsgBox (Application.ThisCell.NumberFormat) ' shows "General"
Application.ThisCell.NumberFormat = "Currency"
'Application.ThisCell.NumberFormat = "#,##0_);[Red](#,##0)"
MsgBox (Application.ThisCell.NumberFormat) ' still shows "General"
test = 12345.6
End Function
How to make it work?
(I need custom formatting rule, not "currency", but custom rule (test example in commented line) doesn't work too)
Please don't kill me for this wacko solution :-)
I have created a function, resulting in the number 4096:
Function very_weird_UDF()
very_weird_UDF = 4096
End Function
Then I have created a conditional formatting rule, based on the present of that UDF (User-Defined Function) inside the formulatext of that cell, as you can see here:
Conditional formatting's formula: =FIND("very_weird_UDF",FORMULATEXT((B2)))
Screenshot of what it looks like:
For your information:
Cell "C3" contains the formula, the other cells in B2:C5 just contain the value 4096.
Cells E2:F5 contain the mentioned =Find(...) formula.
Oh, if you wonder why I use such a weird name for the UDF? Just imagine I used a simpler name, like 'a' or 'f' or something like that. That might highlight a lot of cells who don't use that formula (like a simple =If(...) or an =And(...) or ...
I have the following function for checking whether column L contains the word "completed" and I use INDIRECT to be able to color the whole row with Conditional Formatting:
=INDIRECT("l"&ROW())="completed"
This function works. However, I need to extend this, I want to use Conditional Formatting based on an extra cell as well, so I tried this:
=AND(INDIRECT("l"&ROW())="completed";INDIRECT("m"&ROW())="duplicate")
When I use this second function inside the Excel worksheet they give the proper TRUE or FALSE.
Furthermore, I needed a Custom Formatting on the result of a formula in a cell. I tried the following:
=INDIRECT("n"&ROW())=123456
This only worked if I removed the formula in the cell with the result itself as a number. Again, the function worked when pasted in an worksheet cell.
Is there a way to make this work inside Excel or is there a limit to what Conditional Formatting functions can do?
In case you ask: AND(1;1) works and makes everything yellow, AND(INDIRECT("n"&ROW())=123456;1) does not work, nor does replacing AND with OR.
The semicolon is because I am in the Dutch locale. Replace it with a comma if you are in an English locale.
Not sure why this wouldn't work in Conditional Formatting. But you can simply replace the AND function with * such as:
=(INDIRECT("l"&ROW())="completed")*(INDIRECT("m"&ROW())="duplicate")
You have to think in terms of xlR1C1 formulas to understand CFRs. A CFR based on a formula thinks of it as =RC12="completed" or more completely =AND(RC12="completed", RC13="duplicate").
The xlR1C1 formula does not change no matter what cell you paste it to; it is in this way that CFRs can be applied to a wide range of cells without expending calculation cycles to update the formula for each individual cell. RC12 means 'the cell in column L on the row you are on'. It does not change if filled down, filled right or copied to any other location.
Now unless you are actually working in xlR1C1 (File, Options, Formulas, Working with Formulas, R1C1 reference style) you have to convert the xlR1C1 to xlA1 style. If you are applying the CFR to a number of rows starting with the first row then the R becomes 1 and the C12 becomes $L.
'xlR1C1
=AND(RC12="completed", RC13="duplicate")
'xlA1
=AND($L1="completed", $M1="duplicate")
If you were applying the CFR to a range starting in row 2 change the $L1 to $L2 and the $M1 to $M2.
Among other reasons for not putting the xlR1C1 style formula directly into the CFR creation dialog when working in xlA1 style is that there actually is a RC12 cell in xlA1.
I have a situation where I am referencing cells in a different worksheet and returning the values of cells from that worksheet. Although it works, I find my current method inefficient because I have to repeat the formula in the logical test part of the IF statement:
=IF(**EXTREMELY LONG COMPLICATED FORMULA** <> "", **EXTREMELY LONG COMPLICATED FORMULA**, "")
As you can see, I must repeat the main part of the formula just to check if it is blank first. If I do not do this, I get a zero in the cell (for blank values in the referenced worksheet). I'm looking for something more like:
=IF(**EXTREMELY LONG COMPLICATED FORMULA** <> "", **RETURN VALUE**, "")
This looks cleaner to me because I won't have to repeat myself. Also, if we ever have to update the formula, I won't have to duplicate my changes to the repeated parts. Is there a way to do this?
The above is actually a simplified version of my problem, but the answer should get me where I need to go. My actual formula has nested IF statements checking along the way for blanks. For reference, here it is:
=IFERROR(IF(SMALL(IF(ImportedData!$H$2:$H$1000>=DataFilters!$A$1,IF(ImportedData!$G$2:$G$1000=DataFilters!$A$15,ROW(ImportedData!A$2:A$1000)-ROW(ImportedData!A$2)+1)),ROWS(ImportedData!A$2:ImportedData!A2))<>"",IF(INDEX(ImportedData!A$2:A$1000,SMALL(IF(ImportedData!$H$2:$H$1000>=DataFilters!$A$1,IF(ImportedData!$G$2:$G$1000=DataFilters!$A$15,ROW(ImportedData!A$2:A$1000)-ROW(ImportedData!A$2)+1)),ROWS(ImportedData!A$2:ImportedData!A2)))<>"",INDEX(ImportedData!A$2:A$1000,SMALL(IF(ImportedData!$H$2:$H$1000>=DataFilters!$A$1,IF(ImportedData!$G$2:$G$1000=DataFilters!$A$15,ROW(ImportedData!A$2:A$1000)-ROW(ImportedData!A$2)+1)),ROWS(ImportedData!A$2:ImportedData!A2))),""),""),"")
The most obvious solution is to use a helper column or cell. Just put EXTREMELY LONG COMPLICATED FORMULA somewhere in your spreadsheet, then refer to that cell in your IF formula.
Edit
To avoid a helper column, here is a trick I've used on occasion:
=IFERROR(VALUE(long_formula&""),"")
What this does is, concatenate the result of long formula with an empty string (which converts it to a string), then take the value of all that (which converts it back to a number if possible), then substitute any errors with a blank. (An error would occur if you attempt to take the value of something that's not numerical.)
This will only work if you either have a numerical result or an empty result. It will fail if you have a text result.
As of March 2020, Excel includes the LET function. You can write:
=LET(ELCF,**EXTREMELY LONG COMPLICATED FORMULA**,IF(ELCF <> "", ELCF, ""))
Where the three parameters are:
the name you will use to refer to your calculation,
the calculation itself, and
the final formula using the calculation.
The function also allows for multiple names to be defined. The general syntax is:
=LET(name1, name_value1, calculation_or_name2, [name_value2, calculation_or_name3...])
https://support.microsoft.com/en-us/office/let-function-34842dd8-b92b-4d3f-b325-b8b8f9908999
Do you need the blank in the cell for further calulations or if-functions or Do you just dont want to see the 0s?
Second case:
Just use a number format for the column like
0,00;-0,00;"";#
First case:
Put the following code in a module:
Option Explicit
Public Function IfEmpty(LongFormula As String) As String
If LongFormula = "" Then
IfEmpty = ""
Else
IfEmpty = LongFormula
End If
End Function
And use it in your worksheet like
=IfEmpty(**EXTREMELY LONG COMPLICATED FORMULA**)
I want to count the number of numbers in a single cell.
Example:
In cell A1, I have the following addition:
=12+45+23+51+10 which totals (and shows) 141.
In cell B1, I would like the see how many numbers have been added together, which means that there should be 5 (12 is a number, 45 another one, etc... and all together, there are 5 numbers in cell A1).
I know it seems to be a ridiculous question, but I scanned all the platforms for this issue and did not find any suitable solution. Tried all the LEN and LEN SUBSTITUTE alternatives out there, but somehow it does not work.
Thank you upfront for your help. Optimal solution would be a excel formula, alternatively VBA would also work.
Excel 2013 has a new function Formulatext() which returns the, well, formula text. Using that the Len() and Substitute() approach works.
=LEN(FORMULATEXT(A1))-LEN(SUBSTITUTE(FORMULATEXT(A1),"+",""))+1
Hit Alt+F11 and Insert->Module with the following VBA:
Function NumCount(Rng As Range)
x = Split(Rng.Formula, "+")
NumCount = UBound(x) + 1
End Function
Then you can call =NumCount(A1) on any cell to get the number of numbers in the formula for that cell.
Use this VBA:
Function GetFormula(Cell as Range) as String
GetFormula = Cell.Formula
End Function
and then to get the number of numbers...
=LEN(GetFormula(D99))-LEN(SUBSTITUTE(GetFormula(D99),"+",""))
on this as my D99 contents...
=45+46+47+50+100
The one major drawback here is that I'm assuming everything is + if you have -, *,/ or other operators this gets more challenging. you might be able to use replace for each but you'd always be limited to the 4 basic operators... if someone used exponents or mod, this would be harder.
Also possible in earlier Excel versions without VBA - subject to (i) there is always at least one value in the cells, (ii) the operator is always + and (iii) the cells are in a column.
Replace = with '= in that column, apply the substitution, say:
=LEN(A1)-LEN(SUBSTITUTE(A1,"+",""))+1
in a different column and Paste Special, Value the results for that other column. Then apply Text To Columns on the original column with ' as the delimiter.
*There is no way to do this without using a User Defined Function (UDF) written in Excel VBA. Something like this should work:
Public Function numsAdded(cell1 As Range)
Dim formulaString As String
formulaString = cell1.Formula
numsAdded = Len(formulaString) - Len(Replace(formulaString, "+", "")) + 1
End Function
Once you've added that to a VBA module, you can use it as a function in any cell in your spreadsheet.
*Edit - Apparently there is a way if you have Excel 2013, as teylyn suggests. If you use 2010 or earlier like me, you'll need VBA.
Try this:
=LEN(SUBSTITUTE(F16,"+","+"))
Note: F16 is only an example name for the cell you want to do the counting on.
Example:
F16=45+65+76 # Gives 186
F17=LEN(SUBSTITUTE(F16,"+","+")) # Gives 3
I am trying to get a cell to perform a function based on the hilight color of a cell.
Here is the function I currently have:
=IF(A6.Interior.ColorIndex=6,IF(ROUNDDOWN(IF(M6<3,0,IF(M6<5,1,IF(M6<10,3,(M6/5)+2))),0)=0,0,ROUNDDOWN(IF(M6<3,0,IF(M6<5,1,IF(M6<10,2,(M6/5)+2))),0)),IF(ROUNDDOWN(IF(M6<7,0,IF(M6<10,1,M6/5)),0)=0,0,ROUNDDOWN(IF(M6<7,0,IF(M6<10,1,M6/5)),0)))
Just so you don't have to read through all of that, here's a more simple example
=IF(A6.Interior.ColorIndex=6,"True","False")
All that his is returning is #NAME? . Is there any way that I can do this as a function in a cell or is VBA absolutely required?
Thanks,
Jordan
You cannot use VBA (Interior.ColorIndex) in a formula which is why you receive the error.
It is not possible to do this without VBA.
Function YellowIt(rng As Range) As Boolean
If rng.Interior.ColorIndex = 6 Then
YellowIt = True
Else
YellowIt = False
End If
End Function
However, I do not recommend this: it is not how user-defined VBA functions (UDFs) are intended to be used. They should reflect the behaviour of Excel functions, which cannot read the colour-formatting of a cell. (This function may not work in a future version of Excel.)
It is far better that you base a formula on the original condition (decision) that makes the cell yellow in the first place. Or, alternatively, run a Sub procedure to fill in the True or False values (although, of course, these values will no longer be linked to the original cell's formatting).
I don't believe there's any way to get a cell's color from a formula. The closest you can get is the CELL formula, but (at least as of Excel 2003), it doesn't return the cell's color.
It would be pretty easy to implement with VBA:
Public Function myColor(r As Range) As Integer
myColor = r.Interior.ColorIndex
End Function
Then in the worksheet:
=mycolor(A1)
Although this does not directly address your question, you can actually sort your data by cell colour in Excel (which then makes it pretty easy to label all records with a particular colour in the same way and, hence, condition upon this label).
In Excel 2010, you can do this by going to Data -> Sort -> Sort On "Cell Colour".
I had a similar problem where I needed to only show a value from another Excel cell if the font was black. I created this function:
`Option Explicit
Function blackFont(r As Range) As Boolean
If r.Font.Color = 0 Then
blackFont = True
Else
blackFont = False
End If
End Function
`
In my cell I have this formula:
=IF(blackFont(Y51),Y51," ")
This worked well for me to test for a black font and only show the value in the Y51 cell if it had a black font.
The only easy solution that I have applied is to recreate the primary condition that do the highlights as an IF condition and use it on the IF formula. Something like this. Depending on the highlight condition the formula will change but I think that should be recreated (es. highlight greater than 20).
=IF(B3>20,(B3)," ")