Microsoft Access: Edge Browser Control is finally here :) (5 Viewers)

Jon posted in one of those threads that he closed both threads and removed someone's name because of legal ofcom reasons, but I didn't see anything inappropriate in either threads other than an anonymous contributor.
The person who sent me the database from the deleted article at "You Know Who's" website said they would prefer to remain anonymous when I asked if I could thank them publicly (in line with my standard practice). That was his/her personal preference which I respected.
Absolutely nothing inappropriate in that.
 
The person who sent me the database from the deleted article at "You Know Who's" website said they would prefer to remain anonymous when I asked if I could thank them publicly (in line with my standard practice). That was his/her personal preference which I respected.
Absolutely nothing inappropriate in that.
Okay, but what does that have anything to do with the OP's interesting topic about web browser in form without control being closed off? I was about to comment in that thread because I recently built a document management app that opens a web browser, which I would like to contribute to the Code Repo.
 
Last edited:
It had absolutely nothing to do with the thread being closed.
You raised it as being inappropriate - I responded to that comment.

If you want to post a thread to the Code Repository or Sample Databases, then go ahead.
Not sure I see the relevance to the now closed threads
 
You raised it as being inappropriate - I responded to that comment.
I didn't say there was anything inappropriate in that thread. On the contrary, I said I didn't find anything inappropriate. Why is it that no one is providing straight up honest answers about what's really going on here with "You Know Who" just providing useful code and then the thread gets closed? Is there a problem with "You Know Who" and AWF? This thought police thing is really twisting AWF out of control. I decided to ignore all non-tech forums and now this crap contaminates the tech areas.
 
Last edited:
Jon posted in one of those threads that he closed both threads and removed someone's name because of legal ofcom reasons, but I didn't see anything inappropriate in either threads other than an anonymous contributor.
Your comment implied that the anonymous contribution was inappropriate.

From the site owner's comments, he received a complaint from YKW which caused him to close the two threads and delete all references to that person. That was clear enough.
In the circumstances, none of us here have the right to know the exact details of what happened, whether involved in that thread or otherwise.

I hope @MsAccessNL will post a new thread when he is ready to publish his own code / example app.
 
Ignoring the bits about inappropriate content this main thread has amused me somewhat. All that is happening is that something is being put back that was available in 'days-of-yore'. The IE browser OCX which disappeared at the start of the century worked beautifully and then was gone and if you could find it didn't work with 2003. Ditto were the media player OCX and the RTF OCX (this latter being 'real' RFT and not HTML like the current built-in offering)
 
Also, up to around 2022 or thereabouts, you could also embed Excel, Word and PowerPoint objects into Access with almost zero effort. This functionality depended on the old viewers for those document types which MS has now deprecated.

However I think all of the recent posts (including mine) are off topic. The thread is meant to be about the Edge browser control.
 
Ignoring the bits about inappropriate content this main thread has amused me somewhat. All that is happening is that something is being put back that was available in 'days-of-yore'. The IE browser OCX which disappeared at the start of the century worked beautifully and then was gone and if you could find it didn't work with 2003. Ditto were the media player OCX and the RTF OCX (this latter being 'real' RFT and not HTML like the current built-in offering)
You can find the legacy web browser controls even in the newest versions of Access. However, web technologies have moved on and IE couldn't keep up.

Then, Google developed Chromium and a lot of folks forked it or worked on top of it, Microsoft included, and now a lot of browsers are based on it, Edge is Microsoft's take of Chromium. With the fast and growing amount of frameworks and huge dependency nightmare that all web apps are nowadays, IE just wouldn't stand a chance, so the move is pragmatic, but useful.

Based on my experience lurking forums, it really seems like very few ever used the web browser controls.
 
So using shell commands to externally open user's default web browsers is more common than using web browser controls?
No, I meant actually developing for the web browser control making the contents of the control interact with the application.
 
I’ve used the old web control to do something simple - display images from a windows folder, then using code to drag them on to the main form. However couldn’t get it to work with the new web browser control
 
I use the new browser control to open the Autodesk Vault Thin Client allowing users to browse the Vault to select assembly models to import BOM. Programming the browser using Javascript and the ExecuteJavascript function. The following code logs into the vault using a read only username and password. Very much like building up a SQL string.

Code:
Me.WebBrowser1.ExecuteJavascript _
"{var nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, ""value"").set; " & _
"const $formObject = document.forms[0]; " & _
"const $usernameField = $formObject.elements[0]; " & _
       "nativeInputValueSetter.call($usernameField, '<TheLoginName>'); " & _
"let eventUN = new Event('input', { bubbles: true}); " & _
       "eventUN.simulated = true; " & _
       "$usernameField.dispatchEvent(eventUN); " & _
"const $passwordField = $formObject.elements[1]; " & _
       "nativeInputValueSetter.call($passwordField, '<TheLoginPassword>'); " & _
"let eventPW = new Event('input', { bubbles: true}); " & _
       "eventPW.simulated = true; " & _
       "$passwordField.dispatchEvent(eventPW); " & _
"const $loginButton = $formObject.elements[2]; " & _
       "$loginButton.click();}"
 
Last edited:
I use the new browser control to open the Autodesk Vault Thin Client allowing users to browse the Vault to select assembly models to import BOM. Programming the browser using Javascript and the ExecuteJavascript function. The following code searches logs into the vault using a read only username and password. Very much like building up a SQL string.

Code:
Me.WebBrowser1.ExecuteJavascript _
"{var nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, ""value"").set; " & _
"const $formObject = document.forms[0]; " & _
"const $usernameField = $formObject.elements[0]; " & _
       "nativeInputValueSetter.call($usernameField, '<TheLoginName>'); " & _
"let eventUN = new Event('input', { bubbles: true}); " & _
       "eventUN.simulated = true; " & _
       "$usernameField.dispatchEvent(eventUN); " & _
"const $passwordField = $formObject.elements[1]; " & _
       "nativeInputValueSetter.call($passwordField, '<TheLoginPassword>'); " & _
"let eventPW = new Event('input', { bubbles: true}); " & _
       "eventPW.simulated = true; " & _
       "$passwordField.dispatchEvent(eventPW); " & _
"const $loginButton = $formObject.elements[2]; " & _
       "$loginButton.click();}"

We've been using Access/DotNet interop to directly integrate with online services, such as QuickBooks Online via Rest and OAuth API calls.
We use Tim Hall's JsonConverter module and the following sample code to interface with several online services.

Code:
Option Explicit
Option Compare Database

#If VBA7 Then ' Access 2010 or later
 
    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal Milliseconds As LongPtr)
 
#Else ' Access 2007 or earlier
 
    Public Declare Sub Sleep Lib "kernel32" (ByVal Milliseconds As Long)
 
#End If

Public Function QBOTest()
  
    ' Our .NET interface
    Dim qbo As QBOInterface.QBOInterface
    Set qbo = New QBOInterface.QBOInterface
  
    Dim authCode As String, realmID As String
  
    ' Authorization Code, one-time code from QBO that authorizes our application to read data from customer's QBO account
    authCode = DLookup("AuthCode", "QBOAuthentication") ' will need to be entered by the user
    ' Unique identifier for the client's company in QBO
    realmID = DLookup("RealmID", "QBOAuthentication")
  
    ' Init: clientID, clientSecret, redirectURL, environment, authCode, realmID
    ' These must match exactly what the web application uses
    ' ClientID and ClientSecret come from QBO Developer Account portal
    qbo.Init "Q0uEmaJmYxjLE73PffMaG0EhIhG7**************", "WyBAFRAoLjGwXF27zjl2OUnBjwA**************", "https://accessqbotest.azurewebsites.net/callback", "sandbox", authCode, realmID
  
    Dim aToken As String, rToken As String
  
    ' Access Token, used to communicate with the QBO API, expires within 60 minutes
    aToken = "" ' will come from the database, otherwise will be blank
  
    ' Refresh Token, used to request Access Tokens, expires after 100 days
    rToken = DLookup("RefreshToken", "QBOAuthentication") ' will come from the database, if QBO connectivity has occurred before, otherwise this will be blank
  
    ' Gets our Access Token, if we don't already have one to use
    qbo.GetToken aToken, rToken
          
    Sleep 2000 ' Short delay is required for the API to be called and response received/processed
                      
    ' MsgBox "Access Token: " & qbo.AccessToken
    ' MsgBox "Refresh Token: " & qbo.refreshToken
      
    Dim companyInfo As String
    companyInfo = qbo.GetCompanyInfo
  
    ' MsgBox "Company Info (JSON): " & companyInfo
  
    Dim Json As Object
    Set Json = JsonConverter.ParseJson(companyInfo)
  
    Dim sql As String
    Dim dbs As DAO.Database
    Set dbs = CurrentDb()
  
    RunSQL "DELETE FROM QBOCompany", dbs
    RunSQL "INSERT INTO QBOCompany (ID, CompanyName, CompanyAddr_City, CompanyAddr_Country, CompanyAddr_Line1, CompanyAddr_PostalCode, PrimaryPhone, EmailAddress) VALUES ('" & Json("Id") & "', '" & Json("CompanyName") & "', '" & Json("CompanyAddr")("City") & "', '" & Json("CompanyAddr")("Country") & "', '" & Json("CompanyAddr")("Line1") & "', '" & Json("CompanyAddr")("PostalCode") & "', '" & Json("PrimaryPhone")("FreeFormNumber") & "', '" & Json("Email")("Address") & "')", dbs
      
    dbs.Close
    Set dbs = Nothing
  
    MsgBox "Sync complete!"
      
End Function

Private Sub RunSQL(sql As String, dbs As DAO.Database)

    dbs.Execute sql, dbFailOnError
  
End Sub
 
Last edited:
Hello everyone, I have been attempting to use the Edge Browser Control with dynamic HTML. This is ideal for my use case in using the Browser Control to generate modern UI and graphs through use of html/css/javascript. The issue I'm having is that while the Edge Browser Control works great to render the HTML dynamically, all subsequent calls to RetrieveJavascriptValue fail.

While this issue does not occur if using a local html file and Navigating to it, use of a local file is not ideal as it suffers from the 3 second loading lag and also creates unnecessary temp files on a user's drive.

To reproduce this issue:
  • Create a Form and add the Edge Browser Control
  • Set the ControlSource = "about:blank"
  • Run the below code. The call to RetrieveJavascriptValue in PopulateBrowserDynamic times out every time.
I appreciate any ideas to resolve this issue.

Code:
Private Sub WaitUntilBrowserReady()
    While Me.EdgeBrowser.ReadyState <> acComplete
        DoEvents
    Wend
End Sub

Private Sub Form_Load()
    Call WaitUntilBrowserReady
    Call PopulateBrowserDynamic 
End Sub

' Function: Populates the Browser with dynamic HTML using Javascript (no local file or web address)
' Test Result: This successfully renders the html in the Browser Control, but RetrieveJavascript FAILS every time.
Private Sub PopulateBrowserDynamic()
    Dim html As String, js As String
    Dim title As String

    html = "<html><head><title>My Title Dynamic</title></head><body><h1>Hello World Dynamic</h1></body></html>"

    js = "document.open(); document.write('" & html & "'); document.close();"
    Call Me.EdgeBrowser.ExecuteJavascript(js)
    Call WaitUntilBrowserReady

    ' Attempt to retrieve title of web page

    ' The below times out and title is set to error message of
    ' "RetrieveJavascriptValue timed out. Please verify the JavaScript expression supplied is valid."
    title = Me.EdgeBrowser.RetrieveJavascriptValue("document.title")
    MsgBox title
End Sub
 
I can only conclude the above scenario in my previous post is due to a bug in the Edge Browser Control. I have used the older web browser control extensively with only dynamic html/css/javascript without issue, although at this point the old control does not support modern web standards. With the old web browser control now planned to be deprecated/removed from MS Access in June 2026 (based on a recent post on accessforever.org), any input is appreciated on the best way to report my previous post as a bug to the MS Access team for resolution.
 
I can only conclude the above scenario in my previous post is due to a bug in the Edge Browser Control. I have used the older web browser control extensively with only dynamic html/css/javascript without issue, although at this point the old control does not support modern web standards. With the old web browser control now planned to be deprecated/removed from MS Access in June 2026 (based on a recent post on accessforever.org), any input is appreciated on the best way to report my previous post as a bug to the MS Access team for resolution.
You should use a watch to check when the state is changing, the state can change for many reasons, so you should verify that it's not stuck trying to do something it can't do at that point. I can't replicate the issue as the Edge browser control is not available in my Access installation, but I've seen the problem multiple times in the legacy web browser control. You could also try setting the HTML content in other ways, like navigating to data/text; <html>...</html>, or setting the document when there is actually a document for about:blank, then modifying the document.

Many times, it's better just to put a html file in the temporary files like you were doing, for a few different reasons. Web browsers are some of the most complicated and convoluted pieces of software, so give it another chance. Use you debugger extensively.
 
I used to do similar dynamic html in the old version of the webbrowser control by first navigating to about:blank, and then writing to the DOM document of the loaded empty page.

So, no need for external html file and not relying on js to create the initial document.

Perhaps this technique might work here?
 
Last edited:
The problem i have with the new browser control is that when using it to display local files. updating the control source doesn’t always refresh what is displayed
 
@Edgar_ I have been using the debugger and confirm that the Edge Browser Control is in ReadyState acComplete before calling RetrieveJavascriptValue. The Browser perfectly renders the html/css/javascript using the dynamic injection method with ExecuteJavascript, it is just that calling RetrieveJavascriptValue does not seem to work at all if you are purely populating the control with dynamic content.

@cheekybuddha Using about:blank and then populating the control dynamically is exactly what I prefer to do and that was always the method I used with the old Browser Control without issue. The old Web Browser Control was a bit easier to work with dynamically as you could directly interact with the DOM through the VBA object model. For the Edge Browser Control, that is no longer possible and all direct interactions are done by using the ExecuteJavascript and RetrieveJavascriptValue VBA functions. I have gotten used to these methods, but I'm just running up against these issues with RetrieveJavascriptValue when using the control dynamically.

@CJ_London. I have encountered that same issue with trying to dynamically set the ControlSource and/or calling Navigate on the Edge Browser Control to load a local file dynamically. Besides the desire also not to save temp local files, the 3 second loading lag of local files into the Browser Control does not meet needs for loading time. I'm aware there is a workaround to speed that up, but it requires changing the HOST system file in Windows and I run in shared Terminal Server environments where that is not something IT is open to.
 
I have been using the debugger and confirm that the Edge Browser Control is in ReadyState acComplete before calling RetrieveJavascriptValue. The Browser perfectly renders the html/css/javascript using the dynamic injection method with ExecuteJavascript, it is just that calling RetrieveJavascriptValue does not seem to work at all if you are purely populating the control with dynamic content.
I cannot test it myself, so I cannot say for sure what you are encountering, but it seems like there is something off with how you are approaching it. Instead of waiting for the page to be fully ready, I would recommend testing for the existence of an element that is expected to render. In your case, testing for the presence of document or a part of it might be a better approach. Just because you can see its contents does not necessarily mean the program has reached a stage where it can interact with or manipulate them. Use your watch to monitor that too, besides the state. The state can change many times throughout dynamic content creation. You could add a listener too and have that listener react to the precise moment where you can manipulate the contents.
 

Users who are viewing this thread

Back
Top Bottom