简体   繁体   中英

Excel VBA Dynamic Array spill only complete after end of macro

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM