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
Related
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")
Problem:
I have an Excel sheet that have patterns in some cells, indicating the presence of a certain trait.
I need to give a numeric/text code to each cell that has a pattern, other than the "no pattern/white" cell.
example on how it might look before applying the function
Since I have no experience with programing VBA functions in Excel (or in general), I have tried to generate an UDF that would simply provide a code when the cell has any pattern. The idea was to have a formula written in the cell, something like: =IntPattern(A1), that would return the code of the pattern for cell A1.
The code that I have tried to implement is the following:
Function IntPattern(Pattern As Range)
Application.Volatile
IntPattern=Interior.Pattern
End Function
However, it does not work.
Any help will be greatly appreciated!
The critical line should be
IntPattern = Pattern.Interior.Pattern
The confusion is of your own making: why did you call the range "Pattern"? It is that range that you want the pattern of. Therefore it must be specified in the instruction.
Call the function from a cell with something like =IntPattern(A2) where A2 is the cell from which to read the patter. It can be the cell that contains the formula or any other cell.
If the referenced cell is without patter the return will be xlNone = -4142. Therefore your UDF's functionality can be expanded like,
Function IntPattern(Pattern As Range)
With Pattern.Interior
IntPattern = IIf(.Pattern = xlNone, "No pattern", "Pattern " & .Pattern)
End With
End Function
You can add Application.Volatile if you want that functionality.
The function need to be in a module for it to work. Right click on your project, add a new module and paste the code below. Also, I would not use the word Pattern as the variable since pattern is a property. Try this:
Public Function IntPattern(rng As Range)
Application.Volatile
IntPattern = rng.Interior.pattern
End Function
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.
Ok, so I did have a quick search but did not find an answer that does what I would like... I have a horrible feeling that it is simple.. :)
I would like a formula in cell D1 that will use cells A1, B1 and C1 to evaluate the test shown in B1. This is for producing questions.
The picture shows the data and results.
I have tried indirect() with no success and &, ie
=A1&B1&C1
You can use the Evaluate method in excel VBA. Note that i'm using .Value on the rng2. This is because we want to use the displayed value of the cell (in the format in which it appears to the user lookins at the cell) rather than the underlying value that excel stores in the cell (which is what .value2 gives us).
Public Function EEE(rng As Range, rng2 As Range, rng3 As Range)
EEE = Evaluate(rng.Value2 & rng2.Value & rng3.Value2)
End Function
Note that there is a method of doing it using only worksheet functions, but it rather complicated compared to the VBA solution. An excellent descriptio of the old Evaluate() function and how to use it is given in this article.
Following formula could be used to evaluate the result of combination of A1, B1, C1
=ISLOGICAL(A1&B1&C1)
or
=ISLOGICAL(CONCATENATE(A1,B1,C1))
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