Reference Dynamic Named Range dependent on cell value Excel - excel

I am trying to dynamically reference a name range based on the contents of a cell.
For example, I have the following dynamic named ranges:
tCat1_Pass
tCat2_Pass
tCat3_Pass
Assuming we have the value 2 in Cell A1, I would like to reference tCat2 like the following
"tCat"&A1&"_Pass" which would = "tCat2_Pass"
INDIRECT doesn;t work with this, are there any other solutions, apart from writing a UDF or using CHOOSE?

See below screenshot to use INDIRECT() function.

I have solved this by writing a small UDF:
Public Function nm_return(cat_nbr As Integer, tbl_nm As String)
nm_return = Range("tCat" & cat_nbr & tbl_nm)
End Function

You can also use EVALUATE within Name Manager, i.e. define nm_return as:
=EVALUATE("tCat"&$A$1&"_Pass")

Related

User Defined Indirect Function with COUNTIFS

I am trying to create a UDF to replace the INDIRECT function for use in the COUNTIFS function to allow dynamic ranges.
Goal:
Current:
=countifs(indirect([cell reference to named range],[criteria1]...)
I am trying to achieve:
=countifs(INDIRECTVBA([cell reference to named range],[criteria1...)
The function returns #VALUE at the moment.
Here is my VBA:
Public Function INDIRECTVBA(ref_text As String)
INDIRECTVBA = Range(ref_text)
End Function
The ref_text argument would be a reference to a cell in which a VLOOKUP is dynamically listing a named range based on user selection elsewhere.
My first guess is a data type mismatch but I am out of ideas.
Any help is appreciated!
Thanks,
Jordan
You're returning a Variant value instead of a Range.
This would give an error because CountIf is expecting a Range in its first argument and not a Variant value.
If you want to return a range add As Range to your function declaration and use a Set statement.
Public Function INDIRECTVBA(ref_text As String) As Range
Set INDIRECTVBA = Range(ref_text)
End Function
Because you omit Set the compiler is interpreting it as a Let statement. Without As Range in the function declaration, it is defaulting to As Variant. So the function is retrieving the value within the Range instead of returning the Range itself (Range objects give their Range.Value property by default when in Let statements).
I'm not too educated in CS, so this answer might be inaccurate. I genuinely appreciate learning more when people correct me.

MS-Excel: Retrieve Row Number where VBA Function is located

I hope I'm asking this in the correct forum:
I'm writing a UDF in VBA for MS-Excel; it basically builds a status message for the transaction on that row. It steps through a series of IF statements, evaluating cell values in different columns FOR THAT ROW.
However, this UDF will reside in multiple rows. So it might be in C12, C13, C14, etc. How would the UDF know which row to use? I'm trying something like this, to no effect
Tmp_Row = Application.Evaluate("Row()")
which appears to return a null
What am I missing here ?
Thanking everyone in advance
Application.Caller is seldom used, but when a UDF needs to know who called it, it needs to know about Application.Caller.
Except, you cannot just assume that a function was invoked from a Range. So you should validate its type using the TypeOf...Is operator:
Dim CallingCell As Excel.Range
If TypeOf Application.Caller Is Excel.Range Then
'Caller is a range, so this assignment is safe:
Set CallingCell = Application.Caller
End If
If CallingCell Is Nothing Then
'function wasn't called from a cell, now what?
Else
'working row is CallingCell.Row
End If
Suggestion: make the function take its dependent cells as Range parameters (if you need the Range metadata; if you only need the values then take in Double, Date, String parameters instead) instead of making it fetch values from the sheet. This decouples the worksheet layout from the function's logic, which in turn makes it much more flexible and easier to work with - and won't need any tweaks if/when the worksheet layout changes.
Application.ThisCell
MS Docs:
Returns the cell in which the user-defined function is being called from as a Range object.
You can put it to the test using the following code:
Function testTC()
testTC = Application.ThisCell.Row
End Function
In Excel use the formula
=testTC()
and (Cut)Copy/Paste to various cells.

Excel re-use range that is used by another function

I have a cell C1, where C1 =AVERAGE(E1:E10).
In cell D1 I would like to have D1 =STDEVP(E1:E10) without explicitly typing the range E1:E10 as I need to use this and other ranges multiple times.
Is there a simple way to get/refer to the affected range in C1 for use by another function in another cell? Something like D1 =STDEVP(AFFECTEDRANGE(C1)).
I found a function called INDIRECT which roughly does what I want, but it requires additional columns for my purpose. As I prefer to keep my worksheet clean and compact I'd prefer a function as described above. Does a one-liner like this exist?
A Replace on the Range.Formula property would seem to be sufficient.
range("d1").formula = replace(range("c1").formula, "AVERAGE", "STDEVP", vbtextcompare)
If you want to stay within the worksheet and avoid VBA, use named ranges.
Solved it: I merged the answer of Jeeped with the answer to this post to create a custom reusable function that does what I need.
It now works by setting =AverageToStDev(CELL) as a value for any cell. Note that CELL must be a single cell containing the AVERAGE() function for this to work.
Function AverageToStDev(MyCell As Range)
Application.Volatile
AverageToStDev = Evaluate(Replace(MyCell.Formula, "AVERAGE", "STDEVP", vbTextCompare))
End Function

Issue using Dynamic Named Ranges for Cascading Data Validation

I'm using two cells with Data Validation - the first cell (E9) simply creates a drop down menu based on the range A2:A6, and the second cell (E10) validation uses the source INDIRECT(E9), which will always refer to one of five different named ranges.
When I have the named ranges fixed, (i.e A2:A250), the second drop down works, but I really need the ranges to be dynamic, so far I've been creating named ranges with the following "source" formula:
=OFFSET(LookupLists!$B$2,0,0,COUNTA(LookupLists!$B:$B),1)
With the other ranges being the exact same only in columns C-F.
When I write out this formula it highlights the correct area on the screen, but the drop down button in cell E10 is completely unresponsive, when the drop down list should show the exact area that's being highlighted.
As a note, the lists themselves are created using an array formula and some VBA code to create a sorted unique list based on another part of the spreadsheet, so I've been unable to use tables to create the ranges as some other websites have suggested.
INDIRECT doesn't work with dynamic ranges. Credit to these guys for the solution:
http://chandoo.org/forum/threads/passing-a-named-range-to-a-formula-with-indirect.5854/#post-32423
First, insert a module into you sheet and paste in the UDF:
Option Explicit
Function RetrieveRangeForName(psRange As String) As String
RetrieveRangeForName = Range(psRange).Address
End Function
Then you will need a helper cell, since I don't think UDFs work in the Data Validation dialog. In E11, enter =RetrieveRangeForName(E9).
Then in the Data Validation, set to List, you can enter: =INDIRECT(E11)
The reason it doesn't work as discussed here is that INDIRECT expects a string that it can evaluate to give a reference. However your named range is already a reference. Logically, the only way to use it in INDIRECT is to convert it into a string first which you can do with a UDF:-
Function GetAddress(Name As String) As String
Dim rng As Range, addr As String
Set rng = Worksheets("Sheet1").Range(Name)
addr = rng.Address
GetAddress = addr
End Function
Then use this to define a range called NewRange:-
=INDIRECT(GetAddress(Sheet1!$E$9))
Finally this can be used in the validation for E10 (Named Range ListB is defined as in the question, ListA etc. correspondingly for columns A to E).

Is there an equivalent of the VBA function Cells on the worksheet?

Is there any way to use index numbers to refer to specific cells, like how in VBA you can use Cells(3,2) to refer to cell C2.
I was hoping "=CELLS(3,2)" would work, but, sadly, that doesn't appear to exist. Is there another way to do that?
EDIT:
I should clarify that I need to use this inside of a SUM() worksheet function, so it would need to return the cell reference, not the value inside the cell.
You can use the OFFSET(original_range,rowsOffset,colOffset) formula to get a reference to a range which is some specific offset from a point on the sheet.
There are also two additional parameters you can pass to offset which determine #rows and #columns of the returned range:
=SUM(OFFSET(A1,0,0,12,1))
will give you a range 12 rows by 1 column starting at A1.
=SUM(OFFSET(A1,2,2,12,1)) would start at C3
Like doing Offset(r,c).Resize(12,1) in VBA
You could change the reference style... I often prefer the R1C1 reference style for certain functions I'm writing.
Here's a link that shows how to get to it:
http://www.excelqa.info/2010/12/06/switch-to-r1c1-reference-style-in-excel-2010/
You can just write a custom formula to handle that.
Public Function customFunction(a As Integer, b As Integer, Optional sh As String)
If sh <> "" Then
customFunction = Sheets(sh).Cells(a, b).Value
Else
customFunction = Cells(a, b).Value
End If
End Function

Resources