VBA:循环中的不一致错误91 w/IE.doc参考
问题描述:
我自由地承认,我对HTML对象库不太了解。VBA:循环中的不一致错误91 w/IE.doc参考
我有一个电子表格,包含IRS雇主识别号码,我必须将其识别为在我的数据库中。我只有基于Web的访问这个数据库,其他人已经写了HTML并管理数据库。我相信他们的方法过时了,他们的设计实践很差;但我并不是最终的数据库管理员,所以我知道什么?因此,我最终的正常做法是在搜索页面输入EIN并记录结果。
我的Excel宏是为了
登录到基于Web的数据库查询网站。
循环遍历EIN的,注意哪些EIN的发现
不过,我有以下问题:
- A.登录部分工作得很好,但有一个怪癖:我必须将 保留为验证登录成功(或不是) 的“If Then Else”,否则登录失败。鉴于登录后发生“If Then Else” ,这是完全令人困惑的。
- B.判断EIN是否在数据库中的唯一方法是查看 innerText,并查看EIN是否发生在由 查询得到的页面上。这是行不通的,即我只在 (在测试中)时才得到正面打击,我连续查询两次相同的EIN。 (我碰到了 第二个EIN。)
- C.在循环中,我得到不一致的错误91(对象变量不是 集)。有时循环完成;有时会挂起,但从来没有在 的地方。
我的代码如下所示(虽然我不得不修改URL):
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
有什么建议?
答
我发现使用下面的“等待,直到IE就绪”
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Function IEWait(p_ieExp As InternetExplorer)
'this should go from ready-busy-ready
Dim initialReadyState As Integer
initialReadyState = p_ieExp.ReadyState
'wait 250 ms until it's done
Do While p_ieExp.Busy Or p_ieExp.ReadyState <> READYSTATE_COMPLETE
Sleep 250
Loop
End Function
你会这样称呼它
IEWait IE 'your internet explorer is named "IE"
我也陷入了太多的古怪更好的成功仅使用“就绪”条件之一的错误。在修改我的“准备好”检查方法后,这几乎完全消失了。有时就绪状态不能准确反映状态。
关于你的第一个问题,使用上面提到的Sleep
方法,试着在你的每个命令前加上Sleep 1000
来验证问题出在你的逻辑上,而不是IE加载太慢。或者缓慢地逐步调试。
你所描述的声音听起来非常类似于我在IE部分加载和我的代码会继续执行时遇到的一些问题。
恩德兰:你是一个美丽的人。这是frickin'真棒!像魅力一样工作。这清除了我遇到的所有问题。谢谢! – user3232254
@ user3232254很乐意帮忙! – enderland
仅供参考 - 我必须添加对“Microsoft Internet控件”的引用才能使用。 –