I'm using Excel XP.
My problem is that I wrote a very short function ti simplify one task.
The code is the following:
Function getLastValue() as Integer
getLastValue = ActiveCell.End(xltoLeft).Value
End Function
Then I want to fill by dragging that cell downwards, but the same value will be copied, no matter what value appears in each row. So I wanted to make it relative to the cell calling the function so that it goes to the nearest cell in the left that has a value and copy return it in the cell calling the function.
I made a Sub for it but I want to have it in the form of a function to apply it on arbitrary cells.
Application.Caller is what you want.
You will also need Application.Volatile in order to update the formula when your worksheet changes.
Function getLastValue() As Integer
Application.Volatile
getLastValue = Application.Caller.End(xlToLeft).Value
End Function
Related
I am trying to code my spreadsheet to react to changes to a specific cell in my spreadsheet. This cell contains a formula so the programing is not recognizing any change to the cell although the number is updating the formula is not. I am looking for a way to return the results of the cell containing the formula into another cell as a value so the change can be recognized by the code.
The change event isn't firing because the contents of the cell aren't changing, just what it displays (the formula result) is. You could use the Worksheet_Calculate event and check the value against another static value. If it's changed, then update it and trigger your other code.
It sounds like there's a better way to design your sheet though.
Private Sub Worksheet_Calculate()
Dim watchCell As Range ' set to something
Dim checkCell As Range ' set to something
If checkCell.Value = watchCell.Value Then Exit Sub
' Value has changed. Update the check and trigger action.
checkCell.Value = watchCell.Value
Call SomeOtherResponse
End Sub
I'm an Excel VBA newbie.
How to change the value of the specified cell via a user-defined function? What's wrong with this code:
Function Test(ByVal ACell As Range) As String
ACell.Value = "This text is set by a function"
Test := "Result"
End Function
My wish is ... when I type =Test(E6) in cell E1, Excel will display the specified text in E6.
YES, of course, it is possible.
Put this code in Module1 of VBA editor:
Function UDF_RectangleArea(A As Integer, B As Integer)
Evaluate "FireYourMacro(" & Application.Caller.Offset(0, 1).Address(False, False) & "," & A & "," & B & ")"
UDF_RectangleArea = "Hello world"
End Function
Private Sub FireYourMacro(ResultCell As Range, A As Integer, B As Integer)
ResultCell = A * B
End Sub
The result of this example UDF is returned in another, adjacent cell. The user defined function UDF_RectangleArea calculates the rectangle area based on its two parameters A and B and returns result in a cell to the right. You can easily modify this example function.
The limitation Microsoft imposed on function is bypassed by the use of VBA Evaluate function. Evaluate simply fires VBA macro from within UDF. The reference to the cell is passed by Application.Caller. Have fun!
UDF limitation documentation: https://support.microsoft.com/en-us/help/170787/description-of-limitations-of-custom-functions-in-excel
A VBA UDF can be used as an array function to return results to multiple adjacent cells.
Enter the formula into E1 and E2 and press Ctrl-Shift-Enter to create a multi-cell array formula. Your UDF would look something like this:
Public Function TestArray(rng As Range)
Dim Ansa(1 To 2, 1 To 1) As Variant
Ansa(1, 1) = "First answer"
Ansa(2, 1) = "Second answer"
TestArray = Ansa
End Function
Excel VBA will not allow a user-defined function to alter the value of another cell.
The only thing a UDF is allowed to do (with a few minor exceptions) is to return values to the cells it is called from.
Why not just typing you formula in E6 then ? That's the Excel logic: put your formula where you want the result to appear.
I have defined the next formula to enter it as an Array Formula:
=IF(LenTableRange(Hoja1!$B$15)=Hoja1!$B$4,IF(OFFSET(LenTableRange(Hoja1!$A$15),0,5)="",LenTableRange(Hoja1!$A$15)))
For some extra info:
- LenTableRange returns a range object, the body of the function is:
'Passing a cell as a range, it returns
Function LenTableRange(R As Range) As Range
Application.Volatile
Set LenTableRange = Range(R, R.End(xlDown))
End Function
The data i'm taking is Strings in $A$15 > column, numbers in $B$15 > column. Both columns can have repeated values, that's why I filter it, and the column that referes to OFFSET(LenTableRange($B$15);0;5) referes to dates, that could have no value or empty cell.
As you see it has a user defined function in it.
The UDF 'LenTableRange' works fine.
When I enter the whole formula or the name into a cell it works fine, but when I try the following in VBA:
'I think I have to escape the double quotes as so.
Dim StrForm As String
StrForm = "=IF(LenTablaRango(Hoja1!$B$15)=Hoja1!$B$4,IF(OFFSET(LenTablaRango(Hoja1!$A$15),0,5)="""""",LenTablaRango(Hoja1!$A$15)))"
Debug.Print Application.Evaluate(StrForm)
It gives error 2015.
I suspect it is not reading UDFs inside the formula properly.
Is it really possible to do this?
What is the best way to solve this problem?
So, I'm trying to sum a cell from different sheets but I want the sum to be on the same cell or at least the result. The cell that is first summing, is gonna get deleted after the sum.
In this case, the cell A1 is gonna get deleted.
The code only pastes the formula but doesn't do it.
Private Sub C2_Click()
Sheets("Prueba").Range("A1").Formula = "Sum(Prueba!A1, Reporte!C5)"
End Sub
No error messages though.
Well as Cybernetic.Nomad said you need to use the equal sing = in from of the formula you want. Remember, this is like you where typing in the cell that formula.
Another tip: you can use this
Private Sub C2_Click()
Sheets("Prueba").Range("A1").value= Evaluate("=Sum(Prueba!A1, Reporte!C5)
End Sub
This way you tell VBA to get the value returned from the SUM and put it inside the cell A1 as a value, not formula.
Another tip:
Private Sub C2_Click()
Sheets("Prueba").Range("A1").Formula= "=SUM(Prueba:Reporte!A1:C5)"
End Sub
This way you can SUM across the sheets and all the sheets in between those sheets any value in the range A1:C5. Where you have "Prueba", "Pueba01", "Pueba02", "Prueba03" and "Reporte", all the values in the range A1:C5, in the sheets between "Prueba" and "Reporte" will be summed. If there is any other sheet outside this to sheets wont be summed in the result.
Also you can use:
Private Sub C2_Click()
Sheets("Prueba").Range("A1").value= Evaluate("=SUM(Prueba:Reporte!A1:C5)")
End Sub
I want to get the adjacent cell values for calculation in VBA.
It is easy to get the left cell of the current cell(e.g.H19) usually like this:
=H18
If I copy this cell to other cells, each of them is changed to an appropriate cell number.
But in VBA code, I am not sure if I am right to get the value of the left cell.
Public Function LeftCell()
LeftCell = ActiveCell.Offset(0, -1).Value
End Function
I am not sure this is correct, I tested copying this cell to other cells but each result is not changed automatically.
I clicked all kinds of Calcuation buttons on the Menu, changed Calculation as Automatic, but there is no calculation occur.
The only way I can do is to manually select each cell and press enter.
Is there any way to calculate all cell values?
Otherwise, "The Active Cell" means "The Selected Cell by Cursor"?
Thanks for your help in advance.
Adding a formula as #Chris Harper suggests would work, but then you may as well just write the formula in the cell.
Rather than the ActiveCell you want the cell that called the formula.
Public Function LeftCell()
LeftCell = Application.Caller.Offset(, -1).Value
End Function
Edit: If you want the cell to update whenever you change the value add Application.Volatile True as your first line in the function.
https://msdn.microsoft.com/en-us/library/office/ff193687.aspx
Calculate method in Excel VBA do all kind of calculations. You can even define a range to calculate only a range of specific cells like Worksheets("Sheet1").Calculate.
Yes, ActiveCell is always the Selected Cell.
As an alternative to setting value by Offset, you can use ActiveCell.FormulaR1C1 = "=RC[-1]"