My Dataset contains several transactions in March 2020 in foreign currency. Column A contains the date of each transaction, while column B contains the transaction value in foreign currency (EUR).
I want to calculate the value of each transaction in local currency (being ZAR) in column C using VBA.
Firstly, I obtain all the exchange rates for March 2020 using the STOCKHISTORY function:
Dim exchangeRateSummary As Range
Range("I1").Formula2R1C1 = "=STOCKHISTORY(R1C5,R1C6,R1C7)" 'where R1C5 contains EUR/ZAR, R1C6 contains 01-Mar-20, and R1C7 contains 31-Mar-20
Set exchangeRateSummary = Range("I1").CurrentRegion 'save range as variable
Then I add a VLookup in column C to determine the local currency value of each transaction, by looping through each row:
Dim j As Integer
For j = 2 To 100
cells(j,3).value=cells(j,2).value * Application.WorksheetFunction.VLookup(Cells(j,1),exchangeRateSummary,2,False)
Next j
When I run the code, I get the following error: "Unable to get the VLookup property of the WorksheetFunction class." When I press End, the spill range of exchange rates (created with the stockhistory function) appears on my Excel sheet. When I run the code again, the VLookup works, and provides the correct local currency values in column C.
The problem is therefore that the VLookup does not work within that same macro, as the spill range created by the stock history function only appears after the macro was executed.
One option is to make these codes separate macros, but I would like to automate this process in one click.
Is there a way I can instruct the macro to first calculate and spill that range, before continuing with the VLookup to that range?
Your question is not clear and you should try to improve that. That said, with what youve provided, I think you may be able to do something by forcing calculation in your function where you call the vlookup
. My guess is that simply wrapping the vlookup might be good enough without having to include the Workshet.Calculate
call but you'll have to experiment yourself unless you can provide more info in your question.
so something like: in your worksheet eg stock field in $A$1
, start date in $A$2
call STOCKHISTORY from B1
in Cell B1
=STOCKHISTORY(A1, A2)
Then call a function that wraps around vlookup, triggered by a change in $B$1
, passing your lookup value (say "31-Jan-2020").
=vlookup_wrapper("31-Jan-2020", B1)
and your wrapper looks something like this
Option Explicit
Function vlookup_wrapper(ByVal lookup_val As Variant, ByVal spill_formula) As Variant
'parameter spill_formula never used, only to trigger this function to be called
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("sheet_with_stockhistory_formula")
' force stock history to finish its SPILL
ws.Calculate
'Define range from output of STOCKHISTORY spill
Dim r_in As Range
Set r_in = ws.Range(ws.Range("B1"), ws.Range("B1").End(xlDown))
' Assume want column 2 back
vlookup_wrapper = Application.WorksheetFunction.VLookup(lookup_val, r_in, 2, False)
End Function
Spill range reference via #
Referring to a spill range can be done via the "#" suffix, ie H2#
if the top cell containing the dynamic STOCKHISTORY formula resides eg in H2
. Couldn't test, but VBA should do this job.
So a possible invented lookup result might be received eg via
Dim result: result = [VLOOKUP(100,H2#,2,FALSE)]
or
result = Evaluate("VLookup(" & mySearch & "," & "H2#" & ",2,False")
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.