-1

I would like the data in cells B6 B8 B10 to update every second rather than require me to edit the spreadsheet to show the live time. How can I achieve this and what should the formula look like?

enter image description here

Olivier
  • 13,283
  • 1
  • 8
  • 24
Insider
  • 95
  • 12
  • 5
    Let's start with: why? Reason for asking is that a formula can't update itself, but needs to be triggered. VBA can be used, but it requires to be running in the background constantly and it'll slow your file down and may cause unexpected errors when used together with other files/macros. – P.b Sep 17 '22 at 14:35
  • I would prefer to avoid VBA for the obvious slowing down reasons, i would prefer a formula or another way around ideally. – Insider Sep 17 '22 at 15:58
  • Than, it needs a trigger to recalculate. At any change in the workbook `=NOW()` recalculates, since it's volatile. But without a change it'll remain it's a value. Updating every second or every given lapse is impossible with a formula. But what is the purpose of it? – P.b Sep 17 '22 at 16:35
  • Using vba need not be slow. Consider using OnTime to call a tiny Sub that calculates only the required cells (or just writes the time) and reschedule itself – chris neilsen Sep 17 '22 at 19:51
  • Perhaps [this](https://www.youtube.com/watch?v=JVrPsHcVygY) is what you're looking for? But I do agree with the statment, why? There's no benefit at all to have a "clock" within excel when you have the taskbar for it. I do understand that you try to time zone it (for it there are other VBA codings so it gets updated by internet), as such, what I'd do is a button to "translate" time if needed – Sgdva Sep 20 '22 at 14:14

3 Answers3

6

This answer provides code to recalculate any range at any given time interval by implementing an Application.OnTime loop.

The example sub UpdateSpecificRange in the following code will recalculate the cells B6 to B10 once every second. To stop the updating, call StopUpdatingSpecificRange or StopUpdatingAll.

'Examples:
Sub UpdateSpecificRange()
    RecalculateRange ThisWorkbook.Worksheets("HOME").Range("B6:B10"), 1
End Sub

Sub StopUpdatingSpecificRange()
    RecalculateRange ThisWorkbook.Worksheets("HOME").Range("B6:B10"), 1, False
End Sub

Sub StopUpdatingAll()
    RecalculateRange stopAll:=True
End Sub

For these examples to work, copy this subroutine into any standard module:

Public Sub RecalculateRange(Optional ByVal Range As Range = Nothing, _
                            Optional ByVal refreshTimeSec As Double = 1#, _
                            Optional ByVal schedule As Boolean = True, _
                            Optional ByVal stopAll As Boolean = False, _
                            Optional ByVal Address As String = "")
    Dim nextExec As Double, macroName As String, wasScheduled As Boolean, task
    Static tasks As Collection: If refreshTimeSec < 1 Then refreshTimeSec = 1#
    If tasks Is Nothing Then Set tasks = New Collection
    If stopAll Then
        For Each task In tasks
            Application.OnTime task(1), task(0), , False: tasks.Remove task(0)
        Next task: Exit Sub
    End If
    If Not Range Is Nothing Then Address = Range.Address(external:=True)
    Address = Replace(Address, "'", "''")
    macroName = "'RecalculateRange , " & Replace(refreshTimeSec, ",", ".") _
                & ", , , """ & Address & """'"
    On Error Resume Next: tasks macroName: wasScheduled = (err.Number = 0)
    On Error GoTo -1: On Error GoTo 0

    If schedule Then
        Application.Range(Replace(Address, "''", "'")).Calculate
        If wasScheduled Then tasks.Remove macroName
        nextExec = DateAdd("s", refreshTimeSec, Now())
        tasks.Add Item:=VBA.Array(macroName, nextExec), Key:=macroName
        Application.OnTime nextExec, macroName
    Else
        If wasScheduled Then
            Application.OnTime tasks(macroName)(1), macroName, , False
            tasks.Remove macroName
        End If
    End If
End Sub

You can also call RecalculateRange multiple times with different ranges and different update rates. You can stop updating them individually aswell be calling RecalculateRange with the same parameters you first called RecalculateRange including the parameter schedule:=False. You can also stop updating all of them at once by calling RecalculateRange with the optional parameter StopAll = True as follows: RecalculateRange StopAll:=True

Since Application.OnTime can reopen the workbook if it was closed, we have to stop all the scheduled range updates before the workbook is closed. This can be done automaticaly by leveraging the workbook BeforeClose event. To do this, you have to paste the following code into the ThisWorkbook code module:

Option Explicit 

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    RecalculateRange StopAll:=True
End Sub

Starting the updating automatically when the workbook is opened can also be done in the ThisWorkbook code module, by leveraging the workbook Open event. To do this, you can paste the following into the ThisWorkbook code module:

Private Sub Workbook_Open()
    RecalculateRange ThisWorkbook.Worksheets("HOME").Range("B6:B10"), 1
End Sub

To open the ThisWorkbook code module, double click it in the VBA Project-Explorer as highlighted in the following screenshot: "ThisWorkbook" code module

GWD
  • 3,081
  • 14
  • 30
  • Thanks for the answer. Although I am having some difficulty, do I need to use both parts of the above code in separate modules? Also should I be inputting the name of the worksheet ("HOME") / workbook ("SPX program") at some locations marked green in the code? I am getting errors such as user sub not defined etc. – Insider Sep 24 '22 at 08:57
  • 1
    Hello @Excelnewman , you can place both parts into the same module if you want. If you place the macros into the Workbook with the Worksheet in Question you don't need the Workbook Name, you can just refer to the Workbook as `ThisWorkbook`. If you have multiple Worksheets in your Workbook you can replace the one line of code in the Sub `UpdateB6toB10` with: `StartUpdatingRange ThisWorkbook.Worksheets("HOME").Range("B6:B10"), 1`. After you did that, just run the sub `UpdateB6toB10`. If you continue to see errors please tell me what the error message says. – GWD Sep 24 '22 at 09:19
  • Nearly there. Both parts of the code are now in one module and working however the file reopens automatically after closing. Is there any way to remedy this and only have the cells update when the file is open? Also when first opening the file I have to enter the module and manually run it. – Insider Sep 24 '22 at 09:53
  • 1
    @Excelnewman, yes there is a way to solve both of these issues. I will edit my answer to account for this as soon as I have access to my computer in probably around 1 hour. – GWD Sep 24 '22 at 10:34
  • Have you had any chance to look at this just yet? @GWD – Insider Sep 25 '22 at 08:57
  • Hi @Excelnewman, I'm sorry for the late reply. I had to completely rewrite the answer to implement the requested features. Please try to follow the updated answer and let me know if everything works. – GWD Sep 25 '22 at 20:27
  • 1
    Currently I paste the large code into a standard module, save then attempt to run and get the message : ```Run-time error '429': ActiveX component can't create object``` - when using debug the line in question is : ```Set currTasks = CreateObject("Scripting.Dictionary")``` – Insider Sep 26 '22 at 07:49
  • 1
    I suppose you are working on a Mac? I'll update the code and avoid using a dictionary. – GWD Sep 26 '22 at 07:53
  • Yes I am on a Mac using Excel 16.65. – Insider Sep 26 '22 at 08:15
  • 1
    @Excelnewman, I just updated the code od the sub `RecalculateRange` again. Now it doesn't use a dictionary anymore. Please try it with the updated code and let me know if it works! – GWD Sep 26 '22 at 09:01
  • 1
    all working flawlessly. Great work, thanks. – Insider Sep 26 '22 at 11:09
3

Solved with VBA: -> Update clock every Second

Sub clock_timer()
    Sheets("Sheet1").Range("B6").Value = Now
    Application.OnTime Now + TimeValue("00:00:01"), "clock_timer"
End Sub

Solved without VBA: -> Update clock every Minute

Using Query & Connections, follow these steps;

Step 1: Select "B5 to B10" & click on Insert -> Table
Step 2: Click on Data -> From Table/Range
Step 3: A new pop up will open with Query -> Click on Close & Load
Step 4: Right click on newly created Table under section "Queries & 
        Connections" & go to Properties
Step 5: Edit Refresh option to "Every 1 Minute"

Another Solution without VBA: By downloading the excel's extensions "XLTools"

Hope it Helps...

Sachin Kohli
  • 1,956
  • 1
  • 1
  • 6
-2

Its actually a really simple Answer in VBA.

Sub Macro1()

x = Application.Ontime Now() + Timevalue("00:00:01"), Macro1 
Range("A1").Value = x 

End Sub

This macro will update a clock in Cell A1 on your sheet every second.

A suggestion would be to use "get data from web" tab and call different timezones time from internet in excel cells..

What you have to do is.

Select Data Tab > Get Data From Web > Enter Dateandtime.com in browser that opens within excel.

Once Data is there the date and time from the cell is dynamic. Just hit data and connections. Set the Refresh data every 1 minute or second. This will give you a live clock from the internet. You can also get time from different timezones.

An example would be www.Dateandtime.com

FunThomas
  • 23,043
  • 3
  • 18
  • 34