Reputation: 119
I'm using excel to do some data analysis work.
the scenario is like this:
I use some excel plug-in componnets to get data from remote site.
for example, put =get_the_latest_data(ID)
in A1
, then this function would be called and ID's data would be filled in A2
to A11
.
My goal is
for each id in id_array
sheet1.range("a1") = get_the_latest_data(id)
create a new sheet named id
save data from a2 to a11 to thi new sheet
next
My problem is it would take some time for get_the_latest_data
function to get all the data from remote. So, in my code the new sheet couldn't get the right result. I tried to use application.wait before copy data from sheet1 to the new sheet.
but it didn't work.
Is there any way I can make sure that data is copied to the new sheet after the wanted data is got from remote? btw,I do not have access to the source code of get_the_latest_data
.
Upvotes: 3
Views: 2312
Reputation: 14361
It seems to be a typcal case with a third party data vendor where their generics data-requests are ashynchronus which is not very well exposed to the users. In such cases you may need to check with your vendor for the behaviour of that method you are calling. There has to be some boolean
type of a variable to be set at least to choose to either have a asynch or synch request/retrieve.
Eg. if you are sending one index ticker to get top 10 members, then this method is right now collecting all your index tickers and shooting you back with all the data. So check if the returned data could be split e.g. it's a multi-dimensional array that you could separate the data into the sheets based on the id
. Else talk to this application's API developers as DoEvents
might be too weak to handle this.
I suggest you to use anarrayList/collection item to hold the data returned from your method for each id. Once it's completed you can start creating sheets as you already have caught the data locally.
Dim al as Object
Set al = CreateObject("System.Collections.ArrayList")
for each id in id_array
al.add get_the_latest_data(id) '--possibly returning a variant
next
'--for each item in arrayList then you create a sheet by outputing the data
for i = 0 to al.Count
'--Create new sheet put your code here
'--transpose the data
Sheets(i+1).Range("A2").Resize(UBound(al(i))) = Application.Transpose(al(i))
Next i
Upvotes: 0
Reputation: 17475
Normally, VBA only executes the next step after the former step is fully finished. That is unless the call triggers some background action (e.g. to Refresh a data connection that has "Background refresh" enabled.
You can do the following to solve the issue:
Disable background refresh: If you look in the properties of the connection, unselect "Enable background refresh"
Wait until refresh is finished with data query specific check: Modify your code the following way:
Range("A11").Clear 'To enable the check subCallToTriggerDataLoadHere While Range("A11").Value "" 'Or any other specific check to see that your refresh is finished DoEvents Wend ...
Use the AfterRefresh event of a query: See this post for details
Upvotes: 3