The Access WebBrowser control is one of the greatest and most frustrating controls available to any Access developer!
The beauty of this control is it enables you to gain the power of the web within your database. On the other hand, I have found it very frustrating to program as many properties/methods available to the WebBrowser control in other platforms are simply not implemented in Access’ WebBrowser control. I have also found documentation and concrete advanced examples to be a rare commodity making development more frustrating than it should normally be.
So I thought I’d put ‘pen to paper’, in a manner of speaking, to share some of what I’ve learnt.
In the this article I will touch upon
- WebBrowser Control Limitations!
- URLs From A Table
- URLs From VBA
- Content From a Local File
- Dynamic Content on the Fly
- Opening a Blank Page
- Working With the WebPage
- Retrieving the Current Page’s URL
- Retrieving a Page’s HTML Source Code
- Executing Code on the Webpage
- Form Current Event
- Refreshing the Webpage
- Printing the Webpage
- Saving the Webpage
- Retrieving Information From The WebPage
- Where’s Intellisense?
- Feature Browser Emulation
- Feature Browser Emulation – Alternative
- Mark of the Web (MOTW)
- Working with Local Resources
- Simply Ignoring Script Errors
- HTML Template
- Sample Database
- Resources on the Subject
- Special Thanks
- Page History
WebBrowser Control Limitations!
Before going any further you should be aware of one major limitation of Access’ WebBrowser control and that is that it doesn’t exist for reports!!! That’s right, Microsoft, for God knows what reason, made the control available in forms, but not reports?! As far as I’m concerned, this makes it a half-implemented control. Just one more glaring hole in Access! How can you have a control (and I think it might be the only control like this) that you judge people want to see within a form, but won’t also want to see in the resulting report? The logic eludes me.
That said, you can however, insert a form with a WebBrowser control into a report and link the two, but this will only render in Report and Layout views (and only for the 1st record) and not in Print Preview. Furthermore, even in Report and Layout views the WebBrowser control will not show up when printed!
I have a couple ideas for workarounds, but haven’t had the time to work on them. I’ll keep you posted.
Also, in the same report as above, scrolling within Layout View or Report View causes the Access to crash.
So moral of the story, although you can fenagle a WebBrowser control in a Report, DON’T do it, it just doesn’t work!
URLs From A Table
In the most basic form, you could have a simple table with a field that stored the URL of various websites and then use the field as the WebBrowser’s Control Source. That’s it, as you navigate between records, the WebBrowser will automatically navigate to the URL.
URLs From VBA
Pushing things a little further, what if we wanted to use a VBA string variable to navigate the WebBrowser. Nothing could be easier once again.
Me.WebBrowser0.ControlSource = "=""www.google.ca"""
Or
Const sURL = "www.google.ca"
Me.WebBrowser0.ControlSource = "=""" & sURL & """"
Or
Dim sURL As String
sURL = Me.URLControlName
Me.WebBrowser0.ControlSource = "=""" & sURL & """"
Content From a Local File
Taking things up a small notch, sometimes we simply want to load a local file into the WebBrowser. This can be done by doing
Me.WebBrowser0.ControlSource = "=""M:\Databases\CARDA\Demos\HTML Editor\html\index.html"""
Or
Const sFile = "M:\Databases\CARDA\Demos\HTML Editor\html\index.html"
Me.WebBrowser0.ControlSource = "=""" & sFile & """"
Or
Dim sFile As String
sFile = Me.FileControlName
Me.WebBrowser0.ControlSource = "=""" & sFile & """"
Dynamic Content on the Fly
One of the most recent things I was trying to do was create web pages dynamically, based on HTML stored in a table. Initially, I was taking the table value and pushing it to a file on the PC and then loading the file, but I didn’t like that approach as it makes unnecessary I/Os calls by continually writing to the hard drive.
I thought to myself there had to be a way to do this all in memory.
Now, the WebBrowser exposes all sort of ways to alter the head tag content, the body tag content, but nothing to completely alter the entire document itself. I won’t bore you with all the variations I attempted and will get straight to the point. There were 2, very similar, approaches that work at the end of the day.
With Me.WebBrowser0.Object.Document
.Open
.Write "Some content.
"
.Close
End With
Or
Dim sCmd As String
sCmd = "javascript:document.open('text/html');document.write('Some content.
');document.close();"
Me.WebBrowser0.Object.Document.parentWindow.execScript (sCmd)
In my specific case, I was pulling my HTML from a table, so I ended using the form’s current event and doing
With Me.WebBrowser0.Object.Document
.Open
.Write Me.HTMLFieldName
.Close
End With
Absolute Paths a Must
Also note that when creating webpages on the fly you can’t use relative paths for any resources: css, js, images, … since the webpage has no reference point to use for building relative paths from. As such, you must always use absolute paths. So let say you have a template html file that you read into memory, modify and then use dynamically, then you would need to also use some Replace statement to perform any necessary path updates. It could be as simple as
Replace(GetHTML, """./", """" & Replace(CurrentProject.Path, "\", "/") & "/")
assuming the resources are all found in the same directory as the current database. If you don’t perform such replacements, you will end up with missing content and errors, to the point that the page itself may not display.
Opening a Blank Page
It may be useful at times to show a blank page (perhaps to avoir the “The address is not valid” page) and nothing could be easier! You would simply use “about:blank” as the WebBrowser’s control source, such as:
Me.WebBrowser0.ControlSource = "about:blank"
The above didn’t work when I recently tested in Access 2019 and instead I needed to do:
Me.WebBrowser0.ControlSource = "=""about:blank"""
Working With the WebPage
It is one thing to render a webpage, but what about working with it.
One important thing to note is that to avoid errors and code not working, you need to always ensure the browser is finished working/processing/loading the page. To do so, after setting the ControlSource, or writing content, or whatever else you may do, you need to do something along the lines of
Do While Me.WebBrowser0.Object.Busy Or Me.WebBrowser0.Object.ReadyState <> 4
DoEvents
Loop
This will guarantee that the code doesn’t move on to other things until the browser is done and ready.
Also, if you are doing this at the initial opening of a form, be sure to use the Load event, not the Open event (it won’t work).
Retrieving the Current Page’s URL
If ever you wanted to allow your user’s to freely navigate and then capture the URL they are on, it is remarkably simple to do. The code would look like:
Me.WebBrowser0.LocationURL
Retrieving a Page’s HTML Source Code
Another thing I found hard to find any instruction on was retrieving the web page’s entire HTML source code.
You can easily retrieve the HTML between body tags (<body>…this stuff here…</body>) by simply doing
Me.WebBrowser0.Object.Document.body.innerHTML
but I was, yet again, surprised at how hard it was to find any information on retrieving the entire page’s HTML source code. Once again, I won’t bore you with all my attempts, here’s the solution! Simply do
Me.WebBrowser0.Object.Document.documentElement.outerHTML
Executing Code on the Webpage
Sometimes you might need to execute code on the webpage, say run a javascript function, this can be done quite easily using execScript. This was somewhat demonstrated, but not elaborated, in the ‘Dynamic Content on the Fly’ section above.
Below is an example of how this is done
Let’s display a simple alert dialog to the user
Me.WebBrowser0.Object.Document.parentWindow.execScript ("alert('Hello World!');")
Let’s post a value to the console (this can be very useful during development!)
Me.WebBrowser0.Object.Document.parentWindow.execScript ("console.log('Hello World!');")
Now, let’s say we wanted to run one of the webpage’s javascript function, one called highlightRow, then we’d do something like
Me.WebBrowser0.Object.Document.parentWindow.execScript ("highlightRow();")
Don’t forget that after running such code, it is a good idea to add
Do While Me.WebBrowser0.Object.Busy Or Me.WebBrowser0.Object.ReadyState <> 4
DoEvents
Loop
to ensure that the page finishes processing before moving on to the next thing in your code.
This can be an effective way to pass data from your database to a webpage. You can create a javascript/jQuery/… function on the webpage, or entirely in your VBA code, that accepts input variable(s) and then when you call execScript you simply pass the data along as the appropriate input variable(s). A very simple example to demonstrate this would be (using the built-in alert method) to display a message to the user with the current database’s name (this could just as easily have been data from a form, query, table, …).
Me.WebBrowser0.Object.Document.parentWindow.execScript ("alert('Your Access Database " & Application.CurrentProject.Name & " rocks!');")
For instance, it cannot support any JS Promise code, nor can it support HTML5 Canvas. So before spending too much time developing a functional solution in HTML/JS/… and then dropping it into the Access WebBrowser control, validate things at an early stage! (learn from my mistake 🙁 )
When developing html/js/… be sure to do all your testing in IE. Even if it works in every other browser, if it doesn’t run safely in IE, it most probably will not work in the WebBrowser control! (once again, learn from my mistake 🙁 ) and don’t ask me what we’re supposed to do once they retire IE in June, we’ll have no means to properly develop/test anymore.
Form Current Event
So what if you want to perform an action, say run some JS, when the user switches records?
Your instinct would be to use the form’s current event, and that would be right, and wrong at the same time!
In a general sense, that might work with the exception of the initial load! When the form loads, in my experience, the current event fires before the web browser control is fully loaded…
So what’s the solution?
It to use a combination of events and log when the control is initialized. This is the basic concept
Private bPageInitialized As Boolean
Private Sub Form_Current()
If bPageInitialized Then Call SomeProcedure
End Sub
Private Sub Form_Open(Cancel As Integer)
bPageInitialized = False ' Not strictly necessary
End Sub
Private Sub WebBrowser0_DocumentComplete(ByVal pDisp As Object, URL As Variant)
If pDisp.ReadyState = READYSTATE_COMPLETE Then
bPageInitialized = True
Call SomeProcedure
End If
End Sub
Private Sub SomeProcedure()
'Some code
End Sub
Refreshing the Webpage
Sometimes it can be useful to refresh the webbrowser page. To do so through code you simply do:
Me.WebBrowser0.Object.Refresh
Printing the Webpage
Printing is another one of those common tasks that can easily be accomplished in a variety of ways using simple VBA. Below are a few examples illustrating how you can use a button within Access to do so:
'Opens print dialog
Me.WebBrowser0.Object.Document.parentWindow.execScript ("window.print();")
'Opens print dialog
Me.WebBrowser0.Object.Document.execCommand "Print"
'Provide print preview window and the print dialog from there
Me.WebBrowser0.Object.ExecWB OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_DONTPROMPTUSER
'Print directly without dialogs or print preview
Me.WebBrowser0.Object.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER
Another option is to include the print button directly in your HTML and use standard JS to automate the process. Thus bypassing the need to do any coding within your database application and having it part of the native webpage. This can be a useful solution only if you are the creator of the webpage.
Saving the Webpage
If you want to save the currently displayed webpage there are a number of ways to do so.
Using ExecWB (this requires a Reference to Microsoft Internet Controls)
Me.WebBrowser0.Object.ExecWB OLECMDID_SAVEAS, OLECMDEXECOPT_DONTPROMPTUSER, "C:\Users\Dev\Desktop\TestSave.html"
Me.WebBrowser0.Object.ExecWB 4, 2, "C:\Users\Dev\Desktop\TestSave.html" 'With no reference
Using execCommand
Me.WebBrowser0.Object.Document.execCommand "SaveAs", False, "C:\Users\Dev\Desktop\TestSave.html"
What is bothersome with the above approaches is there doesn’t seem to be a way to avoid the SaveAs pop-up dialog (for one thing, the ExecWB completely ignores the DONTPROMPTUSER option). That said, perhaps the best and easiest solution would be to simply capture the active WebBrowser Control’s HTML since we already have it and save it!
Call OverwriteTxt("C:\Users\Dev\Desktop\TestSave.html", Me.WebBrowser0.Object.Document.documentElement.outerHTML)
Which requires a copy of my OverwriteTxt() functions which can be found at: VBA – Export to Text File
Retrieving Information From The WebPage
The WebBrowser control also enables us to interact with the given webpage to execute code and/or retieve information from it. Here are a couple examples of techniques to retrieve information from various controls on a webpage.
Use JS to pass the src of an image to a JS variable and then retrieve the variable’s value.
Dim oWebBrowserObject As Object
Dim sSrc As String
Set oWebBrowserObject = Me.WebBrowser0.Object
oWebBrowserObject.Document.parentWindow.execScript ("var imgSrc = $('img')[0].src;")
sSrc = oWebBrowserObject.Document.Script.imgSrc
Here’s another approach to the same problem using getElementsByTagName
Dim oWebBrowserObject As Object
Dim sSrc As String
Set oWebBrowserObject = Me.WebBrowser0.Object
sSrc = oWebBrowserObject.Document.getElementsByTagName("img")(0).src
Here’s yet another approach to the same problem using getElementById
Dim oWebBrowserObject As Object
Dim sSrc As String
Set oWebBrowserObject = Me.WebBrowser0.Object
sSrc = oWebBrowserObject.Document.getElementById("ItemPic").src
Retrieve the id of the 1st img control on the page
Dim oWebBrowserObject As Object
Dim sId As String
Set oWebBrowserObject = Me.WebBrowser0.Object
sId = WebBrowserObject.Document.getElementsByTagName("img")(0).id
Or as a single line of code you could do:
Dim sId As String
sId = Me.WebBrowser0.Object.Document.getElementsByTagName("img")(0).id
If you look in the VBE Object Browser under the MSHTML library, under the HTMLDocument class, you will see all the functions, methods, … at your disposition for working with the webpage, notably:
- getElementById
- getElementsByClassName
- getElementsByName
- getElementsByTagName
So, as you can see, using typical JS techniques we can retrieve information quite easily.
Where’s Intellisense?
One of the annoying things working with the WebBrowser control was that intellisense only worked 1 element deep meaning that typing Me.WebBrowser0 would provide intellisense, but the minute you went to a 2nd element deep (me.WebBrowser0.Object), or a 3rd element deep (me.WebBrowser0.Object.Document), … you no longer had any intellisense making development that much more complicated and frustrating.
Thankfully, there is a trick to get it back where it counts most (the Document). If you set a reference to the Microsoft HTML Object Library (mshtml.tlb) and declare a variable for the HTML Document as MSHTML.HTMLDocument, then you regain intellisense for your Document coding. So, I typically end up doing something along the lines of
Sub SomeSub()
#Const Dev = True 'True -> Early Binding, Ref Library Req'd
'False -> Use Late Binding, No Ref Libraries
Dim oWebBrowser As Object
Dim oWebBrowserObject As Object
#If Dev = True Then
Dim oHTMLDoc As MSHTML.HTMLDocument 'Req Ref to Microsoft HTML Object Library
#Else
Dim oHTMLDoc As Object
#End If
On Error GoTo Error_Handler
Set oWebBrowser = Me.WebBrowser0
Set oWebBrowserObject = oWebBrowser.Object
Set oHTMLDoc = oWebBrowserObject.Document
'oHTMLDoc... 'Your code starts here with Intellisense now!
Error_Handler_Exit:
On Error Resume Next
If Not oHTMLDoc Is Nothing Then Set oHTMLDoc = Nothing
If Not oWebBrowserObject Is Nothing Then Set oWebBrowserObject = Nothing
If Not oWebBrowser Is Nothing Then Set oWebBrowser = Nothing
Exit Sub
Error_Handler:
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: SomeSub" & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Sub
in which I use Condition Compilation Directives to use Early Binding during development to gain use of Intellisense and then switch to Late Binding (by simply switching Const Dev to False, and removing any added Reference Libraries) to not require any reference libraries as runtime (when I distribute it to my users).
So now you get

Depending on your needs, you can define many other object variables to simplify your programming. For instance, if you’re going to be working with the webpage it can be useful to define a body object variable and this can easily be done:
Sub SomeSub()
#Const Dev = True 'True -> Early Binding, Ref Library Req'd
'False -> Use Late Binding, No Ref Libraries
Dim oWebBrowser As Object
Dim oWebBrowserObject As Object
#If Dev = True Then
Dim oHTMLDoc As MSHTML.HTMLDocument 'Req Ref to Microsoft HTML Object Library
Dim oHTMLDocBody As MSHTML.HTMLBody
#Else
Dim oHTMLDoc As Object
Dim oHTMLDocBody As Object
#End If
On Error GoTo Error_Handler
Set oWebBrowser = Me.WebBrowser0
Set oWebBrowserObject = oWebBrowser.Object
Set oHTMLDoc = oWebBrowserObject.Document
Set oHTMLDocBody = oHTMLDoc.body
'Your code goes here
Error_Handler_Exit:
On Error Resume Next
If Not oHTMLDocBody Is Nothing Then Set oHTMLDocBody = Nothing
If Not oHTMLDoc Is Nothing Then Set oHTMLDoc = Nothing
If Not oWebBrowserObject Is Nothing Then Set oWebBrowserObject = Nothing
If Not oWebBrowser Is Nothing Then Set oWebBrowser = Nothing
Exit Sub
Error_Handler:
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: SomeSub" & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Sub
and so on. You can define any object variable you’d like to not have to carry along statements like
Me.WebBrowser0.Object.Document.body...
every time you want to refer to an element, loop through some tag, find some class, id, …
For a one off situation it doesn’t simplify things much, but when you get into serious automation, such object variables will save you a ton of typing and make your code easier to read/troubleshoot and you get the added bonus of gaining intellisense!
Feature Browser Emulation
By default, it would seem that, Access WebBrowser runs as an instance of Internet Explorer (IE) 7 regardless of what you have installed on your PC. This can cause major compatibility with any more recent code implementations. Quite often this manifests itself as Javascript errors.
Luckily, there is a relatively easy fix, in that we can actually control the ‘Emulation’ used. So we can actually tell Access to run as IE 8 … IE 11 and on new PCs even Edge guaranteeing the greatest compatibility possible.
This is all controlled by a registry key names ‘FEATURE_BROWSER_EMULATION’.
Previously, refer to my original post on the subject http://www.devhut.net/2013/10/18/webbrowser-activex-control-google-maps-invalid-character-scripting-error/, I was creating this entry in the HKEY_LOCAL_MACHINE (HKLM) registry hive, and it worked just fine. However, some time between when I originally did this and now, this no longer works. This actually turned out to be a blessing in disguise, because when you do so in the HKLM you need to determine the bitness (32 or 64) to write the value in the appropriate key.
However, now, we can simply make the entry in the HKEY_CURRENT_USER (HKCU) registry hive and need now not even be concerned with bitness at all!
We need only make a DWord value entry in the
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
registry key for the exe of interest, so in our case msaccess.exe. This therefore implies that the emulation mode will apply to all Access databases, not just the current one.
| DWord Decimal Value | DWord Hexadecimal Value | Corresponding Emulation | Corresponding JS navigator.userAgent | |||
|---|---|---|---|---|---|---|
| 7000 | 1b58 | IE7 Emulation | Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; NMTE; wbx 1.0.0; Zoom 3.6.0) | |||
| 8000 | 1f40 | IE8 Emulation | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; NMTE; wbx 1.0.0; Zoom 3.6.0) | 8888 | 22b8 | Force IE8 Emulation | Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; NMTE; wbx 1.0.0; Zoom 3.6.0) | 9000 | 2328 | IE9 Emulation | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 10.0; WOW64; Trident/7.0; NMTE) | 9999 | 270f | Force IE9 Emulation | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 10.0; WOW64; Trident/7.0; NMTE) | 10000 | 2710 | IE10 Emulation | Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 10.0; WOW64; Trident/7.0; NMTE) | 10001 | 2711 | Force IE10 Emulation | Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 10.0; WOW64; Trident/7.0; NMTE) | 11000 | 2af8 | IE11 Emulation | Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; NMTE; rv:11.0) like Gecko | 11001 | 2af9 | Force IE11 Emulation | Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; NMTE; rv:11.0) like Gecko | 12001, 13000, 13001, 14000, 140001, … | 2ee1, 32c8, 32c9, 36b0, 36b1 | Emulate the most recent version installed on the local computer (this is between Internet Explorer and Edge) Note: Be careful, a value of 12000 (2ee0) emulates IE11! |
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19044 |
So at the end of the day, unless there is a very particular reason for a specific emulation mode (because you need to support some legacy webpage for instance) you should simply create a DWord value for msaccess.exe with a value of 12000 (or higher) so your WebBrowser control is always running the latest and greatest version available.
Also, although I recommend using the HKCU, keep in mind the Feature Browser Emulation can also be set in either
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
Or
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
So if ever your settings don’t seem to be taking effect, check those registry keys as well as they be interfering with your value.
If you want to validate the version that your WebBrowser control is actually emulating, the simplest method is to navigate your WebBrowser control to https://www.whatsmybrowser.org/.
If you like to live on the edge, what I’ve discovered is, if you open a your database, but don’t open the form containing the WebBrowser control, you can still change the FEATURE_BROWSER_EMULATION value and it will take effect when you open your form. That said, once the form/WebBrowser control has been initialized any changes to the FEATURE_BROWSER_EMULATION do not take effect until you complete close and restart Access.
Feature Browser Emulation – Alternative
[code language=”html”]<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE11" />[/code] Opening the file in IE properly renders using Emulation Mode IE11 and JS confirms this. However, loading the sample file in the WebBrowser control render in IE7.
All that to say the Feature Browser Emulation remains the way to handle this!
IE has a X-UA-Compatibility Meta Tag available to us that allows a web developer to tell the web browser the version of IE that it was designed for and the browser is supposed to adjust itself to that version for best compatibility.
So, it is possible, in the raw HTML to instruct the web browser to change version, thus bypassing the need for the registry hack.
You can learn more about all the X-UA-Compatibility Meta Tag options by consulting the official documentation: [MS-IEDOCO]: X-UA-Compatibility Meta Tag and HTTP Response Header | Microsoft Docs
But basically, you can try to include the following line in the header of every single webpage you will use and it should get the browser to emulate the specified IE version.
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
The above pushes the webbroser to emulate the highest version available.
That said, I have found this to be, at times, unreliable (this is why I didn’t include this when I first created this article), so be sure to test things out, but it might just save you needing to mess around with registry settings!
So think of the Feature Browser Emulation as a one time global fix and the X-UA-Compatible as a individual page fix. So, X-UA-Compatible is only good if you control the webpage(s) you are viewing with the webbrowser control, otherwise, if you are navigating to outside website/webpages, the solution remains to implement the Feature Browser Emulation regisrty hack.
If you want to learn more regarding X-UA-Compatibility, here is a good thread on the subject:
Mark of the Web (MOTW)
Another thing I learnt the hard way was that local files don’t just work. IE, and apparently Edge, using security zones to lock web pages. So, normally, by default, webpages will see code locked down. For instance, my javascript wouldn’t run when I first loaded the pages as is. After some research I found out that you needed to apply the MOTW to the files so as to authorize the pages to run locally.
What does that mean exactly? Say your html file start off like
<!DOCTYPE html> <html> <head>
to get my pages to run properly I ended up with
<!DOCTYPE html> <!-- saved from url=(0016)http://localhost --> <html> <head>
by simply adding the line
<!-- saved from url=(0016)http://localhost -->
following the beginning <html> tag, my files were now trusted and allowed to run uninhibited. Life was good once again!
Working with Local Resources
If you are planning on using local resources within your HTML: script files, images, … you are best to prefix the src attributes with file://
So, instead of:
<img src="C:\temp\sunflower.jpg" alt="Picture of a Sunflower" width="300" height="400">
Do:
<img src="file://C:\temp\sunflower.jpg" alt="Picture of a Sunflower" width="300" height="400">
With regards to script files in particular, it seems that Microsoft has blocked local scripts from running via webbrowser control by default and you must now add a DWORD Registry entry to
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BLOCK_LMZ_SCRIPT
for msaccess.exe with a value of 0. Then close and restrat Access.
So if you have html that renders fine in a web browser, but gives you a scripting error when run via Access’ webbrowser control, try making the above addition you your registry.
Simply Ignoring Script Errors

While not the approach I’d typically recommend, if you don’t want to get into hacking the registry by adjusting the FEATURE_BROWSER_EMULATION value, but would like to make those pesky Script Errors go away, there is a simple fix, you can simply do:
Me.WebBrowser0.Object.Silent = True
What this does is basically stop the script errors from being displayed. The errors are still there, you haven’t actually resolved whatever the actual problem is, but they aren’t being displayed anymore.
Obviously, ignoring the error may load the page (or may not if the script is part of the loading process), but does not garantee functionality. So the page may not work as intended since there are issues with the various scripts used by the webpage. This is why, IMHO, you are better with implementing the FEATURE_BROWSER_EMULATION registry hack.
HTML Template
Based on all of the above, if you control the HTML file being used, below would be the starting point I would use for build the HTML Page.
<!DOCTYPE html> <!-- saved from url=(0016)http://localhost --> <html> <head> <title>YourTitle</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" /> </head> <body> </body> </html>
Some might ask why I use
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
instead of the newer
<meta charset="utf-8">
because it is newer and by default the WebBrowser emulates older versions of IE (unless you override it). So to maximize compatibility and hopefully avoid issues I prefer to stick with the older form. Now if I was build a public site, I’d use the new HTML5 format.
Also, when the new WebBrowser control sees daylight, then it could be good practice to swicth as well.
Sample Database
Below you can download a sample database which illustrates most of what is covered in this article.
Disclaimer/Notes:
If you do not have Microsoft Access, simply download and install the freely available runtime version (this permits running MS Access databases, but not modifying their design):Microsoft Access 2010 Runtime
Microsoft Access 2013 Runtime
Microsoft Access 2016 Runtime
Microsoft 365 Access Runtime
In no event will Devhut.net or CARDA Consultants Inc. be liable to the client/end-user or any third party for any damages, including any lost profits, lost savings or other incidental, consequential or special damages arising out of the operation of or inability to operate the software which CARDA Consultants Inc. has provided, even if CARDA Consultants Inc. has been advised of the possibility of such damages.
Download a Demo Database
Feel free to download a 100% unlocked copy by using the link provided below:
Download “Access - Playing With The WebBrowser Control” PlayingWithTheWebBrowserControl.zip – Downloaded 11743 times – 81.64 KBResources on the Subject
Documentation on the Subject
- UtterAccess – Access and the web HTML Object Library
- MSDN – Internet Feature Controls (section on FEATURE_BROWSER_EMULATION)
- WebBrowserControl object (Access)
- IWebBrowser2::ExecWB Method
- execCommand method
- execCommand Method
Demos and Examples to Learn From
The best thing to learn is to simply dive in and dissect demos and examples, so feel free to check out
Special Thanks
During exploration of this control, I’ve had several back and forths with fellow MVPs to get help and ideas. I’d like to thank them for their continued support. It is in part their knowledge and willingness to share that makes this article and demo databases possible. I hope I’m not overlooking anyone, but I’d like to thank, in no particular order:
- Gustav Brock
- Jack Leach
- Ben Clothier
- James Dettman
- Tom Wickerath
- Adrian Bell
Page History
| Date | Summary of Changes |
|---|---|
| 2019-10-18 | Initial Release |
| 2019-10-31 | Added the Executing Code on the Webpage section Added a ‘table of contents’ to the beginning of the page Added more information to the Feature Browser Emulation section |
| 2019-11-03 | Added the Where’s Intellisense? section |
| 2020-01-07 | Added the Opening a Blank Page and Simply Ignoring Script Errors sections |
| 2020-04-26 | Added the Refreshing the Webpage section Added explanations to the Dynamic Content on the Fly section regarding relative/absolute paths |
| 2020-11-07 | Added Hexadecimal values to the Feature Browser Emulation table Added Demos and Examples to Learn From section to Other Resources |
| 2021-10-07 | Added the Feature Browser Emulation – Alternative section |
| 2022-03-18 | Updated the Emulation value for Edge based on comments and testing. |
| 2022-05-29 | Added the Working with Local Resources section. |
| 2022-09-01 | Added the Printing the Webpage section. |
| 2022-09-01 | Added the HTML Template section. |
| 2022-09-20 | Added the Retrieving Information From The WebPage section. |
| 2022-09-22 | Added a link to the new supporting YouTube video Added the Sample Database section. |
| 2022-09-22 | Added the Saving the Webpage section. Added the Corresponding JS navigator.userAgent column to the Feature Browser Emulation table. |
| 2022-12-05 | Added the Retrieving the Current Page’s URL section. |
Hello Daniel,
I tried to use the web browser emulation with the HKEY_CURRENT_USER trick and it worked fine on my personally owned laptop but NOT on the laptop issued by my company. Both are using Win 10 and Access 365.
I was thinking HKEY_CURRENT_USER would work alone since no admin rights are needed. Is there another set-up that I should do? Is it because I’m logged in to a network domain that the emulation doesn’t work?
Thanks!
Lou
I can’t say what is going on. Perhaps your domain overrides these settings for some reason.
Hi Daniel – excellent excellent work as ever
Just a thought on your Dynamic creation of web forms – have you considered writing a database that links to SQL Azure db and then dynamically creates a simple WEB CRUD form from selected fields which can be selected through Access – using a bootstrap theme.
undoubtedly some security issues but I think you could probably do it!!!
Its something I have considered giving a go but not quite as advanced as yourself.
M
It is most certainly possible and I had thought of it, BUT I already create proper Web based Web Applications and thus I don’t see it as a smart investment of my time presently.
For me, if I want a web based CRUD application I will simply create it using the proper web technologies, and not Access.
Also, don’t forget you can simply link to Azure tables directly and use standard Access forms, queries, reports, … so going through a webbrowser control is simply not necessary.
But, I too had thought of it at one point in time.
Its kind of interesting using Access as a kind of meta platform for other stuff.
Its like SSMS on steroids.
pps
Probably not needed by you but I bet your readership would be very interested and might introduce them to web programming.
Keep in mind it is an MS product. Built in the ’90’s. (anyone got a mix tape I can borrow LOL)
Like so many MS products, the idea was great, but implementation falls short.
When I have to deal with MS Access, I try to keep in mind, “we are supposed to only think INSIDE the box”.
There has been so many times in the past that I have hung Access without even touching the keyboard. No code, just using menus. LOL
I would like to thank you very much for taking the time to do the research and write this article. It is extremely useful for me at the moment. MS Access falls short (in many ways) of being able to format a ‘page’ or ‘report’ the way I want and this HTML allows me to do what Access fails at so badly for my purpose.
By the way, the project is not big enough to bother with the install and maintenance of a web server. But HTML can format the data in a nice and well structured manor.
Again, thank you for your research and this write-up.
Thanks Mark.
whatsmybrowser reported my system as IE11 even with none of the mentioned keys.
However screen size, browser size, color depth etc were not shown and one site telstra.com did not render correctly .
After adding the user key whatsmybrowser shows the sizes and telstra.com renders correctly.
Thank you or this article; very helpful.
I have noticed that when I open an MS Access form with an embedded webbrowsercontrol, the system’s memory usage grows dramatically (approx 100MB each time I open the form). What’s more, the memory is not released when you close the form. The only way to clear the memory is to exit the application.
I cannot find a VBA equivalent of Garbage Collection and can find no alternative. Have you any experience of this?
I do not believe it is possible.
Hi Daniel,
really great page. I got tripped up when I copied your code from “Dynamic Content on the Fly”
.write “Some content.”
Took me ages to work out why VBA didn’t like it – your double quotes are the slanted type (66 99) rather than the normal ones. Once I had changed them it now parses ok.
.Write “Some content.”
I see that in publishing my comment the HTML (html, head, body and p) I copied from above has been interpreted and the double quotes changed to the slanted type. I hope you understand what I was trying to say, if not I’m happy to clarify via email.
I’m hoping this helps towards solving my issue I have been having where first time in I need to assign inner html 2 or 3 times before the web control shows what I want it to (Is form load the wrong place to do this?) but subsequent assignments then work ok. I have been using the loop from “Working With the WebPage” to check status, first time in it seems to stick at 3 (I have waited minutes for it to change)
Great, all now works ok with this change.
Happy for you to reject my comments, but preferably (for other peoples sakes) fix the double quotes in the sample code.
Also noticed, in the same section, .write Me.HTMLFieldName the w in Write is not capitalised (as if it has not parsed in Access)
Not rejecting anything. It’s the weekend and I usually don’t deal with work and try to concentrate on family time as much as possible. This blog is a work of love, not a job. When I have time I contribute. It can go days, weeks without me logging in.
That all said, thank you for flagging the issue. Not too sure how this happened as I usually copy the code directly from the VBA editor into the blog’s text editor? That said, the minute you copy/paste it into VBA the erred quote get flagged in red and the code doesn’t compile.
As for capitalization, this does occurs if Intellisense isn’t enabled which could have been the case during my development, and/or it also does act funny at times (I have dbs in which many variables get capitalized for no reason, or vice versa) which has been reported to MS in the past but nothing ever came of it. Luckily, unlike many other languages, the Case of the code has no impact on its functionality, so it is merely a visual thing, nothing to worry about.
Have you had any issues with “loosing” the Class Object to the Form? I have created a simple form, added the web browser control to display pdf files. When i edit the form, the Class Object Form_(form name) disappears, MS access prompts to override the (form name) to save. When I give it (form name1) it saves (form name1) but the original form does not have any Class Objects associated with it.
Great reference, Daniel. Thanks!
That “bogus” value could simply be 0 (zero) – a little neater than 1234 which might look as some magic number.
Bonus tip:
After setting MSACCESS.EXE to your preferred value, do check the setting for OUTLOOK.EXE. Adjusting that will probably make most of your received e-mail newsletters render as intended.
Thank you for the tip and idea regarding the ‘bogus’ value. You are correct using 0 would most probably be best.
Can I assign Microsoft Web Browser Control to Selenium Web Driver?
The tips you gave above were really helpful to me, thanks a lot.
After hours of research through the internet, I didn’t find any direct solution to “route” a DOM element event to a Sub or Function in VBA, for example, to know when a button has been clicked in the HTML document.
I was able to work around it by using this simple lines of code:
Private Sub WebBrowser0_Click()
On Error Resume Next
Dim e As IHTMLElement
Set e = hdoc.activeElement
If Not (e Is Nothing) Then
If e.getAttribute(“type”) = “button” Then
Exec (e.getAttribute(“id”))
End If
End If
End Sub
Private Sub Exec(str As String)
Text4.value = “Button with ID:” & str & ” was clicked!”
End Sub
I hope it may be useful for anyone out there.
I just found out one more interesting thing to get rid of the script errors and get your html/css/js properly rendered in the WebBrowser object. I followed the steps mentioned above to set the FEATURE_BROWSER_EMULATION to the last version (Microsoft Edge 87. on my case) and tried to use the UIKit web framework (https://getuikit.com) on my application, and (as expected) besides not rendering the controls correctly it started triggering script error notifications due to the js of UIKit.
The solution was to explicitly declare the tag , as show below:
Title
…
All controls are now rendering correctly and not a single script errors is being shown anymore.
You’ll find more info at: https://stackoverflow.com/questions/6771258/what-does-meta-http-equiv-x-ua-compatible-content-ie-edge-do
If you read through my post, this is all discussed.
For some reason when assign the control source to the web browser and it has unicode characters it replaces them with ?.
I ran the code in debug mode and the variable has the unicode characters. Any ideas?
B?nkformarev?gen 7,V?rnamo,Sweden,331 91
Here is my actual variable:
=”https://www.bing.com/maps/default.aspx?where1=Bänkformarevägen%207,Värnamo,Sweden,331%2091&sty=c”
Thanks a lot for sharing all these experiences!
It helped me quite a bit. I wonder why MS does not provide any useful documentation.
I use the webbrowser control in VBA Excel. However, it seems to be somewhat different.
In Excel it seems not possible to use commands with the word “Object” like in “Me.WebBrowser0.Object.Document”. Shouldn`t it be similar to Access?
Thanks again!
The lack of standardization throughout Office & Office VBA is mind-numbing. The fact that MS couldn’t even standardize something like retrieve the current application’s Hwnd, set visibility, … is incomprehensible, but that is life.
Hi Daniel,
thanks a lot for this tutorial.
I open PDFs in this WebBrowserControl which is in a sub form and when I move the main form I load a new path into the control source. That works fine.
Now I look for a possibility to mark text in that WebBrowserControl after it loads.
Do you know if that is possible? I searched a lot in internet but could not find a solution for MSAccess.
Thank You and Best Regards
Michael
For Feature Browser Emulation, don’t forget the following key.
HKEY_USERS\\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
During troubleshooting of an oracle plugin within microsoft, we found that as well.
For the Feature_Browser_Emulation i found the Hexkey 00002ee1 to accurately emulate the Edge 18 Version, and displaying way less Script Errors than a dummy Value, wich might just “fake” to be a Edge 18 Version.
I could not find a way to Emulate Chromium based Edge 79+ yet.
Thank you for your great article.
Main Source: https://stackoverflow.com/questions/31773359/add-new-microsoft-edge-to-web-browser-control
Fantastic information thank-you helped me out a lot!
Hi Daniel,
Thanks for this wonderful tutorial, I am actually interested in Dynamic Content on the Fly.
Unfortunately its not working in my file.
All I see is “Object variable or With block variable not set”
Can you please help?
Copied Code
Private Sub Form_Current()
With Me.MyWebBrowserControl.Object.Document
.Open ‘ << error appears on this line [Object variable or With block variable not set]
.Write " hello world! ”
.Close
End With
End Sub
System Detail
Office 2016 64 Bit
Windows 10 64 Bit
Not sure if it was needed but I already added Reference for “Microsoft HTML Object Library” anyway.
It depends on the event you use. For instance On Open is to early, you have to ensure the control exists and is fully loaded before you can manipulate it. It did work for me in the On Load and On Current events though. I tested in Access 2013 x32 and Access 2019 x64.
You’re using the ‘Web Browser Control’ and not the ‘Microsoft Web Browser’ ActiveX Control?
Also, no references are require for this to work.
Very helpful. I just wanted to let you know that I appreciate your effort here. 🙂
in MS Access form, web browser control …views pdf files ok – – except for 2 PCs and although their default is definitely the Foxit PDF reader like all the other PCs – for some reason their browser control always uses the Adobe Reader – and then the app crashes… am perplexed… any thoughts?
Dear Daniel, thanks for this excellent summary. As a long-time Access Developper, I use the WebBrowserControl heavily, mostly fed by HTML-Files I save in the Resource-Table (MSysResources) so I do not have the hassel with security settings.
What I would like to share is some troubles you can run into with the FEATURE_BROWSER_EMULATION: The Opera browser delivers a utility called browser_assistant.exe, which is installed by default and gracefully deletes ALL your entries in this key every time it is started. Users should be aware of that, and as you described, in your MSAccess-Program, it is too late to reset the value.
I wanted to ask you what you see for the future of the WebBrowserControl – MS is stating since 2016 that it discontinues Internet Explorer, but WebBrowserControl is in fact IE. Have you anything heard about plans in that direction?
From what I understand this will not impact the webbrowser control. Also note that according to the Access Roadmap Microsoft is working on a “New (Modern) Web Browser Control (to support Chromium Edge)”.
Hi Daniel,
I tried to make the webcontrol work for LOCAL FILES.
the webcontrol works beautifully for external webaddresses, but when I want to load a local file, like c:\temp\index.html > it won’t work! Do you know how to fix this?
Thx in advance.
You haven’t provided me any information to be able to offer any advice.
How have you loaded the local file? What is the HTML file’s content? Can you provided a sample on an online shared drive for me to look over?
Hi Daniel,
I wanted to get your example file working and also the QR-code: index.html file. This is a local file, which won’t load in the WebBrowser control.
When inspecting te page it only shows:
When using an online webpage everything works fine in the Webbrowsercontrol.
It seems Microsoft fixed the bug. It is suddenly working again now. Thx. anyway
Everything!? How about Zoom Level.
How can I get a WebBrowser to display at 50% (yeah, yeah, I know I can use the keyboard; but Ctrl + – (Minus) also wants to delete a record…. (that was a new discovery for me)
Ay-oup… here it is
PageZoom = 66
Me.WebBrowser4.Object.ExecWB OLECMDID_OPTICAL_ZOOM, _
OLECMDEXECOPT_DONTPROMPTUSER, _
CLng(PageZoom), vbNull
Hello,
first up, this is a great article and very helpful. However I still run into problems.
I’m currently building a webapp using Vue.js and now I’m trying to include it in my access project using the webbrowser control. Even though I changed the browser version using the emulation method, as well as adding a MOTW, I still get script error messages. I’ve tried setting the key value to 0, which resulted in Edge version 18, as well as the value 11000, which is IE11. Even on other websites that do not use frameworks, I still get script errors.
Do you know anything about that?
Best regards 🙂
Hello ,
i ‘ ve used webbrowser control a long time to view a local file in an access form. all of a sudden i can not see the file anymore, it stays blank. i did not change anything … what could be th reasin ?
Could be a new bug. Have you tried rolling back your installation to a prior build no?
Have you tried performing an Office Repair?
It appears that after setting ‘about:blank’ in the web browser control on Form.Open that it’s not possible to write on the fly HTML to the control. I suspect that the ‘about:blank’ isn’t a document and therefore can’t be manipulated.
Hi Daniel,
I don’t know if this might be an IE or Edge bug, or if it’s specific to the web browser control, but I haven’t been able to get SPAN tags to work with classes defined in a CSS style section in the HEAD. They work with inline style information, just not with a class name referenced in the style section.
Any ideas?
Thanks in advance,
Ian J.
Scratch this one. I’ve just found a couple of places in my css section where the brackets were wrong. Unfortunately when I started writing the css I was using a plain text format and couldn’t see that something was amiss. When I changed it to a .css extension and opened it in Notepad++ then the errors were more visible.
Hi
this is by far better than going to Microsoft site for knowledge on access webbrowser control.
looks like you have mastered it
i have a simple question
if a user enter a search box just words like “google” or “ping” etc.
how do i change search box string to search in user default engine?
thank you
Great post and your site in general.
I have needed to change from just displaying images on a form stored locally to on the web with via a URL. I have the images into webbroswer from URL, so no problem there. But I have to things that I am trying to find more information on but have not been successful.
1. I have a Webbroswer object for an image in a form. Some of the images are larger and other smaller than the window. When the image displays, it presents full size, so I need to scroll to see the whole thing. I need to make the whole image visible in the space available. I tried the image zoom described above and it works. But I don’t know the amount to zoom as I don’t know the image size ahead of time. Is there a way to either fit to the window or read the image size without saving locally?
2. I would like to be able to change the size of the Webbroswer window based on the number of images I need to display in the form. I can do this with image objects with .height, but I have not found out how to do it Webbroswer objects.
Any suggestions appreciated
Some of this is hard to answer without seeing the database, HTML …
For item 1. you can specify a width and height for images in HTML, so simply add those attributes as it will be resized automatically to fit the specified dimensions.
For item 2., I may be misunderstanding the question, but you should be able to re-dimension the control dynamically without issue. I did a very quick test and code like the following worked for me
Hi Daniel,
Second item first. The re-demensioning worked fine. I had two Web Browser controls next to each other and I did not hide the second one first.
Back to the first item. I have the image displaying directly with navigate. But I want to create a dynamic HTML to give me more flexibility. But when I tried to insert the HTLM as you showed above.
With Me.WebBrowser0.Object.Document
.Open
.Write “Some content.”
.Close
End With
I got an error on Open like Ozair asked about in May. I already loaded and image in the WebBrowser and waited for it to complete before I tried to write the HTML code to the same object. Is there a library that I need to load first to use it with ‘Microsoft Web Browser’ ActiveX for HTML support?
I manged to get it to work with the following
With Me.WebBrowser1
.Navigate “about:blank”
Do While .Object.Busy Or .Object.ReadyState 4
DoEvents
Loop
.Document.Open “text/html”
.Document.Write strHTMLtext
.Document.Close
End With
One of the things that was wrong was with the URL to the images. It contained a space. It works if you navigate directly, but does not work for HTML, you need to replace spaces with %20.
But one thing is that IE does a terrible job down scaling the images. Does not seem to be a fix for it. Edge is a bit better, but is is also not as good as Firefox for Chrome.
I tried all of the css settings that I could find and nothing made it better in IE, or the WebBrowser control. I was testing on standalone browsers to make sure the HTML/CSS worked fine before incorporating it into Access.
Thank you for sharing. When I have a moment, I will try to take a closer look at it all and perhaps make some updates to the article.
Thank you for this article !
For anyone having issues with the cursor flickering between “loading” (blue circle) and “normal” when moving the mouse inside a WebBrowserControl, I was able to fix it by setting the Screen.MousePointer property to anything other than 0 (see https://docs.microsoft.com/en-us/office/vba/api/access.screen.mousepointer).
The best approach would be to set it inside got/lostFocus events, like so:
Private Sub WebBrowser1_GotFocus()
Screen.MousePointer = 1
End Sub
Private Sub WebBrowser1_LostFocus()
Screen.MousePointer = 0
End Sub
Indigo, after searching the internet for a long time, your simple tip is what solved my similar issue with the mouse pointer flickering. Thank you!
I am doing something very simple with the web browser control.
It is in a form. The control source for the control is a text box.
You open a file picker window and what you select populates the text box that is the control source for the web browser control.
These files are pdf and are on a network drive
Has worked without issue for 2 years. Suddenly the process stopped working properly.
Some pdfs show in the browser control properly…and some give an error message of
‘There is a problem with Adobe Acrobat/Reader. If it is running please exit and try again(0:521)
I can find no pattern regarding the pdfs the open properly and those that do not.
Any thoughts
Hi Daniel,
thanks for you great post. Du you know how to play mp4 videos from the file system inside the webbroweser control. Each time when I try it a separate window playing the video pops up
Thank you
BR
Andreas
Have you tried
Refer to https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video
I wonder if the issue might be related to your emulation mode?
I am opening PDF files and I can seem to find a way to page down form Vba. We are doing data entry off of PDF’s and I am trying to get it so that after we enter the last value the PDF pages down on the on exit event of the last text box. I have tried using both the MS access option and the ActiveX one.
I have tried multiple different versions of
Me.WebBrowser3.Document.Window.ScrollTo(0, 200)
Me.WebBrowser3.Object.Document.parentwindow.Scroll 1000, 200
Me.WebBrowser3.Document.parentwindow.Scroll 0, 99999
but I can’t seem to figure it out. I also struck out using the Activex controls for Adobe.
I’d like to be able to set the default view of the web browser to “List” when using it to view local files.
Best!
Thank you for this. We had just about given up hope on this, as our calls to the Google Maps JavaScript API started returning “You are using a browser that is not supported”, but setting all three 3 registry keys with “12001” (2EE1) allows https://www.whatsmybrowser.org/ to identify the Web Browser Control as using Edge 18! Woot!
Google Maps JavaScript API now runs again! Thanks!
Please consider updating the article to include 12000/12001 (2EE0/2EE1) as valid Edge 18 values. 11000/11001 will not work for Google APIs anymore.
Although it was buried within the comments, I had almost given up until I found it on a *DIFFERENT* blog post. Once I found it worked, I came back here to day Thanks, and found that the answer was here also, buried under pages of comments…
Thank you for the comment. I’ve updated the article.
@Daniel, thank you for all this valuable info!
Can you please clarify in the text whether “Edge” applies to the original Microsoft Edge browser introduced with Windows 10, and/or also to the new Chromium based Edge browser that is current now?
The previous comment mentions “Edge 18”, but the current version of Chromium Edge is 99!
Just apply the hack and test for yourself as indicated by navigating to a site such as https://www.whatsmybrowser.org/.
By setting the emulation to 12001, 18001, …, you’ll see that the webbrowser control seems to always indicate Edge 18. Until we get a proper update or MS actually releases the new webbrowser control this seems to be the limit of how ‘up-to-date’ we can simulate things (using emulation to pretend we’re running a version released October 2018)!
Excellent article, and the tool would be very useful if it worked and was supported, but a really keen broken tool is not of much use.
I’m not sure what aspect doesn’t work for you, could you explain? Perhaps we can assist you in some fashion.
Hi Daniel. Have there been any updates on this? I’ve tried everything, and I still can’t get rid of the damn script errors. I tried the WB.Object.Silent command (in multiple places), disabling script debugging, the browser emulation hack, you name it. I still keep getting “Message from webpage. ERROR: Script error.” And it’s Google Ads’ script generating the error too (which works FINE in the actual browser). /js/adsbygoogle.js.
Is this a public page you can share so I can test on my end?
Hi Daniel. Thanks for this article and for keeping it up to date, otherwise there would be hardly any info to be found on this subject. In the lower row in the “Feature Browser Emulation”-table you list the decimal values 12001, 13000 etc., but the first hexadecimal value listed is 2ee0 which equals to 12000. So maybe you want to add 12000 to the decimal values, or remove 2ee0 from the hex values.
Thank you for catching that. I have updated the page to fix the issue.
Hi Daniel, thanks for this info. After updating to the latest W11 and Office versions, my WebBrowser control no longer displays Adobe PDFs within the control, and instead open them outside of the control in an Adobe window. Any thoughts on this? Is this related to IE11 no being supported anymore? Thanks!
Hi Daniel,
Thank you for the information (not only in this post but your others have helped me greatly). From the comments, I know I am not the only one having this issue. I created a form with the Wed Browser Control that opens a preview of documents so users can fill in fields about the documents. Around 1 out of 5 PDF’s randomly fail in recent Access versions with an Adobe PDF Document error of “There is a problem with Adobe Acrobat/Reader. If it is running, please exit and try again. (0: 104)”
OR “There is a problem with Adobe Acrobat/Reader. If it is running, please exit and try again. (0:521)”
OR “A running instance of Acrobat has caused an error. (no error code)”
I have tried four different scenarios where two of them work:
Access 2010 – 32 bit – Windows 10 – Only Acrobat Reader installed – Works
Access 2010 – 32 bit – Windows Server 2008 R2 -Both Acrobat Reader and Pro installed – Works
Access 2013 – 64 bit – Windows 10 – Only Acrobat Reader installed – Does NOT work
Access 2016 – 64 bit – Windows Server 2016 – Both Acrobat Reader and Pro installed – Does NOT work
All four of them list Internet Explorer 11 as their browser (even though I have tried the registry modification and while it updated to Edge 18, the issue remained on the 64 bit versions).
Any thoughts/suggestions would be greatly appreciated!
Hi Daniel,
Thanks for the comprehensive information.
I am trying to build a completely self contained Access DB without any dependencies on external files.
Is it possible to build the Control Source HTML on the fly and set it during the onLoad event?
I have been trying by building the HTML code as a text string and then setting the Control souce to that text string but thus far have not had any luck
Thanks
Sure, I do it all the time.
Look at https://www.devhut.net/everything-you-never-wanted-to-know-about-the-access-webbrowser-control/#Dynamic
Dim sHTML As StringsHTML = "Your HTML"
With Me.WebBrowser0.Object.Document
.Open
.Write sHTML
.Close
End With
Thanks Daniel,
I got hung up on making it the ControlSource
That worked like a charm.. Guess I should have paid closer attention during my inital read through.
Thank again
It’s all good. I’m just glad you got it sorted out and functional!
My maps don’t display anymore.
Windows 11, Current Office365.
I edited the registry key to 11001.
“You are using a browser that is not supported by the Google Maps JavaScript API. Please consider changing your browser.”
I set Edge to use IE mode.
What is missing?
Greetings Daniel,
As many have already stated, your efforts here are greatly appreciated. THANK YOU!
After a year of using the technics you’ve brilliantly explained above, I accidentally set a webbroswer controlsource to a local folder containing images stored by my database.
strFilePath = “D:\MyDatabase\Images”
Me!WebBrowse1.ControlSource = “='” & strFilePath & “‘”
I was pleasantly surprised that the browser displayed thumbnails of the images and provided similar file management functions as when using file explorer!
I think some commenters have mentioned using the webbrowsser control to work with the file system, but many casual readers, or those who don’t read comments, may miss out on this functionality.
Finally, I wonder if you or any other readers have any further insights into using this control to work with the file system. If you think this worthy enough to update your article, perhaps you would consider adding a few lines about it and a screenshot of the result.
Best Regards
I must admit I’ve never tried using it to work with the local file system. I’ve done it with other technologies, but never an Access Web Browser control. Thank you for sharing.
That was very helpful. Thank you so much for taking the time to do this!
Hello Daniel,
thanks for the great job you does, that help a lot.
I my Access database, i would like to read local html files in a web browser control. I have downloaded the demo base. I use WebBrowser_ContentFromLocalFile form , have modified the path in the vba code to my first page
(C:\Users\33646\Documents\Astro\Ressources\Devenir astrologue2-Aubier-frameset\Devenir astrologue2-Aubier-TOC.html)
and it works. This page is a Table of contents, with links to other pages of the document. I click to a link and the new page opens in IExplorer7 instead of on the access web control.
Could you help me ?
Thanks
Carlos
(PS: I am french . Please excuse my english)
Are you sure you’re not using the ‘new’ Modern Web Browser control, in which case you should carefully review: https://www.devhut.net/everything-you-never-wanted-to-know-about-the-access-modern-web-browser-control/
Good morning Daniel,
before going further, here are the Access tools & versions I am using.
Win11 to the last update
Access 2016
I have implemented the reg key to set the browser to IE 11
I have a set of HTML files on my PC used as help to some forms and controls. I use the native activeX web control to view the help file. It runs pretty well. Nevertheless, the font used by access web browser is for me too small and heavy, so I changed the CSS to: font Calibri, lighter.
The result is good on both IE and Firefox, but there is no change on access web browser.
It is like the CSS is not used. I have read most of your post but didn’t find a solution.
Could you help me?
Thanks a lot
Regards.
Carlos
I’m not a 100% sure, but I’d think you’d want to run a JS command once the page is fully loaded, such as:
If you have styles defined and need to overrule them, then you might need to do something more like:
var allElements = document.querySelectorAll('*'); for (var i = 0; i < allElements.length; i++) { allElements[i].style.fontFamily = ''; } document.body.style.fontFamily = 'Calibri, sans-serif';or you could also try injecting the following CSS:
* { font-family: Calibri !important; }via JS it might look a little like:
var style = document.createElement('style'); style.type = 'text/css'; var css = '* { font-family: Calibri !important; }'; if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } document.getElementsByTagName('head')[0].appendChild(style);That said, why not simply update the HTML files themselves?
Hi Daniel,
I will have a try on each, and give you my results.
Thanks
Carlos
HI Daniel,
I solved the font issue, injecting the CSS change on the right place.
Thanks
Carlos
Wow, flicker solved!!
Thank you for this.
Glad it helped.