Hola a todos y gracias de antemano.
Estoy intentando descargar una tabla a excel de la página mismarcadores.com.
He conseguido una macro por internet. El problema es que la etiqueta html de la tabla no tiene ID, y siempre que ejecuto la macro salta el siguiente error:
Se ha producido el error 438 en tiempo de ejecución: El objeto no admite esta propiedad o método
La macro que ejecuto es la siguiente:
Sub importartblhtml()
Dim appIE As Object
Dim allRowOfData As Object
Dim curHTMLRow As Object
Dim Fila As Long, Col As Long
Dim Celda As Object
Set appIE = CreateObject("internetexplorer.application")
With appIE
.Visible = True
.navigate "https://www.mismarcadores.com/futbol/espana/laliga/partidos/"
While .Busy = True Or .readyState < 4: DoEvents: Wend
ThisWorkbook.Sheets("Hoja1").Activate
Cells.Select
Selection.ClearContents 'limpiamos contenidos
Set allRowOfData = appIE.document.getElementsById("fs-fixtures")
For Fila = 1 To allRowOfData.Rows.Length - 1
Set curHTMLRow = allRowOfData.Rows(Fila)
For Col = 0 To curHTMLRow.Cells.Length - 1
Set Celda = Sheets("Hoja1").Cells(Fila + 1, Col + 1)
Celda.Value = "'" & curHTMLRow.Cells(Col).innerText
Next Col
Next Fila
.Quit
End With
Set appIE = Nothing
Set curHTMLRow = Nothing
Set Celda = Nothing
End Sub
El error salta al ejecutarse la línea Set allRowOfData = appIE.document.getElementsById("")
He probado con el método getElementsByTag("table")(0) y tampo funciona. Importa toda la página excepto lo que quiero, que son los partidos.
No he encontrado mucha información por internet hacerca de como solucionar el error.
El código html de donde quiero sacar los datos es el siguiente
Alguien sabe si me falta activar alguna referencia o algún otro método para poder descargar esta tabla??
Gracias.
Saludos.
Prueba a sustituir "getElementsById" por "getElementById"
Parece que te sobra una s. Ten en cuenta que en HTML solo puede haber un elemento con una ID en una página, de ahí el singular. En el resto de opciones (class, tag, etc.) puede haber todos los elementos que quieras.
Lo que pasa es que después seguirás teniendo problemas.
Tu segundo problema es que el objeto allRowOfData, tal como lo tienes definido, es un <div>. Por eso no tiene propiedad rows. Lo que tienes que hacer es seleccionar el child del objeto que tenemos identificado con un <id>, que sí que es un objeto tabla, y eso lo hacemos así:
Hola Cron.
Muchas gracias por tu respuesta, funciona perfectamente.
Siento haber tardado en contestar, pero estaba trabajando.
No quisisera abusar, pero al final de la tabla, hay un link que sirve para mostrar más partidos.
Sabrias como activarlo mediante vba??
yo he encontrado este código
Do Until link = "Mostrar más partidos"
i = i + 1
p = appIE.Document.Links(i).tostring
link = Right(p, 20)
Loop
appIE.Document.Links(i).Click
y algún otro parecido, pero no consigo hacerlo funcionar.
Gracias.
Saludos.
Por cómo funciona, deberías hacer click siempre que aparezca "Mostrar más partidos" antes de empezar el volcado de la tabla. El código sería algo así como:
flag = false
Do while flag = false
For Each allRowOfData In .document.getElementsByTagName("a")
If allRowOfData.outertext = "Mostrar más partidos" Then
allRowOfData.Click
flag = false
Exit For
else
flag = true
End If
Next
Loop
He utilizado allRowOfData como variable porque ya estaba declarada como object, por pura vagancia.
Este código se ejecuta una y otra vez hasta que recorre toda la hoja y no encuentra ningún link que diga "Mostrar más partidos". Como cada vez que hace click tarda en cargar, le falta la línea de while appIE.busy bla bla bla. Yo la pondría justo detrás del Do while.
Un saludo
Gracias Cron.
El problema es que el código no reconoce cuando ese link está oculto, y sigue activandolo aun cuando la tabla de los partidos está completa.
Seguire investigando como solucionar eso.
Muchas gracias.
Qué interesante!!
Si miras el código de la página web, verás que el link <a> está dentro de una tabla (un <td> dentro de un <tr> que, a su vez, está dentro de un <table>.
Para hacer que el enlace se muestre o no, simplemente le añaden al código del objeto <table> un código CSS inline así:
style:"display: none;"
Lo que tenemos que hacer es localizar esta tabla (igual que la tabla anterior, esta también tiene una id (tournament-page-fixtures-more), por lo que definiremos dos variables tipo objeto, una para el link y la otra para la tabla exterior. Además, he comprobado que al darle al link lo que produce es una actualización javascript, por lo que no genera un cambio de estado ni en la propiedad busy ni en la propiedad readyState del objeto appIE, por lo que tenemos que hacer una ñapa y decirle a Excel que espere 5 segundos antes de volver a hacer click. Finalmente, el código puede quedar así:
Sub importartblhtml()
Dim appIE As Object
Dim allRowOfData As Object
Dim curHTMLRow As Object
Dim Fila As Long, Col As Long
Dim Celda As Object
Dim flag As Boolean
Set appIE = CreateObject("internetexplorer.application")
Dim link As Object
Dim parentLink As Object
With appIE
.Visible = True
.navigate "https://www.mismarcadores.com/futbol/espana/laliga/partidos/"
While .Busy = True Or .readyState < 4: DoEvents: Wend
ThisWorkbook.Sheets("Hoja1").Activate
Cells.Select
Selection.ClearContents 'limpiamos contenidos
flag = False
Do While flag = False
Set parentLink = appIE.document.getElementById("tournament-page-fixtures-more") 'la tabla que contiene el enlace
If InStr(parentLink.outerhtml, "display: none;") = 0 Then 'Si no encuentra display: none;
For Each link In .document.getElementsByTagName("a") 'Vuelvo a recorrer todos los links. Se podía hacer buscando el lastchild de parentLink, y seguramente sería mejor solución.
If (link.outertext = "Mostrar más partidos") Then
Application.Wait (Now + TimeValue("0:00:05"))
link.Click
flag = False
Exit For
Else
flag = True 'En caso de que no exista el link
End If
Next
Else
flag = True 'En caso de que el link exista, pero dentro de una tabla con style:"display: none;"
End If
Loop
Set allRowOfData = appIE.document.getElementById("fs-fixtures").LastChild
For Fila = 1 To allRowOfData.Rows.Length - 1
Set curHTMLRow = allRowOfData.Rows(Fila)
For Col = 0 To curHTMLRow.Cells.Length - 1
Set Celda = Sheets("Hoja1").Cells(Fila + 1, Col + 1)
Celda.Value = "'" & curHTMLRow.Cells(Col).innerText
Next Col
Next Fila
.Quit
End With
Set appIE = Nothing
Set curHTMLRow = Nothing
Set Celda = Nothing
End Sub
Un saludo