Use UDF from Add-in in Conditional Formatting - excel

I have an add-in xla file that I use to store my regularly used VBA code. This function is stored in the add-in modules.
Public Function IsFormula(cell_ref As Range)
IsFormula = cell_ref.HasFormula
End Function
This correctly returns True or False if I type it into cell: =IsFormula(A1)
However, when I try to create a new formatting rule using the formula option, I get this error 'You cannot use references to other worksheets or workbooks for Conditional Formating criteria.' The error is not because of quotation marks.

There isn't exactly a clear question to be answered here, but if you want to format say all of the cells in Sheet1 that contain formulae then, in Sheet1 A1:
1) define a name (say ‘Formulaic’, with ‘Sheet1’ for “Scope” and =GET.CELL(48,A1) for “Refers to”.
2) Select Sheet1
3) Set required conditional format with “Use a formula to determine which cells to format” and =Formulaic in “Format values where this formula is true:”
The ‘type_num’ (eg 48 above) is described at http://www.mrexcel.com/forum/excel-questions/20611-info-only-get-cell-arguments.html

Related

How to Count Blank excluding hidden columns in Excel

I am trying to count all blank cells in a row while ignoring hidden columns but I can't find any formula that returns the right answer. The SUBTOTAL function only works on hidden rows but I cannot change my data to hide rows instead of columns.
For example, I wan to count blank cells from B2:BA2 but need to ignore any blank cells from hidden columns between that range.
Appreciate any help!
You can try the following VBA function:
Function CntBlnk(Rng As Range)
Dim Cell As Range
Application.Volatile
For Each Cell In Rng
If Cell.EntireColumn.Hidden = False And Len(Trim(Cell)) = 0 Then
CntBlnk = CntBlnk + 1
End If
Next Cell
End Function
Then call the function CntBlnk in the required cell.
A VBA solution is probably the best option here. A set-up using worksheet formulas alone is possible, viz:
=SUMPRODUCT(N(CELL("width",OFFSET(B2,,COLUMN(B2:BA2)-MIN(COLUMN(B2:BA2))))>0),N(B2:BA2=""))
or, Office 365:
=SUMPRODUCT(N(CELL("width",OFFSET(B2,,SEQUENCE(,COLUMNS(B2:BA2),0)))<>0),N(B2:BA2=""))
though it suffers three drawbacks:
It's volatile
Despite said volatility, changes to the column widths in the range passed will not trigger a recalculation of this formula; the user will need to perform a manual recalculation
Columns having a column width of less than 0.5 will be treated as hidden
If you have Excel 365 and are open to using a Lambda, you could also try:
=LAMBDA(range,index,IF(index>COLUMNS(range),0,ISBLANK(INDEX(range,index))*(#CELL("width",INDEX(range,index))>0)+CountVisBlanks(range,index+1)))
where the Lambda is named as CountVisBlanks in the name manager.
As with the other answer using Cell, it suffers from the issue that Cell doesn't update until you force the sheet to re-calculate.
Called as:
=CountVisBlanks(b2:ba2,1)

Change cell formatting

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

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.

Storing/loading conditional format info in VBA

is there a way I can store and later restore conditional formatting information? Upon selecting a cell, I want to
1/ store the condformatting of the corresponding column/row in some arrays
2/ delete the condformatting of the corresponding column/row
3/ change InteriorColor of column/row to something nice (so that I see a crosshair)
4/ upon selecting another cell, I want to restore the condformatting of the original column/row and repeat the process from 1/ for the currently selected cell.
I tried something like
Public condFmt1 As FormatCondition
Set condFmt1 = Range("A1").FormatConditions.Item(1)
...
Set Range("A2").FormatConditions.Item(1) = condFmt1
however the last line gives me a runTime error 438 - Object does support this property or method. Im probably assigning wrongly.
After playing around with it for an hour, I've found a way around using FormatCondition values in VBA.
This code copies my "A1" range's conditional formatting, which is set to change the font to bold if the value is TRUE
Sub CopyFormatCondition()
Dim fC As FormatCondition
Set fC = Range("A1").FormatConditions.Item(1)
Range("A2").FormatConditions.Add Type:=xlCellValue, Operator:=fC.Operator, Formula1:=fC.Formula1
Range("A2").FormatConditions.Item(1).Font.Bold = fC.Font.Bold
End Sub
Some properties such as Type, Operator and Formula1 have to be set when the FormatCondition is being initialised, hence why I had to add a FormatCondition to the range's FormatConditions collection.
Other properties (e.g. Font and Interior) can be set after the FormatCondition's Initialization.
Assuming you're using Excel 2007 or higher, you can achieve your goal also with a Non-VBA solution:
Use an empty cell in your worksheet/workbook as a trigger cell and set it to TRUE. For convenience, name this cell DisableConditionalFormatting or similar.
Select the active area of the worksheet (Ctrl-A) and insert a new rule -> use formula to determine which cells to format. As a formula set =DisableConditionalFormatting. No need to alter the format here.
After setting the new rule, make sure to select the checkbox Stop if true in the conditional formatting rule manager
No you can toggle the conditional formatting for the worksheet on and off by changing the cell DisableConditionalFormatting.

Excel formula to check cell contents

I'm trying to create some conditional formatting at runtime (huzzah) for an add-in (double huzzah), and have found that, apparently, some functions cannot be used as they would in a normal worksheet. (I just get an invalid procedure call error 5 when trying to create the CF referencing a VBA function I could call in a cell, even though it's in the add-in and not the workbook; I can create the CF fine with a built-in function.) The clearest confirmation I've found for this is here, but it doesn't really explain what the problem is; that's the esoteric part, would love to hear more about what I can expect with this.
The rubber-meets-road part is: can I avoid VBA altogether, and use a series of Excel-only, built-in functions to verify whether a given cell contains a constant (i.e. a value entered by a user), a formula (i.e. some kind of calculation, logical operation, etc.--pretty much starts with an =), or a link (i.e. a reference to a cell in another worksheet or another workbook)? I know Excel has this determination at its fingertips; witness the uses and speed of GoTo/Special. How can I get at it though?
Thanks in advance for your help.
Updated for Excel 2013:
For Office versions 2013 and higher, the ISFORMULA¹ function is available. Combining this with the NOT function, AND function and either the COUNTBLANK, ISBLANK or LEN function can produce a formula to determine whether a cell contains a constant.
The standard formulas in E2:F2 are,
=ISFORMULA(D2)
=AND(NOT(ISFORMULA(D2)), LEN(D2))
      
If further information on the nature of the cell value is required the TYPE function can be used to determine if the cell contents are a number, text, boolean, error or array.
When used in concert the native worksheet functions discussed here can reproduce the results available from VBA's Range.SpecialCells method and its xlCellTypeConstants or xlCellTypeFormulas xlCellType enumeration.
¹ The ISFORMULA function was introduced with Excel 2013. It is not available in earlier versions.
excel-2013
I don't think you can avoid VBA altogether but you can create a simple UDF and use it within Excel
Eg
Function IsFormula(Check_Cell As Range)
IsFormula = Check_Cell.HasFormula
End Function
and
Function IsLink(Check_Cell As Range)
If InStr(1, Check_Cell.Formula, "!", vbTextCompare) Then
IsLink = Check_Cell.HasFormula
End If
End Function
=IsFormula(A1) will return TRUE if there is a formula in A1 and FALSE otherwise
=IsLink(A1) will return TRUE if there is a formula in A1 containing '!' otherwise FALSE
You could combine these and create a string output "Formula","Link","Value"
Not sure if this is what you want, but it seems to do what you are asking, at least some of it.
http://www.ozgrid.com/VBA/special-cells.htm
It's the range.specialcells method.
It returns a range that contains only constants, or only formulas, etc.
An example of how this code would be used is shown below:
Sub CheckForConstants()
Dim x As Range
Set x = Selection.SpecialCells(xlCellTypeConstants, xlNumbers)
MsgBox "address of cells that contain numbers only is " & x.Address
Set x = Selection.SpecialCells(xlCellTypeConstants)
MsgBox "address of cells that contain constant of any type is " & x.Address
End Sub
You select a range and then execute this macro and it will return the address of those cells that meet the requirements.
The first x looks for cells that contains numbers only.
The second x looks for cells that contains any constants
The range in this case was selection, but you can set to what you want, i.e. range("a1:b5"), etc.
I went back to the worksheet and used the goto special method.
Apparently it also uses the range.special method.
I used the record macro option and this is what I got.
Selection.SpecialCells(xlCellTypeConstants, 23).Select
Range("M7").Select
Selection.SpecialCells(xlCellTypeFormulas, 23).Select
Range("I6:J16").Select
Selection.SpecialCells(xlCellTypeConstants, 1).Select
Range("L9").Select
ActiveWindow.ScrollWorkbookTabs Position:=xlFirst
Sheets("CP").Select
Application.CutCopyMode = False
Range("I21").Select
ActiveSheet.DrawingObjects.Select
Application.Goto Reference:="GoToSpecialRoutine"
The goto special feature on the worksheet uses the special cells method for some of what it does.
It also uses others as well. In the last 5 lines of codes I changed worksheet and asked it to go to objects.
It doesn't really go to them. It just selects them.
worksheet CP contained objects and it used the code in the last 3 lines to select all the objects on the worksheet.
Best bet to see the code behind goto special is to record a macro and then use the goto / special feature in the worksheet.
When finished, Stop recording and view the macro you recorded.
I don't know of any other features to select by type of cell, but I'm just a newby so it could be there very easily and not be known by me.

Resources