2013-10-03 50 views
0

我沒有太多(或任何)處理內存和內存泄漏問題的經驗,但看起來就是這裏發生的情況。Excel宏中的可能內存泄漏從大量網頁獲取信息

我有了到
Excel宏 - 從工作表中的單元格按照超鏈接
- 從網頁
獲取信息 - 請在信息
一些字符串操作 - 填充單元與信息片獲得

我的代碼大致是:

Sub GetInfo() 
    Dim numRow As Long 
    numRow = Range("E2").Value 

    Do While WorksheetFunction.IsText(Range("D" & numRow)) 
     If Not Range("D" & numRow).EntireRow.Hidden Then 
      URL = Range("D" & numRow).Hyperlinks(1).Address 

      Set IE = CreateObject("InternetExplorer.Application") 
      IE.Visible = True 
      IE.Navigate URL 

      Do While IE.Busy 
       Application.Wait DateAdd("s", 1, Now) 
      Loop 

      If IE.document.GetElementsByName("thing1").Length = 0 Then 
       strFrame = "Unknown" 
       strBasket = "" 
       strBoxName = "Check Manually" 
       strStartIt = "" 
       strEndIt = "" 

      Else 

       strFruitwork = IE.document.GetElementsByName("thing1")(0).innerText 

       If InStr(strFruitwork, "FRUITY") Then 
        strFruit = "Cherry" 

        numStart = InStr(strFruitwork, "ir:") + 3 
        numEnd = InStr(numStart, strFruitwork, " -") 
        strBasket = Mid(strFruitwork, numStart, numEnd - numStart) 

        numStart = InStr(strFruitwork, "ane:") + 4 
        numEnd = InStr(numStart, strFruitwork, " -") 
        strBoxName = Mid(strFruitwork, numStart, numEnd - numStart) 

        numStart = InStr(strFruitwork, "ey:") + 3 
        numEnd = Len(strFruitwork) 
        strStartIt = Mid(strFruitwork, numStart, numEnd - numStart) 

        strEndIt = "NA" 

       Else 
        strFruit = "Berry" 

        allPropBoxes = IE.document.GetElementsByName("_.properties") 
        For PropBox = 0 To IE.document.GetElementsByName("_.properties").Length 
         strFruitInfo = IE.document.GetElementsByName("_.properties")(PropBox).innerText 
         If (InStr(strFruitInfo, "yaddayadda") <> 0) Then 
          Exit For 
         End If 
        Next 

        numStart = InStr(strFruitInfo, "Name:") + 11 
      numEnd = InStr(numStart, strFruitInfo, Chr(10)) 
        strBoxName = Mid(strFruitInfo, numStart, numEnd - numStart) 

        numStart = InStr(strFruitInfo, "BegNum:") + 15 
        numEnd = InStr(numStart, strFruitInfo, Chr(10)) 
        strStartIt = Mid(strFruitInfo, numStart, numEnd - numStart) 

        numStart = InStr(strFruitInfo, "EndNum:") + 13 
        numEnd = InStr(numStart, strFruitInfo, Chr(10)) 
        strEndIt = Mid(strFruitInfo, numStart, numEnd - numStart) 

        numStart = InStr(strFruitInfo, "Basket:") + 5 
        strBasket = Mid(strFruitInfo, numStart, Len(strFruitInfo) - numStart) 

       End If 

      End If 

      Range("F" & numRow).Value = strFruit 
      Range("G" & numRow).Value = strBasket 
      Range("H" & numRow).Value = strBoxName 
      Range("I" & numRow).Value = strStartIt 
      Range("J" & numRow).Value = strEndIt 


      IE.Quit 
      Set IE = Nothing 
      Set strFruit = Nothing 
      Set strFruitwork = Nothing 
      Set strBasket = Nothing 
      Set strBoxName = Nothing 
      Set strStartIt = Nothing 
      Set strEndIt = Nothing 
      Set numStart = Nothing 
      Set numEnd = Nothing 
      Set strFruitInfo = Nothing 
      Set allPropBoxes = Nothing 
      Set PropBox = Nothing 
      Set URL = Nothing 


     End If 
     numRow = numRow + 1 
    Loop 


End Sub 

我會承擔設定=空話應該處理內存問題,但實際上,腳本在卡住之前一次最多隻能工作3-4行(宏在IE窗口打開時卡住,但URL不是鍵入/跟隨)。手動關閉IE窗口,然後再次啓動腳本可以正常工作,但只需3行即可。鑑於我的數據超過900(!)行,你可以得到爲什麼這是一個問題。

任何幫助? (請正確假設我對處理內存事物一無所知)

+2

將CreateObject語句帶出do-while循環。初始化IE的一個實例,並將這個實例用於所有URL。並且IE.Quit和Set IE = Nothing代碼也退出循環。因此,創建IE的實例,在循環中使用它,循環結束後退出IE並將所有內容設置爲Nothing。 – dee

+1

@ DanielDusek的建議(迴應asantaballa的答案)很有意義。出於調試目的,我建議儘可能多地使用「內循環」。我懷疑你掛在「IE繁忙」循環中 - 我會統計你四處走動的次數,並在10秒左右之後退出循環。這將區分「內存不足」和「鏈接未響應」。如果您更改網址(從工作表中的其他位置開始),它是否仍然在三行後掛起?換句話說 - 它是'3',還是它的URL? – Floris

+0

謝謝,這工作:) – Shisa

回答

3

只是一個念頭。我知道會是大量的工作,但考慮做單一

Set IE = CreateObject("InternetExplorer.Application") 

,然後發出多個IE.Navigate URL你行。打開瀏覽器是一個相當繁重的過程,而不僅僅是一個URL,可能會解決/緩解您的問題。

+1

這似乎是一個非常明智的建議。這可能不是唯一的問題,但這是一個好習慣。 – Floris

+0

謝謝,這工作。 :) – Shisa