返回列表 上一主題 發帖

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

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

本帖最後由 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
複製代碼

回復 1# bulletin
工作表一直的 QueryTables.Add 新增Web查詢,檔案越來越龐大,拖慢程式的速度
  1. Option Explicit
  2. Sub DELETE_QueryTables()  '僅須執行一次清除所有QueryTable
  3.     Dim SH As Worksheet, Q As QueryTable
  4.     For Each SH In Sheets           '活頁簿的工作表集合物件
  5.         For Each Q In SH.QueryTables
  6.             Names(Q.Name).Delete    '刪除 定義名稱
  7.             Q.Delete                '刪除 QueryTable
  8.         Next
  9.     Next
  10. End Sub

  11. Sub Ex()
  12.     Dim stockid
  13.     stockid = 2303
  14.     With Sheets("CFSQ")
  15.         .Rows("1:64").ClearContents
  16.         If .QueryTables.Count > 1 Then
  17.             .QueryTables(1).Connection = "URL;http://dj.mybank.com.tw/z/zc/zc3/zc3_" & stockid & ".djhtm"
  18.         Else  '沒有QueryTable時新增
  19.              .QueryTables.Add Connection:="URL;http://dj.mybank.com.tw/z/zc/zc3/zc3_" & stockid & ".djhtm", Destination:=.Range("$A$1")
  20.         End If
  21.         With .QueryTables(1)  '不再新增
  22.             .AdjustColumnWidth = True
  23.             .RefreshPeriod = 0
  24.             .WebSelectionType = xlSpecifiedTables
  25.             .WebFormatting = xlWebFormattingNone
  26.             .WebTables = "3"
  27.             .WebPreFormattedTextToColumns = True
  28.             .WebConsecutiveDelimitersAsOne = True
  29.             .Refresh BackgroundQuery:=False
  30.         End With
  31.     End With
  32. End Sub
複製代碼
感恩的心......(在麻辣家族討論區.用心學習會有進步的)
但資源無限,後援有限,  一天1元的贊助,人人有能力.

TOP

回復 2# GBKEE

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

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

VBA測試專用.zip (289.89 KB)

TOP

本帖最後由 GBKEE 於 2014-2-6 06:43 編輯

回復 3# bulletin
Sub DELETE_QueryTables()  複製在何模組上,執行一次可清除所有工作表上QueryTable
  1. Option Explicit
  2. Private Sub CommandButton1_Click()
  3.     Dim StartTime, LastRow
  4.     StartTime = Timer
  5.     Application.ScreenUpdating = False
  6.     LastRow = Sheets("sheet1").Range("A2").End(xlDown).Row '找出最後一筆資料
  7.     For i = 1 To LastRow
  8.         Dim stockid
  9.         stockid = Range("A" & i).Value
  10.         Application.Wait Now + TimeValue("00:00:01")
  11.         With Sheets("CFSQ")
  12.             .Rows("1:64").ClearContents
  13.             '******************************
  14.             If .QueryTables.Count > 1 Then
  15.                 .QueryTables(1).Connection = "URL;http://dj.mybank.com.tw/z/zc/zc3/zc3_" & stockid & ".djhtm"
  16.             Else  '沒有QueryTable時新增
  17.                 .QueryTables.Add Connection:="URL;http://dj.mybank.com.tw/z/zc/zc3/zc3_" & stockid & ".djhtm", Destination:=.Range("$A$1")
  18.             End If
  19.             With .QueryTables(1)  '不再新增
  20.                 .AdjustColumnWidth = True
  21.                 .RefreshPeriod = 0
  22.                 .WebSelectionType = xlSpecifiedTables
  23.                 .WebFormatting = xlWebFormattingNone
  24.                 .WebTables = "3"
  25.                 .WebPreFormattedTextToColumns = True
  26.                 .WebConsecutiveDelimitersAsOne = True
  27.                 .Refresh BackgroundQuery:=False
  28.             End With
  29.             '******************************
  30.        End With
  31.       
  32.        With Sheets("ISQ")
  33.            .Rows("1:64").ClearContents
  34.            '套上修改 .QueryTables(1).Connection =??? .QueryTables.Add Connection=???
  35.        End With
  36.       
  37.        With Sheets("BSQ")
  38.            .Rows("1:64").ClearContents
  39.            '套上修改 .QueryTables(1).Connection =??? .QueryTables.Add Connection=???
  40.            '.WebTables = """oMainTable""" 須修改
  41.            End With
  42.        End With
  43.        '程式碼
  44.        '
  45.        '
  46.     Next
  47. End Sub
複製代碼
感恩的心......(在麻辣家族討論區.用心學習會有進步的)
但資源無限,後援有限,  一天1元的贊助,人人有能力.

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 於 2014-2-6 13:17 編輯

回復 5# bulletin
另存新檔時,有的檔案有內容,有的檔案沒內容,會是網頁上那檔股票沒有資料?
你附檔存檔的速度沒有你說的慢.
  1. Sub DELETE_QueryTables()  '僅須執行一次清除所有QueryTable
  2.     Dim SH As Worksheet, Q As Variant
  3.     For Each Q In Names
  4.         Q.Delete
  5.     Next
  6.     For Each SH In Sheets           '活頁簿的工作表集合物件
  7.         For Each Q In SH.QueryTables
  8.            Q.Delete
  9.         Next
  10.     Next
  11. End Sub
複製代碼
  1. Private Sub CommandButton1_Click()
  2.     Dim StartTime
  3.     DELETE_QueryTables  '**建議先清除***
  4.     StartTime = Timer
  5.     Application.ScreenUpdating = False
  6.     LastRow = Sheets("sheet1").Range("A2").End(xlDown).Row '找出最後一筆資料
複製代碼
感恩的心......(在麻辣家族討論區.用心學習會有進步的)
但資源無限,後援有限,  一天1元的贊助,人人有能力.

TOP

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

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

謝謝您~

TOP

回復 7# bulletin
2.呼叫Delete_Querytables時,發生1004錯誤
因執行太多次的
  1. With .QueryTables.Add(Connection:=
複製代碼
造成許多Name的位置都相同,導致第1版的Sub DELETE_QueryTables()的錯誤
所以改用 第2版的Sub DELETE_QueryTables()的程式碼





3.BSQ工作表空白問題, 可查是哪一檔股票看網頁是否也無資料
感恩的心......(在麻辣家族討論區.用心學習會有進步的)
但資源無限,後援有限,  一天1元的贊助,人人有能力.

TOP

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

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

TOP

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

TOP

        靜思自在 : 知識要用心體會,才能變成自己的智慧。
返回列表 上一主題