返回列表 上一主題 發帖

[發問] 程式執行速度越來越慢

[發問] 程式執行速度越來越慢

本帖最後由 bulletin 於 2014-2-5 19:14 編輯

各位前輩好
小弟初學,還不知道要怎麼處理資料庫
因此寫了一個程式抓取券商已整理好的財報
程式可以執行
但是發現幾個問題

1. 若沒有另存新檔,資料可抓取,但是隨著時間過去,excel會越變越慢, 從每筆約1秒慢慢變成1分鐘....
     請問這有什麼好方法可以改善嗎?
     先把財報抓下來之後再做資料篩選並另存是否是較好的選擇?
     
註:沒存新檔就是程式最下方的這幾行刪除

            Sheets(Array("CFSQ", "ISQ", "BSQ")).Copy
            ActiveWorkbook.SaveAs Filename:= _
              "C:\Users\user\Documents\KT\投資理財\Excel分析模組\" & stockid & "季報.xlsx", FileFormat:= _
               xlOpenXMLWorkbook, CreateBackup:=False
                       
            Application.DisplayAlerts = True
            Windows(stockid & "季報.xlsx").Close

2. 有另存新檔的程式如下, 平均每筆都需花費1~2分鐘才能完成
     請問程式碼有什麼地方可以改善嗎?
     還是這樣抓取資料天生就註定速度會隨著記憶體空間佔據而逐漸變慢?
     有請各位前輩協助
  1. Private Sub CommandButton1_Click()

  2.     Dim StartTime
  3.     StartTime = Timer
  4.     Application.ScreenUpdating = False

  5.     For i = 1 To 100
  6.         
  7.         Dim stockid
  8.         stockid = Range("A" & i).Value
  9.    
  10.     Application.Wait Now + TimeValue("00:00:01")

  11.        '現金流量表季報
  12.        With Sheets("CFSQ")
  13.            .Rows("1:64").ClearContents
  14.            With .QueryTables.Add(Connection:= _
  15.                "URL;http://dj.mybank.com.tw/z/zc/zc3/zc3_" & stockid & ".djhtm", Destination:=.Range( _
  16.                "$A$1"))
  17.                .Name = "zc3_2002.djhtm"
  18.                .FieldNames = True
  19.                .RowNumbers = False
  20.                .FillAdjacentFormulas = False
  21.                .PreserveFormatting = True
  22.                .RefreshOnFileOpen = False
  23.                .BackgroundQuery = True
  24.                .RefreshStyle = xlInsertDeleteCells
  25.                .SavePassword = False
  26.                .SaveData = True
  27.                .AdjustColumnWidth = True
  28.                .RefreshPeriod = 0
  29.                .WebSelectionType = xlSpecifiedTables
  30.                .WebFormatting = xlWebFormattingNone
  31.                .WebTables = "3"
  32.                .WebPreFormattedTextToColumns = True
  33.                .WebConsecutiveDelimitersAsOne = True
  34.                .WebSingleBlockTextImport = False
  35.                .WebDisableDateRecognition = False
  36.                .WebDisableRedirections = False
  37.                .Refresh BackgroundQuery:=False
  38.            End With
  39.        End With
  40.       
  41.       '損益表季報
  42.        With Sheets("ISQ")
  43.            .Rows("1:64").ClearContents
  44.            With .QueryTables.Add(Connection:= _
  45.                "URL;http://dj.mybank.com.tw/z/zc/zcq/zcq_" & stockid & ".asp.htm", Destination:=.Range( _
  46.                "$A$1"))
  47.                .Name = "zcq_2002.asp"
  48.                .FieldNames = True
  49.                .RowNumbers = False
  50.                .FillAdjacentFormulas = False
  51.                .PreserveFormatting = True
  52.                .RefreshOnFileOpen = False
  53.                .BackgroundQuery = True
  54.                .RefreshStyle = xlInsertDeleteCells
  55.                .SavePassword = False
  56.                .SaveData = True
  57.                .AdjustColumnWidth = True
  58.                .RefreshPeriod = 0
  59.                .WebSelectionType = xlSpecifiedTables
  60.                .WebFormatting = xlWebFormattingNone
  61.                .WebTables = "3"
  62.                .WebPreFormattedTextToColumns = True
  63.                .WebConsecutiveDelimitersAsOne = True
  64.                .WebSingleBlockTextImport = False
  65.                .WebDisableDateRecognition = False
  66.                .WebDisableRedirections = False
  67.                .Refresh BackgroundQuery:=False
  68.            End With
  69.        End With
  70.       
  71.       '資產負債表季報
  72.        With Sheets("BSQ")
  73.            .Rows("1:64").ClearContents
  74.            With .QueryTables.Add(Connection:= _
  75.                "URL;http://dj.mybank.com.tw/z/zc/zcp/zcpa/zcpa_" & stockid & ".asp.htm", Destination:= _
  76.                .Range("$A$1"))
  77.                .Name = "zcpa_2002.asp"
  78.                .FieldNames = True
  79.                .RowNumbers = False
  80.                .FillAdjacentFormulas = False
  81.                .PreserveFormatting = True
  82.                .RefreshOnFileOpen = False
  83.                .BackgroundQuery = True
  84.                .RefreshStyle = xlInsertDeleteCells
  85.                .SavePassword = False
  86.                .SaveData = True
  87.                .AdjustColumnWidth = True
  88.                .RefreshPeriod = 0
  89.                .WebSelectionType = xlSpecifiedTables
  90.                .WebFormatting = xlWebFormattingNone
  91.                .WebTables = """oMainTable"""
  92.                .WebPreFormattedTextToColumns = True
  93.                .WebConsecutiveDelimitersAsOne = True
  94.                .WebSingleBlockTextImport = False
  95.                .WebDisableDateRecognition = False
  96.                .WebDisableRedirections = False
  97.                .Refresh BackgroundQuery:=False
  98.            End With
  99.        End With
  100.       
  101.             Application.DisplayAlerts = False '存檔時直接覆蓋原有檔案
  102.       
  103.         '另存新檔
  104.             Sheets(Array("CFSQ", "ISQ", "BSQ")).Copy
  105.             ActiveWorkbook.SaveAs Filename:= _
  106.               "C:\Users\user\Documents\KT\投資理財\Excel分析模組\" & stockid & "季報.xlsx", FileFormat:= _
  107.                xlOpenXMLWorkbook, CreateBackup:=False
  108.                        
  109.             Application.DisplayAlerts = True
  110.             Windows(stockid & "季報.xlsx").Close
  111.                
  112.     Next i

  113.    Application.ScreenUpdating = True
  114.    EndTime = Timer
  115.    MsgBox "本次下載共花費:" & EndTime - StartTime & "秒"
  116.       
  117.    
  118. End Sub
複製代碼

回復 2# GBKEE

多謝GBKEE版主回復
我的程式放在附件中

請問您回覆的內容該怎麼使用...
我還不會使用module
直接放到一個新的檔案中執行也發生問題
不知道該如何使用它
很抱歉造成您的困擾~

VBA測試專用.zip (289.89 KB)

TOP

回復 4# GBKEE

GBKEE版主您好
我加入您修改的程式,詳如附件
測試之後發現幾個問題

1. 尚未呼叫Delete_QueryTables前,速度差異甚大
不另存新檔:99筆資料共112秒
另存新檔:第1筆就花了121秒...
可見拖累速度是另存新檔的原因,請問有何解決之道?

2. 呼叫Delete_QueryTables,發生錯誤1004
錯誤內容如下圖

我發現錯誤內容是Q.name的地方成為"zc3_2002.djhtm_231"
不懂為何後面會多了_231這幾個字

VBA測試專用.zip (270.05 KB)
  1. Private Sub CommandButton1_Click()

  2.     Dim StartTime
  3.     StartTime = Timer
  4.     Application.ScreenUpdating = False
  5.     LastRow = Sheets("sheet1").Range("A2").End(xlDown).Row '找出最後一筆資料

  6.     For i = 2 To LastRow
  7.         
  8.         Dim stockid
  9.         stockid = Range("A" & i).Value
  10.    
  11.     Application.Wait Now + TimeValue("00:00:01")

  12.        With Sheets("CFSQ")
  13.            '.Rows("1:64").ClearContents
  14.            '******************************
  15.             If .QueryTables.Count > 1 Then
  16.                 .QueryTables(1).Connection = "URL;http://dj.mybank.com.tw/z/zc/zc3/zc3_" & stockid & ".djhtm"
  17.             Else  '沒有QueryTable時新增
  18.                 .QueryTables.Add Connection:="URL;http://dj.mybank.com.tw/z/zc/zc3/zc3_" & stockid & ".djhtm", Destination:=.Range("$A$1")
  19.             End If
  20.             With .QueryTables(1)  '不再新增
  21.                 .AdjustColumnWidth = True
  22.                 .RefreshPeriod = 0
  23.                 .WebSelectionType = xlSpecifiedTables
  24.                 .WebFormatting = xlWebFormattingNone
  25.                 .WebTables = "3"
  26.                 .WebPreFormattedTextToColumns = True
  27.                 .WebConsecutiveDelimitersAsOne = True
  28.                 .Refresh BackgroundQuery:=False
  29.             End With
  30.             '******************************
  31.        End With
  32.       
  33.        With Sheets("ISQ")
  34.            '.Rows("1:64").ClearContents
  35.            '******************************
  36.             If .QueryTables.Count > 1 Then
  37.                 .QueryTables(1).Connection = "URL;http://dj.mybank.com.tw/z/zc/zcq/zcq_" & stockid & ".asp.htm"
  38.             Else  '沒有QueryTable時新增
  39.                 .QueryTables.Add Connection:="URL;http://dj.mybank.com.tw/z/zc/zcq/zcq_" & stockid & ".asp.htm", Destination:=.Range("$A$1")
  40.             End If
  41.             With .QueryTables(1)  '不再新增
  42.                 .AdjustColumnWidth = True
  43.                 .RefreshPeriod = 0
  44.                 .WebSelectionType = xlSpecifiedTables
  45.                 .WebFormatting = xlWebFormattingNone
  46.                 .WebTables = "3"
  47.                 .WebPreFormattedTextToColumns = True
  48.                 .WebConsecutiveDelimitersAsOne = True
  49.                 .Refresh BackgroundQuery:=False
  50.             End With
  51.             '******************************
  52.        End With
  53.       
  54.        With Sheets("BSQ")
  55.            '.Rows("1:64").ClearContents
  56.            '******************************
  57.             If .QueryTables.Count > 1 Then
  58.                 .QueryTables(1).Connection = "URL;http://dj.mybank.com.tw/z/zc/zcp/zcpa/zcpa_" & stockid & ".asp.htm"
  59.             Else  '沒有QueryTable時新增
  60.                 .QueryTables.Add Connection:="URL;http://dj.mybank.com.tw/z/zc/zcp/zcpa/zcpa_" & stockid & ".asp.htm", Destination:=.Range("$A$1")
  61.             End If
  62.             With .QueryTables(1)  '不再新增
  63.                 .AdjustColumnWidth = True
  64.                 .RefreshPeriod = 0
  65.                 .WebSelectionType = xlSpecifiedTables
  66.                 .WebFormatting = xlWebFormattingNone
  67.                 .WebTables = "3"
  68.                 .WebPreFormattedTextToColumns = True
  69.                 .WebConsecutiveDelimitersAsOne = True
  70.                 .Refresh BackgroundQuery:=False
  71.             End With
  72.             '******************************
  73.        End With
  74.       
  75.             Application.DisplayAlerts = False '存檔時直接覆蓋原有檔案
  76.       
  77.             Sheets(Array("CFSQ", "ISQ", "BSQ")).Copy
  78.             ActiveWorkbook.SaveAs Filename:= _
  79.               "C:\Users\user\Desktop\Test\" & stockid & "季報.xlsx", FileFormat:= _
  80.                xlOpenXMLWorkbook, CreateBackup:=False
  81.             Windows(stockid & "季報.xlsx").Close
  82.                        
  83.             Application.DisplayAlerts = True

  84.        DELETE_QueryTables
  85.       
  86.     Next i

  87.    Application.ScreenUpdating = True
  88.    EndTime = Timer
  89.    MsgBox "本次下載共花費:" & EndTime - StartTime & "秒"
  90.       
  91.    
  92. End Sub
複製代碼
3. 程式碼加入之後,BSQ這個sheet內容會變成空白
另存新檔時,有的檔案有內容,有的檔案沒內容,這是什麼原因造成的?

4. Delete_Querytables在每一次迴圈執行完畢後呼叫對嗎?

謝謝版主回覆~

TOP

報告GBKEE版主
也許可能是我的電腦環境問題造成速度變慢....

那請教問題2, 3的問題的原因為何?
2.呼叫Delete_Querytables時,發生1004錯誤
3.BSQ工作表空白問題

謝謝您~

TOP

回報GBKEE版主
空白資料的網頁我都有確認過,實際上都有資料
目前暫未出現   若有其他問題再跟您請教
謝謝

速度的問題我再找找看原因
上個星期一開始寫出來的時候很快,一分鐘約存10個檔,隨檔案增加而時間暴增
不知為何現在每次執行都要1~2分鐘
有可能是虛擬記憶體沒被釋放嗎
好怪

TOP

報告一下結果
昨天把電腦還原到前一次備份
速度就恢復正常了
謝謝GBKEE版主~~

TOP

回復 10# bulletin

請教GBKEE版主
我發現執行時
每100~200筆就會發生1004錯誤
這是因為用到大量的COPY  導致記憶體出錯嗎?

將程式改寫,將資料抓取到名為temp的工作表,依序另存到新檔
是否可以改善?

或是有可能是其他原因所造成?
  1. Private Sub CommandButton1_Click()

  2.     Dim StartTime, LastRow
  3.     StartTime = Timer
  4.     DELETE_QueryTables
  5.     Application.ScreenUpdating = False
  6.     LastRow = Sheets("sheet1").Range("A2").End(xlDown).Row '找出最後一筆資料


  7.     For i = 2 To LastRow
  8.         
  9.         Dim stockid
  10.         stockid = Range("A" & i).Value
  11.    
  12.     Application.Wait Now + TimeValue("00:00:01")

  13.        With Sheets("CFSQ")
  14.            .Rows("1:64").ClearContents
  15.            
  16.            '******************************
  17.             If .QueryTables.Count > 1 Then
  18.                 .QueryTables(1).Connection = "URL;http://dj.mybank.com.tw/z/zc/zc3/zc3_" & stockid & ".djhtm"
  19.             Else  '沒有QueryTable時新增
  20.                 .QueryTables.Add Connection:="URL;http://dj.mybank.com.tw/z/zc/zc3/zc3_" & stockid & ".djhtm", Destination:=.Range("$A$1")
  21.             End If
  22.             With .QueryTables(1)  '不再新增
  23.                 .AdjustColumnWidth = True
  24.                 .RefreshPeriod = 0
  25.                 .WebSelectionType = xlSpecifiedTables
  26.                 .WebFormatting = xlWebFormattingNone
  27.                 .WebTables = "3"
  28.                 .WebPreFormattedTextToColumns = True
  29.                 .WebConsecutiveDelimitersAsOne = True
  30.                 .Refresh BackgroundQuery:=False
  31.             End With
  32.             '******************************
  33.             
  34.        End With
  35.       
  36.        With Sheets("ISQ")
  37.            .Rows("1:64").ClearContents
  38.            
  39.            '******************************
  40.             If .QueryTables.Count > 1 Then
  41.                 .QueryTables(1).Connection = "URL;http://dj.mybank.com.tw/z/zc/zcq/zcq_" & stockid & ".asp.htm"
  42.             Else  '沒有QueryTable時新增
  43.                 .QueryTables.Add Connection:="URL;http://dj.mybank.com.tw/z/zc/zcq/zcq_" & stockid & ".asp.htm", Destination:=.Range("$A$1")
  44.             End If
  45.             With .QueryTables(1)  '不再新增
  46.                 .AdjustColumnWidth = True
  47.                 .RefreshPeriod = 0
  48.                 .WebSelectionType = xlSpecifiedTables
  49.                 .WebFormatting = xlWebFormattingNone
  50.                 .WebTables = "3"
  51.                 .WebPreFormattedTextToColumns = True
  52.                 .WebConsecutiveDelimitersAsOne = True
  53.                 .Refresh BackgroundQuery:=False
  54.             End With
  55.             '******************************
  56.             
  57.        End With
  58.       
  59.        With Sheets("BSQ")
  60.            .Rows("1:64").ClearContents
  61.            
  62.            '******************************
  63.             If .QueryTables.Count > 1 Then
  64.                 .QueryTables(1).Connection = "URL;http://dj.mybank.com.tw/z/zc/zcp/zcpa/zcpa_" & stockid & ".asp.htm"
  65.             Else  '沒有QueryTable時新增
  66.                 .QueryTables.Add Connection:="URL;http://dj.mybank.com.tw/z/zc/zcp/zcpa/zcpa_" & stockid & ".asp.htm", Destination:=.Range("$A$1")
  67.             End If
  68.             With .QueryTables(1)  '不再新增
  69.                 .AdjustColumnWidth = True
  70.                 .RefreshPeriod = 0
  71.                 .WebSelectionType = xlSpecifiedTables
  72.                 .WebFormatting = xlWebFormattingNone
  73.                 .WebTables = "3"
  74.                 .WebPreFormattedTextToColumns = True
  75.                 .WebConsecutiveDelimitersAsOne = True
  76.                 .Refresh BackgroundQuery:=False
  77.             End With
  78.             '******************************
  79.            
  80.        End With
  81.       
  82.             Application.DisplayAlerts = False '存檔時直接覆蓋原有檔案
  83.       
  84.             Sheets(Array("CFSQ", "ISQ", "BSQ")).Copy
  85.             ActiveWorkbook.SaveAs Filename:= _
  86.               "C:\Users\KT\Desktop\Test\" & stockid & "季報.xlsx", FileFormat:= _
  87.                xlOpenXMLWorkbook, CreateBackup:=False
  88.             Windows(stockid & "季報.xlsx").Close
  89.                        
  90.             Application.DisplayAlerts = True
  91.       
  92.     Next i

  93.    Application.ScreenUpdating = True
  94.    EndTime = Timer
  95.    MsgBox "本次下載共花費:" & EndTime - StartTime & "秒"
  96.       
  97.    
  98. End Sub
複製代碼

TOP

回復 12# Hsieh

我也想過是流量管制的問題
多謝說明

無論如何來改寫成temp好了
當做練習也好
到時再請各位前輩指教

TOP

回復 13# bulletin

各位前輩
我又修改了一個,這次直接先開啟新的活頁簿
並將資料直接存入活頁簿中

1. 先抓資料,再複製另存新檔
100筆 --> 102秒
200筆 --> 210秒

2. 先建立新檔再抓資料存檔
100筆 --> 100秒
200筆 --> 206秒

似乎少了複製另存速度稍稍快一點
但是考量網路穩定性以及網站存取的問題
應該是沒有差

此外仍然有錯誤1004的問題, 所以沒辦法測試500筆以上或是所有上市櫃公司1400檔的速度...

錯誤會發生在複製網頁資料,存到工作表中時
不一定會在何時發生
但原則上仍留在100~200筆之間會發生
我再把延遲時間拉長,看能不能避免錯誤1004
謝謝各位前輩指教~
  1. Sub stest()

  2.     Dim StartTime, LastRow
  3.     Dim wbnew As Workbook
  4.    
  5.     DELETE_QueryTables
  6.    
  7.     StartTime = Timer
  8.     LastRow = Sheets("sheet1").Range("A2").End(xlDown).Row '找出最後一筆資料

  9.     Application.ScreenUpdating = False
  10.    
  11.     For i = 2 To 101
  12.         
  13.         Dim stockid
  14.         stockid = Range("A" & i).Value
  15.    
  16.         Application.DisplayAlerts = False
  17.         Application.Wait Now + TimeValue("00:00:01")
  18.         
  19.         
  20.         Set wbnew = Workbooks.Add() '新增活頁簿
  21.         wbnew.SaveAs Filename:="C:\Users\KT\Desktop\Test2\" & stockid & ".xlsx"  '另存新檔

  22.         With wbnew.Sheets(1) 'CFSQ
  23.            '.Rows("1:64").ClearContents
  24.            
  25.            '******************************
  26.             If .QueryTables.Count > 1 Then
  27.                 .QueryTables(1).Connection = "URL;http://dj.mybank.com.tw/z/zc/zc3/zc3_" & stockid & ".djhtm"
  28.             Else  '沒有QueryTable時新增
  29.                 .QueryTables.Add Connection:="URL;http://dj.mybank.com.tw/z/zc/zc3/zc3_" & stockid & ".djhtm", Destination:=.Range("$A$1")
  30.             End If
  31.             With .QueryTables(1)  '不再新增
  32.                 .AdjustColumnWidth = True
  33.                 .RefreshPeriod = 0
  34.                 .WebSelectionType = xlSpecifiedTables
  35.                 .WebFormatting = xlWebFormattingNone
  36.                 .WebTables = "3"
  37.                 .WebPreFormattedTextToColumns = True
  38.                 .WebConsecutiveDelimitersAsOne = True
  39.                 .Refresh BackgroundQuery:=False
  40.             End With
  41.             '******************************
  42.             
  43.        End With
  44.       
  45.     With Sheets(2)
  46.            '.Rows("1:64").ClearContents
  47.            
  48.            '******************************
  49.             If .QueryTables.Count > 1 Then
  50.                 .QueryTables(1).Connection = "URL;http://dj.mybank.com.tw/z/zc/zcq/zcq_" & stockid & ".asp.htm"
  51.             Else  '沒有QueryTable時新增
  52.                 .QueryTables.Add Connection:="URL;http://dj.mybank.com.tw/z/zc/zcq/zcq_" & stockid & ".asp.htm", Destination:=.Range("$A$1")
  53.             End If
  54.             With .QueryTables(1)  '不再新增
  55.                 .AdjustColumnWidth = True
  56.                 .RefreshPeriod = 0
  57.                 .WebSelectionType = xlSpecifiedTables
  58.                 .WebFormatting = xlWebFormattingNone
  59.                 .WebTables = "3"
  60.                 .WebPreFormattedTextToColumns = True
  61.                 .WebConsecutiveDelimitersAsOne = True
  62.                 .Refresh BackgroundQuery:=False
  63.             End With
  64.             '******************************
  65.             
  66.        End With
  67.       
  68.        With Sheets(2)
  69.            '.Rows("1:64").ClearContents
  70.            
  71.            '******************************
  72.             If .QueryTables.Count > 1 Then
  73.                 .QueryTables(1).Connection = "URL;http://dj.mybank.com.tw/z/zc/zcp/zcpa/zcpa_" & stockid & ".asp.htm"
  74.             Else  '沒有QueryTable時新增
  75.                 .QueryTables.Add Connection:="URL;http://dj.mybank.com.tw/z/zc/zcp/zcpa/zcpa_" & stockid & ".asp.htm", Destination:=.Range("$A$1")
  76.             End If
  77.             With .QueryTables(1)  '不再新增
  78.                 .AdjustColumnWidth = True
  79.                 .RefreshPeriod = 0
  80.                 .WebSelectionType = xlSpecifiedTables
  81.                 .WebFormatting = xlWebFormattingNone
  82.                 .WebTables = "3"
  83.                 .WebPreFormattedTextToColumns = True
  84.                 .WebConsecutiveDelimitersAsOne = True
  85.                 .Refresh BackgroundQuery:=False
  86.             End With
  87.             '******************************
  88.            
  89.        End With
  90.       
  91.        Windows(stockid & ".xlsx").Close savechanges:=True
  92.        Application.DisplayAlerts = True

  93.     Next i
  94.    
  95.    
  96.    Application.ScreenUpdating = True
  97.    EndTime = Timer
  98.    MsgBox "本次下載共花費:" & EndTime - StartTime & "秒"
  99.       
  100.    
  101. End Sub
複製代碼

TOP

        靜思自在 : 口說好話、心想好意、身行好事。
返回列表 上一主題