He creado una macro destinada a recorrer los tickers de acciones y en una columna y utilizar una consulta web para extraer datos sobre esos tickers de acciones de Yahoo Finance.
Funciona bien para 10, 15, 20 consultas web, pero sin fallas sobresale en algún momento de las primeras 20 o 30 consultas web.
Seré el primero en decir que soy un aficionado extremo en el código VBA, pero probé algunas cosas para solucionar este problema (borrar el caché, usar pausas) y no parecieron funcionar.
No falla en el mismo elemento cada vez, pero siempre tiene el texto "conectándose a la web" en la barra de estado, así que siento que tiene algo que ver con el tiempo de espera de la conexión, pero no estoy seguro de cómo. atacarlo en este punto. Cualquier idea será bienvenida, así como cualquier optimización de código que me pueda faltar... ¡gracias!
Sub GetData()
Application.Calculation = xlManual
' make the website a variable
Dim sURL As String
Dim Ticker As String
Dim iRow As Integer
Dim iCol As Integer
Dim wqError As ErrObject
' create web query if it doesn't exist
If Worksheets("query").QueryTables.Count = 0 Then
With Worksheets("query").QueryTables.Add(Connection:="URL;", Destination:=Range("Query!A1"))
.Name = "market_data.asp"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlSpecifiedTables
.WebFormatting = xlWebFormattingNone
.WebTables = "4"
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
End With
End If
iRow = 2
iCol = 2
'Loop through Tickers
Do While Worksheets("Data").Range("A" & iRow).Value <> ""
Ticker = Worksheets("Data").Range("A" & iRow).Value
sURL = "http://finance.yahoo.com/q?s=" & Ticker
With Worksheets("query")
.Cells.Clear
.QueryTables(1).Connection = "URL;" & sURL
On Error Resume Next
.QueryTables(1).Refresh BackgroundQuery:=False
Set wqError = Err
On Error GoTo 0
If wqError.Number = 0 Then 'No error
.Range("B1").Copy Worksheets("Data").Cells(iRow, iCol)
.Range("B5").Copy Worksheets("Data").Cells(iRow, iCol + 1)
.Range("B13:B14").Copy Worksheets("Data").Cells(iRow, iCol + 2)
.Range("B18").Copy Worksheets("Data").Cells(iRow, iCol + 4)
.Range("B15").Copy Worksheets("Data").Cells(iRow, iCol + 5)
.Range("B22").Copy Worksheets("Data").Cells(iRow, iCol + 6)
.Range("B16").Copy Worksheets("Data").Cells(iRow, iCol + 7)
.Range("B20").Copy Worksheets("Data").Cells(iRow, iCol + 8)
.Range("B19").Copy Worksheets("Data").Cells(iRow, iCol + 9)
.Range("B25").Copy Worksheets("Data").Cells(iRow, iCol + 10)
.Range("B24").Copy Worksheets("Data").Cells(iRow, iCol + 11)
ElseIf wqError.Number <> 1004 Then
'Report error because it isn't the expected error 1004 Web query returned no data
MsgBox "Web query refresh for " & String(2, vbCrLf) & sURL & String(2, vbCrLf) & " returned error number " & wqError.Number & String(2, vbCrLf) & wqError.Description
End If
End With
iRow = iRow + 1
If iRow Mod 5 = 0 Then Delete_IE_Cache
If iRow Mod 20 = 0 Then ActiveWorkbook.Save
If iRow Mod 20 = 0 Then Application.Wait (Now + TimeValue("0:00:03"))
Loop
'Format results
With Sheets("data")
Range("A:M").HorizontalAlignment = xlCenter
Range("A:A").NumberFormat = "Text"
Range("D:D").NumberFormat = "Text"
Range("I:I").NumberFormat = "Text"
Range("B:C").NumberFormat = "0.00"
Range("E:H").NumberFormat = "0.00"
Range("K:M").NumberFormat = "0.00"
End With
Application.Calculation = xlCalculationAutomatic
End Sub
Respuesta1
No veo ningún código para esperar a que la página termine de cargarse... Puede que no sea necesario, pero no estaría de más poner esto en la parte superior de su módulo y luego llamarlo después de navegar al sitio web+stockticker .
Private Declare Sub AppSleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)
Public Sub PauseApp(PauseInSeconds As Long)
Call AppSleep(PauseInSeconds)
End Sub
Luego en tu código,
sURL = "http://finance.yahoo.com/q?s=" & Ticker
Call sleepie(sURL)
Como dije, puede que no resuelva su problema en absoluto, pero definitivamente ayudará.