问题
In Excel 2003 VBA, I'm trying to browse to this web page...
https://www.google.com/finance?q=NYSE%3AWSO&fstype=ii&ei=cy30UrCEI8KKiALOPw
...and click these two tabs on it:
- "Balance Sheet"
- "Annual Data"
Here's what the HTML for those tabs looks like:<a class=t><b class=t><b class=t>Balance Sheet</b></b></a>
and<a id=annual class="id-annual nac">Annual Data</a>
Finding Annual Data with getElementById, and clicking on it, worked fine.
But Balance Sheet has no ID. Using getElementByClass would be ambiguous with more than one element that has classname "t
". And there doesn't seem to be a getElementByInnerText or getElementByInnerHTML.
So I looped through all elements, looking for classname "t
", and then looking for innerText "Balance Sheet". I'm able to find the element (three of them, which I guess is expected given its structure), BUT clicking it has no effect (I tried clicking all three).
But when I tried that method with Annual Data, it worked fine.
What do I need to do to be able to click the "Balance Sheet" tab? I'm pretty sure I'm finding it; just not successfully clicking on it.
Here's my code:
Option Explicit
Sub TestMain()
Dim strURL As String
strURL = "https://www.google.com/finance?q=NYSE%3AWSO&fstype=ii&ei=cy30UrCEI8KKiALOPw"
Call Main(strURL)
End Sub
Function Main(url_string As String)
Dim oIE As Object, oDoc As Object, oElem As Object
Set oIE = CreateObject("InternetExplorer.Application")
oIE.Visible = True
oIE.Navigate url_string
Do While oIE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
Set oDoc = oIE.document
'Annual Data tab:
Set oElem = GetElementsByClassNameAndInnerText(oDoc, "id-annual", True, "Annual Data", False)
oElem.Click 'this works.
'Quarterly Data:
Set oElem = GetElementsByClassNameAndInnerText(oDoc, "id-interim", True, "Quarterly Data", False)
oElem.Click 'this works.
'Balance Sheet:
Set oElem = GetElementsByClassNameAndInnerText(oDoc, "t", False, "Balance Sheet", True)
oElem.Click 'does NOT work.
'Income Statement:
Set oElem = GetElementsByClassNameAndInnerText(oDoc, "t", False, "Income Statement", True)
oElem.Click 'does NOT work.
oIE.Quit
Set oIE = Nothing
End Function
Public Function GetElementsByClassNameAndInnerText(html_doc As Object, _
class_name As String, is_classname_partial As Boolean, _
inner_text As String, is_innertext_partial As Boolean) As Object
Dim oElem As Object
Dim bClassNameIsMatch As Boolean, bInnerTextIsMatch As Boolean
For Each oElem In html_doc.All
' Debug.Print oElem.GetAttribute("class"), oElem.innertext
bClassNameIsMatch = False 'init for each oElem.
If is_classname_partial Then
If InStr(oElem.GetAttribute("class"), class_name) > 0 Then
bClassNameIsMatch = True
End If
Else
'classname is exact:
If oElem.GetAttribute("class") = class_name Then
bClassNameIsMatch = True
End If
End If
If bClassNameIsMatch Then
bInnerTextIsMatch = False 'init for each oElem.
If is_innertext_partial Then
If InStr(oElem.innertext, inner_text) > 0 Then
bInnerTextIsMatch = True
End If
Else
'innertext is exact:
If oElem.innertext = inner_text Then
bInnerTextIsMatch = True
End If
End If
If bInnerTextIsMatch Then
If oElem.innertext = inner_text Then
Set GetElementsByClassNameAndInnerText = oElem
Exit For
End If
End If
End If
Next oElem
End Function
Thanks,
Greg
回答1:
I can't find a way to click those tabs programatically. The data, at least the tables so far, can be downloaded though as the tabs are only used to select which division is visable, all the data is on the page. In the following function the 6 divisions are copied into a file (could be cleaned up by writing a function to do this). IE is then redirected to this file.
If this is the sort of thing you are looking to do you might be better off looking at Microsofts HTML Object Library or XML in stead of IE and using get ot post to get the data.
I have used references to microsoft HTML object library, Microsoft internet controls and Microsoft scripting runtime for this function.
Function main(url_string As String)
Dim oIE As InternetExplorer
Dim oDivElement As HTMLDivElement
Dim fsoObject As Scripting.FileSystemObject
Dim FileHandle As Scripting.TextStream
Set oIE = CreateObject("InternetExplorer.Application")
oIE.Visible = True
oIE.navigate url_string
Do While oIE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
Set fsoObject = New FileSystemObject
Set FileHandle = fsoObject.CreateTextFile((ThisWorkbook.Path & "\Output.html"), True)
Set oDivElement = oIE.document.getElementById("incinterimdiv")
FileHandle.WriteLine ("Quarterly income")
FileHandle.WriteLine ("<BR> <BR>")
FileHandle.WriteLine (oDivElement.innerHTML)
Set oDivElement = oIE.document.getElementById("incannualdiv")
FileHandle.WriteLine ("<BR> <BR>")
FileHandle.WriteLine ("Annual income")
FileHandle.WriteLine ("<BR> <BR>")
FileHandle.WriteLine (oDivElement.innerHTML)
Set oDivElement = oIE.document.getElementById("balinterimdiv")
FileHandle.WriteLine ("<BR> <BR>")
FileHandle.WriteLine ("Quarterly balance")
FileHandle.WriteLine ("<BR> <BR>")
FileHandle.WriteLine (oDivElement.innerHTML)
Set oDivElement = oIE.document.getElementById("balannualdiv")
FileHandle.WriteLine ("<BR> <BR>")
FileHandle.WriteLine ("Annual balance")
FileHandle.WriteLine ("<BR> <BR>")
FileHandle.WriteLine (oDivElement.innerHTML)
Set oDivElement = oIE.document.getElementById("casinterimdiv")
FileHandle.WriteLine ("<BR> <BR>")
FileHandle.WriteLine ("Quarterly cash flow")
FileHandle.WriteLine ("<BR> <BR>")
FileHandle.WriteLine (oDivElement.innerHTML)
Set oDivElement = oIE.document.getElementById("casannualdiv")
FileHandle.WriteLine ("<BR> <BR>")
FileHandle.WriteLine ("Annual cash flow")
FileHandle.WriteLine ("<BR> <BR>")
FileHandle.WriteLine (oDivElement.innerHTML)
FileHandle.Close
Set FileHandle = Nothing
Set fsoObject = Nothing
Set oDivElement = Nothing
Set oIE = Nothing
End Function
回答2:
This does the trick for me. Step through the code after the web page has loaded to see what is happening.
Sub test()
URL = "https://www.google.com/finance?q=NYSE%3AWSO&fstype=ii&ei=cy30UrCEI8KKiALOPw"
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.navigate URL
Do Until (IE.readyState = 4 And Not IE.Busy)
DoEvents
Loop
' This will 1) "unclick" "the Income Statement" sheet tab and 2) "click" the "Balance Sheet" tab;
' the data below doesn't change, just the tab
IE.document.getElementbyID(":0").classname = "goog-tab"
IE.document.getElementbyID(":1").classname = "goog-tab goog-tab-selected"
' This will change the data below the tabs
IE.document.getElementbyID("incinterimdiv").setAttribute("Style") = "display: none;"
IE.document.getElementbyID("balinterimdiv").setAttribute("Style") = ""
IE.document.getElementbyID("balinterimdiv").setAttribute("Style") = "display: none;"
IE.document.getElementbyID("casinterimdiv").setAttribute("Style") = ""
IE.document.getElementbyID("incinterimdiv").setAttribute("Style") = ""
IE.document.getElementbyID("casinterimdiv").setAttribute("Style") = "display: none;"
End Sub
来源:https://stackoverflow.com/questions/21660096/excel-vba-and-html-dom-cant-click-tab