In VBA, I am used to calculate values of a column, which is the function of another column, with Evaluate() in order not to use a loop. For instance, to assess column 2, whose values are the exponential of column 1's values, I would write (here limited to the first 10 rows):
Dim rng1 As Range
Dim rng2 As Range
Set rng1 = Worksheets("Sheet1").Range(Cells(1,1),Cells(10,1))
Set rng2 = Worksheets("Sheet1").Range(Cells(1,2),Cells(10,2))
rng2 = Evaluate("EXP(" & rng1.Address & ")")
I would now like to proceed on the same way with my own functions. In order to make a test, I created a function that returns the exponential value of the input:
Function TestExpo(alpha) As Double
TestExpo = EXP(alpha)
End Function
and I proceeded in the same way as previously stated with Evaluate():
rng2 = Evaluate("TestExpo(" & rng1.Address & ")")
I did not get an error, but nothing happened on the Excel sheet. I tried to trigger an error by having a typing error in the function name for instance:
rng2 = Evaluate("TestEx(" & rng1.Address & ")")
and I actually got a "Name" error at each cell of rng2 on the sheet. Consequently, the calling function "TestExpo" works. I also tried to use a real number instead of rng1.Address:
rng2 = Evaluate("TestExpo(" & 2 & ")")
and I got the correct value of exp(2) in all cells of rng2 on the sheet, so calling the function and getting back the value in the cells works as such.
I tried to specify differently the type of the input and output. For instance:
Function TestExpo(alpha) ' No error, but no values on the sheet
Function TestExpo(alpha) As Range ' No error, but no values on the sheet
Function TestExpo(alpha) As Variant ' No error, but no values on the sheet
Function TestExpo(alpha As Range) ' No error, but no values on the sheet
Function TestExpo(alpha As Variant) ' No error, but no values on the sheet
Function TestExpo(alpha As Double) ' Value error for each cell of the range rng2
Except for the last test with alpha As Double, I did not get any error but also no values on the Excel sheet.
I am running out of ideas... I tried to find the code for the EXP() function of VBA to see how the input and output are specified, thinking that if I use the same types and arguments in the function "TestExpo", it may work, but I could not find the code of the EXP() function, it may not be public.
Would anyone have had a similar situation and solved it ?
Kind Regards Xavier
Update:
Thanks for your contributions! I moved on!
When I used, as suggested by @FaneDuru
rng2 = Evaluate("""=TestExpo(" & rng1.Address & ")""")
I got a Value error in each cell. Checking the cells in the worksheet, I could see that every cells got attributed the formula:
"=@TestExpo($A$1:$A$35)"
I compared with writing
rng2 = Evaluate("""=EXP(" & rng1.Address & ")""")
which worked and attributed to each cells the formula
"=EXP(@$A$1:$A$35)"
So the @ appeared at a different location. I manually corrected the formula "=@TestExpo($A$1:$A$35)" into "=TestExpo(@$A$1:$A$35)", and it worked !
So the problem is the location of @, and I do not understand why @ gets by default placed in front of the range within the brackets when the function EXP is used but in front of the function name when my own function is used.
Nevertheless, correcting the formula in the cells manually is not handy. Inspired by the proposal of @FaneDuru, I corrected my code by adding .Cells(1,1).Address(0,0) after the range name in the following way:
rng2 = Evaluate("""=TestExpo(" & rng1.Cells(1,1).Address(0,0) & ")""")
and this worked !
Now, the formula in the first cell looks like this:
"=@TestExpo(A1)"
And the cell address is adapted to each line (line 2 the formula is "=@TestExpo(A2)", line 3 "=@TestExpo(A3)", etc)
The @ still appears in front of the function name, but there is one cell name within the brackets instead of the range, and this makes the formula work.
Now I have to admit that I do not really understand how the code syntax works. In fact, adding .Cells(1,1).Address(0,0), I expected that all cells of rng2 would refer to the Cell(1,1) of the range rng1, but instead the formula got adapted to each cell in the proper way.
So, my initial problem has been solved using:
rng2 = Evaluate("""=TestExpo(" & rng1.Cells(1,1).Address(0,0) & ")""")
or even more simple:
rng2 = "=TestExpo(" & rng1.Cells(1,1).Address(0,0) & ")"
Nevertheless, I would be keen on understanding how the code syntax works - i.e. if the code explicitly refers to cell(1,1) in rng1.Cells(1,1).Address(0,0), how is it possible that all the cells of rng2 do not refer to cell(1,1) but refer to the proper cells (cell(2,1), cell(3,1), etc) ?
And I would also like to understand why @ gets by default placed in front of the range when the function EXP is used but in front of the function name when my own function is used. Would anyone have an idea ?