VBA:循环w / IE.doc引用中的错误91不一致

我毫不犹豫地承认,我对HTML对象库不太了解。

我有一个IRS雇主识别号码的电子表格,我必须将其识别为在我的数据库中。 我只有基于Web的访问这个数据库,其他人已经写了HTML和pipe理数据库。 我相信他们的方法是过时的,他们的devise实践很差; 但是我不是数据库pipe理员,所以我知道什么? 因此,我最终的正常做法是在search页面inputEIN并logging结果。

我的Excelmacros是为了

  1. login到基于Web的数据库查询网站。

  2. 循环通过EIN,注意find哪些EIN

但是,我有以下问题:

  • 答:login部分很好地工作,但有一个怪癖:我必须离开“如果然后”,validationlogin成功(或不)​​,否则login失败。 鉴于login后发生“If Then Else”,这完全是莫名其妙的。
  • B.判断EIN是否在数据库中的唯一方法是查看innerText并查看EIN是否发生在查询产生的页面上。 这是行不通的,也就是说,我只是在testing中得到一个正确的命中,我连续两次查询同一个EIN。 (我碰到第二个EIN。)
  • C.在循环中,我得到不一致的错误91(对象variables未设置)。 有时循环完成; 有时会挂起,但从来不在同一个地方。

我的代码如下(虽然我不得不改变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 

有什么build议么?

我发现使用下面的“等到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" 

我只用了一个“准备好”的条件就遇到了很多奇怪的错误。 修改我的“准备好”检查后,这几乎100%消失。 有时准备状态不能准确反映状态。

关于你的第一个问题,使用我上面提到的Sleep方法,试着在你的每个命令之前添加Sleep 1000左右,以validation问题是在你的逻辑中,而不是在IE加载太慢。 或慢慢地用debugging器逐步完成。

你所描述的声音听起来非常相似,当IE浏览器部分加载时,我的代码会继续执行。