VBA: Inkonsistenter Fehler 91 in Schleife mit IE.doc-Referenz
Ich gebe frei zu, dass ich mit der HTML-Objektbibliothek nicht allzu viel Erfahrung habe.
Ich habe eine Tabelle mit IRS-Arbeitgeberidentifikationsnummern, die ich als in meiner Datenbank vorhanden identifizieren muss oder nicht. Ich habe nur webbasierten Zugriff auf diese Datenbank, in die einige andere Personen den HTML-Code geschrieben und die Datenbank verwaltet haben. Ich glaube, ihre Methoden sind veraltet und ihre Designpraktiken schlecht. Aber letztendlich bin ich kein Datenbankmanager. Was weiß ich? Aus diesem Grund ist es meine übliche Praxis, das EIN auf der Suchseite einzugeben und das Ergebnis zu notieren.
Mein Excel-Makro soll
Melden Sie sich bei der webbasierten Datenbank-Abfragesite an.
Durchlaufen Sie die EINs und notieren Sie, welche EINs gefunden wurden
Ich habe jedoch folgende Probleme:
A. Der Login-Teil funktioniert gut, aber mit einer Besonderheit: Ich muss das "If Then Else" lassen, das bestätigt, dass der Login erfolgreich war (oder nicht), andernfalls schlägt der Login fehl. Angesichts der Tatsache, dass "If Then Else" nach dem Login auftritt, ist dies völlig verblüffend.B. Die einzige Möglichkeit, festzustellen, ob sich das EIN in der Datenbank befindet, besteht darin, den Innentext zu prüfen und festzustellen, ob das EIN auf der Seite auftritt, die aus der Abfrage resultiert. Dies funktioniert nicht, d. H. Ich erhalte nur dann einen positiven Treffer, wenn ich (beim Testen) zweimal hintereinander dasselbe EIN abfrage. (Ich bekomme einen Treffer auf der zweiten EIN.)C. In der Schleife erhalte ich inkonsistente Fehler 91 (Objektvariable nicht gesetzt). Manchmal schließt sich die Schleife; manchmal hängt es, aber nie am selben Ort.Mein Code lautet wie folgt (obwohl ich die URLs ändern musste):
Option Explicit
Sub FillFromWorkbookTest()
On Error GoTo ErrHandler
Const cURL = "https://www.someURL.com/LoginPage.jsp"
Const cUsername = "myUSERNAME"
Const cPassword = "myPASSWORD"
Dim IE As Object
Dim Doc As HTMLDocument
Dim LoginForm As HTMLFormElement
Dim UsernameInput As HTMLInputElement
Dim PasswordInput As HTMLInputElement
Dim LoginButton As HTMLInputButtonElement
Dim SearchForm As HTMLFormElement
Dim EINInput As HTMLInputElement
Dim SearchButton As HTMLInputButtonElement
Dim cEIN As String
Dim BotRow As Long
Dim EINRange As Range
Dim c As Variant
Dim i As Integer
Dim EINCheck As String
Dim EINCount As Integer
'## Open Browser & go to Admin Module, and Login
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate cURL
'## Wait for Adimn Module to load
Do Until IE.ReadyState = 4
DoEvents
Loop
'## Get the HTML Document of Admin Module login page (cURL)
Set Doc = IE.document
'## Get Admin Module login form
Set LoginForm = Doc.forms("f1")
'## Get Username input field and populate it
'## HTML: <input id=EIN type=text tabindex=3 size=9 maxlength=9 name=EIN title="Admin Code">
Set UsernameInput = LoginForm.elements("EIN")
UsernameInput.Value = cUsername
'## Get Password input field and populate it
'## HTML: <input id=PIN type=password tabindex=4 size=8 maxlength=8 name=PIN title="PIN">
Set PasswordInput = LoginForm.elements("PIN")
PasswordInput.Value = cPassword
'## Submit LoginForm
'## HTML: <input type=submit value=Login tabindex=5 title="Login"> (no onClick attribute; no element)
LoginForm.submit
Do Until IE.ReadyState = 4
DoEvents
Loop
'## Get the HTML Document of the new page
Set Doc = IE.document
'## Determine if login succeeded
If InStr(Doc.body.innerText, "Invalid Login.") = 0 Then
MsgBox "Login successful."
Else
MsgBox "Login failed."
End If
Debug.Print "Current URL: " & IE.LocationURL
'## Navigate to Global Change and reset HTML Document
IE.Navigate "https://www.someURL.com/LOGGED_IN/SomePage.jsp"
Do Until IE.ReadyState = 4
DoEvents
Loop
Set Doc = IE.document
'## Find last row in spreadsheet
BotRow = Worksheets("Sheet1").Range("A1").End(xlDown).Row
Set EINRange = Range("A1:A" & BotRow)
'## Set loop counter variable
i = 0
'## Cycle through IRS-identified EINs
For Each c In EINRange.Cells
cEIN = c.Value
i = i + 1
'## Get Admin Module login form
Set SearchForm = Doc.forms(0)
'## Get EIN input field and populate it
'## HTML: <input type="text" id=EIN name=EIN title="Enter charity EIN" maxlength=9 size=9 tabindex=11 >
Set EINInput = SearchForm.elements("EIN")
EINInput.Value = cEIN
'## Submit SearchForm
'## HTML: <input type="submit" value="Search" tabindex=15 title="Click here to search charity application" class="black_bold"
'## onclick="if (btn_OnClick(EIN,CODE)) {document.f1.action='SomeOther.jsp'; document.f1.submit(); return true;} else return false;" >
'## (has onClick attribute)
Set SearchButton = Doc.body.getElementsByTagName("table")(2). _
getElementsByTagName("tr")(0). _
getElementsByTagName("td")(0). _
getElementsByTagName("input")(2)
SearchButton.Click
Do Until IE.ReadyState = 4
DoEvents
Loop
'## Get the HTML Document of the new page
Set Doc = IE.document
'## Find EIN string on resulting page; Some number if found; Null if not
EINCheck = Doc.body.getElementsByTagName("table")(3).innerText
EINCount = InStr(1, EINCheck, cEIN, 1)
MsgBox EINCount
'## Determine which EINs are CFC charities
If InStr(1, EINCheck, cEIN, 1) = 0 Then
Worksheets("Sheet1").Range("F" & i).Value = "NO"
Else
Worksheets("Sheet1").Range("F" & i).Value = "YES"
End If
Next c
ErrHandler:
'## Cleanup
MsgBox "Error" & Err.Number & ": " & Err.Description
Set IE = Nothing
Set Doc = Nothing
Set LoginForm = Nothing
Set UsernameInput = Nothing
Set PasswordInput = Nothing
Set LoginButton = Nothing
Set SearchForm = Nothing
Set EINInput = Nothing
Set SearchButton = Nothing
End Sub
Irgendwelche Vorschläge?