2016-03-05 130 views
0

我非常初學VBA的編碼場景(網站腳本更多的是我的東西),但我有一個基於excel的程序,我需要創建它將從基於Intranet的Web導入數據應用到電子表格中。以下是我要設置的要點... 在電子表格中,用戶將輸入以下信息:用戶名,密碼,客戶帳號列表和日期範圍。然後,用戶將點擊「命令按鈕」,這將使以下發生:使用VBA導入特定的網絡數據excel

  1. 基於開放的Web程序,登錄(基於輸入到電子表格登錄/密碼),然後導航到該帳戶搜索屏幕。

  2. 在搜索字段中輸入第一個客戶帳號,然後單擊「搜索」按鈕導航到特定的客戶帳戶。

  3. 導航到「搜索活動」屏幕上,輸入日期範圍,然後點擊「搜索活動按鈕。

  4. 從活動表的特定列提取數據,並將這些數據導入到電子表格。

  5. 如果有多頁數據會出現「下一個結果」按鈕,則應該有一個循環點擊下一個結果按鈕(如果存在)並從每個頁面拉同一列數據直到按鈕不再存在(不再有數據)。

  6. 一旦沒有更多頁面的數據(或者如果只有一個頁面),宏將循環回到賬戶搜索屏幕,並對輸入到電子表格中的賬戶列表中的每個賬戶執行相同的操作,直到沒有其他帳戶。

  7. 一旦完成(所有數據成功導入到電子表格),它應該關閉IE窗口。

這是一個有點複雜,我意識到練成/ VBA絕對不是執行這些功能的最佳解決方案,但不幸的是它是我在這種情況下使用。我已經能夠拼湊出一些VBA,它完成了上面幾乎所有的事情,我遇到的問題是循環遍歷活動頁面,並且拉取數據不會起作用(獲得各種各樣的錯誤,這些錯誤只會讓我更加困惑),有時它會從第一張表單中提取數據,點擊「下一個結果」按鈕,進入下一頁並拋出一個錯誤,甚至會拋出兩三頁並拋出錯誤。它沒有多大意義,但最常見的錯誤是「權限被拒絕」。此外,此代碼目前僅從一個帳戶提取數據,我希望一旦我將它用於一個帳戶,可以很容易地創建一個循環的整個代碼,讓它沿着帳號列表進行,併爲每個直到完成。我已經堅持了幾個星期,我真的準備好拋棄所有事情,從頭開始,任何幫助將非常感激!

下面是我到目前爲止的代碼...

Private Sub CommandButton1_Click() 

    ' open IE, navigate to the desired page and loop until fully loaded 
    Set IE = New InternetExplorerMedium 
    my_url = "https://customerinfo/pages/login.jsp" 
    my_url2 = "https://customerinfo/pages/searchCustomer.jsp" 
    my_url3 = "https://customerinfo/pages/searchAccountActivity.jsp" 

    With IE 
     .Visible = True 
     .navigate my_url 
     Do Until Not .Busy And .readyState = 4 
      DoEvents 
     Loop 
    End With 

    ' Input the userid and password 
    IE.document.getElementById("userId").Value = [B2] 
    IE.document.getElementById("password").Value = [B3] 

    ' Click the "Login" button 
    IE.document.getElementById("action").Click 
    Do Until Not IE.Busy And IE.readyState = 4 
     DoEvents 
    Loop 

    ' Navigate to Search screen 
    With IE 
     .navigate my_url2 
     Do Until Not .Busy And .readyState = 4 
      DoEvents 
     Loop 
    End With 

    ' Input the account number & click search 
    IE.document.getElementById("accountNumber").Value = [B5] 
    IE.document.getElementById("action").Click 
    Do Until Not IE.Busy And IE.readyState = 4 
     DoEvents 
    Loop 

    With IE 
     .navigate my_url3 
     Do Until Not .Busy And .readyState = 4 
      DoEvents 
     Loop 
    End With 

    'Input search criteria 
    IE.document.getElementById("store").Value = [C7] 
    IE.document.getElementById("dateFromMonth").Value = [C10] 
    IE.document.getElementById("dateFromDay").Value = [B11] 
    IE.document.getElementById("dateFromYear").Value = [B12] 
    IE.document.getElementById("timeFromHour").Value = [B20] 
    IE.document.getElementById("timeFromMinute").Value = [B21] 
    IE.document.getElementById("dateToMonth").Value = [C15] 
    IE.document.getElementById("dateToDay").Value = [B16] 
    IE.document.getElementById("dateToYear").Value = [B17] 
    IE.document.getElementById("timeToHour").Value = [B24] 
    IE.document.getElementById("timeToMinute").Value = [B25] 
    IE.document.getElementById("action").Click 
    Do Until Not IE.Busy And IE.readyState = 4 
     DoEvents 
    Loop 

    'Pulls data from activity search 
    Dim TDelements As IHTMLElementCollection 
    Dim TDelement As HTMLTableCell 
    Dim r As Long, i As Long 
    Dim e As Object 

    Application.Wait Now + TimeValue("00:00:05") 
    Set TDelements = IE.document.getElementsByTagName("tr") 
    r = 0 
    For i = 1 To 1 
     Application.Wait Now + TimeValue("00:00:03") 
     For Each TDelement In TDelements 
      If TDelement.className = "searchActivityResultsOldContent" Then 
       Sheet1.Range("E1").Offset(r, 0).Value = TDelement.ChildNodes(8).innerText 
       r = r + 1 
      ElseIf TDelement.className = "searchActivityResultsNewContent" Then 
       Sheet1.Range("E1").Offset(r, 0).Value = TDelement.ChildNodes(8).innerText 
       r = r + 1 
      End If 
     Next 
     Application.Wait Now + TimeValue("00:00:02") 
     Set elems = IE.document.getElementsByTagName("input") 
     For Each e In elems 
      If e.Value = "Next Results" Then 
       e.Click 
       i = 0 
       Exit For 
      End If 
     Next e 
    Next i 

    Do Until Not IE.Busy And IE.readyState = 4 
     DoEvents 
    Loop 
    IE.Quit 

End Sub 
+0

請縮小您的文章範圍,將代碼/文本限制爲唯一必要部分並澄清您的問題/問題。感謝和問候, –

+0

可能的重複[與VBA循環拉取HTML數據的各種錯誤](http://stackoverflow.com/q/35780526/2165759) – omegastripes

回答

0

所以,你點擊「下一步...」元素後發生了什麼?讓我描述一個我遇到的問題。假設代碼流程如下:

  1. 創建IE實例,並導航到某個URL,例如, G。第一個搜索結果頁面。
  2. 檢查頁面是否已加載並準備就緒。等一下。
  3. 創建DispHTMLElementCollection收集目標元素,通過.document.getElementsByTagName()等檢索。
  4. 循環遍歷集合中的元素,做一些事情。
  5. 單擊「Next ...」元素。問題是,在某些情況下,由於某些JS或XHR處理,下一頁在點擊後不會立即開始下載。
  6. 如果下一頁已加載並準備就緒,請進行常規檢查。該檢查只是允許進一步的代碼執行沒有任何延遲,因爲在點擊之後沒有立即開始下一頁的下載,並且當前現有的頁面被確定爲下一頁下載並準備好的,這是錯誤的。簡單的幾秒延遲不能提供可靠的方式來獲得就緒頁面。
  7. 再次,錯誤地從現有頁面而不是下一頁創建DispHTMLElementCollection元素的集合。
  8. 循環創建集合的元素。在循環過程中,下一頁開始下載。該集合仍然包含對這些對象的引用,但實際上該對象的頁面已被卸載。因此要麼嘗試訪問卸載頁面的元素,要麼由於文檔對象沒有響應,該操作給出「權限被拒絕」錯誤。

我的線索,是爲了避免點擊「下一步...」,嘗試從「下一個......」的.href財產錨<a>元素閱讀下頁URL,並調用IE.navigate到該URL,然後檢查頁面的準備情況。請參考example implementing that approach

IMO最有效的方法是使用XHR,如this,thisthis