Change cell formatting - excel

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 ...

Related

Conditional formatting using the INDIRECT function fails with boolean AND or OR or with cells containing formulas

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.

Excel Formula - Check if cell has formula

What formula do you use to check if another cell has formula? For example, I have 2 columns, A has cells which contains either a formula or a value.
(Column A usually contains Formulas but other users try to change their values by directly typing and replacing the formula that was previously there)
In Column B I want to add a formula that will say "HasFormula" if the cell on Column A has formula and say "PlainValue" if it contains a value.
I'm thinking maybe using =ISNUMBER() but that may not be accurate.
I am using Excel 2010.
Excel actually has a builtin ISFORMULA() function.
Say A1 has a formula and you want to check that. In say B1, you can use:
=If(ISFORMULA(A1),"HasFormula","PlainValue")
Edit: Per your comment, you don't have ISFORMULA(). An alternative is to create a quick UDF, and use the custom function in the worksheet.
In a workbook module, put this code:
Function isFormula(ByVal target As Range) As Boolean
isFormula = target.hasFormula
End Function
Then you can call it like this: =isFormula(A1) and it will return TRUE if A1 has a formula.
If you can't use VBA, then you can use this formula:
=IF(ISERROR(FORMULATEXT(A1)),"PlainText","HasFormula")
The MrExcel website (link below) has this method which uses old code from Excel 4 (which is still present for backward compatibility)...
Define a NAME such as "CellToLeftHasFormula" and in the "refers to" box put
=GET.CELL(48,OFFSET(INDIRECT("RC",FALSE),0,-1))
Then in column B use the formula =CellToLeftHasFormula which will return TRUE if it has.
Be aware that this will mean your Excel will now contain a macro and so will need to be saved as such (xlsm). I use this in Excel 2010.
For full explanation (and other .CELL options, besides 48) see MrExcel link: https://www.mrexcel.com/forum/excel-questions/20611-info-only-get-cell-arguments.html
You can use the Range.HasFormula property.
https://learn.microsoft.com/en-us/office/vba/api/excel.range.hasformula
EDIT:
Text and code from the above link:
"True if all cells in the range contain formulas; False if none of the cells in the range contains a formula; null otherwise. Read-only Variant. ..."
Worksheets("Sheet1").Activate
Set rr = Application.InputBox( _
prompt:="Select a range on this worksheet", _
Type:=8)
If rr.HasFormula = True Then
MsgBox "Every cell in the selection contains a formula"
End If
You can restrict the user by protecting the column A.
You can directly check if a cell contains a formula by using a shortcut Ctrl + `.
You can use vba and write a user defined function :
1. Press alt + F11
2. Insert module in workbook
3. Paste this code
Function IsFormula(cell_ref As Range)
IsFormula = cell_ref.HasFormula
End Function
4. Now, use Isformula in the cell wherever you want.

Use cell's color as condition in if statement (function)

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)," ")

In Excel and VBA, how to set value of cell to the formulas result rather than the formula

I'm getting values from one sheet and placing them in another using a macro in Excel. I currently have this which works fine:
sheet.range("B2:B35").Value = "=IF(SUMPRODUCT(--(Raw!$B$11:$B$322=$A2),--(Raw!$D$11:$D$322=All!$B$2),Raw!$H$11:$H$322)<>0,SUMPRODUCT(--(Raw!$B$11:$B$322=$A2),--(Raw!$D$11:$D$322=All!$B$2),Raw!$H$11:$H$322),""-"")"
It, obviously, puts that entire formula as the value of the cell. What I'd like is it just to put the result of the formula into the cell. I've tried adding Evaluate() around the "IF..." part, but then the IF doesn't evaluate correctly (I just end up with "-" in each cell). Is this possible to do or do I have to have separate code to loop through and change the value to the value of the cell?
Use:
sheet.range("B2:B35").Formula = "Your formula here"
If that doesn't work you may have to change the formatting (do this first):
sheet.range("B2:B35").NumberFormat = "General"
Edit:
A solution turned out to be addition of the following line after the OP's code:
sheet.range("B2:B35").value = sheet.range("B2:B35").value

how do i set a value to a range using a function from module in excel vba?

i want to do a simple function in a module in excel vba,
so i can use it as a custom function in excel.
(i use excel 2003, or 2007 , it's doesnt matter)
i create a function(!) in a new workbook and it's looks like this:
Function a()
Sheets(1).Range("A1").Value = 4
end function
but when i try to use it on the sheet1 it's wont work!
i tried many things.
how can i make this work (with no workarounds, i want to use it as a custom function) ?
please help.
thanks,
gadym
A function that uses other cells cannot become a formula function (UDF) in Excel, because it breaks Excel's dependency model (all cell dependencies must be explicit in the formula). However a formula can use cell values as inputs.
Here is a simple function added to a module in VBA:
Public Function testFunction(inputValue As Integer) As Integer
testFunction = inputValue * 2
End Function
This can be used in any cell formula. For example, =testFunction(4) or =testFunction(A5).
EDIT
Okay, reviewing the comment you made against guitarthrower's answer. A formula can only send an answer to the cell it is in - it cannot send an answer to a different cell. Therefore, if a formula is your only choice, you must have a formula in cell A1 that reads input from C1.
Formula in A1:
=a(C1)
Function in module:
Public Function a(string col)
a = iif(col = "ok", "1", "2")
End Function
However, if there is a problem putting a formula into A1, you are left with a manually driven process (a sheet button, a toolbar button etc. to push these values) or a worksheet cell change event. The downside of a worksheet event is that it fires off every single cell change, so you need to keep the code light and not do any heavy duty work - or if you do, make it rare.
You would add a new subroutine to the worksheet:
Private Sub Worksheet_Change(ByVal Target As Range)
This is fired whenever cells are changed; the changed cells are indicated by the Target range. Your code would update A column cells if the Target contained C column cells. This is more work than the formula approach, but it does render the process entirely automatic. I have no access to Excel right now so the following is just from memory and Googled fragments, untested:
For Each cCell In Application.Intersect(Target, Me.Range("C1:C5"))
cCell.Offset(, -2).Value = iif(cCell.Value = "ok", "1", "2")
I would prefer not to use explicit ranges, but rather a named range as it makes your code less fragile to change. But that would make finding the corresponding A column cell a little more tricky to determine and I'm not going to attempt that code without Excel to hand =)
It looks like you're trying to programatically change the value of an cell within your spreadsheet. This can be done, but as Joel Goodwin pointed out, this can't be done with a "User-Defined Function." However, you can do this with a macro or by adding a button to the sheet and putting code in the button.
For example, add a button to your sheet by going to View > Toolbars > Control Toolbox (this will be different for newer versions of Excel) and selecting the button control and adding it to your sheet. Once the button is added, double click on it. This should bring up the Visual Basic editor. Put your code in the body of the Sub that it provides, like this:
Private Sub CommandButton1_Click()
Sheets(1).Range("A1").Value = 4
End Sub
Go back to your worksheet and disable design mode in the control toolbox (it's the icon with the light blue triangle in it). With design mode disabled, click the button and the value of cell A1 will change to 4.
If cell A1 contains the formula =a(), and you want A1 to show 4 (or any other cell with the formula =a() in it) then you need to change your code to this:
Function a()
a = 4
End Function

Resources