How to extended the range variable with CurrentRegion property (vba)? - vba

The range variable extends with the following code:
Option Explicit
Function ESTENDISELEZIONE(Area As Range) As Range
Set ESTENDISELEZIONE = Range(Area, Area.End(xlDown))
End Function
But it doesn't extends with:
Option Explicit
Function ESTENDISELEZIONE(Area As Range) As Range
Set ESTENDISELEZIONE = Range(Area, Area.CurrentRegion)
End Function
And with:
Option Explicit
Function ESTENDISELEZIONE(Area As Range) As Range
Set ESTENDISELEZIONE = Area.CurrentRegion
End Function
The procedure extends the range!
Sub EXTENDSELECTION()
Selection.CurrentRegion.Select
End Sub
Can someone help me?
I've added an example to the question.
In the cell:
=CONTA.SE(ESTENDISELEZIONE(B2);"Orange")
In the formula:
Option Explicit
Function ESTENDISELEZIONE(Area As Range) As
Range
MsgBox(Area.Address)
Set ESTENDISELEZIONE = Area.CurrentRegion
MsgBox(ESTENDISELEZIONE.Address)
End Function

The CurrentRegion property of a Range object won't work in a UDF.
And it doesn't make much sense to try, as it will cause untold problems. Imagine that you changed cell C6 in your spreadsheet - the cell containing =CONTA.SE(ESTENDISELEZIONE(B2);"Orange") will not be recalculated (because it isn't dependent on cell C6) which means you start getting inconsistent data in your worksheet.
Note: Your code works fine if just being used as a normal Function. It is only when used as a UDF that it will have problems.

Related

Excel: Passing the current cell as argument when calling vba function from worksheet

I'm trying to make a VBA function that accepts a cell as argument and works from there using a variety of Range.Offset. This function will be called in the worksheet cells. For testing I'm using this simple script:
Public Function testPublic(targetCell As Range) As Boolean
targetCell.Offset(0, 3).Value2 = "Test is successful!"
testPublic = True
End Function
To see if I can get the cell reference to work, I pass simple references such as C5, but I only get #VALUE! error. Not sure what's wrong with this.
Tried to change Range as Variant, still doesn't work
You cannot use a function called as a UDF from a worksheet to update another cell in the worksheet: the function can only return a value to the cell containing the function (an array formula can return multiple values, but again only to the cells where the formula was entered).
For more information see: https://support.microsoft.com/en-us/topic/description-of-limitations-of-custom-functions-in-excel-f2f0ce5d-8ea5-6ce7-fddc-79d36192b7a1
Try below calling code
If testPublic(targetCell:=Range1) Then
MsgBox "success"
End If
The function code is as below. Change for ByRef and ByVal as per your logic.
Public Function testPublic(ByRef targetCell As Range) As Boolean
targetCell.Offset(0, 3).Value2 = "Test is successful!"
testPublic = True
End Function

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.

How to prevent VBA function from re-executing inside the code

I'm calling VBA function from an Excel worksheet. When I change a cell inside the code of the VBA function, Excel tries to re-execute that function again (and again in the second iteration and ...)
Example: if you have the code:
Function test() As Variant
Range("A1") = 1
test = "test"
End Function
When you use "=test()" anywhere, it will return #VALUE!. A debug will show that when you update A1, it will try to re-execute test().
Can you prevent Excel from doing this? E.g. saying 'don't update any of my numbers until I'm done with this function'? I've tried the Application.Calculation flag, or doing some external concurrency checks, but that doesn't seem to work ...
Try:
Function test() as Variant
test="test"
End Function
As Gary's student says in his comment: UDF's should only change worksheet entries of the cells that call the function, and this value should be returned as a result of the function, not by changing a cell value of an explicit address.
In other words, this does not work:
Function test() As Variant
Range("A1") = 1
test = "test"
End Function
Instead call test() from cell A1 and do this:
Function test() As Variant
test = 1
End Function
If the desired behaviour is to edit multiple cells (the return value of the function AND another cell), this should be implemented through a sub rather than a function.
To answer your specific question of how to stop the Function re-executing when you change A1 or your function, and stop it returning #Value: 1. Use the Excel user interface (Formulas--> calculation options) to change calculation mode to manual 2. add some error trapping to your function like this.
Function test() As Variant
On Error Resume Next
Range("A1") = 1
test = "test"
End Function
as has already been said the function will not change the value of A1

Capture the value of multiple cell range in a custom formulaarray

I've written my own function in VBA to do some things.
Parameters are Variant.
Private Function ProcessedValuesEx(pValues As Variant)
The problem occurs when I select a multiple cell range as my function parameter.
When it executes, the parameter has no value. I'm not able to see any content. Even with the VBA inspector.
When selection only one cell there is no problem. The parameter gets the content of the cell.
Perhaps set the argument as a range, and then loop through each cell in the range, like so:
Private Function ProcessedValuesEx(ByVal rValues As Range)
Dim pValue As Range
For Each pValue In rValues.Cells
'Do something with pValue here
Next pValue
End Function