Автоматизируйте IE через Excel, чтобы заполнить раскрывающийся список и продолжить - PullRequest
2 голосов
/ 07 августа 2020

По общему признанию, все еще новичок ie с автоматизацией IE через Excel, но был бы признателен за любую помощь, которую может предложить с этим. По сути, это открывает веб-страницу, выбирает кнопку, заполняет 2 раскрывающихся списка, вводит значение и затем нажимает другую кнопку, чтобы отобразить то, что мне нужно. У меня есть эта работа с использованием SendKeys с кучей {Tabs}, {`}, {Down} и т. Д. c, но это довольно неуклюже. Я бы предпочел сделать это правильно, но я могу добраться только до первого раскрывающегося списка, выбрать нужное значение, а затем он остановится. Я думаю, что мне не хватает того, что я говорю IE принять то, что я ввел, и продолжить. Кодировка ниже. Комментарии включены, чтобы показать, что он делает и где останавливается.

Dim WebIDStr As String: WebIDStr = "CD00003630"
Dim IE As Object
WebNavStr = "https://a810-dobnow.nyc.gov/Publish/#!/"
On Error Resume Next
Set IE = Nothing
Set IE = CreateObject("InternetExplorer.Application")
With IE
    .Visible = True
    .navigate WebNavStr
    Do Until .readyState = 4: DoEvents: Loop
End With
' Won't work without a delay??
Application.Wait (Now + TimeValue("00:00:03"))
IE.document.getElementsByClassName("white ng-scope")(3).Click
' the next command works and fills-in the dropdown with the value
' that I need but then locks up. Can't move on from here.
IE.document.getElementById("DeviceOptions").selectedIndex = 4
' GOOD to HERE. Tried the next 2 lines but they don't do anything, unfortunately
IE.document.getElementById("DeviceOptions").Focus
IE.document.getElementById("DeviceOptions").Click
' This is where I need to get to. Next Dropdown Value = 1
IE.document.getElementById("craneDeviceOption").selectedIndex = 1
' Once 2nd dropdown selected, fill in "DevCraneID" box
IE.document.getElementById("DevCraneID").Value = WebIDStr
' Press the "Select" button
IE.document.getElementById("Search4")(0).Click
' IE.Quit
' Set IE = Nothing

1 Ответ

4 голосов
/ 07 августа 2020

Хорошо, поскольку вы написали, что хотите понять, как это работает, я подробно прокомментировал весь код.

Это рабочий код:

Sub DeviceSearch()

  'Define constants
  Const url As String = "https://a810-dobnow.nyc.gov/Publish/#!/"
  
  'Declare variables
  Dim ie As Object
  Dim htmlDoc As Object
  Dim nodeDeviceTypeDropdown As Object
  Dim nodeCraneDeviceDropdown As Object
  Dim nodeCraneDeviceID As Object
  
  Dim searchTerm As String
  
  'Initialize variables
  searchTerm = "CD00003630" 'craneID
  
  'Initialize Internet Explorer, set visibility,
  'call URL and wait until page is fully loaded
  Set ie = CreateObject("InternetExplorer.Application")
  ie.Visible = True
  ie.navigate url
  Do Until ie.readyState = 4: DoEvents: Loop
  'Wait to load dynamic content after IE reports it's ready
  Application.Wait (Now + TimeSerial(0, 0, 3))
  'Shorten html document string for lazy coders ;-)
  'Seriously: You can of course also use "With ie.document"
  Set htmlDoc = ie.document
  
  'Open the Device Search section
  htmlDoc.getElementsByClassName("white ng-scope")(3).Click
  
  'Try to get the first dropdown.
  'Never use "On Error Resume Next" for the whole code.
  'We use it here because if an html id can't be found
  'a runtime error occours. But after the critical part
  'we switch the error detection back on with "On Error GoTo 0"
  '(I use this here only to show you what to do if not sure if
  'you can get an element by id. In this case it's not realy
  'requiered because we can assume the dropdown is present.)
  On Error Resume Next
  Set nodeDeviceTypeDropdown = htmlDoc.getElementById("DeviceOptions")
  On Error GoTo 0
  
  'Now we can check if the dropdown element was found
  'If an object variable has no value it is "Nothing"
  'To check if it has a value we must check if it's
  '"Not" "Nothing"
  'You can use this mechanism for every object variable
  'in VBA
  If Not nodeDeviceTypeDropdown Is Nothing Then
    'Select the wanted dropdown entry
    nodeDeviceTypeDropdown.selectedIndex = 4
    
    'To make the selection work you must trigger the
    'html change event of the dropdown
    Call TriggerEvent(htmlDoc, nodeDeviceTypeDropdown, "change")
    
    'Give time to generate the code for the second dropdown
    Application.Wait (Now + TimeSerial(0, 0, 1))
  Else
    'Dropdown not found
    MsgBox "The Dropdown for Device Search was not found"
    'Stop makro
    Exit Sub
  End If
  
  'Here we can use the second dropdown "Search Crane Device"
  'We do it from here without error handling
  Set nodeCraneDeviceDropdown = htmlDoc.getElementById("craneDeviceOption")
  'Select the wanted dropdown entry
  nodeCraneDeviceDropdown.selectedIndex = 1
  'Trigger the change event of this dropdown
  Call TriggerEvent(htmlDoc, nodeCraneDeviceDropdown, "change")
  'Give time to generate the code for the text field
  Application.Wait (Now + TimeSerial(0, 0, 1))
    
  'Now we have the text field present and can enter the search term (craneID)
  'Get the html input element
  Set nodeCraneDeviceID = htmlDoc.getElementById("DevCraneDeviceID")
  '
  'It is not enough to enter the ID. The input field also has html events
  'that must be triggered so that the entered value is not only displayed
  'but also taken over to submit.
  'We have to embed the entering of the crane id in the both events
  '"compositionstart" and "compositionend"
  Call TriggerEvent(htmlDoc, nodeCraneDeviceID, "compositionstart")
  nodeCraneDeviceID.Value = searchTerm
  Call TriggerEvent(htmlDoc, nodeCraneDeviceID, "compositionend")
  
  'Click the submit button
  htmlDoc.getElementById("search4").Click
  
  'Give time to load the result page
  Application.Wait (Now + TimeSerial(0, 0, 5))
  
  'Do here what you want with the result
  '...
End Sub

Это процедура для запуска html событий

Private Sub TriggerEvent(htmlDocument As Object, htmlElementWithEvent As Object, eventType As String)

  Dim theEvent As Object

  htmlElementWithEvent.Focus
  Set theEvent = htmlDocument.createEvent("HTMLEvents")
  theEvent.initEvent eventType, True, False
  htmlElementWithEvent.dispatchEvent theEvent
End Sub

Вот два скриншота из FireFox html инспектора с событиями элементов Если вы не знаете, какие события необходимы, вы должны попробовать, пока они не сработают; -)

Все события для используемых раскрывающихся списков на странице Bild dropdownevents89jwk.jpg auf abload.de

The events for the used input field on the page Снимок inputevents8bjf7.jpg на abload.de

...