Skip to content

VBA.Timer midnight issue #67

@6DiegoDiego9

Description

@6DiegoDiego9

During last days I kept an always-on SeleniumVBA loop running with a 2000ms sleep each run.
Each morning, I found the script hung.
After the nth night crash, I investigated and found that it was simply waiting for the VBA.Timer to reach an overlimit number equivalent to 24:00:02 that could never reach because at midnight VBA.Timer resets to 0.

I thought about a couple of solutions to this bug:

  • adding the VBA.Date to VBA.Timer: CLng(VBA.Date) + (CDbl(VBA.Timer) / 86400)
  • going with the Windows API timers, that never reset

Since I already fine-tuned my all-purpose Sleep procedure for my master library, reaching my goal of <0.0% CPU usage, DoEvents, accuracy +-<10ms, I thought it would be a good idea to move it to the WebShared module for use by SeleniumVBA too, as in my last pull request.

I was also about to modify your WaitUntilReady procedure:

'@Description("Waits until element is interactable")
Public Function WaitUntilReady(element As WebElement, Optional ByVal maxWaitTimeMS As Long = 30000) As WebElement
    'waits until element is interactable, returns the input element for further action
    'such as "Click" on same line
    'see https://www.w3.org/TR/webdriver/#element-displayedness
    Dim startTime As Single
    Dim nowTime As Single
    Dim endTime As Single
    
    startTime = VBA.Timer
    nowTime = startTime
    endTime = startTime + maxWaitTimeMS / 1000#
    
    Do While nowTime < endTime
        If element.IsDisplayed Then Exit Do
        nowTime = VBA.Timer()
        Dim elapsedTime As Single
        If nowTime < startTime Then
            endTime = endTime - elapsedTime
            startTime = 0
        End If
        elapsedTime = nowTime - startTime
        DoEvents    'yield to other processes.
    Loop

    Set WaitUntilReady = element
End Function

using the Windows API functions, like this:

'@Description("Waits until element is interactable")
Public Function WaitUntilReady(element As WebElement, Optional ByVal maxWaitTimeMS As Long = 30000) As WebElement
    'waits until element is interactable, returns the input element for further action
    'such as "Click" on same line
    'see https://www.w3.org/TR/webdriver/#element-displayedness
    
    Dim cTimeStart As Currency, cTimeNow As Currency
    Dim dTimeElapsed As Currency, cMaxWaitTimeMS As Currency
    
    getTime cTimeStart
    
    Static cPerSecond As Currency
    If cPerSecond = 0 Then getFrequency cPerSecond
    cMaxWaitTimeMS = CCur(maxWaitTimeMS) * (cPerSecond / 1000)
    
    Do
        If element.IsDisplayed Then Exit Do
        getTime cTimeNow
        DoEvents 'yield to other processes
    Loop Until (cTimeNow - cTimeStart) >= cMaxWaitTimeMS
    
    Set WaitUntilReady = element
End Function

or at least using the VBA.Date to VBA.Timer solution,
but I didn't understand its "If nowTime < startTime" branch:
I can only think of a nowTime that is less than startTime when midnight passes, however I can't understand what the following lines accomplish. They don't seem to approach the midnight issue.

So, I leave my pull request and this last function modification for your review @GCuser99.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions