返回列表 上一主題 發帖

用迴圈抓資料越跑越慢,該如何釋放記憶體?

用迴圈抓資料越跑越慢,該如何釋放記憶體?

各位前輩大家好,

我有個程式使用迴圈及querytable.add的方式抓取外部資料(抓完會執行querytable.delete)
並在匯入資料後用worksheets.copy的方式另存,
此時程式會自動新增一個活頁簿,待存檔後再將新增的活頁簿關閉

但我發現如此一來,因為每次copy工作表時都會新增一個活頁簿
如果我的迴圈一共要抓好幾百次的資料
那就會增加好幾百個活頁簿
雖然之後會關閉,但不曉得記憶體有沒有釋放掉,因為活頁簿的編號會一直增加上去
而程式跑的速度也越來越慢....@@"

可以請各位前輩幫忙解答一下嗎? 謝謝

本帖最後由 sasho 於 2014-6-16 18:16 編輯

回復 2# GBKEE

感謝G大的指點,但可能我表達的不是很清楚,所以讓大家誤會我的問題了
跟G大所示範的一樣,程式再匯入網頁資料後都會另存成一個CSV檔案並關閉,
同時,將所新增的querytable delete掉,程式碼如下:
  1. Sub 取得資料(strURL As String, Table As String)

  2. Dim xlSheet As Excel.Worksheet
  3. Set xlSheet = Sheets("Temp")

  4. Do
  5.     Application.DisplayAlerts = False
  6.      With xlSheet.QueryTables.Add("URL;" & strURL, xlSheet.Cells(1, 1))
  7.          .WebFormatting = xlWebFormattingNone
  8.          .WebSelectionType = xlSpecifiedTables
  9.          .WebTables = Table
  10.          .BackgroundQuery = False

  11.          On Error Resume Next
  12.          Do
  13.              Err.Clear
  14.              .Refresh 0
  15.             
  16.              If Err.Number Then
  17.                  Application.Wait Now + TimeValue("00:00:01")
  18.              End If

  19.          Loop Until Err.Number = 0
  20.          
  21.          .Delete
  22.          'If Err.Number <> 0 Then Err.Clear: MsgBox Err.Number    '被免資料抓取不成功,而顯示訊息
  23.          
  24.          On Error GoTo 0
  25.      End With

  26.      If Err.Number = 0 Then
  27.          Application.DisplayAlerts = True
  28.          Exit Sub
  29.      End If
  30. Loop

  31. 儲存CSV DownloadDate,id
  32. End Sub

  33. Sub 儲存CSV(SaveDate As String, CSVname As String)
  34.    
  35. Dim TestObj As Object
  36. Dim CSVfile As String, CSVfolder As String
  37. Dim TestFolder As Boolean
  38.    
  39.     FilePath = "D:\TSE\"
  40.     CSVfolder = FilePath & SaveDate & "\"
  41.     CSVfile = CSVfolder & CSVname & "_" & SaveDate & ".csv"
  42.     'Debug.Print CSVfile
  43.    
  44.     Set TestObj = CreateObject("Scripting.FileSystemObject")
  45.     TestFolder = TestObj.FolderExists(CSVfolder)
  46.     If TestFolder = False Then TestObj.CreateFolder (CSVfolder)

  47.     On Error Resume Next
  48.     Kill CSVfile
  49.     On Error GoTo 0

  50.     Worksheets(Tempname).Copy
  51.     Application.DisplayAlerts = False
  52.     With ActiveWorkbook
  53.         .SaveAs FileName:=CSVfile, FileFormat:=xlCSV
  54.         .Close 0
  55.     End With
  56.     Application.DisplayAlerts = True
  57.    
  58. End Sub
複製代碼
我的問題是在於,由於我用迴圈一共要抓幾百筆的資料
我從儲存下來的檔案最後變動時間觀察,發現一開始可能一秒鐘可以抓五到六個檔案
但到後面,可能一秒鐘就只能抓兩個檔案,檔案大小都差不多
一直不知道為什麼速度會越來越慢,每抓完一筆檔案就執行一次 doevents
所以應該不至於造成CPU資源被吃光
唯一能想到的就是,每次另存一個檔案,就會新開一個活頁簿
比方說,活頁簿1、活頁簿2、活頁簿3....到最後的活頁簿999
雖然把資料複製過去後、另存新檔後該活頁簿就會關閉,但EXCEL好像還是會占用到記憶體資源   
是不是因為這樣才導致速度越來越慢呢?

還是說,是因為我複製的方式不正確才會導致記憶體增加的呢?
G大跟我的差別在於,匯入資料後G大是workbook.add然後複製匯入的range
而我則是直接將整個worksheet copy
不曉得這兩者的方式有差嗎

謝謝各位前輩指點 m(_ _)m

TOP

回復 5# stillfish00

時間變長的部分,應該是在匯入網頁資料所花的時間
一開始匯入很順,但越到後面就越卡,不知道是什麼原因

同時我有觀察EXCEL在工作管理員中占用的記憶體容量
從程式執行前到程式執行後,整個記憶體增加了不少
一樣也是不知道原因

懇請各位大大解救一下

TOP

回復 8# stillfish00

我使用的是EXCEL 2010,執行QueryTables.delete並不會將匯入資料刪除,只會把連線刪除而已

另外,我在另存匯入資料後,也會在執行worksheets.cells.delete,所以資料是不會向右累積的

感謝

TOP

回復 10# GBKEE


感謝G大的分享

不過小弟我還是不太了解,為什麼在EXCEL中用迴圈匯入資料會越匯越慢....
我使用的是win 7、64位元、6G記憶體
平常有清除系統垃圾的習慣,且在執行程式時,不論CPU或是記憶體都顯示尚有多餘的資源(從工作管理員觀察)
況且,如果是因為系統資源不足所導致的問題,應該不會出現執行程式初期速度較快,而執行到後面速度就整個拖下來的情況才是
應該是從頭到尾都很慢才是
不曉得我這樣推論是否正確呢?

TOP

回復 12# GBKEE


感謝G版大的幫忙,因為我無法上傳檔案,所以把檔案放在如下的dropbox的網址
另外,最近幾天測試的結果,發現問題是出在兩個部分
一個是匯入網頁資料,另一個是將匯入資料另存成csv檔
根據記錄的資料,這兩個動作都會隨著迴圈越跑越多而越來越慢
還請G版大指點一下,謝謝

https://www.dropbox.com/s/n0ycnc7q4gqtbrb/%E6%8A%93%E5%8F%96%E4%B8%8A%E5%B8%82%E8%B3%87%E6%96%99.xls

TOP

回復 14# GBKEE

實際測試G大所提供的程式,確實比之前的那個還要快很多
仔細比對後,我發現主要的問題是在於調整格式這部分

因為這些資料我會再匯入到mysql當中,所以資料格式不能出錯
所以在最一開始我所提供的程式中,在sub 調整格式()的最後,我有再加上一段指令
cells.NumberFormatLocal = "G/通用格式"
而這段指令是G大所提供的程式碼中所沒有的
目前推測就是因為這段敘述,導致整個程式速度降了下來
以及程式執行過程,EXCEL所占用的記憶體不斷攀高

感謝G大的指點,受教了!

TOP

        靜思自在 : 生氣,就是拿別人的過錯來懲罰自己。
返回列表 上一主題