Find Range Name Using Active Cell - vba

I'm a beginner when it comes to programming in VBA.
I have one cell that is part of a named range. Using that active cell, I want to be able to find what range that cell is a part of and pass it into a VBA function or subroutine as a Range object.
Can anyone provide me with guidance as to how to proceed, or is this not possible?
Thanks in advance!

Here is a simple example.
The code checks if the selected cell is part of a named range. If so, the named range is passed to a function:
Sub Main()
Dim nm As Integer
For nm = 1 To ActiveWorkbook.Names.Count
If Not Intersect(Selection, Range(ActiveWorkbook.Names(nm).Name)) Is Nothing Then
Debug.Print MyFunc(Range(ActiveWorkbook.Names(nm).Name)) // Prints TRUE or FALSE
End If
Next nm
End Sub
Function MyFunc(Named_Range As Range) As Boolean
MyFunc = Named_Range.Cells.Count > 2 ~~>Courtesy of `Thomas Inzina`
End Function

Related

Excel VBA .Find Function changing values in selection

Heya this is probably simple but I cannot figure out what is wrong.
I am trying to do .find for a specific date and change that selection to a user input date.
I have a userform to select a date from a combobox (date1_cbo). The combobox source is linked to dates on a worksheet (Backend). There is a textbox below for writing the new date to change it to (date1_txt). I keep getting an error
object variable or with block variable not set.
I have tried a few options without any luck here is my code:
Dim selection As Range
Dim check As Boolean
'input box validation
check = IsDate(date1_txt.Value)
If check = True Then
'find cell matching combobox
With Worksheets("Backend").Range("A1:A500")
Set selection = .Find(date1_cbo.Value) 'this is the problem
selection.Value = date1_txt.Value
End With
Else
End If
Interestingly .Find returns the range or Nothing. however because the combobox is linked to the cells I am searching through this should never return nothing... I dont understand why the error is occurring.
a variable named as 'selection' is bad coding practice but totally legal. Don't use such names for the sake of clarity.
Error 91 is caused when you are trying to read a property( .value) from null object. your selection variable is null cause date formats on the sheet and combobox are different.
Just convert to date before attempting to find it in sheet.
Set selection = .Find(CDate(date1_cbo.Value)) '/ once again, selection is valid but bad name for variable.
You are using a variable named Selection. VBA uses it as well. Rename your variable to anything else, rewrite your code and it should work. Even Selection1 is quite ok:
Public Sub TestMe()
Dim selection1 As Range
With Worksheets(1).Range("A1:A500")
Set selection1 = .Find("vi")
End With
If Not selection Is Nothing Then
selection1.Value = "some other value"
End If
End Sub
To change multiple values with Find() as here - A1:A10, then some possibility is to do it like this:
Public Sub TestMe()
Dim myRng As Range
With Worksheets(1).Range("A1:A500")
.Range("A1:A10") = "vi"
Set myRng = .Find("vi")
If Not myRng Is Nothing Then
Do Until myRng Is Nothing
myRng.Value = "New value"
Set myRng = .Find("vi")
Loop
End If
End With
End Sub
It is a bit slow, as far as it loops every time and it can be improved, if the range is united and replaced at once.

Excel VBA own function in worksheet which changes value on a sheet

I'm trying to use my own VBA function in an Excel sheet with a return value and the same function manipulates a cell on the same or on an other sheet, but the result is #VALUE! A minimal working example (Office Prof Plus 2010, 32-bit):
Function abc() As Integer
Dim i%
i = 0
Sheet1.Cells(1, 2).Value = 2
abc = i
End Function
When I execute Debug.Print abc it obviously writes a 2 to the cell B2 and the printed result is 0. What I want to do now is =abc() in cell A1 on Sheet1, but I only get #VALUE!. Btw, it doesn't work either if Application.EnableEvents and Application.Calculation is disabled resp. set to manual.
Two questions: Why? And any idea how to resolve? Thx.
It's well known that you can't update the worksheet with a UDF (other than the cell with the UDF in). However, there is a pretty awful workaround which checks every time you make a change on your worksheet and places a 2 in B1 for you if your function happens to be =abc()
Have your dummy function in in a standard module
Public Function abc() As Integer
abc = 0
End Function
Then in the Sheet1 module place the following code
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
If Target.Formula = "=abc()" Then
Me.Cells(1, 2).Value = 2
End If
End Sub
This type of User Defined Function (called from within a cell) can't modify cell values other than to return a value to the cell containing the UDF.

Searching and Returning bold values in VBA

I know that this probably isn't the most ideal way to to do this but just bear with me.
I have a document with a few tables on it. I'm using a userform to search the tables/sub-categories and return the relevant values. I want to select the sub categories with a range of option buttons on a userform, these will in turn set the range for the search function to look within. I also want to dynamically update the option buttons if a new table was to be added or anything along those lines.
The only thing that differentiates the title of a sub-category/table, and the items within it, is that the title of a sub-category/table is bold. So what I'm looking to do is search the first column of the spreadsheet and return the names of any entries in bold. These values are then used to set the names of the option buttons :).
The following function is my attempt at finding the text entities in column a that are in bold, returning them and setting each to an individual variable to be used in another function. The bold1 .... variables are all globally defined variables as I need them in another sub, as is the page variable which contains the relevant page to be used. Currently the code returns an error stating "variable or with block not set" and using the debugger I can see that bold1 .... and all the other boldx variables have no value set. Does anybody know whats going on/how to fix this function.
Thanks in advance :)
Sub SelectBold()
Dim Bcell As Range
For Each Bcell In Worksheets(Page).Range("A1:A500")
If Bcell.Font.Bold = True Then
Set bold1 = Bcell
End If
Next
End Sub
EDIT: I simplified the above function, to remove clutter and help narrow in on the issue. I want the above function to store the contents of the found cell (any cell in the document in bold at this stage) in the variable bold1
This will return an array of values from bold cells in column A of Page.
You can fill a combo or list box with theses values using their list property.
ComboBox1.List = getSubCategories("Sheet1")
Function getSubCategories(Page As String) As String()
Dim arrSubCategories() As String
Dim count As Long
Dim c As Range
With Worksheets(Page)
For Each c In .Range("A2", .Range("A" & Rows.count).End(xlUp))
If c.Font.Bold Then
ReDim Preserve arrSubCategories(count)
arrSubCategories(count) = c.Value
count = count + 1
End If
Next
End With
getSubCategories = arrSubCategories
End Function
you may find useful to have a Range returned with subcategories cells found:
Function SelectBold(Page As String, colIndex As String) As Range
With Worksheets(Page)
With .Range(colIndex & "1", .Cells(.Rows.Count, colIndex).End(xlUp)).Offset(, .UsedRange.Columns.Count)
.FormulaR1C1 = "=if(isbold(RC[-1]),"""",1)"
.Value = .Value
If WorksheetFunction.CountA(.Cells) < .Rows.Count Then Set SelectBold = Intersect(.SpecialCells(xlCellTypeBlanks).EntireRow, .Parent.Columns(1))
.Clear
End With
End With
End Function
Function IsBold(rCell As Range)
IsBold = rCell.Font.Bold
End Function
to be possibly exploited as follows:
Option Explicit
Sub main()
Dim subCategoriesRng As Range, cell As Range
Set subCategoriesRng = SelectBold(Worksheets("bolds").Name, "A") '<--| pass worksheet name and column to search in
If Not subCategoriesRng Is Nothing Then
For Each cell In subCategoriesRng '<--| loop through subcategories cells
'... code
Next cell
End If
End Sub

Value in cell as variable in select formula

I have programmed the following VBA code:
Sub test()
Dim Variable As Variant
Variable = "R2:R11"
Sheet1.Select
Range(Variable).Select
End Sub
This formula works perfectly. Now I want to replace the "R2:R11" part of the variable and instead referring to a cell (W12) in the spreadsheet. In this cell I have written "R2:R11" and I changed the formula to the following:
Variable = Sheet1.Range("W12")
which leads to the following code:
Sub test()
Dim Variable As Variant
Variable = Sheet1.Range("W12")
Sheet1.Select
Range(Variable).Select
End Sub
However, with this formula I now get the ERROR 1004.
Do you guys have any solution how I can make the variable referring to the cell in the spreadsheet and then use it in the select formula?
Thanks for any help :-)
You need to declare your variables properly and access the actual .Value property of the Range object.
Sub test()
Dim Variable As String
Variable = Sheet1.Range("W12").Value
Sheet1.Select
Range(Variable).Select
End Sub
Which can also be written as:
Sub test()
Sheet1.Activate
Range([W12]).Activate
End Sub
A note on the .Value property - if you omit this, the value will usually be assigned anyway because it's the default property of the range object. That being said there are scenarios where this won't be the case and therefore it's always best practice to explicitly state that you want the value.
you most probably typed "R2:R11" in W12 cell, i.e with double quotes too
in that cell you only have to type R1:R12
moreover you can simply code
Sub test()
Sheet1.Range(Sheet1.Range("W12")).Select
End Sub

Count visible blank cells using VBA?

When I enter the following function as a UDF in a cell:
Function VisibleBlankCells(r As Range) As Long
On Error Resume Next
VisibleBlankCells = Intersect(r.SpecialCells(xlCellTypeVisible), r.SpecialCells(xlCellTypeBlanks)).Count
On Error GoTo 0
End Function
r.SpecialCells(xlCellTypeBlanks) evaluates ALL cells in r as empty regardless of whether they contain text or not. What might be the cause of this and an alternative solution?
Get rid of the On Error Resume Next for a start - you should always assume that your code will fail and account for it accordingly, simply ignoring errors will just complicate matters.
Secondly ,there is no need to use Intersect - just identify the visible cells directly, and then use a further SpecialCells() method to identify the blank child cells.
Function VisibleBlankCells(r As Range) As Long
VisibleBlankCells = r.SpecialCells(xlCellTypeVisible).SpecialCells(xlCellTypeBlanks).Count
End Function
tested with this:
Sub test_code()
Dim r As Range: Set r = Selection
Debug.Print CountBlanks(r)
End Sub
Function CountBlanks(r As Range) As Long
CountBlanks = r.SpecialCells(xlCellTypeVisible).SpecialCells(xlCellTypeBlanks).Count
End Function
This kind of filter mechanism won't work in an UDF (see this for information on that). I suggest a looping inside your UDF:
Public Function VisibleBlankCells(rng As Range) As Long
Dim i As Integer
Dim cell As Range
i = 0
For Each cell In rng
If cell.Rows.Hidden = False And _
cell.Columns.Hidden = False And _
cell.Value = "" Then
i = i + 1
End If
Next
VisibleBlankCells = i
End Function
However, there may be some problems regarding the updating and functionality:
The value of the UDF only updates after editing the referenced range or calling other UDFs. So if you hide a column or row in that range, it won't have an instant effect
In the (working) execution of your code in a Sub, the visible cells (also) refer to yet unused cells in your worksheet to be "not visible". In my solution however, all cells that are not contained in a hidden row/column are considered visible.