Access: nuevo control navegador web EdgeBrowser o Modern browser. Esperar carga de página al ejecutar javascript

El nuevo control de navegador de internet que Microsoft ha incluido en Access actualiza el anterior y está basado en Edge. Incorpora un par de métodos muy útiles e interesantes para interactuar con su contenido mediante VBA que son ExecuteJavascript y RetrieveJavascriptValue (parece un control derivado y limitado respecto al WebView2 en Visual Studio).

Nuevo control navegador Edge en Access
Explorador de objetos de MS Access

Existe bastante información en internet, por ejemplo, muy completa en https://www.devhut.net/everything-you-never-wanted-to-know-about-the-access-modern-web-browser-control/.

Sin embargo los métodos para ejecutar Javascript (ExecuteJavascript) en el navegador y poder disponer en Access de resultados del navegador (RetrieveJavascriptValue) tienen alguna peculiaridad relacionada con la ejecución asíncrona y la carga o actualización de la página web del navegador en el momento que se están automatizando tareas desde Access. En particular con la espera a que cargue la página para que los resultados al ejecutar Javascript u obtener valores sea el esperado.

No es tan sencillo como con el control anterior usando las propiedades Busy y ReadyState del control, pues la primera no existe y la segunda no se comporta como se espera. Hace falta además usar el evento DocumentComplete.

El problema que ocurre es que cuando se trata de automatizar una navegación web desde Access con VBA, por ejemplo pulsando clicks (ExecuteJavascript) y una vez que se ejecuta ese click obtener ciertos resultados (RetrieveJavascriptValue), resulta que puede ocurrir (y ocurre) que la instrucción RetrieveJavascriptValue se ejecuta antes de que la web se haya actualizado y no se obtienen los resultados esperados. No basta en este caso con usar una espera basada en la propiedad ReadyState, no funciona…

Un ejemplo de caso práctico podría ser una web de este estilo, tipo tabla con diferentes botones o enlaces, que al pulsarlos abren otra página o bien cargan algo en la página. Se trata de automatizar los clicks y obtener ciertos valores deseados una vez se haya ejecutado la acción de cada click (por ejemplo obtener todo el contenido html que se haya generado al hacer click y tratarlo de alguna manera)

Ejemplo de una web para la que usamos un control EdgeBrowser para automatizar los clicks y obtener resultados

Un posible código que uno esperaría que funcionase sería el siguiente (pero no funciona):

'EdgeBrowser es el nombre del control navegador
Dim js As String
Dim contenidoHtml as String
 
For i=1 To 4
    js="document.getElementById('click_" & i & "').click();"
    EdgeBrowser.ExecuteJavascript js
    'esperar a que el navegador acabe
    Do While EdgeBrowser.ReadyState <> 4
        DoEvents
    Loop
    'obtener todo el Html para hacer algo
    contenidoHtml = EdgeBrowser.RetrieveJavascriptValue("document.getElementsByTagName('html')[0].outerHTML")
    ' usar contenidoHtml....
Next i

Pero no va a funcionar como uno espera, pues de esa manera no se espera a que se complete el Javascript ejecutado y lo que obtendremos con RetrieveJavascriptValue no es lo que queremos.

Solución

Tras muchas, muchas pruebas, parece que lo que hay que usar es el evento DocumentComplete del navegador y esperar a que este evento se produzca para poder asegurarse de que el Javascript que hemos pedido que se ejecute ha finalizado. Por ello una posible forma es mediante el uso de una variable global (de tipo boolean) que indicará si este evento del navegador se ha producido o no. Por tanto el código anterior modificado para que funcione sería el siguiente:

Option Compare Database
Dim gContinue As Boolean
 

'EdgeBrowser es el nombre del control navegador Dim js As String Dim contenidoHtml as String   For i=1 To 4 js="document.getElementById('click_" & i & "').click();" gContinue = False EdgeBrowser.ExecuteJavascript js 'esperar a que el navegador nos diga que ha completado Do While gContinue = False DoEvents Loop 'obtener todo el Html para hacer algo contenidoHtml = EdgeBrowser.RetrieveJavascriptValue("document.getElementsByTagName('html')[0].outerHTML") ' usar contenidoHtml.... Next i
Private Sub EdgeBrowser_DocumentComplete(url As Variant)   ' actualizar el valor de la variable global para que las esperas finalicen gContinue = True   End Sub

De esa manera sí nos aseguramos que lo que la web hace al pulsar el click se ha ejecutado y entonces podemos obtener ya lo que queramos. Por tanto cada vez que queramos ejecutar Javascript en el navegador con ExecuteJavascript tendremos que inicializar la variable global de espera a False y hacer una espera hasta que sea True (puede simplificarse creando alguna función o rutina para ello)

Nota sobre el evento Navigate y la espera a que el navegador acabe

La verdad es que la documentación de este nuevo control no es muy detallada. En las pruebas que he realizado resulta que para el evento Navigate del control navegador, que se usa para navegar a una dirección determinada, la espera a que el navegador complete la carga sí hay que hacerla con la propiedad ReadyState para evitar comportamientos erráticos.

Por ejemplo:

url = "https://abrazalaweb.net"
EdgeBrowser.Navigate url
' esperar al navegador
Do While EdgeBrowser.ReadyState <> 4
    DoEvents
Loop

3 Comments

  1. Fernando Uribe Jaramillo · viernes, 29 diciembre, 2023 Reply

    Cuando se navega en la página de PowerBi mediante el navegador (Me.EdgeBrowser0.Navigate «https://app.powerbi.com») Sale el siguiente error:

    «No tiene permisos de acceso para ver esta página.
    DETALLES TÉCNICOS
    Power BI no ha podido leer los metadatos de la aplicación. Compruebe el estado del servicio Power BI en la página de soporte técnico siguiente y vuelva a intentarlo más tarde.
    Fecha y hora: 2023-12-23 19:57:47Z
    Id. de la actividad: 8f4a0d2d-51da-44e7-b126-f90fc4c1a0e8
    Id. de la solicitud: 97f89348-ae92-4b57-8ec1-6d88dac8d42a»

    Licencias utilizadas:
    . Microsoft 365 Familia
    . Power BI PRO (Pagada para un usuario).
    SQL Server 2019 Express (la versión gratuita)
    . Computador: ASUS ZenBook 13, RAM 16 GB.
    Sistema operativo: Windows 10 Pro, 64 Bits, Versión 22H2

Leave a Reply

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.