I use a lot of WEBSERVICE calls in my workbook, which is connectionless. Therefore, the only way to periodically refresh values is with a macro. To do so automatically upon workbook open and every 30 seconds thereafter, the following works great:
Dim TimeToRun
Sub auto_open()
Sheets("DataInput").Select
Sheets("DataInput").Range("A1").Activate
Application.CalculateFull
Call ScheduleWorkbookRefresh
End Sub
Sub ScheduleWorkbookRefresh()
TimeToRun = Now + TimeValue("00:00:30")
Application.OnTime TimeToRun, "WorkbookRefresh"
End Sub
Sub WorkbookRefresh()
Application.CalculateFull
Call ScheduleWorkbookRefresh
End Sub
Sub auto_close()
Application.OnTime TimeToRun, "WorkbookRefresh", , False
End Sub
As usual, users claim the refresh interval of 30 seconds is somewhere between too short and too long. So, the idea is to let users fill in the interval they want in cell B9. However, there doesn't seem to be an acceptable way to put a cell number (or variable) into the TimeValue function.
Any ideas on how I might modify the macro to allow users to choose their own refresh interval, other than making the macro available for user edit (similar to handing a loaded gun, safety off, to a troop of chimpanzees)?
Use TimeToRun = Now + TimeValue("00:00:" & Sheets("DataInput").Range("A1").Value)
Related
my purpose is to update Bloomberg data and do some calculatations with different tickers. But it seems that VBA will run all the calculations without waiting the data to be updated.
Here is the code:
Application.Calculation = xlCalculationAutomatic
For i = 1 To 3
Call Worksheets("Sheet1").Range("data1").Select 'the cells "data1" contains the function =BDH(ticker, field, start date, end date) to get the information from Bloomberg'
Call Application.Run("RefreshCurrentSelection")
Worksheets("sheet1").Range("d3").Value = Worksheets("sheet1").Range("sum") 'the cells "sum" takes the sum of all BB info'
Anyone know how to fix it?
Bloomberg formulae update is asynchronous so your code won't wait until the update is over. You need to schedule the rest of your code to a later time, check if the data has been updated.
It would look like this:
Application.Run "RefreshCurrentSelection"
update
Sub update()
If (check if the links have been updated) Then
Worksheets("sheet1").Range("d3").Value = Worksheets("sheet1").Range("sum")
Else
Application.OnTime earliestTime:= Date + Time + timeserial(0, 0, 1), _
procedure:="update", Schedule:=True
End if
End Sub
That would ask the Bloomberg API to refresh the data, then wait 1 second, check if the data is updated, wait another second if not etc. until the data is updated and then it would run the range assignment.
You have to split it up between a check and a refresh.
Sub RefreshData()
Application.Calculation = xlCalculationAutomatic
Worksheets("Sheet1").Range("A1:A4").Select 'the cells "data1" contains the function =BDH(ticker, field, start date, end date) to get the information from Bloomberg'
Application.Run "RefreshCurrentSelection"
'Check to see if it filled
Call Check_API
End Sub
Sub Check_API()
If Application.WorksheetFunction.CountIfs(Range("A1:A4"), "#N/A Requesting Data...") > 0 Then
'Check every 3 seconds
Application.OnTime Now + TimeValue("00:00:03"), "Check_API"
Else
'What to do after API filled
Worksheets("sheet1").Range("D3").Value = Application.WorksheetFunction.Sum(Worksheets("Sheet1").Range("A1:A4")) 'the cells "sum" takes the sum of all BB info'
End If
End Sub
Also, instead of focusing on the selection, you can do:
Refresh based on default option setting:
Application.Run "RefreshData"
Refresh current selection:
Application.Run "RefreshCurrentSelection"
Refresh current worksheet:
Application.Run "RefreshEntireWorksheet"
Refresh current workbook:
Application.Run "RefreshEntireWorkbook"
Refresh all workbooks:
Application.Run "RefreshAllWorkbooks"
If you were interested. Still the better option is implementing the v3 COM API class that can be found in Bloomberg's SDK with VBA examples.
Even though your Calls seems odd, you should be able to make use of the value from Application.CalculationState.
There are other ways to "pause" Excel, but you can do a simple While loop that do nothing except waiting for value of Application.CalculationState becomes xlDone.
Do Until Application.CalculationState=xlDone
Loop
hi there im creating a spreadsheet to use for clocking in and out of work and have a simple wee GUI set up already. along with this i have the current time showing as soon as i start up the worksheet but it shows on every page i was wondering how to stop this?? sample code below:
Global clockOn As Boolean
Sub runClock()
Range("M15").Value = Now()
If clockOn = True Then
Application.OnTime Now + TimeValue("00:00:01"), "runClock"
End If
End Sub
Sub Auto_Open()
clockOn = True
runClock
End Sub
Sub stopClock()
clockOn = False
End Sub
on top of this i will be doing a macro to put the information onto a specific page all going well as this will be depending on the day selected from the drop down menu any help with this would be greatly appriciated :) as in maybe an if statement in the VBA code to select the correct page and leave the data there.
You need to specify the sheet that you are putting the value on; currently you only specify the range, but you don't specify the sheet. Can be done multiple ways, such as:
Sheets(1).Range("M15").Value = Now()
This selects the first sheet in the workbook. If you have multiple workbooks, you will need to specify that somehow as well (by referring to the active workbook, or the name of a workbook, etc.). For example:
Activeworkbook.sheets(1).Range("M15").Value = Now()
I have a list of stock prices pulled from Google finance and placed in different sheets in my Excel. I'm wondering, Can I refresh Excel sheet every SECOND (not minute) according to the Google finance stock price?
This can be done without having a macro constantly running. It relies on the Application.OnTime method which allows an action to be scheduled out in the future. I have used this approach to force Excel to refresh data from external sources.
The code below is based nearly exclusively on the code at this link: http://www.cpearson.com/excel/ontime.aspx
The reference for Application.OnTime is at: https://msdn.microsoft.com/en-us/library/office/ff196165.aspx
Dim RunWhen As Date
Sub StartTimer()
Dim secondsBetween As Integer
secondsBetween = 1
RunWhen = Now + TimeSerial(0, 0, secondsBetween)
Application.OnTime EarliestTime:=RunWhen, Procedure:="CodeToRun", Schedule:=True
End Sub
Sub StopTimer()
On Error Resume Next
Application.OnTime EarliestTime:=RunWhen, Procedure:="CodeToRun", Schedule:=False
End Sub
Sub EntryPoint()
'you can add other code here to determine when to start
StartTimer
End Sub
Sub CodeToRun()
'this is the "action" part
[A1] = WorksheetFunction.RandBetween(0, 100)
'be sure to call the start again if you want it to repeat
StartTimer
End Sub
In this code, the StartTimer and StopTimer calls are used to manage the Timers. The EntryPoint code gets things started and CodeToRun includes the actual code to run. Note that to make it repeat, you call StartTimer within CodeToRun. This allows it to loop. You can stop the loop by calling the StopTimer or simply not calling StartTimer again. This can be done with some logic in CodeToRun.
I am simply putting a random number in A1 so that you can see it update.
Sub RefreshFormulasEverySecond()
Dim dtTargetTime As Date
Debug.Print "Started"
Do While Range("A1").Value <> "STOP"
Application.Calculate
dtTargetTime = Now + TimeValue("0:00:01")
Do While Now < dtTargetTime
DoEvents
Loop
Debug.Print Now
Loop
Debug.Print "Stopped"
End Sub
You could have this macro running in the background. Paste it into a VBA module. You can run it from there or else put a button on the sheet and use that to trigger it. It's written to stop running when the word "STOP" is typed in cell A1 of whatever sheet the user is looking at.
I'm not sure it's the greatest idea to have a macro running continuously in the background, but that was the only way I could think of.
Regarding MS Excel, I want to know how to create an Excel file that is deleted from the computer when a certain date or time is reached.
Is it possible? If it is, please tell me how it can be done?
If you add this code to the ThisWorkbook module, then the workbook will self-destruct if the current date is later than 1 Jan 2014.
Private Sub Workbook_Open()
If Now() > #1/1/2014# Then Call SuicideSub
End Sub
'
Sub SuicideSub()
'courtesy Tom Ogilvy
With ThisWorkbook
.Saved = True
.ChangeFileAccess xlReadOnly
Kill .FullName
.Close False
End With
End Sub
You can call function DoSomething at a certain time in the future or by specifying the time interval by calling Activate_timer, but I don't think you can delete workbook direct from VBA. You can try to call in DoSomething function some batch file which closes the book first and then remove it.
Sub Activate_timer()
' at a certain time in the future
'Application.OnTime DateSerial(2014,01,01)+TimeSerial(0,0,0), "DoSomething"
' or by specifying the time interval
Application.OnTime Now + TimeValue("01:40:00"), "DoSomething"
End Sub
Sub DoSomething()
'call the batch file
End Sub
I was thinking it would be a nice convenience if, while a bunch of people are viewing the same workbook for read-only, they could be notified with a pop-up on their screen every time the workbook has been updated. That way they know right away what they are looking at may no longer be accurate. Thanks
Here is a crafty little way of doing what you want. The idea is to get FileDateTime(ThisWorkbook.FullName), the date the workbook file was last modified. You first get this date at the time of opening the workbook, store it in a cell in your workbook, and then check back periodically whether FileDateTime(ThisWorkbook.FullName) returns a date different from what was stored.
In this example I store the date in Sheet1.Range("A1"), but you could store it in a hidden sheet or wherever.
In your ThisWorkbook module, define the Workbook_Open event as follows:
Private Sub Workbook_Open()
userNotified = False
'Store date last modified.
dateLastModifiedWhenOpened = FileDateTime(ThisWorkbook.FullName)
'How often will we check back?
runTimeInterval = TimeValue("00:00:05")
'Set timer for next check.
Application.OnTime Now + runTimeInterval, _
"CheckWhetherThisWorkbookFileModifiedSinceOpening"
End Sub
In a code module:
Public dateLastModifiedWhenOpened As Date
Public nextRunTime As Date
Public runTimeInterval As Date
Public userNotified As Boolean
Sub CheckWhetherThisWorkbookFileModifiedSinceOpening()
If Not FileDateTime(ThisWorkbook.FullName) = dateLastModifiedWhenOpened Then
MsgBox "This workbook file has been modified since you opened it." _
& vbCrLf & "Modified at: " & FileDateTime(ThisWorkbook.FullName)
userNotified = True
Else
'Set timer for next check.
nextRunTime = Now + runTimeInterval
Application.OnTime nextRunTime, _
"CheckWhetherThisWorkbookFileModifiedSinceOpening"
End If
End Sub
It may be a good idea to clean up upon closing the workbook. In your ThisWorkbook module:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If Not userNotified Then
'Cancel the next check.
Application.OnTime nextRunTime, _
"CheckWhetherThisWorkbookFileModifiedSinceOpening", , False
End If
End Sub
You can share your workbook via the Review ribbon, Share Workbook.
In the advanced options you can set "Update changes" to as often as 5 minutes. In your case you probably want "Just see other users' changes".