I have been automating the IE browser to conduct web scraping for many years across a number of sites.
I have recently come across a combobox that will only work properly after it has been manipulated by a human.
To clarify - if I automate the selection of the dropdown using code, the combobox value changes correctly. Or rather - it APPEARS to. But then the automation clicks the download button and the file that downloads is not the option that was selected in the combobox!
But if I pause the code at this point and I change the dropdown manually in the browser before letting the code continue, the download is the option that was selected.
My question is this:
How do I alter my combobox code so that the browser actions on the combobox are the same as what would have been sent if the combobox had had its dropdown changed manually?
(Or to put it another way - how can the function be written so that its automation will mimic a humans input on a combobox)
Relevant extract below:
Option Explicit
'Requirements:
' Reference Library = Microsoft Internet Controls
' DLL = SHDocVw (dll/COM Shell Document Viewer)
#If VBA7 And Win64 Then
' 64 bit Excel
Private Declare PtrSafe Sub Sleep _
Lib "Kernel32" ( _
ByVal dwMilliseconds As LongLong)
#Else
' 32 bit Excel
Private Declare Sub Sleep _
Lib "Kernel32" ( _
ByVal dwMilliseconds As Long)
#End If
Private mappIE As InternetExplorerMedium
Private mblnSilentFails As Boolean
Public Function fnblnActionInputComboBox_ByITextByID(ByVal strElmtId As String, ByVal strOptionInnerText As String) As Boolean
Dim objElement As Object
Dim blnResult As Boolean
Dim i As Long
Set objElement = pfnobjSetElementById(strElmtId, mblnSilentFails)
If objElement Is Nothing Then
GoTo ExitProcedure
End If
With objElement
If .Type <> "select-one" Then
'Call pDebugPrintElementNotFound("Type", "select-one (but matched on Id:=" & strElmtId & ")")
MsgBox "Element Id '" & strElmtId & " has Type '" & .Type & "' (Code was expecting 'select-one')", vbCritical
GoTo ExitProcedure
End If
If LenB(strOptionInnerText) Then
.Focus
For i = 0 To .Options.Length - 1
If InStr(1, .Options(i).innerText, strOptionInnerText, vbTextCompare) Then
strOptionInnerText = .Options(i).innerText
.Options(i).Focus
Sleep 20
.Options(i).Selected = True
Sleep 20
.Options(i).Click
Sleep 20
.Options(i).fireevent ("onchange")
.selectedIndex = i
Do Until .ReadyState = "complete"
Sleep 100
Loop
blnResult = True
Exit For
End If
Next i
End If
End With
ExitProcedure:
Set objElement = Nothing
fnblnActionInputComboBox_ByITextByID = blnResult
End Function
Private Function pfnobjSetElementById(ByVal strElmtId As String, ByVal blnBatchMode As Boolean) As Object
'/ this function is to deal with a known bug in IEs use of GetElementById
Dim objElement As Object
Dim strMsg As String
Dim blnSuccess As Boolean
On Error Resume Next
Set objElement = mappIE.Document.GetElementById(strElmtId)
On Error GoTo 0
If objElement Is Nothing Then
'If Not blnBatchMode Then
'Call pDebugPrintElementNotFound("Id", strElmtId)
'End If
ElseIf objElement.ID = strElmtId Then
blnSuccess = True
Set pfnobjSetElementById = objElement
Else
With objElement
strMsg = "Known IE bug found. Element '" & .ID & "' only matches the required Id ('" & strElmtId & "') on its Value! ('" & .Value & "')"
End With
End If
If LenB(strMsg) Then
If blnBatchMode Then
Debug.Print strMsg
Else
MsgBox strMsg
End If
End If
ExitProcedure:
' scrap object
If Not TypeName(objElement) = "Nothing" Then
Set objElement = Nothing
End If
End Function
I am unable to provide the website or the HTML code. In any case, I want this function to be generic enough so that I can apply it to any html combobox and it will work.
Bookmarks