Board logo

標題: [發問] 可否用迴圈或變數匯入大量資料? [打印本頁]

作者: smart3135    時間: 2014-4-22 00:54     標題: 有沒有方法可以用EXCEL VAB抓取上市櫃所有個股的資訊?

想請問各位先進,小弟最近在學EXCEL VBA,想利用EXCEL VBA下載個股的一些資訊,如各季各年的損益表、資產負債表、現金流量表、月營收、年度股利等等資料
目前是有寫出一個EXCEL VBA能抓取單獨個股的資訊,但如果想要更換其他個股,就必須將這個檔案複製另存成另一個檔案,再打開檔案進到visual basic編緝器將
裡面的個股代號以取代的方式變更,如果要這樣一個一個複製完成上市櫃所有的個股excel應該是很沒有效率的,不知道有沒有方法能一次下載很多個股的資料呢?
附上我自己寫的EXCEL VBA,還請各位大大幫忙解惑,感謝!
[attach]18107[/attach]
作者: smart3135    時間: 2014-4-22 19:02     標題: 可否用迴圈或變數匯入大量資料?

請問一下各位先進,這是我從某網站匯入EXCEL的程式碼,不知道能不能使用迴圈或變數的方式取其他個股相同的財報?
也就是程式碼中的2330可以用迴圈或變數來變更嗎?懇請各位VBA高手指點,謝謝!
https://www.cathayholdings.com/securities/exclude_AL/market.aspx?btn=1-00-00&st=2330
  1. Sub 抓季損益表資料()
  2.     With ActiveSheet.QueryTables.Add(Connection:= _
  3.         "URL;https://djinfo.cathaysec.com.tw/Z/ZC/ZCQ/ZCQ.DJHTM?A=2330", Destination _
  4.         :=Range("$A$1"))
  5.         .Name = "ZCQ.DJHTM?A=2330"
  6.         .FieldNames = True
  7.         .RowNumbers = False
  8.         .FillAdjacentFormulas = False
  9.         .PreserveFormatting = True
  10.         .RefreshOnFileOpen = False
  11.         .BackgroundQuery = True
  12.         .RefreshStyle = xlInsertDeleteCells
  13.         .SavePassword = False
  14.         .SaveData = True
  15.         .AdjustColumnWidth = True
  16.         .RefreshPeriod = 0
  17.         .WebSelectionType = xlSpecifiedTables
  18.         .WebFormatting = xlWebFormattingNone
  19.         .WebTables = "3"
  20.         .WebPreFormattedTextToColumns = True
  21.         .WebConsecutiveDelimitersAsOne = True
  22.         .WebSingleBlockTextImport = False
  23.         .WebDisableDateRecognition = False
  24.         .WebDisableRedirections = False
  25.         .Refresh BackgroundQuery:=False
  26.     End With
  27. Sub End
複製代碼

作者: GBKEE    時間: 2014-4-22 20:39

回復 2# smart3135
試試看
  1. Option Explicit
  2. Sub 抓季損益表資料()
  3.     Dim Rng As Range, AR(), URL As String, E As Variant
  4.     For E = Sheets.Count To 2 Step -1
  5.         Sheets(E).Delete   '工作表刪除
  6.     Next
  7.     AR = Array(2303, 2485, 2030)
  8.     Sheets(1).Range("A1:A3") = Application.WorksheetFunction.Transpose(AR)
  9.     Set Rng = Sheets(1).Range("A1:A3")
  10.     For Each E In Rng   '迴圈 儲存格
  11.     ' For Each E In AR  '迴圈 也可以用陣列
  12.         With Sheets.Add(, Sheets(1))  '新增工作表
  13.             .Name = E
  14.             URL = "URL;https://djinfo.cathaysec.com.tw/Z/ZC/ZCQ/ZCQ.DJHTM?A=" & E
  15.             With .QueryTables.Add(Connection:=URL, Destination:=.Range("$A$1"))
  16.                 .Name = "ZCQ.DJHTM?A=" & E
  17.                 .PreserveFormatting = True
  18.                 .BackgroundQuery = True
  19.                 .RefreshStyle = xlInsertDeleteCells
  20.                 .SaveData = True
  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.         End With
  31.     Next
  32. End Sub
複製代碼

作者: smart3135    時間: 2014-4-23 00:37

回復 3# GBKEE
感謝GBKEE大大指點新手,目前人在上班,等下班再來測試結果,也會試著了解其中的語法,有問題再請您多多指點,再次感謝!
作者: smart3135    時間: 2014-4-23 09:46

回復 3# GBKEE
感謝GBKEE版主的分享,這個真的是太棒了,雖然我裡面很多的程式碼和語法我還是一知半解,但確實是有接近我想要寫出的結果
另外有個問題請教一下,就是AR = Array(2303, 2485, 2030)只能一個一個代號加入,能否寫成用一個區間範圍來設定
例如1101-2330之間所有符合的股票代號,並讓VBA自行判定非股票代碼的數字就不是抓資料,再請指點,感謝!
作者: GBKEE    時間: 2014-4-23 20:37

回復 5# smart3135
  1. Option Explicit
  2. Sub 抓季損益表資料()
  3.     Dim E As Integer
  4.     Application.DisplayAlerts = False  '停止系統的警告提示
  5.     For E = 1101 To 2330
  6.         With Sheets.Add(, Sheets(1))   '新增工作表
  7.             .Name = E
  8.             URL = "URL;https://djinfo.cathaysec.com.tw/Z/ZC/ZCQ/ZCQ.DJHTM?A=" & E
  9.             With .QueryTables.Add(Connection:=URL, Destination:=.Range("$A$1"))
  10.                 .Name = "ZCQ.DJHTM?A=" & E
  11.                 .PreserveFormatting = True
  12.                 .BackgroundQuery = True
  13.                 .RefreshStyle = xlInsertDeleteCells
  14.                 .SaveData = True
  15.                 .AdjustColumnWidth = True
  16.                 .RefreshPeriod = 0
  17.                 .WebSelectionType = xlSpecifiedTables
  18.                 .WebFormatting = xlWebFormattingNone
  19.                 .WebTables = "3"
  20.                 .WebPreFormattedTextToColumns = True
  21.                 .WebConsecutiveDelimitersAsOne = True
  22.                 .Refresh BackgroundQuery:=False
  23.             End With
  24.             
  25.             If .[A1] = -E Then  '這網頁如股票代碼錯誤會傳回負號.
  26.                 Stop            'STOP 是給你回到工作表驗證用,可刪掉這程式碼
  27.                 ActiveSheet.Delete
  28.             End If
  29.         End With
  30.     Next
  31.     Application.DisplayAlerts = True   '程式結速:恢復系統的警告提示
  32. End Sub
複製代碼

作者: smart3135    時間: 2014-4-24 06:33

回復 6# GBKEE
感謝版主的回答,另外想再請教一個問題,不知道VBA有沒有辦法將我抓取下來的資料貼到記事本再自動存檔
之前有嚐試過,但EXCEL VBA似乎沒法控制EXCEL以外的軟體或程式,後來我是使用EXCEL另存新檔中的存成
文字檔(tab字元分隔)(*txt),這樣可以存成文字檔,不過不知道存檔的路徑資料夾有沒有辦用先前做出迴圈的變數E來指定
例如:我想將抓取下來的1101季損益表先放到sheet(1),再另存成XYZ.TXT,存檔路徑是C:\E\XYZ.TXT
其中E就是我希望能隨著抓取的股票代號一起變更的變數,也就是若抓取的資料是1101,那麼存檔路徑就是C:\1101\XYZ.TXT
存檔路徑資料夾若VBA有辦法利用程式碼新增當然最好,如果沒辦法的話我可以自己建立,完成後將1101季損益表的工作表刪除,
再新增下一個1102季損益表的工作表,再重覆上述的動作,問題有點多,希望我表達的意思不會太難懂,再麻煩大大囉!感謝!
作者: GBKEE    時間: 2014-4-24 09:07

本帖最後由 GBKEE 於 2014-4-24 09:11 編輯

回復 7# smart3135
試試看
  1. Option Explicit
  2. Sub 抓季損益表資料()
  3.     Dim E As Integer, URL As String, xPath As String
  4.     URL = "URL;https://djinfo.cathaysec.com.tw/Z/ZC/ZCQ/ZCQ.DJHTM?A="
  5.     xPath = "C:\季損益表"
  6.     '存檔路徑是C:\E\XYZ.TXT, 建議改為 C:\季損益表\1101.txt
  7.     With ThisWorkbook
  8.        ' If .Sheets.Count = 1 Then .Sheets.Add  '配合讀取txt檔到工作表時必須有2張工作表
  9.         With .Sheets(1)   '活頁簿的第 1 張工作表
  10.             If .QueryTables.Count = 0 Then
  11.                 With .QueryTables.Add(Connection:=URL, Destination:=.Range("$A$1"))
  12.                     .Refresh BackgroundQuery:=False
  13.                 End With
  14.             End If
  15.             For E = 1101 To 2330
  16.                 With .QueryTables(1)
  17.                     .Connection = URL & E
  18.                     .PreserveFormatting = True
  19.                     .BackgroundQuery = True
  20.                     .RefreshStyle = xlInsertDeleteCells
  21.                     .SaveData = True
  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.                 If .[A1] <> -E Then  '這網頁如股票代碼錯誤會傳回負號.
  32.                     If Dir(xPath, vbDirectory) = "" Then MkDir xPath '目錄不存在則新徵增此目錄
  33.                     Maketxt xPath & "\" & E & ".TXT", .QueryTables(1)
  34.                     'Redalltxt xPath & "\" & E & ".TXT"  '讀取txt檔到工作表
  35.                 End If
  36.             Next
  37.         End With
  38.     End With
  39. End Sub
  40. Sub Maketxt(xF As String, Q As QueryTable)   '將匯入資料存入指定的txt
  41.     Dim fs As Object, E As Range, C As Variant
  42.     Set fs = CreateObject("Scripting.FileSystemObject")
  43.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  44.     For Each E In Q.ResultRange.Rows
  45.         C = Application.Transpose(Application.Transpose(E.Value))
  46.         C = Join(C, vbTab)
  47.         fs.WriteLine C
  48.     Next
  49.     fs.Close
  50. End Sub
  51. Sub Redalltxt(xF As String)   '
  52.     Dim fs As Object, E, D As New DataObject
  53.     'DataObject 物件 在進行轉換動作時,做為格式化文字資料的暫存區域。其也可以暫存和儲存在 DataObject 的文字片段相關的格式。
  54.     '宣告 Dim D As New DataObject '須在工具-> 設定引用項目加入 新增引用 Microsoft Forms 2.0 Object Library ,專案 加入一表單即可
  55.     Set fs = CreateObject("Scripting.FileSystemObject")
  56.     Set fs = fs.OpenTextFile(xF, 1)
  57.      E = fs.readall
  58.     fs.Close
  59.     With D
  60.         .SetText E
  61.         .PutInClipboard
  62.         With Sheets(2)
  63.             .UsedRange.Clear
  64.             .Activate
  65.             .Range("A1").Select
  66.             .PasteSpecial Format:="Unicode 文字"
  67.             .Cells.Font.Size = 12
  68.             .Cells.Font.Bold = False
  69.             .Cells.EntireColumn.AutoFit
  70.         End With
  71.     End With
  72. End Sub
  73. Sub Set_FormDLL()   '新增引用 Microsoft Forms 2.0 Object Library
  74.     On Error Resume Next
  75.     FormDLL = "FM20.DLL"
  76.     ThisWorkbook.VBProject.References.AddFromFile "C:\windows\system32\" & FormDLL
  77. '2003版的目錄為 C:\windows\system32\ ,你需修改此目錄
  78. End Sub
複製代碼
[attach]18130[/attach]
作者: smart3135    時間: 2014-4-24 09:35

回復 8# GBKEE
WOW,GBKEE版主真的太神了,裡面的語法有好多還看不懂,目前正用逐行執行來了解,慢慢消化吸收,很感謝您的回答
不過可能我前面表達的不是很清楚,就您的程式碼來說,產生的結果會變成在C:\季損益表\1101.txt,1102.txt,1103.txt
也就是在C槽季損益表資料夾下會產生一個個照個股代碼命名的txt檔,但我希望產生的結果是C:\季損益表\1101\ISQ.txt
C:\季損益表\1102\ISQ.txt,C:\季損益表\1103\ISQ.txt,也就是txt檔名是固定的,由我自己指定檔名,這裡是先預設ISQ.txt
而能隨著個股代碼變動的是資料夾名稱,資料夾若無法由VBA產生我可以自行建立,不知道VBA有沒有辦法做到這樣的結果
再次懇請大大指點迷津,感謝!

    [attach]18131[/attach]
[attach]18132[/attach]
作者: GBKEE    時間: 2014-4-24 10:05

本帖最後由 GBKEE 於 2014-4-25 05:45 編輯

回復 9# smart3135
  1. Option Explicit
  2. Sub Ex()
  3.     MkDir_Sub "D:\Test\季損益表\1103\ISQ.txt"
  4. End Sub
  5. Sub MkDir_Sub(S As String)
  6.     Dim AR, i As Integer, xPath As String
  7.     If Dir(S) = "" Then
  8.         AR = Split(S, "\")
  9.         '如S參數所接收字串="D:\MYSUB\ABC\1101.TXT
  10.         'Split函數將S以"\"分割為陣列
  11.         'AR(0) = "D:"
  12.         'AR(1) = "MYSUB"
  13.         'AR(2) = "ABC"
  14.         'AR(3) = "1101.TXT"
  15.         'UBound(AR)傳回AR陣列的上限元素索引值,3
  16.         xPath = AR(0)
  17.         For i = 1 To UBound(AR) - 1
  18.             xPath = xPath & "\" & AR(i)
  19.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  20.             'MkDir : 創建目錄
  21.         Next
  22.     End If
  23. End Sub
複製代碼

作者: smart3135    時間: 2014-4-24 10:13

回復 8# GBKEE
再補充一下,當抓取資料的網站查無該資料時就會出錯,因為我的連結是抓損益季表(合併財報),而當個股無合併財報可抓取資料時就會出錯
但查詢損益表(季表)是有資料的,不知VBA程式碼能不能做到當主要網頁資料[損益季表(合併財報)]抓不到時就去抓次要網頁資料[損益表(季表)]
[attach]18133[/attach]

損益季表(合併財報0
[attach]18134[/attach]

損益表(季表)
[attach]18135[/attach]
作者: smart3135    時間: 2014-4-24 13:41

本帖最後由 smart3135 於 2014-4-24 13:43 編輯
回復  smart3135
試試看
GBKEE 發表於 2014-4-24 09:07


呼!花了點時間慢慢研究一個個程式碼的意思及語法,再將GBKEE版大提供的程式碼稍做修改,終於完成了!現在只要執行VBA就能將我要的ISQ.TXT檔放在
迴圈變數E所產生的資料夾下,也就是C:\季損益表\1101\、C:\季損益表\1102\,唯一要注意的是C槽下的季損益表資料夾一定要自己先建立,否則執行程式時會出錯
現在就只剩下上一篇提出的問題:當抓取網頁資料時若無資料要如何跳過或去抓取有資料的網頁以避免出錯,再請GBKEE大大指點囉!感恩!
  1. Option Explicit
  2. Sub 抓季損益表資料()
  3.     Dim E As Integer, URL As String, xPath As String, ISQ As String
  4.     URL = "URL;https://djinfo.cathaysec.com.tw/Z/ZC/ZCQ/ZCQ.DJHTM?A="
  5.     For E = 1101 To 2330
  6.         xPath = "C:\" & "季損益表" & "\" & E & "\"
  7.         '存檔路徑是C:\E\XYZ.TXT, 建議改為 C:\季損益表\1101.txt
  8.         With ThisWorkbook
  9.            ' If .Sheets.Count = 1 Then .Sheets.Add  '配合讀取txt檔到工作表時必須有2張工作表
  10.             With .Sheets(1)   '活頁簿的第 1 張工作表
  11.                 If .QueryTables.Count = 0 Then
  12.                     With .QueryTables.Add(Connection:=URL, Destination:=.Range("$A$1"))
  13.                         .Refresh BackgroundQuery:=False
  14.                     End With
  15.                 End If
  16.                     With .QueryTables(1)
  17.                         .Connection = URL & E
  18.                         .PreserveFormatting = True
  19.                         .BackgroundQuery = True
  20.                         .RefreshStyle = xlInsertDeleteCells
  21.                         .SaveData = True
  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.                     If .[A1] <> -E Then  '這網頁如股票代碼錯誤會傳回負號.
  32.                         If Dir(xPath, vbDirectory) = "" Then MkDir xPath '目錄不存在則新徵增此目錄
  33.                         Maketxt xPath & "ISQ.TXT", .QueryTables(1)
  34.                         'Redalltxt xPath & "\" & E & ".TXT"  '讀取txt檔到工作表
  35.                     End If
  36.                
  37.             End With
  38.         End With
  39.     Next
  40. End Sub
  41. Sub Maketxt(xF As String, Q As QueryTable)   '將匯入資料存入指定的txt
  42.     Dim fs As Object, E As Range, C As Variant
  43.     Set fs = CreateObject("Scripting.FileSystemObject")
  44.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  45.     For Each E In Q.ResultRange.Rows
  46.         C = Application.Transpose(Application.Transpose(E.Value))
  47.         C = Join(C, vbTab)
  48.         fs.WriteLine C
  49.     Next
  50.     fs.Close
  51. End Sub
  52. Sub Redalltxt(xF As String)   '
  53.     Dim fs As Object, E, D As New DataObject
  54.     'DataObject 物件 在進行轉換動作時,做為格式化文字資料的暫存區域。其也可以暫存和儲存在 DataObject 的文字片段相關的格式。
  55.     '宣告 Dim D As New DataObject '須在工具-> 設定引用項目加入 新增引用 Microsoft Forms 2.0 Object Library ,專案 加入一表單即可
  56.     Set fs = CreateObject("Scripting.FileSystemObject")
  57.     Set fs = fs.OpenTextFile(xF, 1)
  58.      E = fs.readall
  59.     fs.Close
  60.     With D
  61.         .SetText E
  62.         .PutInClipboard
  63.         With Sheets(2)
  64.             .UsedRange.Clear
  65.             .Activate
  66.             .Range("A1").Select
  67.             .PasteSpecial Format:="Unicode 文字"
  68.             .Cells.Font.Size = 12
  69.             .Cells.Font.Bold = False
  70.             .Cells.EntireColumn.AutoFit
  71.         End With
  72.     End With
  73. End Sub
  74. Sub Set_FormDLL()   '新增引用 Microsoft Forms 2.0 Object Library
  75.     On Error Resume Next
  76.     FormDLL = "FM20.DLL"
  77.     ThisWorkbook.VBProject.References.AddFromFile "C:\windows\system32\" & FormDLL
  78. '2003版的目錄為 C:\windows\system32\ ,你需修改此目錄
  79. End Sub
複製代碼

作者: GBKEE    時間: 2014-4-24 16:55

本帖最後由 GBKEE 於 2014-4-24 17:04 編輯

回復 12# smart3135
  1. Option Explicit
  2. Sub 抓季損益表資料()
  3.     Dim E As Integer, URL As String, xPath As String, xFile As String
  4.     Dim Msg As Boolean
  5.     URL = "URL;https://djinfo.cathaysec.com.tw/Z/ZC/ZCQ/ZCQ.DJHTM?A="
  6.     xPath = "C:\季損益表"
  7.     With ThisWorkbook
  8.         With .Sheets(1)      '活頁簿的第 1 張工作表
  9.             If .QueryTables.Count = 0 Then
  10.                 With .QueryTables.Add(Connection:=URL, Destination:=.Range("$A$1"))
  11.                     .Refresh BackgroundQuery:=False
  12.                 End With
  13.             End If
  14.             For E = 1339 To 2330
  15. ER:
  16.                 With .QueryTables(1)
  17.                     If Msg = False Then
  18.                       .Connection = URL & E
  19.                     ElseIf Msg Then
  20.                                   'https://djinfo.cathaysec.com.tw/z/zc/zcq/zcq0_1339_ACC.djhtm   損益表(累計季表)
  21.                        .Connection = "URL;https://djinfo.cathaysec.com.tw/z/zc/zcq/zcq0_" & E & "_ACC.djhtm"
  22.                     End If
  23.                     .PreserveFormatting = True
  24.                     .BackgroundQuery = True
  25.                     .RefreshStyle = xlInsertDeleteCells
  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.                     .Refresh BackgroundQuery:=False
  35.                 End With
  36.                 If InStr(.[A3], "查無") Then Msg = True: GoTo ER
  37.                 If InStr(.[A3], "個股代碼錯誤") = 0 Then '這網頁如股票代碼錯誤會傳回負號.
  38.                      xFile = xPath & "\" & E & "\ISQ.txt"
  39.                     MkDir_Sub xFile       '10#的程式 'C槽下的季損益表資料夾不需先建立
  40.                     Maketxt xFile, .QueryTables(1)
  41.                 End If
  42.                 Msg = False
  43.             Next
  44.         End With
  45.     End With
  46. End Sub
複製代碼

作者: smart3135    時間: 2014-4-24 19:54

回復 13# GBKEE
抱歉,GBKEE大大,圖片中的語法一開始就執行錯誤,不知道是否語法有誤,這段語法真的看不懂,再請您教導一下,感謝!
[attach]18146[/attach]
作者: GBKEE    時間: 2014-4-24 20:11

回復 14# smart3135
註解有在看嗎? 要複製第10#的 MkDir_Sub 程式到模組上.
作者: smart3135    時間: 2014-4-24 20:49

回復 15# GBKEE
Sorry,剛剛註解是有看了,不過不太懂意思,原來是要把先前#10的程式碼放到模組中,之後就解決了
VBA執行大量迴圈後似乎會佔用記憶體的空間,導致迴圈的執行到後面會越來越慢,不知道我的觀念對不對
目前正在搜索有關釋放記憶體的文章,再次大力感謝GBKEE大大不厭其煩的指導^^:handshake
作者: smart3135    時間: 2014-4-25 05:23

本帖最後由 smart3135 於 2014-4-25 05:25 編輯

回復 8# GBKEE
GBKEE版主您好,昨天您提到將EXCEL匯入的資料存入指定的txt,我用逐行執行,發現它是用迴圈的方式,將EXCEL匯入的資料一列一列的存入指定的txt中
直到遇到空白資料即停止迴圈不再存入,想請問若要將EXCEL匯入的資料存入到txt中,是只能用這種一列一列存入的方式嗎?
這種方式應該就像是點選EXCEL的第一列,然後按滑鼠右鍵複製(或Ctrl+C),再貼到txt中的第一列,第二列資料就換到EXCEL第二列重覆一樣的動作
直到沒有資料能貼上為止,不知道我這樣解讀對不對,主要是想請問,有沒有方法能讓EXCEL資料,像點選EXCEL左上角的全選(Cells.select),然後直接全部複製,
再全部直接貼到txt中,這樣應該就不用走迴圈,一次貼上即可,因為不清楚VBA有沒有語法能做到這樣,所以要再請您幫忙解惑一下囉!感謝!
  1. Sub Maketxt(xF As String, Q As QueryTable)   '將匯入資料存入指定的txt
  2.     Dim fs As Object, E As Range, C As Variant
  3.     Set fs = CreateObject("Scripting.FileSystemObject")
  4.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  5.     For Each E In Q.ResultRange.Rows
  6.         C = Application.Transpose(Application.Transpose(E.Value))
  7.         C = Join(C, vbTab)
  8.         fs.WriteLine C
  9.     Next
  10.     fs.Close
  11. End Sub
複製代碼

作者: GBKEE    時間: 2014-4-25 05:57

本帖最後由 GBKEE 於 2014-4-25 07:28 編輯

回復 17# smart3135
10# 的程式碼看不懂,已加註說明了.
會出現記憶體不足的視窗,在XP,記憶體1GB,2003版,執行5分鐘內可完成,擴充你的記憶體試試看
全部直接貼到txt中,這樣應該就不用走迴圈,慢慢再研究.
作者: smart3135    時間: 2014-4-25 06:21

本帖最後由 smart3135 於 2014-4-25 06:22 編輯

回復 18# GBKEE
不好意思,又發現一個問題要來請教您了,先前有向您請教當損益季表(合併財報)的資料抓不到時,就去抓損益表(季表),其中的關鍵字是在A3儲存格
鍵入查無,則第一個連結抓不到時就會去抓第二個連結的資料,但我在試著抓損益年表時,當個股不存在時,不是出現個股代碼錯誤,而是在A3出現查無損益年表(合併報表)
這時會去抓第二個連結,結果一樣會在A3出現查無損益年表,這時就無法跳出迴圈,變成一直在迴圈裡打轉了,兩個無法抓取資料的連結都在A3出現相同的關鍵字
以致程式碼無法區別,就持續走無盡迴圈,不知道這個問題有沒有辦法解決?資料一次貼上的方式我會再慢慢try,感謝您耐心的回答,謝謝!
  1. Option Explicit
  2. Sub 抓年損益表資料()
  3.     Dim E As Integer, URL As String, xPath As String, xFile As String
  4.     Dim Msg As Boolean
  5.     URL = "URL;https://djinfo.cathaysec.com.tw/z/zc/zcq/zcqa/zcqa.djhtm?A="
  6.     xPath = "G:\財報資料"
  7.     With ThisWorkbook
  8.         With .Sheets(1)      '活頁簿的第 1 張工作表
  9.             If .QueryTables.Count = 0 Then
  10.                 With .QueryTables.Add(Connection:=URL, Destination:=.Range("$A$1"))
  11.                     .Refresh BackgroundQuery:=False
  12.                 End With
  13.             End If
  14.             For E = 1341 To 2000
  15. ER:
  16.                 With .QueryTables(1)
  17.                     If Msg = False Then
  18.                       .Connection = URL & E
  19.                     ElseIf Msg Then
  20.                     'https://djinfo.cathaysec.com.tw/z/zc/zcq/zcqa/zcqa0_1339_ACC.djhtm   損益表(年表)
  21.                        .Connection = "URL;https://djinfo.cathaysec.com.tw/z/zc/zcq/zcqa/zcqa0_" & E & "_ACC.djhtm"
  22.                     End If
  23.                     .PreserveFormatting = True
  24.                     .BackgroundQuery = True
  25.                     .RefreshStyle = xlInsertDeleteCells
  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.                     .Refresh BackgroundQuery:=False
  35.                 End With
  36.                 If InStr(.[A3], "查無") Then Msg = True: GoTo ER
  37.                 If InStr(.[A3], "個股代碼錯誤") = False Then '這網頁如股票代碼錯誤會傳回負號.
  38.                      xFile = xPath & "\" & E & "\IS.txt"
  39.                     MkDir_Sub xFile       '10#的程式 'C槽下的季損益表資料夾不需先建立
  40.                     Maketxt xFile, .QueryTables(1)
  41.                 End If
  42.                 Msg = False
  43.             Next
  44.         End With
  45.     End With
  46. End Sub
複製代碼

作者: smart3135    時間: 2014-4-25 06:44

回復 18# GBKEE
抱歉,剛剛試著試著,好像成功了,造成您的困擾,真不好意思!
作者: GBKEE    時間: 2014-4-25 07:15

回復 19# smart3135
你用的是 https://djinfo.cathaysec.com.tw/z/zc/zcq/zcqa/zcqa.djhtm
可修改如下
  1. End With
  2.                
  3.                 If InStr(.[A3], "查無") And Msg = True Then GoTo xlNext
  4.                 If InStr(.[A3], "查無") Then Msg = True: GoTo ER
  5.                 If InStr(.[A3], "個股代碼錯誤") = False Then '這網頁如股票代碼錯誤會傳回負號.
  6.                     xFile = xPath & "\" & E & "\IS.txt"
  7.                     MkDir_Sub xFile       '10#的程式 'C槽下的季損益表資料夾不需先建立
  8.                     Maketxt xFile, .QueryTables(1)
  9.                 End If
  10. xlNext:
  11.                 Msg = False
  12.             Next
複製代碼

作者: smart3135    時間: 2014-4-25 10:43

本帖最後由 smart3135 於 2014-4-25 10:46 編輯

回復 21# GBKEE

1420月營收




GBKEE版主您好,請見以上連結,目前已無1420這支個股,因為1420潤泰紡織已併入2915潤泰全,但該網站仍將1420直接顯示2915潤泰全的合併月膋收
在VBA在擷取合併月營收時仍會擷取到資料,我試了很久,try了很多條件仍無法避免,不知能否利用VBA寫出類似像您在21#回覆的程式碼避免擷取到這種已無個股代號的資料呢?謝謝!
[attach]18160[/attach]
作者: GBKEE    時間: 2014-4-25 11:18

本帖最後由 GBKEE 於 2014-4-25 12:47 編輯

回復 22# smart3135
  1. End With               
  2.                 If E = 1420 Then GoTo xlNext   '加上試試看
  3.             'If InStr(.[A3], "查無") And Msg = True Or E = 1420 Then GoTo xlNext  '或者可這樣寫
  4.             If InStr(.[A3], "查無") Then Msg = True: GoTo ER
  5.                 If InStr(.[A3], "個股代碼錯誤") = False Then '這網頁如股票代碼錯誤會傳回負號.
  6.                     xFile = XPath & "\" & E & "\IS.txt"
  7.                     MkDir_Sub xFile       '10#的程式 'C槽下的季損益表資料夾不需先建立
  8.                     Maketxt xFile, .QueryTables(1)
  9.                 End If
  10. xlNext:
  11.                 Msg = False
  12.             Next
複製代碼

作者: smart3135    時間: 2014-4-25 11:52

回復 23# GBKEE
GBKEE版主您好,將您的程式碼套入之後是可以將1420跳過不抓資料了,不過因為1420也是在迴圈變數E的其中一碼,是不是無法用迴圈方式去避免抓取資料
只能一個一個像這樣[If E = 1420 Then GoTo xlNext]設定讓它跳過呢?因為像這種股票還真不少,要一個一個找出來可能要花些功夫
另外像這段[If InStr(.[A3], "查無") And Msg = True Or E = 2149 Then GoTo xlNext]當中的2149是代表什麼呢?我把Or E = 2149拿掉似乎不影響擷取資料
這個網站的資料出現"查無"是在A2儲存格,所以我把A3改成A2,附上程式碼,謝謝!
  1. Option Explicit
  2. Sub 抓季月營收資料()
  3.     Dim E As Integer, URL As String, xPath As String, xFile As String
  4.     Dim Msg As Boolean
  5.     URL = "URL;https://djinfo.cathaysec.com.tw/Z/ZC/ZCH/ZCH.DJHTM?A="
  6.     xPath = "G:\財報資料"
  7.     With ThisWorkbook
  8.         With .Sheets(1)      '活頁簿的第 1 張工作表
  9.             If .QueryTables.Count = 0 Then
  10.                 With .QueryTables.Add(Connection:=URL, Destination:=.Range("$A$1"))
  11.                     .Refresh BackgroundQuery:=False
  12.                 End With
  13.             End If
  14.                 Rows(1).Delete
  15.                 Columns(1).Delete
  16.             For E = 1101 To 3000
  17. ER:
  18.                 With .QueryTables(1)
  19.                     .Connection = URL & E
  20.                     .PreserveFormatting = True
  21.                     .BackgroundQuery = True
  22.                     .RefreshStyle = xlInsertDeleteCells
  23.                     .SaveData = True
  24.                     .AdjustColumnWidth = True
  25.                     .RefreshPeriod = 0
  26.                     .WebSelectionType = xlSpecifiedTables
  27.                     .WebFormatting = xlWebFormattingNone
  28.                     .WebTables = "3"
  29.                     .WebPreFormattedTextToColumns = True
  30.                     .WebConsecutiveDelimitersAsOne = True
  31.                     .Refresh BackgroundQuery:=False
  32.                 End With
  33.                 If E = 1420 Then GoTo xlNext   '加上試試看
  34.                 If InStr(.[A2], "查無") And Msg = True Then GoTo xlNext
  35.                 If InStr(.[A2], "查無") Then Msg = True: GoTo ER
  36.                 If InStr(.[A3], "個股代碼錯誤") = False Then '這網頁如股票代碼錯誤會傳回負號.
  37.                      xFile = xPath & "\" & E & "\REVENUE.txt"
  38.                     MkDir_Sub xFile       '10#的程式 'C槽下的季損益表資料夾不需先建立
  39.                     Maketxt xFile, .QueryTables(1)
  40.                 End If
  41. xlNext:
  42.              Msg = False
  43.             Next
  44.         End With
  45.     End With
  46. End Sub
複製代碼

作者: GBKEE    時間: 2014-4-25 13:03

回復 24# smart3135
1420 key錯成 2149 可簡化不需 If E = 1420 Then GoTo xlNext
  1. Rows(1).Delete
  2.                 Columns(1).Delete
  3.             AR = Array(1420, 1580, 2000)  '你是要一個一個找出的
  4.             For E = 1101 To 3000
  5.                 X = Application.Match(E, AR, 0)
  6.                 If IsNumeric(X) Then GoTo xlNext  '直接到 xlNext行
  7.                                                  ' 'If E = 1420 Then GoTo xlNext   '不需要
  8. ER:
  9.                 With .QueryTables(1)
  10.                
複製代碼

作者: smart3135    時間: 2014-4-25 13:40

回復 25# GBKEE
感謝版主的回覆,看來我只能一個一個把有問題的找出來了,不過照您25#回覆的程式碼,可以簡化一些,感謝幫忙
另外我發現這個擷取資料的VBA最花時間的地方就是在將EXCEL資料一列一列匯入到txt,之前有向您提及我要自己try看看能不能用一次貼上的方式
但try了很多次仍是無法達成,主要在於對程式碼較不了解,比較不清楚怎麼做變化,因為匯入的資料要從1101~9962,資料蠻龐大的,若跑完整個VBA
大約要耗時40分鐘以上,所以才希望能夠讓程式的動作再簡化一些,這應該是最後一次需要做修正了,如果可以的話再請版主多指點一下囉!萬分感謝!
附上您先前提供的程式碼
  1. Sub Maketxt(xF As String, Q As QueryTable)   '將匯入資料存入指定的txt
  2.     Dim fs As Object, E As Range, C As Variant
  3.     Set fs = CreateObject("Scripting.FileSystemObject")
  4.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  5.     For Each E In Q.ResultRange.Rows
  6.         C = Application.Transpose(Application.Transpose(E.Value))
  7.         C = Join(C, vbTab)
  8.         fs.WriteLine C
  9.     Next
  10.     fs.Close
  11. End Sub
複製代碼
另外25#中的AR及X未定義,我直接將兩個都定義成Variant,就可以順利執行程式了
作者: GBKEE    時間: 2014-4-25 18:55

本帖最後由 GBKEE 於 2014-4-26 15:42 編輯

回復 26# smart3135
大約要耗時40分鐘以上,是有點久,電腦要減肥了
建議減肥方式如下
1將下面文字複製到記事本  存檔為附檔名 ".BAT",傳送到桌面上 ,不定時的清理垃圾檔案
2不定時的清空資源回收筒
3 不定時清空IE的瀏覽記錄
4 定時的清理磁碟
5擴充記憶體

4203天仁(後抓取)是錯誤的股票號碼,這些股票名稱(代號) 連續一起輸入在Sheets(2)的A欄
  1. Option Explicit
  2. Sub 抓季月營收資料()
  3.     Dim E As Integer, URL As String, xPath As String, xFile As String
  4.     Dim i As Integer, ii As Integer, Rng As Range, S1 As String, S2 As String, t As Date
  5.     Dim AR()
  6.     t = Time
  7.     AR = Array(4203) '輸入 4203天仁(後抓取)是錯誤的股票號碼
  8.     URL = "URL;https://djinfo.cathaysec.com.tw/Z/ZC/ZCH/ZCH.DJHTM?A="
  9.     xPath = "D:\財報資料"
  10.     With ThisWorkbook
  11.         .Sheets(2).UsedRange.Offset(, 1).Clear
  12.         '4203天仁(後抓取)是錯誤的股票號碼 這些 股票名稱(代號) 連續一起輸入在Sheets(2)的A欄
  13.         Set Rng = .Sheets(2).Range("A:A").SpecialCells(xlCellTypeConstants)
  14.         If Rng Is Nothing Then
  15.             AR = Array()
  16.         ElseIf Rng.Count = 1 Then
  17.             AR = Array(Rng.Value)
  18.         Else
  19.             AR = Application.Transpose(Application.Transpose(Rng))
  20.         End If        '***************************************************
  21.         Application.ScreenUpdating = False
  22.         Application.StatusBar = " "
  23.         With .Sheets(1)      '活頁簿的第 1 張工作表
  24.             If .QueryTables.Count = 0 Then
  25.                 With .QueryTables.Add(Connection:=URL, Destination:=.Range("$A$1"))
  26.                     .Refresh BackgroundQuery:=False
  27.                 End With
  28.             End If
  29.                 .Rows(1).Delete
  30.                 .Columns(1).Delete
  31.             For E = 1101 To 5000
  32.                 With .QueryTables(1)
  33.                     .Connection = URL & E
  34.                     .PreserveFormatting = True
  35.                     .BackgroundQuery = True
  36.                     .RefreshStyle = xlInsertDeleteCells
  37.                     .SaveData = True
  38.                     .AdjustColumnWidth = True
  39.                     .RefreshPeriod = 0
  40.                     .WebSelectionType = xlSpecifiedTables
  41.                     .WebFormatting = xlWebFormattingNone
  42.                     .WebTables = "3"
  43.                     .WebPreFormattedTextToColumns = True
  44.                     .WebConsecutiveDelimitersAsOne = True
  45.                     .Refresh BackgroundQuery:=False
  46.                     If .ResultRange(1) < 0 Or InStr(.ResultRange(2, 1), "查無") Then GoTo xLnext
  47.                     '匯入資料的 A1 < 0  OR  匯入資料的 A2 "查無"
  48.                     S1 = .ResultRange(1)
  49.                     S2 = Mid(S1, 1, InStr(S1, "(") - 1) '股票名稱
  50.                 End With
  51.                 With ThisWorkbook.Sheets(2).Range("B:B")
  52.                     Set Rng = .Find(S2, lookat:=xlPart) '搜尋:股票名稱
  53.                     If Rng Is Nothing Then
  54.                         i = i + 1
  55.                         .Range("A" & i) = S1  '股票名稱代碼
  56.                     Else
  57.                         Rng.Cells(1, 2) = S1   '重複的股票
  58.                         If UBound(Filter(AR, E)) > -1 And UBound(AR) > -1 Then
  59.                         'Filter(AR, E) > -1   '比對到如4203天仁(後抓取)是錯誤
  60.                             Rng.Cells(1, 2) = Rng.Cells(1, 2) & "***" '後抓取是錯誤
  61.                             GoTo xLnext:
  62.                         End If
  63.                         S2 = Mid(Trim(Rng), InStr(Trim(Rng), "(") + 1)
  64.                         S2 = Mid(S2, 1, Len(S2) - 1)    '舊的股票[代碼]
  65.                         xFile = xPath & "\" & S2 & "\*.*" '殺掉所有檔案
  66.                         If Dir(xFile) <> "" Then
  67.                             ii = ii - 1
  68.                             Kill xFile
  69.                             xFile = xPath & "\" & S2
  70.                             If Dir(xFile, vbDirectory) <> "" Then RmDir xFile '資料夾也刪除了
  71.                         End If
  72.                     End If
  73.                 End With
  74.                 ii = ii + 1
  75.                 xFile = xPath & "\" & E & "\REVENUE.txt"
  76.                 MkDir_Sub xFile
  77.                 Maketxt xFile, .QueryTables(1)
  78. xLnext:
  79.                 S1 = " " & Sheets(1).QueryTables(1).ResultRange(1)
  80.                 If Val(S1) < 0 Then S1 = " 查無"
  81.                 Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & "  " & E & S1
  82.             Next
  83.         End With
  84.     End With
  85.     Application.ScreenUpdating = True
  86.     Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & " Ok "
  87.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - t, ["MM分SS秒"])
  88. End Sub
  89. Private Sub Maketxt(xF As String, Q As QueryTable)   '將匯入資料存入指定的txt
  90.     Dim fs As Object, E As Range, C As Variant
  91.     Set fs = CreateObject("Scripting.FileSystemObject")
  92.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  93.     For Each E In Q.ResultRange.Rows
  94.         C = Application.Transpose(Application.Transpose(E.Value))
  95.         C = Join(C, vbTab)
  96.         fs.WriteLine C
  97.     Next
  98.     fs.Close
  99. End Sub
複製代碼

作者: smart3135    時間: 2014-4-26 11:25

回復 27# GBKEE
GBKEE版主您好,今早下班後就開始在Try您在27#回覆的程式碼,結果的確會將一些重覆的個股txt刪除,但不知有沒有辦法將一起建立的資料夾也刪除呢?
舉例來說,1202和2913兩個都是農林,所以程式執行完會將1202的txt刪除,但1202的資料夾仍是存在的,不知沒有沒辦法連資料夾一起刪除呢?
另外還有一個問題,就是這個程式碼保留的資料都是sheet(2)的第二欄個股代號資料,若我沒解讀錯誤的話,程式應該是將個股代碼相同,先抓取的txt刪除,保留後抓取的txt
但就會遇到1233天仁(先抓取)是正確的,4203天仁(後抓取)是錯誤的問題,結果就是正確的1233天仁txt被刪除,這部分我想應該不太好解決
所以,如果可以的話,我還是傾向在您24#回覆的程式碼,用一個一個挑出的方式,這些不需要的代號我都有了,只要輸入AR=Array()中就可以了,只是我要輸入的代號
大概有200個左右,如果全部輸入,如AR=Array(1202,1433,1502,1610.....................)這樣要把200個代碼全部輸入會跳到第二行,然後就會出錯,不知道有沒有辦法
解決這個問題呢?先感謝您的指導!
[attach]18170[/attach]
作者: smart3135    時間: 2014-4-26 14:22

回復 27# GBKEE
版主,不好意思,再請教一個問題,現在我要設定迴圈為for E = 1101  9962,但我已經知道某些數字區間是不需要去擷取的,如果想跳過該使用怎樣的語法呢?先謝謝您!
大概的構想如下:
  1. Dim E As Integer
  2.                          For E = 1101 To 2000
  3.                          IF E = 3800到4100 then goto xlNext '想設定某個區間,請教語法該怎麼設
  4.                          IF E = 6850到8000 then goto xlNext '想設定某個區間,請教語法該怎麼設
  5.                          IF E = 8550到9000 then goto xlNext '想設定某個區間,請教語法該怎麼設
  6.                          IF E = 9000到9800 then goto xlNext '想設定某個區間,請教語法該怎麼設,共四個區間

  7. xlNext:         
  8.                          next
  9. End sub
複製代碼

作者: GBKEE    時間: 2014-4-26 15:45

本帖最後由 GBKEE 於 2014-4-26 15:52 編輯

回復 29# smart3135
1233天仁(先抓取)是正確的,4203天仁(後抓取)是錯誤的問題
這一些錯誤股票名稱(代號) 天仁(4203) 連續一起輸入在Sheets(2)的A欄,後程式可解決.

28# 的所有問題.27#程式碼已更新了,可再看一次,減肥有試一下嗎?

試試看
  1. Sub Ex()
  2.     Dim E As Integer
  3.     For E = 500 To 5000
  4.         Select Case E
  5.             Case 500 To 1000
  6.                 GoTo xNext
  7.             Case 1500 To 2000
  8.                 GoTo xNext
  9.             Case 2500 To 3000
  10.                 GoTo xNext
  11.         End Select
  12.         MsgBox E
  13. xNext:
  14.     Next
  15. End Sub
  16. Sub Ex1()
  17.     Dim E As Integer
  18.     For E = 500 To 5000
  19.         If E >= 500 And E <= 1000 Or E >= 1500 And E <= 2000 Or E >= 2500 And E <= 3000 Then
  20.                 GoTo xNext
  21.         End If
  22.         MsgBox E
  23. xNext:
  24.     Next
  25. End Sub
複製代碼

作者: smart3135    時間: 2014-4-26 19:13

回復 30# GBKEE
先感謝GBKEE版主一一耐心的回答,因為今晚還要上班,所以您在27#更新的程式碼,可能要等到明天才能try了!
至於電腦減肥部分
1將下面文字複製到記事本  存檔為附檔名 ".BAT",傳送到桌面上 ,不定時的清理垃圾檔案-這個BAT檔我一直都有在用,是否每次執行完VBA就要清一次呢?
2不定時的清空資源回收筒 -最近丟到資源回收筒的資料較多,有空會試一下清空會不會好一點
3 不定時清空IE的瀏覽記錄-平常都是用chorme流灠器為主,不過最近因為要EXCEL匯入WEB資料所以有比較常用,會清空再來試試
4 定時的清理磁碟-兩天前才剛將磁碟重組
5擴充記憶體-我的系統是WIN7 64位元+office 2007,記憶體是4G,不知道這樣有需要擴充嗎?

我有發現會跑那麼久是因為我給的區間越大,程式跑到越後面就越慢,例如我程式碼設定For E = 1101 to 9962,只執行一次,跑起來可能需要40分鐘
但我將程式碼設定For E = 1101 to 3000,For E = 3001 to 5000,For E = 5001 to 7000,For E = 7001 to 9962,共執行四次,合計起來的時間就不需要那麼久
E的區間設定越小,完成的時間就越短,這部分就不太理解為什麼會這樣了!

另外雖然您在27#的程式碼已更新,不過還是希望能了解一下我在28#向您提問的AR=Array(1202,1433,1502,1610.....................)這樣要把200個代碼全部輸入
會跳到第二行,然後就會出錯,不知道有沒有辦法解決這個問題呢?

不知道這個AR的Array區間有沒有辦法輸入200個引數以上呢?
作者: GBKEE    時間: 2014-4-26 20:21

本帖最後由 GBKEE 於 2014-4-26 20:22 編輯

回復 31# smart3135
這個BAT檔我一直都有在用,是否每次執行完VBA就要清一次呢?,你要跑這程式當然最好是的,檔案開開關關會製造一些暫存檔,就需要清一下
WIN7 64位元+office 2007,記憶體是4G,是不需擴充了,另就就開機時系統要載太入的常駐應用程式.佔據太多的記憶體.這也是主因之ㄧ.
XP,32位元, 1GB, 2003版, 27#程式 For 1101 To 5000的迴圈 ,減肥後7分鐘內搞定.
E的區間設定越小,完成的時間就越短,這部分就不太理解為什麼會這樣了,這是想當然的
  1. Option Explicit
  2. Sub Ex()
  3.     Dim Ar
  4.     Ar = Array(56, 78, _
  5.          9, 10, 12 _
  6.        , 888, 999, _
  7.        56789)
  8. End Sub
複製代碼
[attach]18172[/attach]
作者: smart3135    時間: 2014-4-26 21:30

回復 32# GBKEE
哇 1101到5000跑完只要七分鐘 好威!
我之前也有試過接下引號跳下一行,但一直失敗,原來要跳下一行前接的下引號後面要有空格,又學到一招了,再次感謝您的指導!
作者: smart3135    時間: 2014-4-27 09:55

回復 27# GBKEE
GBKEE版主早安,有些問題想請教您:
1.今早下班回來就馬上試了您昨天在27#提供的程式碼,我有再加上要跳過的代號在AR中,也照提示將代號都輸入到sheet(2)的A欄
直接跑一次,奇怪的事發生了,我設定For E = 1101 to 5000,每次跑到一半時就會出錯,出錯的位置是在If UBound(Filter(AR, E)) > -1 And UBound(AR) > -1 Then,不清楚哪裡出了問題
附上程式碼和檔案,請您幫忙看看 
2.另外我有發現您27#的程式碼在出錯前的執行時速度非常快,和您先前提供的程式碼讓我在23#完成的程式有很大的落差,這當中究竟有什麼差異呢?為什麼速度會差這麼多呢?
一樣我兩個VBA程式都有附上,也麻煩您幫忙看看為什麼會有如此大的差異
3.我用您先前提供的跑下來,第一段1101 to 5000,費時12分48秒,抓了992筆資料
第二段5001 to 9962,費時13分50秒,抓了515筆資料
我在跑第二段時有先使用清除系統的.bat檔,並將EXCEL關閉再開啟重新執行VBA,結果看來並沒有瘦身的效果,不知道為什麼會這樣?
4.另外在將資料匯入txt的程式碼中,如下
   For Each E In Q.ResultRange.Rows
        C = Application.Transpose(Application.Transpose(E.Value))
        C = Join(C, vbTab)
        fs.WriteLine C
    Next
其中Q.ResultRange.Rows的Rows是不是代表列,也就是將資料一列一列存入txt,直到沒有資料為止
之後我有想到,因為用一列一列的方式來匯入資料要跑很多次迴圈,如果是用一欄一欄的方式匯入就會少跑很多次迴圈
我有試著將Rows改為Columns,但執行到下二行的C = Join(C, vbTab)就會出錯,不知道有沒有辦法用欄的方式匯入呢?

問題有點多,再麻煩您幫忙一下囉!感謝!
  1. Option Explicit
  2. Sub 抓季月營收資料()
  3.     Dim E As Integer, URL As String, xPath As String, xFile As String
  4.     Dim i As Integer, ii As Integer, Rng As Range, S1 As String, S2 As String, t As Date
  5.     Dim AR()
  6.     t = Time
  7.     AR = Array(1202, 1420, 1433, 1502, 1518, 1610, 1716, 2346, 2372, 2391, 2513, 2526, 2541, 2802, 2803, 2804, 2806, _
  8.             2813, 2814, 2815, 2817, 2818, 2819, 2821, 2826, 2830, 2839, 2840, 2843, 2844, 2848, 2907, 2909, 4101, 4112, _
  9.             4175, 4201, 4203, 4204, 4301, 4302, 4405, 4407, 4409, 4410, 4411, 4412, 4504, 4505, 4507, 4508, 4509, 4512, _
  10.             4514, 4516, 4517, 4519, 4520, 4521, 4524, 4525, 4531, 4603, 4604, 4605, 4606, 4607, 4608, 4701, 4704, 4705, _
  11.             4708, 4709, 4710, 4713, 4715, 4718, 4901, 4902, 5001, 5003, 5004, 5005, 5012, 5101, 5311, 5319, 5320, 5322, _
  12.             5323, 5327, 5330, 5331, 5334, 5335, 5337, 5341, 5342, 5354, 5357, 5358, 5359, 5360, 5361, 5362, 5363, 5366, _
  13.             5368, 5369, 5374, 5377, 5379, 5380, 5382, 5389, 5391, 5393, 5394, 5396, 5397, 5399, 5404, 5405, 5408, 5409, _
  14.             5411, 5412, 5415, 5416, 5417, 5418, 5419, 5420, 5421, 5422, 5423, 5424, 5427, 5428, 5430, 5431, 5433, 5435, _
  15.             5440, 5444, 5445, 5446, 5447, 5449, 5453, 5456, 5458, 5459, 5461, 5462, 5463, 5470, 5472, 5476, 5477, 5482, _
  16.             5485, 5486, 5495, 5496, 5499, 5509, 5517, 5527, 5606, 5705, 5804, 5805, 5806, 5807, 5809, 5812, 5814, 5815, _
  17.             5854, 6003, 6006, 6019, 6102, 6106, 6401, 6501, 8001, 8003, 8903, 8904, 8912, 8914, 8915, 8918, 8920, 8922, 8939, 9105, 9909)
  18.             '輸入 4203天仁(後抓取)是錯誤的股票號碼
  19.     URL = "URL;https://djinfo.cathaysec.com.tw/Z/ZC/ZCH/ZCH.DJHTM?A="
  20.     xPath = "G:\財報資料"
  21.     With ThisWorkbook
  22.         .Sheets(2).UsedRange.Offset(, 1).Clear
  23.         '4203天仁(後抓取)是錯誤的股票號碼 這些 股票名稱(代號) 連續一起輸入在Sheets(2)的A欄
  24.         Set Rng = .Sheets(2).Range("A:A").SpecialCells(xlCellTypeConstants)
  25.         If Rng Is Nothing Then
  26.             AR = Array()
  27.         ElseIf Rng.Count = 1 Then
  28.             AR = Array(Rng.Value)
  29.         Else
  30.             AR = Application.Transpose(Application.Transpose(Rng))
  31.         End If        '***************************************************
  32.         Application.ScreenUpdating = False
  33.         Application.StatusBar = " "
  34.         With .Sheets(1)      '活頁簿的第 1 張工作表
  35.             If .QueryTables.Count = 0 Then
  36.                 With .QueryTables.Add(Connection:=URL, Destination:=.Range("$A$1"))
  37.                     .Refresh BackgroundQuery:=False
  38.                 End With
  39.             End If
  40.                 .Rows(1).Delete
  41.                 .Columns(1).Delete
  42.             For E = 1101 To 5000
  43.                 With .QueryTables(1)
  44.                     .Connection = URL & E
  45.                     .PreserveFormatting = True
  46.                     .BackgroundQuery = True
  47.                     .RefreshStyle = xlInsertDeleteCells
  48.                     .SaveData = True
  49.                     .AdjustColumnWidth = True
  50.                     .RefreshPeriod = 0
  51.                     .WebSelectionType = xlSpecifiedTables
  52.                     .WebFormatting = xlWebFormattingNone
  53.                     .WebTables = "3"
  54.                     .WebPreFormattedTextToColumns = True
  55.                     .WebConsecutiveDelimitersAsOne = True
  56.                     .Refresh BackgroundQuery:=False
  57.                     If .ResultRange(1) < 0 Or InStr(.ResultRange(2, 1), "查無") Then GoTo xLnext
  58.                     '匯入資料的 A1 < 0  OR  匯入資料的 A2 "查無"
  59.                     S1 = .ResultRange(1)
  60.                     S2 = Mid(S1, 1, InStr(S1, "(") - 1) '股票名稱
  61.                 End With
  62.                 With ThisWorkbook.Sheets(2).Range("B:B")
  63.                     Set Rng = .Find(S2, lookat:=xlPart) '搜尋:股票名稱
  64.                     If Rng Is Nothing Then
  65.                         i = i + 1
  66.                         .Range("A" & i) = S1  '股票名稱代碼
  67.                     Else
  68.                         Rng.Cells(1, 2) = S1   '重複的股票
  69.                         If UBound(Filter(AR, E)) > -1 And UBound(AR) > -1 Then
  70.                         'Filter(AR, E) > -1   '比對到如4203天仁(後抓取)是錯誤
  71.                             Rng.Cells(1, 2) = Rng.Cells(1, 2) & "***" '後抓取是錯誤
  72.                             GoTo xLnext:
  73.                         End If
  74.                         S2 = Mid(Trim(Rng), InStr(Trim(Rng), "(") + 1)
  75.                         S2 = Mid(S2, 1, Len(S2) - 1)    '舊的股票[代碼]
  76.                         xFile = xPath & "\" & S2 & "\*.*" '殺掉所有檔案
  77.                         If Dir(xFile) <> "" Then
  78.                             ii = ii - 1
  79.                             Kill xFile
  80.                             xFile = xPath & "\" & S2
  81.                             If Dir(xFile, vbDirectory) <> "" Then RmDir xFile '資料夾也刪除了
  82.                         End If
  83.                     End If
  84.                 End With
  85.                 ii = ii + 1
  86.                 xFile = xPath & "\" & E & "\REVENUE.txt"
  87.                 MkDir_Sub xFile
  88.                 Maketxt xFile, .QueryTables(1)
  89. xLnext:
  90.                 S1 = " " & Sheets(1).QueryTables(1).ResultRange(1)
  91.                 If Val(S1) < 0 Then S1 = " 查無"
  92.                 Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & "  " & E & S1
  93.             Next
  94.         End With
  95.     End With
  96.     Application.ScreenUpdating = True
  97.     Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & " Ok "
  98.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - t, ["MM分SS秒"])
  99. End Sub
  100. Private Sub MkDir_Sub(s As String)
  101.     Dim AR, i As Integer, xPath As String
  102.     If Dir(s) = "" Then
  103.         AR = Split(s, "\")
  104.         xPath = AR(0)
  105.         For i = 1 To UBound(AR) - 1
  106.             xPath = xPath & "\" & AR(i)
  107.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  108.         Next
  109.     End If
  110. End Sub
  111. Private Sub Maketxt(xF As String, Q As QueryTable)   '將匯入資料存入指定的txt
  112.     Dim fs As Object, E As Range, C As Variant
  113.     Set fs = CreateObject("Scripting.FileSystemObject")
  114.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  115.     For Each E In Q.ResultRange.Rows
  116.         C = Application.Transpose(Application.Transpose(E.Value))
  117.         C = Join(C, vbTab)
  118.         fs.WriteLine C
  119.     Next
  120.     fs.Close
  121. End Sub
複製代碼
[attach]18174[/attach]
作者: GBKEE    時間: 2014-4-27 15:13

本帖最後由 GBKEE 於 2014-4-27 15:24 編輯

回復 34# smart3135
  1. Option Explicit
  2. Private Sub Test()
  3.     Dim fs As Object, E As Range, C As Variant
  4.     Set fs = CreateObject("Scripting.FileSystemObject")
  5.     Set fs = fs.CreateTextFile("D:\財報資料\1101\Test.TXT", True)
  6.     '創見一個檔案,如檔案存在可覆蓋掉
  7.     '文字檔的寫入是
  8.     For Each E In Sheets(1).UsedRange.Columns
  9.         C = E.Value  '-> 陣列(1 To 列數,1 To 欗數)的二維陣列
  10.         C = Application.Transpose(E.Value) '因為第二維只有一欄,轉置一次可變為一維陣列
  11.        '如E In UsedRange.rows
  12.        'C = E.Value  '-> 陣列(1 To 列數,1 To 欗數)的二維陣列
  13.        'C = Application.Transpose(Application.Transpose(E.Value)) '第二維不只一欄,所以轉置二次才可變為一維陣列
  14.         C = Join(C, vbTab)
  15.         'Join 函數 傳回一個字串,該字串是透過連結某個陣列中的多個子字串而建立的。
  16.         'Join 函數 使用的陣列必須是一維陣列
  17.         fs.WriteLine C
  18.     Next
  19.     fs.Close
  20. End Sub
複製代碼
[attach]18175[/attach]


詳看註解可明瞭.

  1. Option Explicit
  2. Sub 抓季月營收資料()
  3.     Dim E As Integer, URL As String, xPath As String, xFile As String
  4.     Dim i As Integer, ii As Integer, Rng As Range, S1 As String, S2 As String, t As Date
  5.     Dim AR()
  6.     t = Time
  7.     URL = "URL;https://djinfo.cathaysec.com.tw/Z/ZC/ZCH/ZCH.DJHTM?A="
  8.     xPath = "D:\財報資料"
  9.     Application.DisplayStatusBar = True
  10.     With ThisWorkbook
  11.         '兩者取一即可 (選擇儲存格較方便)
  12.         '***'不需要的股票如4203天仁(後抓取)是錯誤的股票號碼 置入-> Ar陣列
  13.    ' AR = Array(1202, 1420, 1433, 1502, 1518, 1610, 1716, 2346, 2372, 2391, 2513, 2526, 2541, 2802, 2803, 2804, 2806, _
  14.             2813, 2814, 2815, 2817, 2818, 2819, 2821, 2826, 2830, 2839, 2840, 2843, 2844, 2848, 2907, 2909, 4101, 4112, _
  15.             4175, 4201, 4203, 4204, 4301, 4302, 4405, 4407, 4409, 4410, 4411, 4412, 4504, 4505, 4507, 4508, 4509, 4512, _
  16.             4514, 4516, 4517, 4519, 4520, 4521, 4524, 4525, 4531, 4603, 4604, 4605, 4606, 4607, 4608, 4701, 4704, 4705, _
  17.             4708, 4709, 4710, 4713, 4715, 4718, 4901, 4902, 5001, 5003, 5004, 5005, 5012, 5101, 5311, 5319, 5320, 5322, _
  18.             5323, 5327, 5330, 5331, 5334, 5335, 5337, 5341, 5342, 5354, 5357, 5358, 5359, 5360, 5361, 5362, 5363, 5366, _
  19.             5368, 5369, 5374, 5377, 5379, 5380, 5382, 5389, 5391, 5393, 5394, 5396, 5397, 5399, 5404, 5405, 5408, 5409, _
  20.             5411, 5412, 5415, 5416, 5417, 5418, 5419, 5420, 5421, 5422, 5423, 5424, 5427, 5428, 5430, 5431, 5433, 5435, _
  21.             5440, 5444, 5445, 5446, 5447, 5449, 5453, 5456, 5458, 5459, 5461, 5462, 5463, 5470, 5472, 5476, 5477, 5482, _
  22.             5485, 5486, 5495, 5496, 5499, 5509, 5517, 5527, 5606, 5705, 5804, 5805, 5806, 5807, 5809, 5812, 5814, 5815, _
  23.             5854, 6003, 6006, 6019, 6102, 6106, 6401, 6501, 8001, 8003, 8903, 8904, 8912, 8914, 8915, 8918, 8920, 8922, 8939, 9105, 9909)
  24.             
  25.         '***A欄中不需要的股票 如4203天仁(後抓取)號碼的儲存格  置入-> Ar陣列
  26.         Set Rng = .Sheets(2).Range("A:A").SpecialCells(xlCellTypeConstants)
  27.         If Rng Is Nothing Then
  28.             AR = Array()
  29.         ElseIf Rng.Count = 1 Then
  30.             AR = Array(Rng.Value)
  31.         Else
  32.             AR = Application.Transpose(Rng.Value)
  33.             
  34.             '先前出錯是這裡寫錯 AR = Application.Transpose(Application.Transpose(Rng.Value))
  35.             'Rng.Value=>單欄二維陣列
  36.         End If
  37.         '***************************************************
  38.         .Sheets(2).UsedRange.Offset(, 1).Clear
  39.         Application.ScreenUpdating = False
  40.         Application.StatusBar = " "
  41.         With .Sheets(1)      '活頁簿的第 1 張工作表
  42.             If .QueryTables.Count = 0 Then
  43.                 With .QueryTables.Add(Connection:=URL, Destination:=.Range("$A$1"))
  44.                     .Refresh BackgroundQuery:=False
  45.                 End With
  46.             End If
  47.             .Rows(1).Delete
  48.             .Columns(1).Delete
  49.             For E = 1101 To 5000
  50.                 If UBound(Filter(AR, E)) > -1 Then GoTo xLnext
  51.                 'Filter(AR, E)函數 等同使用Find方法 如 Set Rng = .Find(S2, lookat:=xlPart) '搜尋:股票名稱
  52.                 With .QueryTables(1)
  53.                     .Connection = URL & E
  54.                     .PreserveFormatting = True
  55.                     .BackgroundQuery = True
  56.                     .RefreshStyle = xlInsertDeleteCells
  57.                     .SaveData = True
  58.                     .AdjustColumnWidth = True
  59.                     .RefreshPeriod = 0
  60.                     .WebSelectionType = xlSpecifiedTables
  61.                     .WebFormatting = xlWebFormattingNone
  62.                     .WebTables = "3"
  63.                     .WebPreFormattedTextToColumns = True
  64.                     .WebConsecutiveDelimitersAsOne = True
  65.                     .Refresh BackgroundQuery:=False
  66.                     If InStr(.ResultRange(2, 1), "查無") Then      '查無這檔股票
  67.                         Mark_Code E                                '查無的股票 放置A攔
  68.                         GoTo xLnext
  69.                     End If
  70.                     S1 = .ResultRange(1)                '匯入資料的第1個儲存格
  71.                     S2 = Mid(S1, 1, InStr(S1, "(") - 1) '股票名稱
  72.                 End With
  73.                
  74.                 With ThisWorkbook.Sheets(2).Range("B:B")
  75.                     Set Rng = .Find(S2, lookat:=xlPart) '搜尋:股票名稱
  76.                     If Rng Is Nothing Then
  77.                         i = i + 1
  78.                         .Range("A" & i) = S1  '股票名稱代碼
  79.                     Else
  80.                        Mark_Code E '重複的股票 放置A攔
  81.                         S2 = Mid(Trim(Rng), InStr(Trim(Rng), "(") + 1)
  82.                         S2 = Mid(S2, 1, Len(S2) - 1)    '舊的股票[代碼]
  83.                         xFile = xPath & "\" & S2 & "\*.*" '殺掉所有檔案
  84.                         If Dir(xFile) <> "" Then
  85.                             ii = ii - 1
  86.                             Kill xFile
  87.                             xFile = xPath & "\" & S2
  88.                             If Dir(xFile, vbDirectory) <> "" Then RmDir xFile '資料夾也刪除了
  89.                         End If
  90.                     End If
  91.                 End With
  92.                 ii = ii + 1
  93.                 xFile = xPath & "\" & E & "\REVENUE.txt"
  94.                 MkDir_Sub xFile
  95.                 Maketxt xFile, .QueryTables(1)
  96. xLnext:
  97.                 S1 = " " & Sheets(1).QueryTables(1).ResultRange(1)
  98.                 If Val(S1) < 0 Then S1 = " 查無"
  99.                 Application.StatusBar = Application.text(Time - t, ["MM分SS秒"]) & " 共匯入 " & ii & " 文字檔,  讀取 " & S1 & " 中..."
  100.             Next
  101.         End With
  102.     End With
  103.     Application.ScreenUpdating = True
  104.     Application.StatusBar = Application.text(Time - t, ["MM分SS秒"]) & " 共匯入 " & ii & " 文字檔,  讀取完畢 !! "
  105.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.text(Time - t, ["MM分SS秒"])
  106.     ThisWorkbook.Save
  107. End Sub
複製代碼
  1. Private Sub Mark_Code(S As Integer)
  2.     With ThisWorkbook.Sheets(2).Range("A:A") '重複的股票 放置A攔
  3.         .Cells(Application.Count(.Cells) + 1, "A") = S
  4.         '股票代號放置 A攔最後一個儲存格
  5.         '執行一次後,下次再執行 [抓季月營收資料]程式時,For 迴圈中可踢除這股票代號
  6.     End With
  7. End Sub
複製代碼
[attach]18176[/attach]
作者: smart3135    時間: 2014-4-28 07:23

本帖最後由 GBKEE 於 2014-4-28 07:29 編輯

回復 35# GBKEE
感謝GBKEE版主這幾天來不斷的教導,真的讓我在EXCEL VBA上學習到很多,其他仍有許多需要擷取的資料,如資產負債表 現金流量表等,這些我都能用這幾天學到的
稍加修改就能完成,唯獨有兩種資料比較特別,我無法獨立完成,所以又要再來請教GBKEE版主了
1.
上櫃月成交資訊

 上面連結為上櫃個股月成交資訊,即使輸入個股代號,網址仍不變,據了解是因為網頁為POST,並非GET,所以沒辦法擷取報表
 不知道有沒有辦法也用VBA做迴圈來擷取資料?(在EXCEL匯入WEB資料時似乎沒法等到下面的成交資訊表格來匯入資訊)
2.請件兩個EXCEL附件,這是在網路上面找到的,主要是要抓一年內的集保資料,但都只能用自行輸入的方式來一個一個擷取資料
 不知道有沒有辦法也用類似這兩天您所提供的程式碼來抓取集保資料,結果就如附件中的TXT檔,再麻煩您指點一下囉!感謝!
   
集保資料


[attach]18178[/attach]
作者: smart3135    時間: 2014-4-28 07:41

回復 35# GBKEE
抱歉 檔案不知道為什麼上傳失敗 所以再上傳一次
[attach]18180[/attach]
作者: GBKEE    時間: 2014-4-28 11:23

回復 37# smart3135
先回覆上櫃月成交資訊,事情忙完再繼續回覆你
  1. Option Explicit
  2. Dim IE As Object
  3. Sub IE_Application()
  4.     Set IE = CreateObject("InternetExplorer.Application")
  5.     With IE
  6.         .Navigate "http://www.gretai.org.tw/ch/stock/statistics/monthly/st42.php"
  7.      '   .Visible = True   '不顯示ie
  8.         Do While .Busy Or .ReadyState <> 4: DoEvents: Loop
  9.   End With
  10. End Sub
  11. Sub 上櫃月成交資訊()
  12.     Dim E As Range, xPath As String, xFile As String, A As Object, FS As Object, F As Object
  13.     Dim i As Integer, ii As Integer, t As Date, AR(), Rng As Range, r, c, s
  14.     Set FS = CreateObject("Scripting.FileSystemObject")
  15.     Ie_Url = "http://www.gretai.org.tw/ch/stock/statistics/monthly/st42.php"
  16.     t = Time
  17.     Application.DisplayStatusBar = True
  18.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  19.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  20.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  21.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  22.     xPath = "D:\財報資料"
  23.     IE_Application    '
  24.     Application.StatusBar = " "
  25.     For Each E In Rng
  26.         With IE
  27.             Set A = .Document.getelementbyid("input_stock_code")
  28.             A.Value = E
  29.             A.ParentNode.submit
  30.             Do While .Busy Or .ReadyState <> 4:    Loop
  31.             Set A = .Document.getelementsbytagname("TABLE")
  32.             xFile = xPath & "\" & E & "\上櫃月成交.txt"
  33.             MkDir_Sub xFile
  34.             With FS.CreateTextFile(xFile, True)
  35.                 For i = 1 To A(2).Rows.Length - 1
  36.                     s = ""
  37.                     For c = 0 To A(2).Rows(i).Cells.Length - 1
  38.                         s = s & A(2).Rows(i).Cells(c).innertext & vbTab
  39.                     Next
  40.                     .WriteLine s
  41.                 Next
  42.                 .Close
  43.             End With
  44.             ii = ii + 1
  45.         End With
  46.         Application.StatusBar = Application.text(Time - t, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii & " 文字檔"
  47.     Next
  48.     IE.Quit
  49.     Application.StatusBar = Application.text(Time - t, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii & " 文字檔,  讀取完畢 !! "
  50.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.text(Time - t, ["MM分SS秒"])
  51.     ThisWorkbook.Save
  52. End Sub
複製代碼

作者: smart3135    時間: 2014-4-28 13:13

回復 38# GBKEE
GBKEE版主您好,這個程式碼我有試了,可以成功,不過不知道為什麼跑起來非常慢,上櫃公司統計共663家,我將它輸入到Sheets(3)的A欄
跑一個文字檔的時間大約要4-5秒,確定有清理系統了,不過還是非常慢
另外有辦法像之前將匯入資料顯示在EXCEL以便逐行執行時可以看出EXCEL如何變化,麻煩您了,謝謝!
  1. Option Explicit
  2. Dim IE As Object
  3. Sub IE_Application()
  4.     Set IE = CreateObject("InternetExplorer.Application")
  5.     With IE
  6.         .Navigate "http://www.gretai.org.tw/ch/stock/statistics/monthly/st42.php"
  7.      '   .Visible = True   '不顯示ie
  8.         Do While .Busy Or .ReadyState <> 4: DoEvents: Loop
  9.   End With
  10. End Sub
  11. Sub 上櫃月成交資訊()
  12.     Dim E As Range, xPath As String, xFile As String, A As Object, fs As Object, F As Object, IE_URL As String
  13.     Dim i As Integer, ii As Integer, t As Date, AR(), Rng As Range, r, C, S
  14.     Set fs = CreateObject("Scripting.FileSystemObject")
  15.     IE_URL = "http://www.gretai.org.tw/ch/stock/statistics/monthly/st42.php"
  16.     t = Time
  17.     Application.DisplayStatusBar = True
  18.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  19.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  20.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  21.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  22.     xPath = "G:\財報資料"
  23.     IE_Application    '
  24.     Application.StatusBar = " "
  25.     For Each E In Rng
  26.         With IE
  27.             Set A = .Document.getelementbyid("input_stock_code")
  28.             A.Value = E
  29.             A.ParentNode.submit
  30.             Do While .Busy Or .ReadyState <> 4:    Loop
  31.             Set A = .Document.getelementsbytagname("TABLE")
  32.             xFile = xPath & "\" & E & "\HPM.txt"
  33.             MkDir_Sub xFile
  34.             With fs.CreateTextFile(xFile, True)
  35.                 For i = 1 To A(2).Rows.Length - 1
  36.                     S = ""
  37.                     For C = 0 To A(2).Rows(i).Cells.Length - 1
  38.                         S = S & A(2).Rows(i).Cells(C).innertext & vbTab
  39.                     Next
  40.                     .WriteLine S
  41.                 Next
  42.                 .Close
  43.             End With
  44.             ii = ii + 1
  45.         End With
  46.         Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii & " 文字檔"
  47.     Next
  48.     IE.Quit
  49.     Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii & " 文字檔,  讀取完畢 !! "
  50.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - t, ["MM分SS秒"])
  51.     ThisWorkbook.Save
  52. End Sub
  53. Sub MkDir_Sub(S As String)
  54.     Dim AR, i As Integer, xPath As String
  55.     If Dir(S) = "" Then
  56.         AR = Split(S, "\")
  57.         xPath = AR(0)
  58.         For i = 1 To UBound(AR) - 1
  59.             xPath = xPath & "\" & AR(i)
  60.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  61.         Next
  62.     End If
  63. End Sub
  64. Sub Maketxt(xF As String, Q As QueryTable)   '將匯入資料存入指定的txt
  65.     Dim fs As Object, E As Range, C As Variant
  66.     Set fs = CreateObject("Scripting.FileSystemObject")
  67.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  68.     For Each E In Q.ResultRange.Rows
  69.         C = Application.Transpose(Application.Transpose(E.Value))
  70.         C = Join(C, vbTab)
  71.         fs.WriteLine C
  72.     Next
  73.     fs.Close
  74. End Sub
複製代碼

作者: GBKEE    時間: 2014-4-28 17:48

回復 39# smart3135
跑一個文字檔的時間大約要4-5秒,確定有清理系統了,不過還是非常慢 ?
可能是越老的版本速度越快,試試2003版看看
另外有辦法像之前將匯入資料顯示在EXCEL以便逐行執行時可以看出EXCEL如何變化,如此速度更慢了.

[attach]18182[/attach]
  1. Option Explicit
  2. Sub 集保戶股權_WEB_製圖()
  3.     Dim WB As Workbook, Rng As Range
  4.     Dim Ar(), A, i As Integer, strDate As String, stkno As String, Qur As String
  5.     With CreateObject("InternetExplorer.Application")
  6.         .Navigate "http://www.tdcc.com.tw/smWeb/QryStock.jsp"
  7.         Do While .Busy Or .ReadyState <> 4: DoEvents: Loop
  8.         Set A = .document.All.tags("option") '資料日期的內容
  9.         ReDim Ar(A.Length - 1)
  10.         For i = 0 To A.Length - 1
  11.             Ar(i) = A(i).innerHTML
  12.         Next
  13.         .Quit
  14.     End With
  15.     Set WB = Workbooks.Add
  16.     With WB
  17.         .Sheets(1).Name = "圖表"
  18.         .Sheets(2).Name = "資料庫"
  19.     End With
  20.     stkno = InputBox("輸入股票代號", "股票代號", 2317)    '
  21.     If stkno = "" Or Len(stkno) <> 4 Or Val(stkno) = 0 Then MsgBox "股票代號"
  22.     For i = 0 To UBound(Ar)
  23.         strDate = Ar(i)  '導入月份
  24.         Qur = "http://www.tdcc.com.tw/smWeb/QryStock.jsp?SCA_DATE=" & strDate & "&SqlMethod=StockNo&StockNo=" & stkno & "&StockName=&sub=%ACd%B8%DF"          '
  25.         With WB.Sheets(3)
  26.             If .QueryTables.Count = 0 Then
  27.                 .QueryTables.Add "URL;" & Qur, .[A1]
  28.             Else
  29.                 .QueryTables(1).Connection = "URL;" & Qur
  30.             End If
  31.             With .QueryTables(1)
  32.                 .WebSelectionType = xlSpecifiedTables
  33.                 .WebFormatting = xlWebFormattingNone
  34.                 .WebTables = "6,7,8"
  35.                 .WebPreFormattedTextToColumns = True
  36.                 .WebConsecutiveDelimitersAsOne = True
  37.                 .WebSingleBlockTextImport = False
  38.                 .WebDisableDateRecognition = False
  39.                 .WebDisableRedirections = False
  40.                 .Refresh BackgroundQuery:=False
  41.                 If Application.Count(.ResultRange) = 0 Then
  42.                     MsgBox "股票代號 " & stkno & " 錯誤"
  43.                     WB.Close , False
  44.                     Exit Sub
  45.                 End If
  46.                 If i = 0 Then WB.Sheets(2).Cells(2, i + 1).Resize(15) = .ResultRange.Range("B6").Resize(15).Value
  47.                 WB.Sheets(2).Cells(1, i + 2) = Mid(.ResultRange.Range("A3"), 6)
  48.                 WB.Sheets(2).Cells(2, i + 2).Resize(15) = .ResultRange.Range("E6").Resize(15).Value
  49.             End With
  50.         End With
  51.     Next
  52.     With WB
  53.       Set Rng = .Sheets(2).UsedRange
  54.        With .Sheets(1)
  55.             With .ChartObjects.Add(.[B3].Left, .[B3].Top, .[B3].Resize(, 15).Width, .[B3].Resize(25).Height).Chart
  56.                 .ChartType = xlLineMarkers
  57.                 .SetSourceData Rng, xlRows
  58.                 .SeriesCollection(13).AxisGroup = 2
  59.                 .HasTitle = True
  60.                 .ChartTitle.Characters.Text = WB.Sheets(3).[A1]
  61.                 .PlotArea.Interior.ColorIndex = 23
  62.             End With
  63.         End With
  64.         .Activate
  65.     End With
  66. End Sub
複製代碼

作者: smart3135    時間: 2014-4-28 19:14

回復 40# GBKEE
版主您好,剛剛將電腦關閉後重新開啟後再重新執行VBA,結果很不錯,一個平均一秒多,可能之前我在執行VBA時開啟太多其他軟體了
[attach]18183[/attach]
這個是擷取年成交資訊,還有一個月成交資訊,因為月成交資訊是要點月份來選擇,我會先自己做看看,不行的話會再來向您討教
另外您附上的集保資料我還沒試,晚上會利用時間來試試,不過我有稍微瞄了一下,有看到INPUT BOX,因為我是要用迴圈連續擷取資料
不是要用INPUT BOX輸入代碼來擷取資料,也不需要附檔的圖,只需要文字檔內容即,不知道我是否解讀錯誤,會利用時間了解看看,再次感謝您!
作者: smart3135    時間: 2014-4-29 11:17

回復 38# GBKEE
GBKEE版主早安,我在抓上市個股年成交資訊又遇到問題了,原本是想利用您在37#的抓取上櫃年成交的程式碼來修改,但卻出錯,能請您再幫忙看一下嗎?
另外因為希望將匯入資料的EXCEL表格做一些修改再存入txt,所以我也有用先前抓其他資料的VBA來測試,但因為先前連結的網站是國泰證券,需要的資料只要將
最後的個股代碼設定成迴圈變數,就能將資料一個一個擷取下來,但上市年成交資訊的網頁不是這樣的格式,所以不清楚該怎麼做迴圈設定擷取資訊
請您再指點一下,如果可以的話,希望兩種都能學,附上兩個EXCEL VBA以及連結的資訊
[attach]18190[/attach]

"URL;https://djinfo.cathaysec.com.tw/Z/ZC/ZCC/ZCC.DJHTM?A=2330"    >>>>>>>>>這是先前利用國泰證券做的連結網址,只要將最後改成迴圈變數就可以了

"URL;http://www.twse.com.tw/ch/trading/exchange/FMNPTK/genpage/Report201404/2330_F3_1_11.php?STK_NO=2330&myear=2014&mmon=04"
這是證交所上市個股2330的年成交資訊連結,不知道有沒有辦法用迴圈變數做連結

"URL;http://www.twse.com.tw/ch/trading/exchange/FMNPTK/FMNPTKMAIN.php"      >>>>>>>>>>>>>>這是證交所上市個股年成交資訊首頁


這張圖就是想要抓的表格,上面有提到希望能先匯到EXCEL再存到文字檔就是希望年的順序可以反過來,也就是越新的年度排越上面,另外資料在匯入EXCEL後會將
(元,股)也變成一列,這一列也希望能刪除
[attach]18191[/attach]
作者: GBKEE    時間: 2014-4-30 10:27

本帖最後由 GBKEE 於 2014-4-30 10:30 編輯

回復 42# smart3135
WEB 查詢請 版上有許多討論 可搜尋 http://www.twse.com.tw/ch/trading/exchange/FMNPTK/FMNPTKMAIN.php  這字串
上市與 上櫃 網頁的建置不同
  1. Option Explicit
  2. Dim IE As Object
  3. Sub IE_Application()
  4.     Set IE = CreateObject("InternetExplorer.Application")
  5.     With IE
  6.         .Navigate "http://www.twse.com.tw/ch/trading/exchange/FMNPTK/FMNPTKMAIN.php"
  7.         .Visible = True   '顯示ie
  8.         Do While .Busy Or .ReadyState <> 4: DoEvents: Loop
  9.   End With
  10. End Sub
  11. Sub 上市年成交資訊()
  12.     Dim E As Range, xPath As String, xFile As String, A As Object, fs As Object, F As Object, IE_URL As String
  13.     Dim i As Integer, ii As Integer, t As Date, AR(), Rng As Range, r, C, S
  14.     Set fs = CreateObject("Scripting.FileSystemObject")
  15.     IE_URL = "http://www.twse.com.tw/ch/trading/exchange/FMNPTK/FMNPTKMAIN.php"
  16.     t = Time
  17.     Application.DisplayStatusBar = True
  18.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  19.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  20.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  21.     '你已將上市的股票代號,在Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  22.     xPath = "D:\財報資料"
  23.     IE_Application    '
  24.     Application.StatusBar = " "
  25.     Sheets(1).Activate
  26.     For Each E In Rng
  27.         With IE
  28.             Do While .Busy Or .ReadyState <> 4:    Loop
  29.             Set A = .Document.getelementbyid("STK_NO")
  30.             A.Value = E
  31.              .Document.getelementSbyNAME("login_btn")(0).Click  '按下查詢
  32.             Do While .Busy Or .ReadyState <> 4:    Loop
  33.             Set A = .Document.getelementsbytagname("TABLE")
  34.             xFile = xPath & "\" & E & "\HPM.txt"
  35.             MkDir_Sub xFile
  36.              With Sheets(1)
  37.                 .Cells.Clear
  38.                 For i = 1 To A(7).Rows.Length - 1
  39.                     For C = 0 To A(7).Rows(i).Cells.Length - 1
  40.                     .Cells(i, C + 1) = A(7).Rows(i).Cells(C).innertext
  41.                     Next
  42.                 Next
  43.                 .UsedRange.Sort Key1:=.Range("A2"), Order1:=xlDescending, Header:=True  '排序:xlDescending ( 由大至小 )
  44.                 Maketxt xFile, .UsedRange
  45.             End With
  46.             ii = ii + 1
  47.         End With
  48.         Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & " 共匯入上市年成交 " & ii & " 文字檔"
  49.     Next
  50.     IE.Quit
  51.     Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & " 共匯入上市年成交 " & ii & " 文字檔,  讀取完畢 !! "
  52.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - t, ["MM分SS秒"])
  53.     ThisWorkbook.Save
  54. End Sub
  55. Sub Maketxt(xF As String, Q As Range)   '***   Q As Range  ****
  56.     Dim fs As Object, E As Range, C As Variant
  57.     Set fs = CreateObject("Scripting.FileSystemObject")
  58.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  59.     For Each E In Q.Rows   '修改這  Q.ResultRange.Rows
  60.     C = Application.Transpose(Application.Transpose(E.Value))
  61.         C = Join(C, vbTab)
  62.         fs.WriteLine C
  63.     Next
  64.     fs.Close
  65. End Sub
  66. Sub MkDir_Sub(S As String)
  67.     Dim AR, i As Integer, xPath As String
  68.     If Dir(S) = "" Then
  69.         AR = Split(S, "\")
  70.         xPath = AR(0)
  71.         For i = 1 To UBound(AR) - 1
  72.             xPath = xPath & "\" & AR(i)
  73.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  74.         Next
  75.     End If
  76. End Sub
複製代碼

作者: smart3135    時間: 2014-5-1 20:30

回復 43# GBKEE
不好意思,GBKEE版主,請問是搜尋 http://www.twse.com.tw/ch/trading/exchange/FMNPTK/FMNPTKMAIN.php這字串嗎?
因為我在版上搜索這字串是查無結果的,所以想跟您確認一下,我也想好好學習網頁建置不同上的差別在哪?謝謝您!
作者: smart3135    時間: 2014-5-2 05:12

回復 43# GBKEE
哈囉!GBKEE版主,又來向您討教囉!關於在43#的程式碼在sheet(3)的A欄套用上市個股代號後是可行的,但若我想將網址改成月成交資訊
會多了一個"年"查詢欄,又該如何設定"年"的查詢欄位可以多查幾年呢?例如首頁是直接跳出103年,再輸入股票代碼即可查詢,我想將102年、101年的資料
也一起匯入,應該怎麼做變化呢?我想關鍵是不是在以下的程式碼,因為對內容的語法不太了解,所以想再來請教您一下!
我若直接將月成交資訊的網址帶入,只能匯入103年的資料,不知道是不是各年度的月成交資訊能像股票代碼一樣在sheet(3)的某欄位輸入當成迴圈
就能匯入需要的資料,例如我想要103、102、101、100年的月成交資訊,就在sheet(3)的B欄從上往下key入,再做一些程式碼的變更就能讓程式去依照
sheet(3)的B欄輸入的年份匯入月成交資訊,不知這樣的想法對不對,再請您指點一番!謝謝!
   Do While .Busy Or .ReadyState <> 4:    Loop
            Set A = .Document.getelementbyid("STK_NO")
            A.Value = E
             .Document.getelementSbyNAME("login_btn")(0).Click  '按下查詢
            Do While .Busy Or .ReadyState <> 4:    Loop
            Set A = .Document.getelementsbytagname("TABLE")


上櫃月成交資訊

[attach]18199[/attach]



上市月成交資訊

[attach]18200[/attach]
作者: smart3135    時間: 2014-5-4 06:02

回復 38# GBKEE
GBKEE版主您好,又來向您討教了,因為先前不懂為什麼查詢上市與上櫃年成交資訊的VBA程式碼中分別有"STK_NO"與"input stock code",之後才想到是要去找網頁原紿碼
雖然大部分都看不懂,不過確實是分別在上市與上櫃年成交資訊的網頁原始碼中找到上述兩個字串,我想這應該是必定要寫在VBA中的關鍵字串,後來去查了一下上櫃的月成交資訊
有看到多出日期欄的字串,測試了將字串寫入VBA,但卻會出錯,嘗試多次變更仍無法順利執行,不知該如何將這些字串正確地寫入VBA,當然上市的月成交資訊
測試結果也和上櫃的一樣,都是無功而返,所以只能再度叨擾您了,懇請您再次賜教,感謝!
[attach]18205[/attach]

上櫃年成交資訊
[attach]18203[/attach]

上櫃月成交資訊
[attach]18204[/attach]
作者: GBKEE    時間: 2014-5-4 15:51

回復 46# smart3135
  1. For Each E In Rng
  2.         For Each X In Rng1
  3.             With IE
  4.          'http://forum.twbts.com/viewthread.php?tid=8111  chrom 中可查看元素的結構
  5.          '<select name="yy" class="input-select ui-corner-all" id="y_date1" onchange="query()">
  6.          '<option value="1996">85</option><option value="1997">86</option><option value="1998">87</option>         
  7.                 Set B = .document.getelementsbytagname("select")("YY")
  8.                 B.Value = X
  9.                 Set A = .document.getelementbyid("input_stock_code")
  10.                 A.Value = E
  11.    
複製代碼

作者: smart3135    時間: 2014-5-5 05:57

回復 47# GBKEE
感謝版主耐心的回答,看了文章之後,大概了解了相對引數的關鍵字,也有試著將相對引數"select"和"yy"代入,結果是可行的
不過有點問題:
1.在迴圈執行程式時是會依照我在sheet(3) B欄輸入的年份匯入文字檔,不過下一年份的資料又會覆蓋原來的文字檔內容
    例如我在sheet(3) B欄輸入的年份是2014、2013、2012,結果2014的寫完後再寫下一筆的2013就會把原來寫入的2014覆蓋掉
    不知道能不能將三年的資料都寫入文字檔?
2.年份迴圈是否只能利用像個股代號一樣在sheet(3) 某欄輸入想要擷取的年份資料,能不能直接寫入VBA中呢?
3.寫入的文字檔是從開始有數字資料時寫起,不知道能不能由最上方個股代號那一列開始寫入,也就是文字檔中會看得到個股代號
4.因為這個VBA程式是直接將資料寫入文字檔,無法看到資料匯入EXCEL的動作,不知道能不能做日期排序
    例如寫入的第一年份資料由上到下是103年1月份到103年5月份,不知道能不能將5月份寫到最上方
我想問題會這麼多,應該是我VBA基礎還沒打好就急於學習更進階的東西,看來我可能得多看些書、文章、影片充實自己的VBA基礎,很感謝版主連日來不厭其煩的回答!
[attach]18206[/attach]
[attach]18207[/attach]
  1. Option Explicit
  2. Dim IE As Object
  3. Sub IE_Application()
  4.     Set IE = CreateObject("InternetExplorer.Application")
  5.     With IE
  6.         .Navigate "http://www.gretai.org.tw/ch/stock/statistics/monthly/st44.php"
  7.      '   .Visible = True   '不顯示ie
  8.         Do While .Busy Or .ReadyState <> 4: DoEvents: Loop
  9.   End With
  10. End Sub
  11. Sub 上櫃月成交資訊()
  12.     Dim E, X As Range, xPath As String, xFile As String, A, B As Object, fs As Object, F As Object, IE_URL As String
  13.     Dim i As Integer, ii As Integer, t As Date, AR(), Rng, Rng1 As Range, r, C, S
  14.     Set fs = CreateObject("Scripting.FileSystemObject")
  15.     IE_URL = "http://www.gretai.org.tw/ch/stock/statistics/monthly/st44.php"
  16.     t = Time
  17.     Application.DisplayStatusBar = True
  18.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  19.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  20.     Set Rng1 = ThisWorkbook.Sheets(3).Range("b:b")
  21.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  22.     If Application.Count(Rng1) = 0 Then MsgBox "沒有股票代號": Exit Sub
  23.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  24.     Set Rng1 = Rng1.SpecialCells(xlCellTypeConstants)
  25.     xPath = "D:\財報資料"
  26.     IE_Application    '
  27.     Application.StatusBar = " "
  28.     For Each E In Rng
  29.         For Each X In Rng1
  30.             With IE
  31.                 Set B = .document.getelementsbytagname("select")("yy")
  32.                 B.Value = X
  33.                 Set A = .document.getelementbyid("input_stock_code")
  34.                 A.Value = E
  35.                 A.ParentNode.submit
  36.                 Do While .Busy Or .ReadyState <> 4:    Loop
  37.                 Set A = .document.getelementsbytagname("TABLE")
  38.                 xFile = xPath & "\" & E & "\HPM.txt"
  39.                 MkDir_Sub xFile
  40.                 With fs.CreateTextFile(xFile, True)
  41.                     For i = 1 To A(2).Rows.Length - 1
  42.                         S = ""
  43.                         For C = 0 To A(2).Rows(i).Cells.Length - 1
  44.                             S = S & A(2).Rows(i).Cells(C).innertext & vbTab
  45.                         Next C
  46.                         .WriteLine S
  47.                     Next i
  48.                     .Close
  49.                 End With
  50.             ii = ii + 1
  51.             End With
  52.         Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii & " 文字檔"
  53.         Next X
  54.     Next E
  55.     IE.Quit
  56.     Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii & " 文字檔,  讀取完畢 !! "
  57.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - t, ["MM分SS秒"])
  58.     ThisWorkbook.Save
  59. End Sub
  60. Sub MkDir_Sub(S As String)
  61.     Dim AR, i As Integer, xPath As String
  62.     If Dir(S) = "" Then
  63.         AR = Split(S, "\")
  64.         xPath = AR(0)
  65.         For i = 1 To UBound(AR) - 1
  66.             xPath = xPath & "\" & AR(i)
  67.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  68.         Next
  69.     End If
  70. End Sub
  71. Sub Maketxt(xF As String, Q As QueryTable)   '將匯入資料存入指定的txt
  72.     Dim fs As Object, E As Range, C As Variant
  73.     Set fs = CreateObject("Scripting.FileSystemObject")
  74.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  75.     For Each E In Q.ResultRange.Rows
  76.         C = Application.Transpose(Application.Transpose(E.Value))
  77.         C = Join(C, vbTab)
  78.         fs.WriteLine C
  79.     Next
  80.     fs.Close
  81. End Sub
複製代碼
[attach]18208[/attach]
作者: GBKEE    時間: 2014-5-7 17:04

回復 48# smart3135
  1. Option Explicit
  2. Dim IE As Object
  3. Sub IE_Application()
  4.     Set IE = CreateObject("InternetExplorer.Application")
  5.     With IE
  6.         .Navigate "http://www.gretai.org.tw/ch/stock/statistics/monthly/st44.php"
  7.         .Visible = True   '不顯示ie
  8.         Do While .Busy Or .readyState <> 4: DoEvents: Loop
  9.   End With
  10. End Sub
  11. Sub 上櫃月成交資訊()
  12.     Dim Rng As Range, Rng1 As Range, E As Range, X As Range, T As Date, xPath As String, xFile As String
  13.     Dim Ea As Variant, ar(), ii As Integer
  14.     T = Time
  15.     Application.DisplayStatusBar = True
  16.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  17.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  18.     Set Rng1 = ThisWorkbook.Sheets(3).Range("b:b")
  19.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  20.     If Application.Count(Rng1) = 0 Then MsgBox "沒有股票代號": Exit Sub
  21.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  22.     Set Rng1 = Rng1.SpecialCells(xlCellTypeConstants)
  23.     xPath = "G:\財報資料"
  24.     IE_Application    '
  25.     Application.StatusBar = " "
  26.     For Each E In Rng
  27.         Sheets(1).UsedRange.Clear  '下載資料置於此工作表,變換股票時:清空
  28.         For Each X In Rng1
  29.             With IE
  30.                 .document.getElementsByTagName("select")("yy").Value = X
  31.                  With .document.getelementbyid("input_stock_code")
  32.                     .Value = E
  33.                     .ParentNode.submit
  34.                 End With
  35.                 Do While .Busy Or .readyState <> 4:    Loop
  36.                 If Application.Count(Sheets(1).UsedRange) = 0 Then '此工作表清空時:下載第一年度時
  37.                     ar = Array(0, 2)
  38.                 Else
  39.                     ar = Array(2)
  40.                 End If
  41.                 For Each Ea In ar
  42.                     Ep .document.getElementsByTagName("TABLE")(Ea).outerHTML
  43.                 Next
  44.             ii = ii + 1
  45.             End With
  46.         Next X
  47.         xFile = xPath & "\" & E & "\HPM.txt"
  48.         MkDir_Sub xFile
  49.         Maketxt xFile, Sheets(1).UsedRange
  50.         Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii & " 文字檔"
  51.     Next E
  52.     IE.Quit
  53.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii & " 文字檔,  讀取完畢 !! "
  54.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  55.     ThisWorkbook.Save
  56. End Sub
  57. Sub Ep(S As String)
  58.     Dim D As New DataObject, E As Shape, FormDLL As String
  59.     'DataObject 物件 在進行轉換動作時,做為格式化文字資料的暫存區域。其也可以暫存和儲存在 DataObject 的文字片段相關的格式。
  60.     '宣告 Dim D As New DataObject '須在工具-> 設定引用項目加入 新增引用 Microsoft Forms 2.0 Object Library ,專案 加入一表單即可
  61.     On Error GoTo ER
  62.     With D
  63.         .SetText S
  64.         .PutInClipboard
  65.         With Sheets(1)
  66.             .Range("a" & .Rows.Count).End(xlUp).Offset(1).Select
  67.             .PasteSpecial Format:="Unicode 文字"
  68.         End With
  69.     End With
  70.     Exit Sub
  71. ER:
  72.     FormDLL = "FM20.DLL"
  73.     ThisWorkbook.VBProject.References.AddFromFile "C:\windows\system32\" & FormDLL
  74.     Resume
  75. End Sub
  76. Sub MkDir_Sub(S As String)
  77.     Dim ar, i As Integer, xPath As String
  78.     If Dir(S) = "" Then
  79.         ar = Split(S, "\")
  80.         xPath = ar(0)
  81.         For i = 1 To UBound(ar) - 1
  82.             xPath = xPath & "\" & ar(i)
  83.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  84.         Next
  85.     End If
  86. End Sub
  87. Sub Maketxt(xF As String, Q As Range)    '將匯入資料存入指定的txt
  88.     Dim fs As Object, E As Range, C As Variant
  89.     Q.Range("C1") = ""
  90.     Q.Range("a4", Q.Range("a4").End(xlDown)).Replace "年", ""
  91.     Q.Columns(1).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
  92.     Set fs = CreateObject("Scripting.FileSystemObject")
  93.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  94.     For Each E In Q.Rows
  95.         C = Application.Transpose(Application.Transpose(E.Value))
  96.         C = Join(C, vbTab)
  97.         fs.WriteLine C
  98.     Next
  99.     fs.Close
  100. End Sub
複製代碼

作者: smart3135    時間: 2014-5-12 00:04

回復 49# GBKEE
感謝GBKEE版主,49#程式碼我研究了幾天,不過還是太深奧了,有看沒有很懂,但實際上執行結果是成功的,有試著依樣畫葫蘆,將上市的網頁連結及相關引數帶入程式碼試著擷取資料
但在跑到 .ParentNode.submit會出現沒有使用權限,因為不懂這段程式碼的意思,能請您再幫忙一下嗎?
另外不知道在49#的執行結果中,有沒有辦法將月份越新的往上排序呢?再麻煩您一下囉!感謝!
例如:程式執行結果為
103年1月
103年2月
103年3月
103年4月

希望結果為
103年4月
103年3月
103年2月
103年1月
  1. Option Explicit
  2. Dim IE As Object
  3. Sub IE_Application()
  4.     Set IE = CreateObject("InternetExplorer.Application")
  5.     With IE
  6.         .Navigate "http://www.twse.com.tw/ch/trading/exchange/FMSRFK/FMSRFKMAIN.php"
  7. '        .Visible = True   '不顯示ie
  8.         Do While .Busy Or .readyState <> 4: DoEvents: Loop
  9.   End With
  10. End Sub
  11. Sub 上市月成交資訊()
  12.     Dim Rng As Range, Rng1 As Range, E As Range, X As Range, T As Date, xPath As String, xFile As String
  13.     Dim Ea As Variant, ar(), ii As Integer
  14.     T = Time
  15.     Application.DisplayStatusBar = True
  16.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  17.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  18.     Set Rng1 = ThisWorkbook.Sheets(3).Range("b:b")
  19.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  20.     If Application.Count(Rng1) = 0 Then MsgBox "沒有股票代號": Exit Sub
  21.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  22.     Set Rng1 = Rng1.SpecialCells(xlCellTypeConstants)
  23.     xPath = "G:\財報資料"
  24.     IE_Application    '
  25.     Application.StatusBar = " "
  26.     For Each E In Rng
  27.         Sheets(1).UsedRange.Clear  '下載資料置於此工作表,變換股票時:清空
  28.         For Each X In Rng1
  29.             With IE
  30.                 .Document.getElementsByTagName("select")("myear").Value = X
  31.                  With .Document.getelementbyid("STK_NO")
  32.                     .Value = E
  33.                     .Document.getelementSbyNAME("login_btn")(0).Click  '按下查詢
  34.                     .ParentNode.submit
  35.                 End With
  36.                 Do While .Busy Or .readyState <> 4:    Loop
  37.                 If Application.Count(Sheets(1).UsedRange) = 0 Then '此工作表清空時:下載第一年度時
  38.                     ar = Array(0, 2)
  39.                 Else
  40.                     ar = Array(2)
  41.                 End If
  42.                 For Each Ea In ar
  43.                     Ep .Document.getElementsByTagName("TABLE")(Ea).outerHTML
  44.                 Next
  45.             ii = ii + 1
  46.             End With
  47.         Next X
  48.         xFile = xPath & "\" & E & "\HPM.txt"
  49.         MkDir_Sub xFile
  50.         Maketxt xFile, Sheets(1).UsedRange
  51.         Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii & " 文字檔"
  52.     Next E
  53.     IE.Quit
  54.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii & " 文字檔,  讀取完畢 !! "
  55.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  56.     ThisWorkbook.Save
  57. End Sub
  58. Sub Ep(S As String)
  59.     Dim D As New DataObject, E As Shape, FormDLL As String
  60.     'DataObject 物件 在進行轉換動作時,做為格式化文字資料的暫存區域。其也可以暫存和儲存在 DataObject 的文字片段相關的格式。
  61.     '宣告 Dim D As New DataObject '須在工具-> 設定引用項目加入 新增引用 Microsoft Forms 2.0 Object Library ,專案 加入一表單即可
  62.     On Error GoTo ER
  63.     With D
  64.         .SetText S
  65.         .PutInClipboard
  66.         With Sheets(1)
  67.             .Range("a" & .Rows.Count).End(xlUp).Offset(1).Select
  68.             .PasteSpecial Format:="Unicode 文字"
  69.         End With
  70.     End With
  71.     Exit Sub
  72. ER:
  73.     FormDLL = "FM20.DLL"
  74.     ThisWorkbook.VBProject.References.AddFromFile "C:\windows\system32\" & FormDLL
  75.     Resume
  76. End Sub
  77. Sub MkDir_Sub(S As String)
  78.     Dim ar, i As Integer, xPath As String
  79.     If Dir(S) = "" Then
  80.         ar = Split(S, "\")
  81.         xPath = ar(0)
  82.         For i = 1 To UBound(ar) - 1
  83.             xPath = xPath & "\" & ar(i)
  84.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  85.         Next
  86.     End If
  87. End Sub
  88. Sub Maketxt(xF As String, Q As Range)    '將匯入資料存入指定的txt
  89.     Dim fs As Object, E As Range, C As Variant
  90.     Q.Range("C1") = ""
  91.     Q.Range("a4", Q.Range("a4").End(xlDown)).Replace "年", ""
  92.     Q.Columns(1).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
  93.     Set fs = CreateObject("Scripting.FileSystemObject")
  94.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  95.     For Each E In Q.Rows
  96.         C = Application.Transpose(Application.Transpose(E.Value))
  97.         C = Join(C, vbTab)
  98.         fs.WriteLine C
  99.     Next
  100.     fs.Close
  101. End Sub
複製代碼
[attach]18259[/attach]
作者: GBKEE    時間: 2014-5-15 16:21

回復 50# smart3135


   
但在跑到 .ParentNode.submit會出現沒有使用權限,因為不懂這段程式碼的意思,能請您再幫忙一下嗎?
希望結果為
103年4月
103年3月
103年2月
103年1月
上市,上櫃的網頁建置不一樣
試試看
  1. Option Explicit
  2. Dim IE As Object
  3. Sub IE_Application()
  4.     Set IE = CreateObject("InternetExplorer.Application")
  5.     With IE
  6.         .Navigate "http://www.twse.com.tw/ch/trading/exchange/FMSRFK/FMSRFKMAIN.php"
  7.         .Visible = True   '不顯示ie
  8.         Do While .Busy Or .readyState <> 4: DoEvents: Loop
  9.   End With
  10. End Sub
  11. Sub 上市月成交資訊()
  12.     Dim Rng As Range, Rng1 As Range, E As Range, X As Range, T As Date, xPath As String, xFile As String
  13.     Dim Ea As Variant, ar(), ii As Integer
  14.     T = Time
  15.     Application.DisplayStatusBar = True
  16.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  17.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  18.     Set Rng1 = ThisWorkbook.Sheets(3).Range("b:b")
  19.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  20.     If Application.Count(Rng1) = 0 Then MsgBox "沒有股票代號": Exit Sub
  21.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  22.     Set Rng1 = Rng1.SpecialCells(xlCellTypeConstants)
  23.     xPath = "D:\財報資料"
  24.     IE_Application    '
  25.     Application.StatusBar = " "
  26.     For Each E In Rng
  27.         With Sheets(1)
  28.             .Activate
  29.             .Cells.Clear  '下載資料置於此工作表,變換股票時:清空
  30.         End With
  31.         For Each X In Rng1
  32.             With IE
  33.                 .Document.getElementsByTagName("select")("myear").Value = X
  34.                  With .Document.getelementbyid("STK_NO")
  35.                     .Value = E
  36.                     .Document.getelementSbyNAME("login_btn")(0).Click  '按下查詢
  37.                 End With
  38.                 Do While .Busy Or .readyState <> 4:    Loop
  39.                 Ep .Document.getElementsByTagName("TABLE")(7).outerHTML
  40.             End With
  41.         Next X
  42.         xFile = xPath & "\" & E & "\HPM.txt"
  43.         MkDir_Sub xFile
  44.         Maketxt xFile, Sheets(1).Range("A1").CurrentRegion, E.Value
  45.         ii = ii + 1
  46.         Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii & " 文字檔"
  47.     Next E
  48.     IE.Quit
  49.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii & " 文字檔,  讀取完畢 !! "
  50.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  51.     ThisWorkbook.Save
  52. End Sub
  53. Sub Ep(S As String)
  54.     Dim D As New DataObject, i As Integer, FormDLL As String, Rng As Range
  55.     'DataObject 物件 在進行轉換動作時,做為格式化文字資料的暫存區域。其也可以暫存和儲存在 DataObject 的文字片段相關的格式。
  56.     '宣告 Dim D As New DataObject '須在工具-> 設定引用項目加入 新增引用 Microsoft Forms 2.0 Object Library ,專案 加入一表單即可
  57.     On Error GoTo ER
  58.     With D
  59.         .SetText S
  60.         .PutInClipboard
  61.         With Sheets(1)
  62.             With .Range("a" & .Rows.Count).End(xlUp)
  63.                 If .Row = 1 Then
  64.                     Set Rng = .Cells
  65.                 Else
  66.                     Set Rng = .Offset(1)
  67.                 End If
  68.                 Rng.Select
  69.                 .Parent.PasteSpecial Format:="Unicode 文字"
  70.                 Set Rng = Rng.Range("A3", Rng.Range("A3").End(xlDown)).Resize(, 9)
  71.                 'Sort :資料排序
  72.                 Rng.Sort Key1:=Rng.Range("B2"), Order1:=xlDescending, Header:=xlYes ', _
  73.                 OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod _
  74.                 :=xlStroke, DataOption1:=xlSortNorma
  75.                 If .Row = 1 Then
  76.                     .Range("A2").EntireRow.Delete
  77.                 Else
  78.                     .Range("A2:A4").EntireRow.Delete
  79.                 End If
  80.             End With
  81.         End With
  82.     End With
  83.     Exit Sub
  84. ER:
  85.     ThisWorkbook.VBProject.References.AddFromFile "C:\windows\system32\FM20.DLL"
  86.     Resume
  87. End Sub
  88. Sub Maketxt(xF As String, Q As Range, Code As String)     '將匯入資料存入指定的txt
  89.     Dim fs As Object, E As Range, C As Variant
  90.     Set fs = CreateObject("Scripting.FileSystemObject")
  91.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  92.     Q.Cells(1) = Code & " 月成交資訊"   '加入股票代號
  93.     For Each E In Q.Rows
  94.         C = Application.Transpose(Application.Transpose(E.Value))
  95.         C = Join(C, vbTab)
  96.         fs.WriteLine C
  97.     Next
  98.     fs.Close
  99. End Sub
  100. Sub MkDir_Sub(S As String)
  101.     Dim ar, i As Integer, xPath As String
  102.     If Dir(S) = "" Then
  103.         ar = Split(S, "\")
  104.         xPath = ar(0)
  105.         For i = 1 To UBound(ar) - 1
  106.             xPath = xPath & "\" & ar(i)
  107.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  108.         Next
  109.     End If
  110. End Sub
複製代碼

作者: smart3135    時間: 2014-5-16 08:28

回復 51# GBKEE
感謝GBKEE版主,這些程式碼又讓我學到很多,我也試著將上櫃資料自行排序,試了許久,終於成功了
不過這個上市在寫入文字檔的程式碼中有一些不太了解,想再向您請益:
1.和市櫃不同的地方是多了一個Code,而這個Code會直接代入E的代號,想請問這個Code是什麼?
2.在 [Q.Cells(1) = Code & " 月成交資訊"   '加入股票代號]這段程式碼的結果會變成[股票代號&月成交資訊],因為我想除了連股票代號之外,連股票名稱也能顯示
舉例來說:跑第一檔股票時結果會是"1101月成交資訊",我想要的結果是"1101亞泥月成交資訊",我有試著用原來A1儲存格保留的"103年1101亞泥月成交資訊"
來做修改,有用mid函數,也有用replce,並將[Q.Cells(1) = Code & " 月成交資訊"   '加入股票代號]用註解跳過,但只要這段跳過就會在fs.WriteLine C出錯
如果不跳過,在這裡加入其他程式碼一樣會在fs.WriteLine C出錯,不清楚為何會這樣?

原來的程式碼
  1. Sub Maketxt(xF As String, Q As Range, Code As String)     '將匯入資料存入指定的txt
  2.     Dim fs As Object, E As Range, C As Variant
  3.     Set fs = CreateObject("Scripting.FileSystemObject")
  4.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  5.     Q.Cells(1) = Code & " 月成交資訊"   '加入股票代號
  6.     For Each E In Q.Rows
  7.         C = Application.Transpose(Application.Transpose(E.Value))
  8.         C = Join(C, vbTab)
  9.         fs.WriteLine C
  10.     Next
  11.     fs.Close
  12. End Sub
複製代碼
我自己修改的程式碼(會出錯)
  1. Sub Maketxt(xF As String, Q As Range, Code As String)     '將匯入資料存入指定的txt
  2.     Dim fs As Object, E As Range, C As Variant, A As String, B As String
  3.     Set fs = CreateObject("Scripting.FileSystemObject")
  4.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  5.     A = Q.Cells(1)
  6.     B = Mid(A, 5, 15)
  7.     Q.Cells(1) = B
  8. '    Q.Cells(1) = Code & " 月成交資訊"   '加入股票代號
  9.     For Each E In Q.Rows
  10.         C = Application.Transpose(Application.Transpose(E.Value))
  11.         C = Join(C, vbTab)
  12.         fs.WriteLine C
  13.     Next
  14.     fs.Close
  15. End Sub
複製代碼

作者: GBKEE    時間: 2014-5-16 15:57

回復 52# smart3135
Q.Cells(1) 有不可見字元如圖,會造成程式碼的錯誤,所以變通一下
  1. Q.Cells(1) = Code & " 月成交資訊"   '加入股票代號
複製代碼
[attach]18297[/attach]
作者: smart3135    時間: 2014-5-16 19:09

回復 53# GBKEE
版主您好,不好意思,請問一下加了a=Q.Cells(1)有什麼不同呢?雖然執行時不會出錯,不過結果還是沒變,因為執行到下面,輸出的結果還是Q.Cells(1) = Code & "月成交資訊"
我試著再修改了一下,不過還是如之前會出錯,不知您說的變通是指?????
  1. Sub Maketxt(xF As String, Q As Range, Code As String)     '將匯入資料存入指定的txt
  2.     Dim fs As Object, E As Range, C As Variant
  3.     Dim A As String, B As String
  4.     A = Q.Cells(1)
  5. '    B = Mid(A, 9, 20)  '這段程式碼加入的話就會出錯,用註解跳過則不會出錯,但這段程式碼是要擷取正確文字
  6.     Set fs = CreateObject("Scripting.FileSystemObject")
  7.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  8.     Q.Cells(1) = Code & B   '加入股票代號
  9.     For Each E In Q.Rows
  10.         C = Application.Transpose(Application.Transpose(E.Value))
  11.         C = Join(C, vbTab)
  12.         fs.WriteLine C
  13.     Next
  14.     fs.Close
  15. End Sub
複製代碼

作者: smart3135    時間: 2014-5-17 13:38

回復 51# GBKEE
不好意思,GBKEE版主,又發現一個比較大的問題了,我想要的資料是近三年的月成交資料,可是有些個股是近1-2年才上市櫃的,所以在上市網頁輸入時會出現查無
而在上櫃網頁則是只會出現上櫃後開始的月成交資料,當查到上市櫃前的年份就會出現查無,如果讓VBA直接執行的話,執行到上市櫃不到三年的個股代號就會出錯
還會有無窮迴圈的狀況,不知道有沒有辦法加入其他程式碼來避免這種錯誤?
舉例來說:如果個股只有上市櫃不到一年、或一年到兩年,能不能只擷取該個股有的資料,當遇到查無的年份就結束該個股的資料擷取,跳到下一個股
附件是我將Sheet(3)代入一些上市櫃不到三年的個股代號會出錯的EXCEL,再請您指導一下,謝謝!

[attach]18308[/attach]
作者: GBKEE    時間: 2014-5-17 17:29

回復 55# smart3135


   
加了a=Q.Cells(1)有什麼不同呢?雖然執行時不會出錯,不過結果還是沒變,

加了a=Q.Cells(1),只是為了顯示於圖示:區域變數視窗中的不可見字元
  1. Sub 上市月成交資訊()
  2.     Dim Rng As Range, Rng1 As Range, E As Range, X As Range, T As Date, xPath As String, xFile As String
  3.     Dim Ea As Variant, ar(), ii As Integer
  4.     T = Time
  5.     Application.DisplayStatusBar = True
  6.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  7.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  8.     Set Rng1 = ThisWorkbook.Sheets(3).Range("b:b")
  9.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  10.     If Application.Count(Rng1) = 0 Then MsgBox "沒有股票代號": Exit Sub
  11.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  12.     Set Rng1 = Rng1.SpecialCells(xlCellTypeConstants)
  13.     xPath = "D:\財報資料"
  14.     IE_Application    '
  15.     Application.StatusBar = " "
  16.     For Each E In Rng
  17.         With Sheets(1)
  18.             .Activate
  19.             .Cells.Clear  '下載資料置於此工作表,變換股票時:清空
  20.         End With
  21.         For Each X In Rng1
  22.             With IE
  23.                 .Document.getElementsByTagName("select")("myear").Value = X
  24.                  With .Document.getelementbyid("STK_NO")
  25.                     .Value = E
  26.                     .Document.getelementSbyNAME("login_btn")(0).Click  '按下查詢
  27.                 End With
  28.                 Do While .Busy Or .readyState <> 4:    Loop
  29.                 If .Document.getElementsByTagName("TABLE")(7).Rows.Length > 1 Then
  30.                     Ep .Document.getElementsByTagName("TABLE")(7).outerHTML
  31.                 Else
  32.                     GoTo Nn
  33.                 End If
  34.             End With
  35.         Next X
  36. Nn:
  37.         xFile = xPath & "\" & E & "\HPM.txt"
  38.         MkDir_Sub xFile
  39.         Maketxt xFile, Sheets(1).Range("A1").CurrentRegion, E.Value
  40.         ii = ii + 1
  41.         Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii & " 文字檔"
  42.     Next E
  43.     IE.Quit
  44.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii & " 文字檔,  讀取完畢 !! "
  45.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  46. '    ThisWorkbook.Save
  47. End Sub
複製代碼
  1. Option Explicit
  2. Dim IE As Object
  3. Sub IE_Application()
  4.     If Not IE Is Nothing Then IE.Quit  '當查到上櫃的年份就會出現查無,此IE無法再度查詢,關閉它
  5.     Set IE = CreateObject("InternetExplorer.Application")
  6.     With IE
  7.         .Navigate "http://www.gretai.org.tw/ch/stock/statistics/monthly/st44.php"
  8.         .Visible = True   '不顯示ie
  9.         Do While .Busy Or .readyState <> 4: DoEvents: Loop
  10.     End With
  11. End Sub
  12. Sub 上櫃月成交資訊()
  13.     Dim Rng As Range, Rng1 As Range, E As Range, X As Range, T As Date, xPath As String, xFile As String
  14.     Dim Ea As Variant, AR(), ii As Integer, Msg As Boolean
  15.     T = Time
  16.     Application.DisplayStatusBar = True
  17.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  18.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  19.     Set Rng1 = ThisWorkbook.Sheets(3).Range("b:b")
  20.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  21.     If Application.Count(Rng1) = 0 Then MsgBox "沒有股票代號": Exit Sub
  22.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  23.     Set Rng1 = Rng1.SpecialCells(xlCellTypeConstants)
  24.     xPath = "D:\財報資料"
  25.     Application.StatusBar = " "
  26.     For Each E In Rng
  27.         If Msg = False Then IE_Application   '當查到上櫃的年份就會出現查無,重開IE
  28.         Sheets(1).UsedRange.Clear            '下載資料置於此工作表,變換股票時:清空
  29.         For Each X In Rng1
  30.             With IE
  31.                 .document.getElementsByTagName("select")("yy").Value = X
  32.                 Do While .Busy Or .readyState <> 4:    Loop
  33.                  With .document.getelementbyid("input_stock_code")
  34.                     .Value = E
  35.                     .ParentNode.submit
  36.                 End With
  37.                 Do While .Busy Or .readyState <> 4:    Loop
  38.                 If InStr(.document.getElementsByTagName("TABLE")(0).innerHTML, "查無該筆資料") = 0 Then
  39.                     Msg = True
  40.                     If Application.Count(Sheets(1).UsedRange) = 0 Then '此工作表清空時:下載第一年度時
  41.                         AR = Array(0, 2)
  42.                     Else
  43.                         AR = Array(2)
  44.                     End If
  45.                     For Each Ea In AR
  46.                         Ep .document.getElementsByTagName("TABLE")(Ea).outerHTML
  47.                     Next
  48.                 Else
  49.                     Msg = False          '上櫃的年份就會出現查無
  50.                     GoTo NN
  51.                 End If
  52.             ii = ii + 1
  53.             End With
  54.         Next X
  55. NN:
  56.         xFile = xPath & "\" & E & "\HPM.txt"
  57.         MkDir_Sub xFile
  58.         Maketxt xFile, Sheets(1).UsedRange
  59.         Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii / 3 & " 文字檔"
  60.     Next E
  61.     IE.Quit
  62.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上櫃月成交 " & ii / 3 & " 文字檔,  讀取完畢 !! "
  63.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  64. End Sub
  65. Sub Maketxt(xF As String, Q As Range)    '將匯入資料存入指定的txt
  66.     Dim fs As Object, E As Range, C As Variant
  67.     Q.Range("C1") = ""
  68.     Q.Range("A1") = Q.Range("B1") & " " & "月成交資料"
  69.     Q.Range("B1") = ""
  70.     Q.Range("a4", Q.Range("a4").End(xlDown)).Replace "年", ""
  71.     Q.Columns(1).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
  72.     Q.Rows(3).Delete     '上櫃月成交資料當月還未結束時就會有資料了,所以要將還沒結束的月份刪除
  73.     '是Q.Rows(3)不 Rows(4)
  74.     Set fs = CreateObject("Scripting.FileSystemObject")
  75.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  76.     For Each E In Q.Rows
  77.         C = Application.Transpose(Application.Transpose(E.Value))
  78.         C = Join(C, vbTab)
  79.         fs.WriteLine C
  80.     Next
  81.     fs.Close
  82. End Sub
複製代碼

作者: smart3135    時間: 2014-5-19 12:30

回復 53# GBKEE
GBKEE版主您好,這幾天終於弄懂了為什麼這個程式碼會出錯了,原來您說的不可見字元是Q.Cells(1)文字中內含的問號
我是著用以下方法讓它不會出錯,也能取得個股名稱一起代入,不過下面的方法只能適用個股名稱是兩個字的,如果遇上三個字的還是會出錯
不知是否還有其他變通方式?再請您指點一下,謝謝!
另外還想請問您Code As String的Code是怎麼帶出個股編號的?因為我在這個程式中似乎找不到和Code有相關的程式碼能取得個股編號,再麻煩您解惑一下,謝謝!
  1. Sub Maketxt(xF As String, Q As Range, Code As String)     '將匯入資料存入指定的txt
  2.     Dim fs As Object, E As Range, C As Variant, A As String, B As String
  3.     Set fs = CreateObject("Scripting.FileSystemObject")
  4.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  5.     A = Q.Cells(1)
  6.     B = Mid(A, 11, 2)
  7.     Q.Cells(1) = Code & B & " 月成交資訊"   '加入股票代號
  8.     For Each E In Q.Rows
  9.         C = Application.Transpose(Application.Transpose(E.Value))
  10.         C = Join(C, vbTab)
  11.         fs.WriteLine C
  12.     Next
  13.     fs.Close
  14. End Sub
複製代碼

作者: smart3135    時間: 2014-5-19 12:53

回復 53# GBKEE
抱歉,更正一下,上一篇回覆的內容有點錯誤
如果遇上三個字的還是會出錯改成如果遇上三個字的個股名稱就只能擷取到兩個字
作者: smart3135    時間: 2014-5-19 13:25

回復 40# GBKEE
抱歉,先前有個問題一直忘了問您,您在40#中回覆的程式碼確實是可以製圖及取得集保戶近一年資料,不過和我想要的格式不大相同
在您後面指導如何利用檢視網頁原始碼取得關鍵引數後,我有試著利用取得上市月資料的程式碼將集保戶網頁及相關引數代入,但在中途就會出錯
不大清楚問題出在什麼地方,附上程式碼以及我想要完成的文字檔格式,再麻煩您教導一下,感謝!

集保戶網頁

[attach]18315[/attach]
  1. Option Explicit
  2. Dim IE As Object
  3. Sub IE_Application()
  4.     Set IE = CreateObject("InternetExplorer.Application")
  5.     With IE
  6.         .Navigate "http://www.tdcc.com.tw/smWeb/QryStock.jsp"
  7.         .Visible = True   '不顯示ie
  8.         Do While .Busy Or .readyState <> 4: DoEvents: Loop
  9.   End With
  10. End Sub
  11. Sub 集保()
  12.     Dim Rng As Range, Rng1 As Range, E As Range, X As Range, T As Date, xPath As String, xFile As String
  13.     Dim Ea As Variant, ar(), ii As Integer
  14.     T = Time
  15.     Application.DisplayStatusBar = True
  16.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  17.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  18.     Set Rng1 = ThisWorkbook.Sheets(3).Range("b:b")
  19.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  20.     If Application.Count(Rng1) = 0 Then MsgBox "沒有股票代號": Exit Sub
  21.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  22.     Set Rng1 = Rng1.SpecialCells(xlCellTypeConstants)
  23.     xPath = "D:\財報資料"
  24.     IE_Application    '
  25.     Application.StatusBar = " "
  26.     For Each E In Rng
  27.         With Sheets(1)
  28.             .Activate
  29.             .Cells.Clear  '下載資料置於此工作表,變換股票時:清空
  30.         End With
  31.         For Each X In Rng1
  32.             With IE
  33.                 .Document.getElementsByTagName("select")("SCA_DATE").Value = X
  34.                  With .Document.getelementbyid("StockNo")
  35.                     .Value = E
  36.                     .Document.getelementSbyNAME("login_btn")(0).Click  '按下查詢
  37.                 End With
  38.                 Do While .Busy Or .readyState <> 4:    Loop
  39.                 If .Document.getElementsByTagName("TABLE")(7).Rows.Length > 1 Then
  40.                     Ep .Document.getElementsByTagName("TABLE")(7).outerHTML
  41.                 Else
  42.                     GoTo Nn
  43.                 End If
  44.             End With
  45.         Next X
  46. Nn:
  47.         xFile = xPath & "\" & E & "\SHD.txt"
  48.         MkDir_Sub xFile
  49.         Maketxt xFile, Sheets(1).Range("A1").CurrentRegion, E.Value
  50.         ii = ii + 1
  51.         Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔"
  52.     Next E
  53.     IE.Quit
  54.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔,  讀取完畢 !! "
  55.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  56. '    ThisWorkbook.Save
  57. End Sub
  58. Sub Ep(S As String)
  59.     Dim D As New DataObject, i As Integer, FormDLL As String, Rng As Range
  60.     'DataObject 物件 在進行轉換動作時,做為格式化文字資料的暫存區域。其也可以暫存和儲存在 DataObject 的文字片段相關的格式。
  61.     '宣告 Dim D As New DataObject '須在工具-> 設定引用項目加入 新增引用 Microsoft Forms 2.0 Object Library ,專案 加入一表單即可
  62.     On Error GoTo ER
  63.     With D
  64.         .SetText S
  65.         .PutInClipboard
  66.         With Sheets(1)
  67.             With .Range("a" & .Rows.Count).End(xlUp)
  68.                 If .Row = 1 Then
  69.                     Set Rng = .Cells
  70.                 Else
  71.                     Set Rng = .Offset(1)
  72.                 End If
  73.                 Rng.Select
  74.                 .Parent.PasteSpecial Format:="Unicode 文字"
  75.                 Set Rng = Rng.Range("A3", Rng.Range("A3").End(xlDown)).Resize(, 9)
  76.                 'Sort :資料排序
  77.                 Rng.Sort Key1:=Rng.Range("B2"), Order1:=xlDescending, Header:=xlYes ', _
  78.                 OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod _
  79.                 :=xlStroke, DataOption1:=xlSortNorma
  80.                 If .Row = 1 Then
  81.                     .Range("A2").EntireRow.Delete
  82.                 Else
  83.                     .Range("A2:A4").EntireRow.Delete
  84.                 End If
  85.             End With
  86.         End With
  87.     End With
  88.     Exit Sub
  89. ER:
  90.     ThisWorkbook.VBProject.References.AddFromFile "C:\windows\system32\FM20.DLL"
  91.     Resume
  92. End Sub
  93. Sub Maketxt(xF As String, Q As Range, Code As String)     '將匯入資料存入指定的txt
  94.     Dim fs As Object, E As Range, C As Variant
  95.     Set fs = CreateObject("Scripting.FileSystemObject")
  96.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  97.     For Each E In Q.Rows
  98.         C = Application.Transpose(Application.Transpose(E.Value))
  99.         C = Join(C, vbTab)
  100.         fs.WriteLine C
  101.     Next
  102.     fs.Close
  103. End Sub
  104. Sub MkDir_Sub(S As String)
  105.     Dim ar, i As Integer, xPath As String
  106.     If Dir(S) = "" Then
  107.         ar = Split(S, "\")
  108.         xPath = ar(0)
  109.         For i = 1 To UBound(ar) - 1
  110.             xPath = xPath & "\" & ar(i)
  111.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  112.         Next
  113.     End If
  114. End Sub
複製代碼
[attach]18316[/attach]
作者: GBKEE    時間: 2014-5-19 16:18

本帖最後由 GBKEE 於 2014-5-20 16:04 編輯

回復 59# smart3135
  1. Option Explicit
  2. Dim IE As Object, A As Integer
  3. Sub IE_Application()
  4.     Dim i As Integer
  5.     Set IE = CreateObject("InternetExplorer.Application")
  6.     With IE
  7.         .Navigate "http://www.tdcc.com.tw/smWeb/QryStock.jsp"
  8.         .Visible = True   '不顯示ie
  9.         Do While .Busy Or .readyState <> 4: DoEvents: Loop
  10.         '讀取集保戶股權分散表查詢的資料日期總個數
  11.         A = .document.getelementsByTagName("select")("SCA_DATE").Length - 1
  12.   End With
  13. End Sub
  14. Sub 集保()
  15.     Dim Rng As Range, E As Range, x As Variant, T As Date, xPath As String, xFile As String
  16.     Dim Ea As Variant, ii As Integer
  17.     T = Time
  18.     Application.DisplayStatusBar = True
  19.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  20.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  21.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  22.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  23.     xPath = "D:\財報資料"
  24.     IE_Application    '
  25.     Application.StatusBar = " "
  26.     For Each E In Rng
  27.         With Sheets(1)
  28.             .Activate
  29.             .Cells.Clear  '下載資料置於此工作表,變換股票時:清空
  30.         End With
  31.         For x = 0 To A
  32.             With IE
  33.                 .document.getelementsByTagName("select")("SCA_DATE")(x).Selected = True
  34.                                             '這裡的資料日期 需用 Select 它是有[年度月份日期]的
  35.                  .document.getElementById("StockNo").Value = E
  36.                     .document.getelementsByTagName("INPUT")("sub").Click  '按下查詢
  37.                        '這裡的查詢是<INPUT TYPE="submit" VALUE="查詢" name="sub">
  38.                 'End With
  39.                 Do While .Busy Or .readyState <> 4:    Loop
  40.                 Ep .document.getelementsByTagName("TABLE")(7).outerHTML
  41.             End With
  42.         Next x
  43.         xFile = xPath & "\" & E & "\SHD.txt"
  44.         MkDir_Sub xFile
  45.         
  46.         Maketxt xFile, Sheets(1).Range("A1").CurrentRegion, E.Value
  47.         '***想請問您Code As String的Code是怎麼帶出個股編號的 ****
  48.         'xFile(第一個引數), Sheets(1).Range("A1").CurrentRegion(第二個引數),E.Value(第三個引數)
  49.         
  50.         ii = ii + 1
  51.         Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔"
  52.     Next E
  53.     IE.Quit
  54.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔,  讀取完畢 !! "
  55.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  56. '    ThisWorkbook.Save
  57. End Sub
  58. Sub Maketxt(xF As String, Q As Range, Code As String)     '將匯入資料存入指定的txt
  59.           '***想請問您Code As String的Code是怎麼帶出個股編號的 ****
  60.           ' xF(接收的引數名稱) As String(字串型態), Q As Range(Range物件型態), Code As String(字串型態)
  61.     Dim fs As Object, E As Range, C As Variant
  62.     Set fs = CreateObject("Scripting.FileSystemObject")
  63.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  64.     For Each E In Q.Rows
  65.         C = Application.Transpose(Application.Transpose(E.Value))
  66.         C = Join(C, vbTab)
  67.         fs.WriteLine C
  68.     Next
  69.     fs.Close
  70. End Sub
複製代碼

作者: smart3135    時間: 2014-5-19 19:06

回復 60# GBKEE
版主抱歉,請問一下,我將您提供的程式碼代入後出錯位置及出錯訊息仍和之前一樣,能麻煩您再幫忙看一下嗎?感恩!
[attach]18317[/attach]
  1. Option Explicit
  2. Dim IE As Object, A As Integer
  3. Sub IE_Application()
  4.     Dim I As Integer
  5.     Set IE = CreateObject("InternetExplorer.Application")
  6.     With IE
  7.         .Navigate "http://www.tdcc.com.tw/smWeb/QryStock.jsp"
  8.         .Visible = True   '不顯示ie
  9.         Do While .Busy Or .readyState <> 4: DoEvents: Loop
  10.         '讀取集保戶股權分散表查詢的資料日期總個數
  11.         A = .document.getelementsByTagName("select")("SCA_DATE").Length - 1
  12.   End With
  13. End Sub
  14. Sub 集保()
  15.     Dim Rng As Range, E As Range, x As Variant, T As Date, xPath As String, xFile As String
  16.     Dim Ea As Variant, ii As Integer
  17.     T = Time
  18.     Application.DisplayStatusBar = True
  19.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  20.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  21.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  22.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  23.     xPath = "D:\財報資料"
  24.     IE_Application    '
  25.     Application.StatusBar = " "
  26.     For Each E In Rng
  27.         With Sheets(1)
  28.             .Activate
  29.             .Cells.Clear  '下載資料置於此工作表,變換股票時:清空
  30.         End With
  31.         For x = A - 1 To A
  32.             With IE
  33.                 .document.getelementsByTagName("select")("SCA_DATE")(x).Selected = True
  34.                                             '這裡的資料日期 需用 Select 它是有[年度月份日期]的
  35.                  .document.getElementById("StockNo").Value = E
  36.                     .document.getelementsByTagName("INPUT")("sub").Click  '按下查詢
  37.                        '這裡的查詢是<INPUT TYPE="submit" VALUE="查詢" name="sub">
  38.                 'End With
  39.                 Do While .Busy Or .readyState <> 4:    Loop
  40.                 Ep .document.getelementsByTagName("TABLE")(7).outerHTML
  41.             End With
  42.         Next x
  43.         xFile = xPath & "\" & E & "\SHD.txt"
  44.         MkDir_Sub xFile
  45.         
  46.         Maketxt xFile, Sheets(1).Range("A1").CurrentRegion, E.Value
  47.         '***想請問您Code As String的Code是怎麼帶出個股編號的 ****
  48.         'xFile(第一個引數), Sheets(1).Range("A1").CurrentRegion(第二個引數),E.Value(第三個引數)
  49.         
  50.         ii = ii + 1
  51.         Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔"
  52.     Next E
  53.     IE.Quit
  54.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔,  讀取完畢 !! "
  55.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  56. '    ThisWorkbook.Save
  57. End Sub
  58. Sub Ep(S As String)
  59.     Dim D As New DataObject, E As Shape, FormDLL As String, Rng As Range
  60.     'DataObject 物件 在進行轉換動作時,做為格式化文字資料的暫存區域。其也可以暫存和儲存在 DataObject 的文字片段相關的格式。
  61.     '宣告 Dim D As New DataObject '須在工具-> 設定引用項目加入 新增引用 Microsoft Forms 2.0 Object Library ,專案 加入一表單即可
  62.     On Error GoTo ER
  63.     With D
  64.         .SetText S
  65.         .PutInClipboard
  66.         With Sheets(1)
  67.             .Range("a" & .Rows.Count).End(xlUp).Offset(1).Select
  68.             .PasteSpecial Format:="Unicode 文字"
  69. '            Set Rng = Selection
  70. '                Rng.Sort Key1:=Rng.Range("B2"), Order1:=xlDescending, Header:=xlYes ', _
  71.                 OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod _
  72.                 :=xlStroke, DataOption1:=xlSortNorma
  73.         End With
  74.     End With
  75.     Exit Sub
  76. ER:
  77.     FormDLL = "FM20.DLL"
  78.     ThisWorkbook.VBProject.References.AddFromFile "C:\windows\system32\" & FormDLL
  79.     Resume
  80. End Sub
  81. Sub Maketxt(xF As String, Q As Range, Code As String)     '將匯入資料存入指定的txt
  82.           '***想請問您Code As String的Code是怎麼帶出個股編號的 ****
  83.           ' xF(接收的引數名稱) As String(字串型態), Q As Range(Range物件型態), Code As String(字串型態)
  84.     Dim fs As Object, E As Range, C As Variant
  85.     Set fs = CreateObject("Scripting.FileSystemObject")
  86.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  87.     For Each E In Q.Rows
  88.         C = Application.Transpose(Application.Transpose(E.Value))
  89.         C = Join(C, vbTab)
  90.         fs.WriteLine C
  91.     Next
  92.     fs.Close
  93. End Sub
  94. Sub MkDir_Sub(S As String)
  95.     Dim AR, I As Integer, xPath As String
  96.     If Dir(S) = "" Then
  97.         AR = Split(S, "\")
  98.         xPath = AR(0)
  99.         For I = 1 To UBound(AR) - 1
  100.             xPath = xPath & "\" & AR(I)
  101.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  102.         Next
  103.     End If
  104. End Sub
複製代碼

作者: GBKEE    時間: 2014-5-20 15:59

本帖最後由 GBKEE 於 2014-5-20 16:01 編輯

回復 61# smart3135
該我說抱歉
  1. 31.        For x = A - 1 To A            
複製代碼
需更正
  1. For x = 0 To A
複製代碼
請在指出哪裡錯誤.
作者: smart3135    時間: 2014-5-21 09:28

回復 62# GBKEE
版主您好,不好意思,我有試著將For x = A - 1 To A 改成For x = 0 To A,不過出錯訊息和出錯位置仍相同,能不能再麻煩您測試一下呢?
另外在更之前的上櫃年成交資料,就是用比較舊的寫法,不貼上EXCEL直接寫入TXT的程式碼,雖然有資料,不過最上方少了個股代號和名稱,不知這部分能不能
也擷取到資料並寫入TXT?或是是有可以先貼到EXCEL再寫入TXT的方法?再麻煩您了!
  1. Option Explicit
  2. Dim IE As Object, A As Integer
  3. Sub IE_Application()
  4.     Dim I As Integer
  5.     Set IE = CreateObject("InternetExplorer.Application")
  6.     With IE
  7.         .Navigate "http://www.tdcc.com.tw/smWeb/QryStock.jsp"
  8.         .Visible = True   '不顯示ie
  9.         Do While .Busy Or .readyState <> 4: DoEvents: Loop
  10.         '讀取集保戶股權分散表查詢的資料日期總個數
  11.         A = .document.getelementsByTagName("select")("SCA_DATE").Length - 1
  12.   End With
  13. End Sub
  14. Sub 集保()
  15.     Dim Rng As Range, E As Range, x As Variant, T As Date, xPath As String, xFile As String
  16.     Dim Ea As Variant, ii As Integer
  17.     T = Time
  18.     Application.DisplayStatusBar = True
  19.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  20.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  21.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  22.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  23.     xPath = "D:\財報資料"
  24.     IE_Application    '
  25.     Application.StatusBar = " "
  26.     For Each E In Rng
  27.         With Sheets(1)
  28.             .Activate
  29.             .Cells.Clear  '下載資料置於此工作表,變換股票時:清空
  30.         End With
  31.         For x = 0 To A
  32.             With IE
  33.                 .document.getelementsByTagName("select")("SCA_DATE")(x).Selected = True
  34.                                             '這裡的資料日期 需用 Select 它是有[年度月份日期]的
  35.                  .document.getElementById("StockNo").Value = E
  36.                     .document.getelementsByTagName("INPUT")("sub").Click  '按下查詢
  37.                        '這裡的查詢是<INPUT TYPE="submit" VALUE="查詢" name="sub">
  38.                 'End With
  39.                 Do While .Busy Or .readyState <> 4:    Loop
  40.                 Ep .document.getelementsByTagName("TABLE")(7).outerHTML
  41.             End With
  42.         Next x
  43.         xFile = xPath & "\" & E & "\SHD.txt"
  44.         MkDir_Sub xFile
  45.         
  46.         Maketxt xFile, Sheets(1).Range("A1").CurrentRegion, E.Value
  47.         '***想請問您Code As String的Code是怎麼帶出個股編號的 ****
  48.         'xFile(第一個引數), Sheets(1).Range("A1").CurrentRegion(第二個引數),E.Value(第三個引數)
  49.         
  50.         ii = ii + 1
  51.         Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔"
  52.     Next E
  53.     IE.Quit
  54.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔,  讀取完畢 !! "
  55.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  56. '    ThisWorkbook.Save
  57. End Sub
  58. Sub Ep(S As String)
  59.     Dim D As New DataObject, E As Shape, FormDLL As String, Rng As Range
  60.     'DataObject 物件 在進行轉換動作時,做為格式化文字資料的暫存區域。其也可以暫存和儲存在 DataObject 的文字片段相關的格式。
  61.     '宣告 Dim D As New DataObject '須在工具-> 設定引用項目加入 新增引用 Microsoft Forms 2.0 Object Library ,專案 加入一表單即可
  62.     On Error GoTo ER
  63.     With D
  64.         .SetText S
  65.         .PutInClipboard
  66.         With Sheets(1)
  67.             .Range("a" & .Rows.Count).End(xlUp).Offset(1).Select
  68.             .PasteSpecial Format:="Unicode 文字"
  69. '            Set Rng = Selection
  70. '                Rng.Sort Key1:=Rng.Range("B2"), Order1:=xlDescending, Header:=xlYes ', _
  71.                 OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod _
  72.                 :=xlStroke, DataOption1:=xlSortNorma
  73.         End With
  74.     End With
  75.     Exit Sub
  76. ER:
  77.     FormDLL = "FM20.DLL"
  78.     ThisWorkbook.VBProject.References.AddFromFile "C:\windows\system32\" & FormDLL
  79.     Resume
  80. End Sub
  81. Sub Maketxt(xF As String, Q As Range, Code As String)     '將匯入資料存入指定的txt
  82.           '***想請問您Code As String的Code是怎麼帶出個股編號的 ****
  83.           ' xF(接收的引數名稱) As String(字串型態), Q As Range(Range物件型態), Code As String(字串型態)
  84.     Dim fs As Object, E As Range, C As Variant
  85.     Set fs = CreateObject("Scripting.FileSystemObject")
  86.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  87.     For Each E In Q.Rows
  88.         C = Application.Transpose(Application.Transpose(E.Value))
  89.         C = Join(C, vbTab)
  90.         fs.WriteLine C
  91.     Next
  92.     fs.Close
  93. End Sub
  94. Sub MkDir_Sub(S As String)
  95.     Dim AR, I As Integer, xPath As String
  96.     If Dir(S) = "" Then
  97.         AR = Split(S, "\")
  98.         xPath = AR(0)
  99.         For I = 1 To UBound(AR) - 1
  100.             xPath = xPath & "\" & AR(I)
  101.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  102.         Next
  103.     End If
  104. End Sub
複製代碼
  1. Option Explicit
  2. Dim IE As Object
  3. Sub IE_Application()
  4.     Set IE = CreateObject("InternetExplorer.Application")
  5.     With IE
  6.         .Navigate "http://www.gretai.org.tw/ch/stock/statistics/monthly/st42.php"
  7.         .Visible = True   '不顯示ie
  8.         Do While .Busy Or .ReadyState <> 4: DoEvents: Loop
  9.   End With
  10. End Sub
  11. Sub 上櫃年成交資訊()
  12.     Dim E As Range, xPath As String, xFile As String, A As Object, fs As Object, F As Object, IE_URL As String
  13.     Dim i As Integer, ii As Integer, t As Date, AR(), Rng As Range, r, C, S
  14.     Set fs = CreateObject("Scripting.FileSystemObject")
  15.     IE_URL = "http://www.gretai.org.tw/ch/stock/statistics/monthly/st42.php"
  16.     t = Time
  17.     Application.DisplayStatusBar = True
  18.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  19.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  20.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  21.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  22.     xPath = "D:\財報資料"
  23.     IE_Application    '
  24.     Application.StatusBar = " "
  25.     For Each E In Rng
  26.         With IE
  27.             Set A = .Document.getelementbyid("input_stock_code")
  28.             A.Value = E
  29.             A.ParentNode.submit
  30.             Do While .Busy Or .ReadyState <> 4:    Loop
  31.             Set A = .Document.getelementsbytagname("TABLE")
  32.             xFile = xPath & "\" & E & "\HPY.txt"
  33.             MkDir_Sub xFile
  34.             With fs.CreateTextFile(xFile, True)
  35.                 For i = 1 To A(2).Rows.Length - 1
  36.                     S = ""
  37.                     For C = 0 To A(2).Rows(i).Cells.Length - 1
  38.                         S = S & A(2).Rows(i).Cells(C).innertext & vbTab
  39.                     Next
  40.                     .WriteLine S
  41.                 Next
  42.                 .Close
  43.             End With
  44.             ii = ii + 1
  45.         End With
  46.         Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & " 共匯入上櫃年成交 " & ii & " 文字檔"
  47.     Next
  48.     IE.Quit
  49.     Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & " 共匯入上櫃年成交 " & ii & " 文字檔,  讀取完畢 !! "
  50.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - t, ["MM分SS秒"])
  51. '    ThisWorkbook.Save
  52. End Sub
  53. Sub MkDir_Sub(S As String)
  54.     Dim AR, i As Integer, xPath As String
  55.     If Dir(S) = "" Then
  56.         AR = Split(S, "\")
  57.         xPath = AR(0)
  58.         For i = 1 To UBound(AR) - 1
  59.             xPath = xPath & "\" & AR(i)
  60.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  61.         Next
  62.     End If
  63. End Sub
  64. Sub Maketxt(xF As String, Q As QueryTable)   '將匯入資料存入指定的txt
  65.     Dim fs As Object, E As Range, C As Variant
  66.     Set fs = CreateObject("Scripting.FileSystemObject")
  67.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  68.     For Each E In Q.ResultRange.Rows
  69.         C = Application.Transpose(Application.Transpose(E.Value))
  70.         C = Join(C, vbTab)
  71.         fs.WriteLine C
  72.     Next
  73.     fs.Close
  74. End Sub
複製代碼
[attach]18322[/attach]
作者: GBKEE    時間: 2014-5-21 16:11

回復 63# smart3135

   
成For x = 0 To A,不過出錯訊息和出錯位置仍相同
我測試沒出錯,請說明出錯訊息和出錯位置.
  1. With fs.CreateTextFile(xFile, True)
  2.                 S = Split(A(0).innertext, ")")(1)
  3.                 .WriteLine Split(S, vbLf)(0) '最上方加上個股代號和名稱了.
  4.                 For i = 1 To A(2).Rows.Length - 1
  5.                     S = ""
  6.                     For C = 0 To A(2).Rows(i).Cells.Length - 1
  7.                         S = S & A(2).Rows(i).Cells(C).innertext & vbTab
  8.                     Next
  9.                     .WriteLine S
  10.                 Next
  11.                 .Close
  12.             End With
複製代碼

作者: smart3135    時間: 2014-5-21 20:17

回復 64# GBKEE
版主您好,集保程序我有試著再執行一次,結果還是一樣,出錯訊息如圖:
[attach]18326[/attach]

另外您提供的程式碼我有加入上櫃年成交中,最上方是有寫入了,不過是寫入空白資料,不是股票代號和名稱,能麻煩您再看一下嗎?
  1. Sub 上櫃年成交資訊()
  2.     Dim E As Range, xPath As String, xFile As String, A As Object, fs As Object, F As Object, IE_URL As String
  3.     Dim i As Integer, ii As Integer, t As Date, AR(), Rng As Range, r, C, S
  4.     Set fs = CreateObject("Scripting.FileSystemObject")
  5.     IE_URL = "http://www.gretai.org.tw/ch/stock/statistics/monthly/st42.php"
  6.     t = Time
  7.     Application.DisplayStatusBar = True
  8.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  9.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  10.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  11.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  12.     xPath = "D:\財報資料"
  13.     IE_Application    '
  14.     Application.StatusBar = " "
  15.     For Each E In Rng
  16.         With IE
  17.             Set A = .Document.getelementbyid("input_stock_code")
  18.             A.Value = E
  19.             A.ParentNode.submit
  20.             Do While .Busy Or .ReadyState <> 4:    Loop
  21.             Set A = .Document.getelementsbytagname("TABLE")
  22.             xFile = xPath & "\" & E & "\HPY.txt"
  23.             MkDir_Sub xFile
  24.             With fs.CreateTextFile(xFile, True)
  25.                 S = Split(A(0).innertext, ")")(1)
  26.                 .WriteLine Split(S, vbLf)(0) '最上方加上個股代號和名稱了.
  27.                 For i = 1 To A(2).Rows.Length - 1
  28.                     S = ""
  29.                     For C = 0 To A(2).Rows(i).Cells.Length - 1
  30.                         S = S & A(2).Rows(i).Cells(C).innertext & vbTab
  31.                     Next
  32.                     .WriteLine S
  33.                 Next
  34.                 .Close
  35.             End With
  36.             ii = ii + 1
  37.         End With
  38.         Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & " 共匯入上櫃年成交 " & ii & " 文字檔"
  39.     Next
  40.     IE.Quit
  41.     Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & " 共匯入上櫃年成交 " & ii & " 文字檔,  讀取完畢 !! "
  42.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - t, ["MM分SS秒"])
  43. '    ThisWorkbook.Save
  44. End Sub
複製代碼
[attach]18327[/attach]
作者: smart3135    時間: 2014-5-22 09:34

本帖最後由 smart3135 於 2014-5-22 09:35 編輯

回復 64# GBKEE
版主您好,今天利用上櫃月成交資料的程式碼來做了一些修正,已經可以順利擷取上櫃年成交資料了,只是還有一些小問題:
1.多餘的語法該刪除的我應該都刪除了,不確定有沒有多餘不必要的語法沒被刪除
2.在擷取資料貼到EXCEL後,日期的部分會變成文字,請見附圖,不過網頁顯示的只是單純的日期
舉例來說:網頁顯示的表格是4/17,但匯入EXCEL後就會變成4月17日,而寫入文字檔時則變成2014/4/17
我有試著在匯入EXCEL之前將日期欄位的儲存格格式先設定成文字,不過貼上EXCEL後還是會被修改格式
我希望寫入文字檔的日期資料只要月日就好,也就是4/17,不知道這部分有沒有辦法修改?
另外如65#回覆,集保戶資料的問題還是未能解決,再麻煩您幫忙看一下囉!感謝!
[attach]18329[/attach]
[attach]18330[/attach]
  1. Option Explicit
  2. Dim IE As Object
  3. Sub IE_Application()
  4.     If Not IE Is Nothing Then IE.Quit  '當查到上櫃的年份就會出現查無,此IE無法再度查詢,關閉它
  5.     Set IE = CreateObject("InternetExplorer.Application")
  6.     With IE
  7.         .Navigate "http://www.gretai.org.tw/ch/stock/statistics/monthly/st42.php"
  8. '        .Visible = True   '不顯示ie
  9.         Do While .Busy Or .readyState <> 4: DoEvents: Loop
  10.     End With
  11. End Sub
  12. Sub 上櫃年成交資訊()
  13.     Dim Rng As Range, Rng1 As Range, E As Range, T As Date, xPath As String, xFile As String
  14.     Dim Ea As Variant, AR(), ii As Integer
  15.     T = Time
  16.     Application.DisplayStatusBar = True
  17.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  18.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  19.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  20.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  21.     xPath = "G:\財報資料"
  22.     IE_Application
  23.     Application.StatusBar = " "
  24.     For Each E In Rng
  25.         Sheets(1).UsedRange.Clear            '下載資料置於此工作表,變換股票時:清空
  26.             With IE
  27.                  With .document.getelementbyid("input_stock_code")
  28.                     .Value = E
  29.                     .ParentNode.submit
  30.                 End With
  31.                 Do While .Busy Or .readyState <> 4:    Loop
  32.                 If Application.Count(Sheets(1).UsedRange) = 0 Then '此工作表清空時:下載第一年度時
  33.                     AR = Array(0, 2)
  34. '                Else
  35. '                    AR = Array(2)
  36.                 End If
  37.                 For Each Ea In AR
  38.                     Ep .document.getElementsByTagName("TABLE")(Ea).outerHTML
  39.                 Next
  40.             End With
  41.         ii = ii + 1
  42.         xFile = xPath & "\" & E & "\HPM.txt"
  43.         MkDir_Sub xFile
  44.         Maketxt xFile, Sheets(1).UsedRange
  45.         Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上櫃" & E & "年成交 " & ii & " 文字檔"
  46.     Next E
  47.     IE.Quit
  48.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上櫃年成交 " & ii & " 文字檔,  讀取完畢 !! "
  49.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  50. End Sub
  51. Sub Ep(S As String)
  52.     Dim D As New DataObject, E As Shape, FormDLL As String, Rng As Range
  53.     'DataObject 物件 在進行轉換動作時,做為格式化文字資料的暫存區域。其也可以暫存和儲存在 DataObject 的文字片段相關的格式。
  54.     '宣告 Dim D As New DataObject '須在工具-> 設定引用項目加入 新增引用 Microsoft Forms 2.0 Object Library ,專案 加入一表單即可
  55.     On Error GoTo ER
  56.     With D
  57.         .SetText S
  58.         .PutInClipboard
  59.         With Sheets(1)
  60.             .Range("a" & .Rows.Count).End(xlUp).Select
  61.             If .Range("a1") <> "" Then .Range("a" & .Rows.Count).End(xlUp).Offset(1).Select
  62.             .PasteSpecial Format:="Unicode 文字"
  63.         End With
  64.     End With
  65.     Exit Sub
  66. ER:
  67.     FormDLL = "FM20.DLL"
  68.     ThisWorkbook.VBProject.References.AddFromFile "C:\windows\system32\" & FormDLL
  69.     Resume
  70. End Sub
  71. Sub MkDir_Sub(S As String)
  72.     Dim AR, i As Integer, xPath As String
  73.     If Dir(S) = "" Then
  74.         AR = Split(S, "\")
  75.         xPath = AR(0)
  76.         For i = 1 To UBound(AR) - 1
  77.             xPath = xPath & "\" & AR(i)
  78.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  79.         Next
  80.     End If
  81. End Sub
  82. Sub Maketxt(xF As String, Q As Range)    '將匯入資料存入指定的txt
  83.     Dim fs As Object, E As Range, C As Variant
  84.     Q.Range("C1").Clear
  85.     Q.Range("A1") = Q.Range("B1") & " " & "年成交資料"
  86.     Q.Range("B1").Clear
  87.     Q.Rows(2).Delete
  88.     Set fs = CreateObject("Scripting.FileSystemObject")
  89.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  90.     For Each E In Q.Rows
  91.         C = Application.Transpose(Application.Transpose(E.Value))
  92.         C = Join(C, vbTab)
  93.         fs.WriteLine C
  94.     Next
  95.     fs.Close
  96. End Sub
複製代碼
[attach]18331[/attach]
作者: GBKEE    時間: 2014-5-22 16:04     標題:

本帖最後由 GBKEE 於 2014-5-22 16:28 編輯

回復 66# smart3135
  1. S = Split(A(0).innertext, ")")(1)
  2.                 .WriteLine Split(S, vbLf)(0) '最上方加上個股代號和名稱了.
複製代碼
集保程序我有試著再執行一次,結果還是一樣,出錯訊息如圖

2003版
確定可以寫入股票代號及名稱
集保程序,一樣確定沒有出現錯誤.
你是在2007中執行嗎?(請有2007版測試一下)
希望寫入文字檔的日期資料只要月日就好,也就是4/17
  1. Sub Maketxt(xF As String, Q As Range)    '將匯入資料存入指定的txt
  2.     Dim fs As Object, E As Range, C As Variant, R As Range
  3.     With Q
  4.         .Range("C1").Clear
  5.         .Range("A1") = Q.Range("B1") & " " & "年成交資料"
  6.         .Range("B1").Clear
  7.         .Rows(2).Delete
  8.         .Range("H:H,F:F").NumberFormatLocal = "m/d;@"
  9.         .EntireColumn.AutoFit
  10.     End With
  11.     Set fs = CreateObject("Scripting.FileSystemObject")
  12.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  13.     For Each E In Q.Rows
  14.          C = ""
  15.          For Each R In E.Cells
  16.             C = C & IIf(C <> "", vbTab, "") & R.Text
  17.             'C = Application.Transpose(Application.Transpose(E.Value))
  18.             'C  = Join(C, vbTab)
  19.         Next
  20.         fs.WriteLine C
  21.     Next
  22.     fs.Close
  23. End Sub
複製代碼

作者: smart3135    時間: 2014-5-22 19:22

回復 67# GBKEE
版主您好,因為我有雙系統,一個是WIN7+2007,一個是XP+2003,我平常都是開WIN7的,經你提醒,今天試著用2003跑一次集保程序
結果真的可以執行,不會出錯,但在2007卻會出錯,這部分可能還要再研究一下為什麼會這樣
另外寫入日期部分經帶入您的程式碼後已可正常寫入日期,再次感謝您大力協助,謝謝您!
作者: smart3135    時間: 2014-5-23 11:11

本帖最後由 smart3135 於 2014-5-23 11:13 編輯

回復 67# GBKEE
版主您好,經過今天早上不斷使用2003版測試,終於做出我想要的輸出文字檔結果,不過還是有些問題會發生,先附上程式碼與附檔
[attach]18346[/attach]
這裡是完整的程式碼
  1. Option Explicit
  2. Dim IE As Object, A As Integer
  3. Sub IE_Application()
  4.     Dim I As Integer
  5.     Set IE = CreateObject("InternetExplorer.Application")
  6.     With IE
  7.         .Navigate "http://www.tdcc.com.tw/smWeb/QryStock.jsp"
  8. '        .Visible = True   '不顯示ie
  9.         Do While .Busy Or .readyState <> 4: DoEvents: Loop
  10.         '讀取集保戶股權分散表查詢的資料日期總個數
  11.         A = .document.getelementsByTagName("select")("SCA_DATE").Length - 1
  12.   End With
  13. End Sub
  14. Sub 集保()
  15.     Dim Rng As Range, E As Range, x As Variant, T As Date, xPath As String, xFile As String
  16.     Dim Ea As Variant, ii As Integer, F As String, H As String, J As Integer
  17.     T = Time
  18.     Application.DisplayStatusBar = True
  19.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  20.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  21.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  22.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  23.     xPath = "E:\財報資料"
  24.     IE_Application    '
  25.     Application.StatusBar = " "
  26.     For Each E In Rng
  27.         With Sheets(1)
  28.             .Activate
  29.             .Cells.Clear  '下載資料置於此工作表,變換股票時:清空
  30.         End With
  31.             With IE
  32.                 .document.getElementById("StockNo").Value = E
  33.                 .document.getelementsByTagName("INPUT")("sub").Click  '按下查詢
  34.                        '這裡的查詢是<INPUT TYPE="submit" VALUE="查詢" name="sub">
  35.                 Do While .Busy Or .readyState <> 4:    Loop
  36.                 Ep .document.getelementsByTagName("TABLE")(5).outerHTML
  37.             End With
  38.         
  39.         For x = 0 To A
  40.             With IE
  41.                 .document.getelementsByTagName("select")("SCA_DATE")(x).Selected = True
  42.                                             '這裡的資料日期 需用 Select 它是有[年度月份日期]的
  43.                 .document.getElementById("StockNo").Value = E
  44.                 .document.getelementsByTagName("INPUT")("sub").Click  '按下查詢
  45.                        '這裡的查詢是<INPUT TYPE="submit" VALUE="查詢" name="sub">
  46.                 Do While .Busy Or .readyState <> 4:    Loop
  47.                 Ep .document.getelementsByTagName("TABLE")(6).outerHTML
  48.             End With
  49.             With IE
  50.                 .document.getelementsByTagName("select")("SCA_DATE")(x).Selected = True
  51.                                             '這裡的資料日期 需用 Select 它是有[年度月份日期]的
  52.                 .document.getElementById("StockNo").Value = E
  53.                 .document.getelementsByTagName("INPUT")("sub").Click  '按下查詢
  54.                        '這裡的查詢是<INPUT TYPE="submit" VALUE="查詢" name="sub">
  55.                 Do While .Busy Or .readyState <> 4:    Loop
  56.                 Ep .document.getelementsByTagName("TABLE")(7).outerHTML
  57.             End With
  58.         Next x
  59.         With Sheets(1)
  60.             F = .Range("a3")
  61.             J = Len(F)
  62.             If J >= 19 Then
  63.                 H = Mid(F, 1, 3)
  64.             Else
  65.                 H = Mid(F, 1, 2)
  66.             End If
  67.             .Range("a1") = E & "-" & H & " " & "集保戶股權分散表"
  68.             .Rows("2:4").Delete
  69.         End With
  70.         xFile = xPath & "\" & E & "\SHD.txt"
  71.         MkDir_Sub xFile
  72.         Maketxt xFile, Sheets(1).UsedRange, E.Value
  73.         '***想請問您Code As String的Code是怎麼帶出個股編號的 ****
  74.         'xFile(第一個引數), Sheets(1).Range("A1").CurrentRegion(第二個引數),E.Value(第三個引數)
  75.         ii = ii + 1
  76.         Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔"
  77.     Next E
  78.     IE.Quit
  79.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔,  讀取完畢 !! "
  80.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  81. '    ThisWorkbook.Save
  82. End Sub
  83. Sub Ep(S As String)
  84.     Dim D As New DataObject, E As Shape, FormDLL As String, Rng As Range
  85.     'DataObject 物件 在進行轉換動作時,做為格式化文字資料的暫存區域。其也可以暫存和儲存在 DataObject 的文字片段相關的格式。
  86.     '宣告 Dim D As New DataObject '須在工具-> 設定引用項目加入 新增引用 Microsoft Forms 2.0 Object Library ,專案 加入一表單即可
  87.     On Error GoTo ER
  88.     With D
  89.         .SetText S
  90.         .PutInClipboard
  91.         With Sheets(1)
  92.             .Range("a" & .Rows.Count).End(xlUp).Select
  93.             Set Rng = Selection
  94.             If Rng = 15 Then
  95.                 Rng.Offset(3).Select
  96.             Else
  97.                 Rng.Offset(2).Select
  98.             End If
  99.             .PasteSpecial Format:="Unicode 文字"
  100. '            If Selection = "" Then Selection.Offset(1).Select
  101. '            Set Rng = Selection
  102. '                Rng.Sort Key1:=Rng.Range("B2"), Order1:=xlDescending, Header:=xlYes ', _
  103.                 OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod _
  104.                 :=xlStroke, DataOption1:=xlSortNorma
  105.         End With
  106.     End With
  107.     Exit Sub
  108. ER:
  109.     FormDLL = "FM20.DLL"
  110.     ThisWorkbook.VBProject.References.AddFromFile "C:\windows\system32\" & FormDLL
  111.     Resume
  112. End Sub
  113. Sub Maketxt(xF As String, Q As Range, Code As String)     '將匯入資料存入指定的txt
  114.           '***想請問您Code As String的Code是怎麼帶出個股編號的 ****
  115.           ' xF(接收的引數名稱) As String(字串型態), Q As Range(Range物件型態), Code As String(字串型態)
  116.     Dim fs As Object, E As Range, C As Variant
  117.     Set fs = CreateObject("Scripting.FileSystemObject")
  118.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  119.     For Each E In Q.Rows
  120.         C = Application.Transpose(Application.Transpose(E.Value))
  121.         C = Join(C, vbTab)
  122.         fs.WriteLine C
  123.     Next
  124.     fs.Close
  125. End Sub
  126. Sub MkDir_Sub(S As String)
  127.     Dim AR, I As Integer, xPath As String
  128.     If Dir(S) = "" Then
  129.         AR = Split(S, "\")
  130.         xPath = AR(0)
  131.         For I = 1 To UBound(AR) - 1
  132.             xPath = xPath & "\" & AR(I)
  133.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  134.         Next
  135.     End If
  136. End Sub
複製代碼
因為我要的文字檔除了個股代號和名稱之外,還有日期也要一併寫入,所以我就自己加了以下這些東西
  1.             With IE
  2.                 .document.getElementById("StockNo").Value = E
  3.                 .document.getelementsByTagName("INPUT")("sub").Click  '按下查詢
  4.                        '這裡的查詢是<INPUT TYPE="submit" VALUE="查詢" name="sub">
  5.                 Do While .Busy Or .readyState <> 4:    Loop
  6.                 Ep .document.getelementsByTagName("TABLE")(5).outerHTML
  7.             End With
  8.         
  9.         For x = 0 To A
  10.             With IE
  11.                 .document.getelementsByTagName("select")("SCA_DATE")(x).Selected = True
  12.                                             '這裡的資料日期 需用 Select 它是有[年度月份日期]的
  13.                 .document.getElementById("StockNo").Value = E
  14.                 .document.getelementsByTagName("INPUT")("sub").Click  '按下查詢
  15.                        '這裡的查詢是<INPUT TYPE="submit" VALUE="查詢" name="sub">
  16.                 Do While .Busy Or .readyState <> 4:    Loop
  17.                 Ep .document.getelementsByTagName("TABLE")(6).outerHTML
  18.             End With
  19.             With IE
  20.                 .document.getelementsByTagName("select")("SCA_DATE")(x).Selected = True
  21.                                             '這裡的資料日期 需用 Select 它是有[年度月份日期]的
  22.                 .document.getElementById("StockNo").Value = E
  23.                 .document.getelementsByTagName("INPUT")("sub").Click  '按下查詢
  24.                        '這裡的查詢是<INPUT TYPE="submit" VALUE="查詢" name="sub">
  25.                 Do While .Busy Or .readyState <> 4:    Loop
  26.                 Ep .document.getelementsByTagName("TABLE")(7).outerHTML
  27.             End With
複製代碼
1.首先第一段是為了要擷取("TABLE")(5)才能匯入個股名稱,所以我加了這些語法,由於個股名稱只需要擷取一次
    所以將這段語法寫在x迴圈之外,但不知道這樣的語法正不正確
2.因為要擷取的日期是在("TABLE")(6),所以將這段也寫入,就只是複製("TABLE")(7)的改成6而已,也不確定這樣寫到底正不正確
3.以上程式碼在2003使用F8逐行執行時是可以正常的,但使用F5連續執行時有時會出錯,不然就是("TABLE")(5)和("TABLE")(6)會有資料重覆或者漏抓
    以("TABLE")(6)抓到的日期來說,會抓到兩個一樣的日期(日期錯誤),但資料內容的("TABLE")(7)卻是不同的(內容正確),也就是日期和資料內容對不上
    不知道是不和我的語法有問題

另外先前向您提過,用2007執行上述程式碼時會出錯,出錯代碼為"424",出錯訊息為"此處需要物件",我有點說明進去看,但真的看不太懂
我將說明內容存成PDF一起放在附件中,可以的話再麻煩您看看是不是可以找出為什麼這個程式碼沒法在2007執行的原因,再次感謝您!
作者: GBKEE    時間: 2014-5-23 15:59

回復 69# smart3135
  1. Sub 集保()
  2.     Dim Rng As Range, E As Range, x As Variant, T As Date, xPath As String, xFile As String
  3.     Dim Ea As Variant, ii As Integer, F As String, H As String, J As Integer, StockNo As Object
  4.     T = Time
  5.     Application.DisplayStatusBar = True
  6.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  7.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  8.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  9.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  10.     xPath = "D:\財報資料"
  11.     IE_Application    '
  12.     Application.StatusBar = " "
  13.     For Each E In Rng
  14.         With Sheets(1)
  15.             .Activate
  16.             .Cells.Clear  '下載資料置於此工作表,變換股票時:清空
  17.         End With
  18.         For x = 0 To A
  19.             With IE
  20.                 .document.getelementsByTagName("select")("SCA_DATE")(x).Selected = True
  21.                                             '這裡的資料日期 需用 Select 它是有[年度月份日期]的
  22.                 Set StockNo = .document.getElementById("StockNo")
  23.                 '出錯代碼為"424",出錯訊息為"此處需要物件",就給它設為物件,2007版試試看是否可行
  24.                 StockNo.Value = E
  25.                 .document.getelementsByTagName("INPUT")("sub").Click  '按下查詢
  26.                 Do While .Busy Or .readyState <> 4:    Loop
  27.                 If x = 0 Then Sheets(1).Cells(1) = .document.getelementsByTagName("TABLE")(5).INNERTEXT
  28.                 Ep .document.getelementsByTagName("TABLE")(6).INNERTEXT
  29.                 Ep .document.getelementsByTagName("TABLE")(7).outerHTML
  30.             End With
  31.         Next x
  32.         xFile = xPath & "\" & E & "\SHD.txt"
  33.         MkDir_Sub xFile
  34.         Maketxt xFile, Sheets(1).UsedRange, E.Value
  35.         ii = ii + 1
  36.         Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔"
  37.     Next E
  38.     IE.Quit
  39.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔,  讀取完畢 !! "
  40.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  41. '    ThisWorkbook.Save
  42. End Sub
  43. Sub Ep(S As String)
  44.     Dim D As New DataObject, E As Shape, FormDLL As String, Rng As Range
  45.     'DataObject 物件 在進行轉換動作時,做為格式化文字資料的暫存區域。其也可以暫存和儲存在 DataObject 的文字片段相關的格式。
  46.     '宣告 Dim D As New DataObject '須在工具-> 設定引用項目加入 新增引用 Microsoft Forms 2.0 Object Library ,專案 加入一表單即可
  47.     On Error GoTo ER
  48.     With D
  49.         .SetText S
  50.         .PutInClipboard
  51.         With Sheets(1)
  52.             .Range("a" & .UsedRange.Rows.Count + 1).Select
  53.             Set Rng = Selection
  54.             .PasteSpecial Format:="Unicode 文字"
  55.         End With
  56.     End With
  57.     Exit Sub
  58. ER:
  59.     FormDLL = "FM20.DLL"
  60.     ThisWorkbook.VBProject.References.AddFromFile "C:\windows\system32\" & FormDLL
  61.     Resume
  62. End Sub
複製代碼

作者: smart3135    時間: 2014-5-23 19:14

回復 70# GBKEE
哈囉!版主您好,再度將您修正過後都程式碼代入之後仍是在相同位置出現"424"的錯誤,由於您的EXCEL版本並非2007,所以也沒辦法一一測試我的錯誤
看來這個問題似乎需要再慢慢研究
我用2003執行是正常的,不過在執行的過程中,我發現抓下來的資料會有一些問題
[attach]18352[/attach]
如圖,有些日期的資料是重覆的,有些日期的資料卻漏抓,103年3月份抓了2次,103年2月卻漏抓,但這個情況只有在按下F5連續執行時才會發生
按F8逐行執行則不會,不知道為什麼會這樣?想請問兩個問題
1.這種狀況有辦法加入其他程式碼來避免嗎?
2.就我的感覺應該是F5連續執行的速度太快,以致於網頁反應不及,還來不及跳到下一筆日期就抓資料了才會出錯,不知道這樣推斷正不正確?

附上完整的文字檔,再麻煩您幫忙看看囉!感謝!
[attach]18351[/attach]
作者: smart3135    時間: 2014-5-24 12:50

回復 70# GBKEE
版主您好,我在無意中發現了可以解決錯誤的方法,也不需要再另外設物件,只要將.document.getElementById("StockNo").Value=E
改成.document.All("StockNo").Value=E就可以了,也就是getElementById改成All就可以正常執行了
只是不清楚為什麼這樣改就可以了
  1.     For Each E In Rng
  2.         With Sheets(1)
  3.             .Activate
  4.             .Cells.Clear  '下載資料置於此工作表,變換股票時:清空
  5.         End With
  6.         For x = 0 To A
  7.             With IE
  8.                 .document.getelementsByTagName("select")("SCA_DATE")(x).Selected = True
  9.                                             '這裡的資料日期 需用 Select 它是有[年度月份日期]的
  10.                 .document.All("StockNo").Value = E
  11.                 .document.getelementsByTagName("INPUT")("sub").Click  '按下查詢
  12.                 Do While .Busy Or .readyState <> 4:    Loop
  13.                 If x = 0 Then Sheets(1).Cells(1) = .document.getelementsByTagName("TABLE")(5).INNERTEXT
  14.                 Ep .document.getelementsByTagName("TABLE")(6).INNERTEXT
  15.                 Ep .document.getelementsByTagName("TABLE")(7).outerHTML
  16.             End With
  17.         Next x
  18.         xFile = xPath & "\" & E & "\SHD.txt"
  19.         MkDir_Sub xFile
  20.         Maketxt xFile, Sheets(1).UsedRange, E.Value
  21.         ii = ii + 1
  22.         Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔"
  23.     Next E
複製代碼
不過又遇到了另一個問題,就是當個股遇到沒當年度月份的資料時,就會出現查無資料的視窗,這是連續執行的結果
[attach]18356[/attach]

而當我用F8逐行執行的結果,當遇到查無年度月份資料時,就會一直在Do While .Busy Or .readyState <> 4:    Loop執行無窮迴圈
請問這部分是否有辦法解決?我個人猜想應該是要修正變數A或x的程式碼,但卻不清楚該怎麼修改,只好再麻煩您幫忙看看了,謝謝!
[attach]18357[/attach]
作者: GBKEE    時間: 2014-5-25 16:16

回復 72# smart3135
  1. Sub 集保()
  2.     Dim Rng As Range, E As Range, x As Variant, T As Date, xPath As String, xFile As String
  3.     Dim Ea As Variant, ii As Integer, F As String, H As String, j As Integer
  4.     T = Time
  5.     Application.DisplayStatusBar = True
  6.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  7.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  8.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  9.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  10.     xPath = "D:\財報資料"
  11.     IE_Application    '
  12.     IE.Visible = True   '必須顯示IE ,查無資料,按下確定鍵
  13.     Application.StatusBar = " "
  14.     For Each E In Rng
  15.         With Sheets(1)
  16.             .Activate
  17.             .Cells.Clear  '下載資料置於此工作表,變換股票時:清空
  18.         End With
  19.         For x = 0 To A
  20.             With IE
  21.                 .document.getelementsbytagname("select")("SCA_DATE")(x).Selected = True
  22.                '.document.getElementById("StockNo").Value = E  'getElementById於 2007有錯誤
  23.                 .document.ALL("StockNo").Value = E             'ALL 於2007可行
  24.                 .document.getelementsbytagname("INPUT")("sub").Click  '按下查詢
  25.                 On Error Resume Next   '程式有錯誤時:繼續執行下去
  26.                 Do While .Busy Or .readyState <> 4
  27.                     Do
  28.                         Err.Clear
  29.                         'IE接收資料尚未完成 .document.getelementsbytagname("TABLE").Length 會有錯誤
  30.                         If .document.getelementsbytagname("TABLE").Length <= 5 Then '查無資料
  31.                             Application.SendKeys "~", True ' 按下確定鍵
  32.                             GoTo Nextx
  33.                         End If
  34.                     Loop Until Err = 0
  35.                  Loop
  36.                  On Error GoTo 0   '程式有錯誤時:不處裡
  37.                 If x = 0 Then Sheets(1).Cells(1) = .document.getelementsbytagname("TABLE")(5).INNERTEXT
  38.                 Ep .document.getelementsbytagname("TABLE")(6).INNERTEXT
  39.                 Ep .document.getelementsbytagname("TABLE")(7).outerHTML
  40.             End With
  41.         Next x
  42. Nextx:
  43.         If Sheets(1).UsedRange.Rows.Count > 1 Then
  44.             xFile = xPath & "\" & E & "\SHD.txt"
  45.             MkDir_Sub xFile
  46.             Maketxt xFile, Sheets(1).UsedRange, E.Value
  47.             ii = ii + 1
  48.             Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔"
  49.         End If
  50.     Next E
  51.     IE.Quit
  52.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔,  讀取完畢 !! "
  53.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  54. '    ThisWorkbook.Save
  55. End Sub
複製代碼

作者: smart3135    時間: 2014-5-25 23:53

回復 73# GBKEE
版主您好,試著將您新增的程式碼代入,的確是可以避免錯誤的發生,但在執行程式後會變成擷取的資料不完整
例如1301的資料是從2014年5月到2013年5月,可是在擷取資料時卻沒辦法抓下完整資料,有時只抓到一個月,有時只抓到三個月
不知您是否能幫忙執行看看是否和我說的結果相同
相較於之前還未加入您在73#的程式碼,雖然當遇到查無日期會出錯,不過當有完整一年份資料日期時
抓到的資料都是完整的
我自己也有適著寫入一些程式碼,或著變換程式碼的一些先後位置,但執行結果都不理想
不知道有沒有更適合的程式碼,能避免出錯,也能讓抓到的資料是完整的,再麻煩您幫忙看看了,謝謝!
附帶一提,不會出錯的那個程式用F8逐行執行似乎可以抓到完整資料,但用F5連續執行,抓到的資料就會不完整
不知道是不是因為用連續執行的速度太快,網頁來不及反應,所以抓到的資料才不完整
[attach]18365[/attach]
作者: smart3135    時間: 2014-5-26 09:50

回復 73# GBKEE
版主,不好意思,上一篇回覆其中一個檔案有錯誤,我再重新附上
另外我花了一些時間做出了另一個版本的程式,是利用儲存格輸入日期當作迴圈,已測試可以抓資料,但有些小問題:
1.有些語法我不太懂怎麼簡化,所以可能寫的比較複雜一點
2.利用儲存格當日期迴圈的缺點,就是每個月都要更新儲存格中的日期
3.我自己寫的程式碼執行到代碼1340時還是會出錯,不過如果把第一個代碼重新設成1340開始抓資料又正常
4.因為表頭的文字會重覆抓取,但我只需要一次,所以用一列一列刪除的笨方法

這個程式寫的比較粗糙,抓資料的速度似乎也比較慢,不過確實可以達到我需要的結果,除了遇到某些代碼會卡住需要重新設定外
其他都還OK,再請您幫忙看一下是否有錯誤的地方需要修正,謝謝!
[attach]18368[/attach]
  1. Option Explicit
  2. Sub 集保完成()
  3.     Dim E As Range, X As Range, URL As String, xPath As String, xFile As String, rng As Range, rng1 As Range
  4.     Dim Msg As Boolean, I As Integer, t As Date, S As String, BB As String, CC As String, rng2 As Range
  5.     t = Time
  6.     URL = "URL;http://www.tdcc.com.tw/smWeb/QryStock.jsp?SCA_DATE="
  7.     BB = "&SqlMethod=StockNo&StockNo="
  8.     CC = "&sub=%ACd%B8%DF"
  9.     xPath = "D:\財報資料"
  10.     With ThisWorkbook
  11.         With .Sheets(3)
  12.             Set rng = .Range("A1", .Range("A1").End(xlDown))
  13.             Set rng1 = .Range("B1", .Range("B1").End(xlDown))
  14.         End With
  15. '        .Sheets(3).Activate    '兩種寫法都可以 不過第一種比較簡化 所以第二種跳過
  16. '        .Sheets(3).Range("a1").Select
  17. '        Range(Selection, Selection.End(xlDown)).Select
  18. '        Set rng = Selection
  19. ''        Set rng = .Sheets(3).Range("A:A")  '這裡這樣設定會變成無窮迴圈
  20. '        .Sheets(1).Activate
  21.         With .Sheets(1)      '活頁簿的第 1 張工作表
  22.             If .QueryTables.Count = 0 Then
  23.                 With .QueryTables.Add(Connection:=URL, Destination:=.Range("$A$1"))
  24.                     .Refresh BackgroundQuery:=False
  25.                 End With
  26.             End If
  27.             
  28.             For Each E In rng
  29.                 With ThisWorkbook
  30.                 .Sheets(2).Cells.Clear
  31. '                .Activate
  32.                 .Sheets(1).Cells.Clear  '下載資料置於此工作表,變換股票時:清空
  33.             End With

  34.                 For Each X In rng1
  35.                     With .QueryTables(1)
  36.                         .Connection = URL & X & BB & E & CC
  37.                         .PreserveFormatting = True
  38.                         .BackgroundQuery = True
  39.                         .RefreshStyle = xlInsertDeleteCells
  40.                         .SaveData = True
  41.                         .AdjustColumnWidth = True
  42.                         .RefreshPeriod = 0
  43.                         .WebSelectionType = xlSpecifiedTables
  44.                         .WebFormatting = xlWebFormattingNone
  45.                         .WebTables = "6,7,8"
  46.                         On Error GoTo xlnext
  47.                         .WebPreFormattedTextToColumns = True
  48.                         .WebConsecutiveDelimitersAsOne = True
  49.                         .Refresh BackgroundQuery:=False
  50.                     End With
  51.                     Set rng2 = Sheets(1).UsedRange
  52.                     If Sheets(2).Range("a1") = "" Then
  53.                         rng2.Copy Sheets(2).Range("a" & .Rows.Count).End(xlUp)
  54.                     Else
  55.                         rng2.Copy Sheets(2).Range("a" & .Rows.Count).End(xlUp).Offset(2, 0)
  56.                     End If
  57.                 Next X
  58. xlnext:
  59.                     Sheets(2).Range("2:2,22:22,43:43,64:64,85:85,106:106,127:127,148:148,169:169,190:190,211:211,232:232,253:253").Delete
  60.                     xFile = xPath & "\" & E & "\SHD.txt"
  61.                     MkDir_Sub xFile       '10#的程式 'C槽下的季損益表資料夾不需先建立
  62.                     Maketxt xFile, Sheets(2).UsedRange

  63. '                S = " " & Sheets(1).QueryTables(1).ResultRange(1)
  64. '                If Val(S) < 0 Then S = " 查無"
  65.                 I = I + 1
  66.                 Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & "  " & E & "匯入" & I & "個文字檔"
  67.                 Msg = False
  68.             Next E
  69.         End With
  70.     End With
  71.     MsgBox "共匯入 文字檔" & I & " 費時 " & Application.Text(Time - t, ["MM分SS秒"])
  72. End Sub
  73. Sub MkDir_Sub(S As String)
  74.     Dim AR, I As Integer, xPath As String
  75.     If Dir(S) = "" Then
  76.         AR = Split(S, "\")
  77.         xPath = AR(0)
  78.         For I = 1 To UBound(AR) - 1
  79.             xPath = xPath & "\" & AR(I)
  80.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  81.         Next
  82.     End If
  83. End Sub
  84. Sub Maketxt(xF As String, Q As Range)   '將匯入資料存入指定的txt
  85.     Dim fs As Object, E As Range, C As Variant
  86.     Set fs = CreateObject("Scripting.FileSystemObject")
  87.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  88.     For Each E In Q.Rows
  89.         C = Application.Transpose(Application.Transpose(E.Value))
  90.         C = Join(C, vbTab)
  91.         fs.WriteLine C
  92.     Next
  93.     fs.Close
  94. End Sub
複製代碼

作者: smart3135    時間: 2014-5-26 11:45

回復 73# GBKEE
Sorry,儲存格又忘了填上資料,再附上正確檔案
[attach]18370[/attach]
作者: GBKEE    時間: 2014-5-26 17:12

本帖最後由 GBKEE 於 2014-5-26 17:15 編輯

回復 75# smart3135
  1. Option Explicit
  2. Sub 集保完成()
  3.     Dim E As Range, X As Range, URL As String, xPath As String, xFile As String, rng As Range, rng1 As Range
  4.     Dim Msg As Boolean, I As Integer, t As Date, S As String, BB As String, CC As String, rng2 As Range
  5.     IE_Application  '更新集保戶股權分散表查詢的資料日期
  6.     t = Time
  7.     URL = "URL;http://www.tdcc.com.tw/smWeb/QryStock.jsp?SCA_DATE="
  8.     BB = "&SqlMethod=StockNo&StockNo="
  9.     CC = "&sub=%ACd%B8%DF"
  10.     xPath = "D:\財報資料"
  11.     With ThisWorkbook
  12.         With .Sheets(3)
  13.             Set rng = .Range("A1", .Range("A1").End(xlDown))
  14.             Set rng1 = .Range("B1", .Range("B1").End(xlDown))
  15.         End With
  16.         With .Sheets(1)      '活頁簿的第 1 張工作表
  17.             If .QueryTables.Count = 0 Then
  18.                 With .QueryTables.Add(Connection:=URL, Destination:=.Range("$A$1"))
  19.                     .Refresh BackgroundQuery:=False
  20.                 End With
  21.             End If
  22.             
  23.             For Each E In rng
  24.                 With ThisWorkbook
  25.                 .Sheets(2).Cells.Clear
  26.                 .Sheets(1).Cells.Clear  '下載資料置於此工作表,變換股票時:清空
  27.             End With
  28.                 For Each X In rng1
  29.                     With .QueryTables(1)
  30.                         .Connection = URL & X & BB & E & CC
  31.                         .PreserveFormatting = True
  32.                         .BackgroundQuery = True
  33.                         .RefreshStyle = xlInsertDeleteCells
  34.                         .SaveData = True
  35.                         .AdjustColumnWidth = True
  36.                         .RefreshPeriod = 0
  37.                         .WebSelectionType = xlSpecifiedTables
  38.                         .WebFormatting = xlWebFormattingNone
  39.                         If X.Row = 1 Then
  40.                         .WebTables = "6,7,8"
  41.                         Else
  42.                             .WebTables = "7,8"
  43.                         End If
  44.                         On Error GoTo xlnext
  45.                         .WebPreFormattedTextToColumns = True
  46.                         .WebConsecutiveDelimitersAsOne = True
  47.                         .Refresh BackgroundQuery:=False
  48.                         If Sheets(2).Range("a1") = "" Then
  49.                             .ResultRange.Copy Sheets(2).Range("a" & Sheets(2).Rows.Count).End(xlUp)
  50.                         Else
  51.                             .ResultRange.Copy Sheets(2).Range("a" & Sheets(2).Rows.Count).End(xlUp).Offset(2, 0)
  52.                         End If
  53.                     End With
  54.                 Next
  55. xlnext:
  56.       
  57.                     xFile = xPath & "\" & E & "\SHD.txt"
  58.                     MkDir_Sub xFile       '10#的程式 'C槽下的季損益表資料夾不需先建立
  59.                     Maketxt xFile, Sheets(2).UsedRange
  60.                 I = I + 1
  61.                 Application.StatusBar = Application.Text(Time - t, ["MM分SS秒"]) & "  " & E & "匯入" & I & "個文字檔"
  62.                 Msg = False
  63.             Next E
  64.         End With
  65.     End With
  66.     MsgBox "共匯入 文字檔" & I & " 費時 " & Application.Text(Time - t, ["MM分SS秒"])
  67. End Sub
  68. Sub Maketxt(xF As String, Q As Range)   '將匯入資料存入指定的txt
  69.     Dim fs As Object, E As Range, C As Variant
  70.     '*************************
  71.     Q.Columns(1).SpecialCells(xlCellTypeBlanks).EntireRow.Delete  '刪除空白列
  72.     '*************************
  73.     Set fs = CreateObject("Scripting.FileSystemObject")
  74.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  75.     For Each E In Q.Rows
  76.         C = Application.Transpose(Application.Transpose(E.Value))
  77.         C = Join(C, vbTab)
  78.         fs.WriteLine C
  79.     Next
  80.     fs.Close
  81. End Sub
  82. Private Sub IE_Application() '更新集保戶股權分散表查詢的資料日期
  83.     Dim IE As Object, A As Object, I As Integer
  84.     Set IE = CreateObject("InternetExplorer.Application")
  85.     With IE
  86.         .Navigate "http://www.tdcc.com.tw/smWeb/QryStock.jsp"
  87.         .Visible = True
  88.         Do While .Busy Or .readyState <> 4: DoEvents: Loop
  89.         '讀取集保戶股權分散表查詢的資料日期
  90.         Set A = .document.getelementsbytagname("option")
  91.        For I = 0 To A.Length - 1
  92.         ThisWorkbook.Sheets(3).Cells(I + 1, "B") = A(I).INNERTEXT
  93.        Next
  94.        .Quit
  95.   End With
  96. End Sub
複製代碼

作者: GBKEE    時間: 2014-5-26 17:13

回復 74# smart3135
  1. Option Explicit
  2. Dim IE As Object, A As Integer
  3. Sub IE_Application()
  4.     Dim I As Integer
  5.     Set IE = CreateObject("InternetExplorer.Application")
  6.     With IE
  7.         .Navigate "http://www.tdcc.com.tw/smWeb/QryStock.jsp"
  8.         .Visible = True   '不顯示ie
  9.         Do While .Busy Or .readyState <> 4: DoEvents: Loop
  10.         '讀取集保戶股權分散表查詢的資料日期總個數
  11.         A = .document.getelementsbytagname("select")("SCA_DATE").Length - 1
  12.   End With
  13. End Sub
  14. Sub 集保()
  15.     Dim Rng As Range, E As Range, x As Variant, T As Date, xPath As String, xFile As String
  16.     Dim Ea As Variant, ii As Integer, F As String, H As String, J As Integer
  17.     Dim StockNo  As Object
  18.     T = Time
  19.     Application.DisplayStatusBar = True
  20.     '請將上櫃的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  21.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  22.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  23.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  24.     xPath = "D:\財報資料"
  25.     IE_Application    '
  26.     Application.StatusBar = " "
  27.     For Each E In Rng
  28.             With Sheets(1)
  29.                 .Activate
  30.                 .Cells.Clear  '下載資料置於此工作表,變換股票時:清空
  31.             End With
  32.             For x = 0 To A
  33.                 With IE
  34.                     .document.getelementsbytagname("select")("SCA_DATE")(x).Selected = True
  35.                    '.document.getElementById("StockNo").Value = E  'getElementById於 2007有錯誤
  36.                     .document.ALL("StockNo").Value = E             'ALL 於2007可行
  37.                     .document.getelementsbytagname("INPUT")("sub").Click  '按下查詢
  38.                     Do While .Busy Or .readyState <> 4
  39.                         .document.Focus
  40.                         Application.SendKeys "~", True ' 按下確定鍵
  41.                     Loop
  42.                     Set StockNo = Nothing
  43.                     Do While StockNo Is Nothing
  44.                         Set StockNo = .document.getelementsbytagname("TABLE")
  45.                     Loop
  46.                     With StockNo
  47.                        If .Length <= 5 Then GoTo Nextx  '查無資料
  48.                         If x = 0 Then Sheets(1).Cells(1) = .Item(5).INNERTEXT
  49.                         Ep .Item(6).INNERTEXT
  50.                         Ep .Item(7).outerHTML
  51.                     End With
  52.                 End With
  53.             Next x
  54. Nextx:
  55.             If Sheets(1).UsedRange.Rows.Count > 1 Then
  56.                 xFile = xPath & "\" & E & "\SHD.txt"
  57.                 MkDir_Sub xFile
  58.                 Maketxt xFile, Sheets(1).UsedRange, E.Value
  59.                 ii = ii + 1
  60.                 Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔"
  61.             End If
  62.             Debug.Print IE.document.getelementsbytagname("TABLE").Length
  63.         Next E
  64.     IE.Quit
  65.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔,  讀取完畢 !! "
  66.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  67. '    ThisWorkbook.Save
  68. End Sub
複製代碼

作者: smart3135    時間: 2015-2-10 11:34

回復  smart3135
GBKEE 發表於 2014-5-26 17:13

GBKEE版主您好,去年有向您請教如何用迴圈抓取股市大量資料,幫助非常大,今年已經有新的年度資料,我想要抓取新的年度資料
但不知道為什麼去年度可以正常執行的VBA程式碼,到了今年卻會一直出錯,我嘗試新增、刪除、變更一些程式碼,但都無效
能不能請您再次幫忙看看程式碼有什麼問題嗎?感謝您!
[attach]20242[/attach]
出錯圖
[attach]20243[/attach]
[attach]20244[/attach]
作者: GBKEE    時間: 2015-2-10 17:29

回復 79# smart3135
  1. For Each E In Rng
  2.         With IE
  3.             Do While .Busy Or .ReadyState <> 4:    Loop
  4.             .Document.getelementbyid("STK_NO").Value = E
  5.             .Document.getelementSbyNAME("login_btn")(0).Click '按下查詢
  6.             Do While .Busy Or .ReadyState <> 4:    Loop
  7.             .Refresh  '網頁 需重新整理 ,才有資料下載
  8.             Do While .Busy Or .ReadyState <> 4:    Loop
  9.             Set a = .Document.getelementsbytagname("TABLE")
  10.             Do While a.Length <> 14:   Loop    '直到 a元素的子項目有14個
  11.             xFile = xPath & "\" & E & "\HPY.txt"
複製代碼

作者: smart3135    時間: 2015-2-11 08:32

本帖最後由 smart3135 於 2015-2-11 08:33 編輯
回復  smart3135
GBKEE 發表於 2015-2-10 17:29

版主您好,有試著套用您的程式碼,但在加入Refresh後會出現下圖錯誤
[attach]20248[/attach]

若是將Refresh註解跳過,是可以順利執行,不過有時候跑到一半的時候就不動了,似乎是在執行無限迴圈
必須要按ESC強制停止,再按偵錯就會跳到Do While .Busy Or .ReadyState <> 4:    Loop這段程式碼
應該就是這段程式碼在執行無限迴圈
[attach]20249[/attach]
[attach]20250[/attach]

[attach]20251[/attach]
作者: GBKEE    時間: 2015-2-11 16:10

回復 81# smart3135

在IE8下可執行,請看看你的IE [網際網路選項]需修改什麼!!
作者: smart3135    時間: 2015-2-12 12:49

回復  smart3135

在IE8下可執行,請看看你的IE [網際網路選項]需修改什麼!!
GBKEE 發表於 2015-2-11 16:10

Hello版主,經確認之後應該是和我的系統問題有關係,因為今天重灌電腦後,再用原來的程式碼跑一次
就是最原始的那個VBA,還未加入您修改的程式碼就可以順利執行了,不過還是又跟您多學到一些了,感謝!
作者: smart3135    時間: 2017-6-14 16:07

回復 56# GBKEE
不好意思,由於今年證交所網址大改版,原本的抓資料程式碼都會出錯,有試著看網頁原始碼修改程式碼
無奈功力太淺還是沒辦法,不知道是否還有機會請版主指點一下究竟該如何修改呢?
[attach]27331[/attach]
  1. Option Explicit
  2. Dim IE As Object
  3. Sub IE_Application()
  4.     Set IE = CreateObject("InternetExplorer.Application")
  5.     With IE
  6.         .Navigate "http://www.twse.com.tw/ch/trading/exchange/FMSRFK/FMSRFKMAIN.php"
  7. '        .Visible = True   '不顯示ie
  8.         Do While .Busy Or .readyState <> 4: DoEvents: Loop
  9.   End With
  10. End Sub
  11. Sub 上市月成交資訊()
  12.     Dim Rng As Range, Rng1 As Range, E As Range, X As Range, T As Date, xPath As String, xFile As String
  13.     Dim Ea As Variant, ar(), ii, aa As Integer
  14.     T = Time
  15.     Application.DisplayStatusBar = True
  16.     '請將上市的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  17.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  18.     Set Rng1 = ThisWorkbook.Sheets(3).Range("b:b")
  19.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  20.     If Application.Count(Rng1) = 0 Then MsgBox "沒有股票代號": Exit Sub
  21.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  22.     Set Rng1 = Rng1.SpecialCells(xlCellTypeConstants)
  23.     xPath = "F:\財報資料"
  24.     IE_Application    '
  25.     Application.StatusBar = " "
  26.     For Each E In Rng
  27. MR:
  28.         With Sheets(1)
  29.             .Activate
  30.             .Cells.Clear  '下載資料置於此工作表,變換股票時:清空
  31.         End With
  32.         For Each X In Rng1
  33.             With IE
  34.                 .Document.getElementsByTagName("select")("query_year").Value = X
  35.                 .Document.getelementsbyname("CO_ID")(0).Value = E
  36.                 .Document.getelementsbyname("query-button")(0).Click  '按下查詢
  37.                 Do While .Busy Or .readyState <> 4:    Loop
  38.                 On Error Resume Next
  39.                 If InStr(.Document.getElementsByTagName("TABLE")(3).outerHTML, "查無") Then GoTo Nn
  40.                 If .Document.getElementsByTagName("TABLE")(3).Rows.Length > 1 Then
  41.                     Ep .Document.getElementsByTagName("TABLE")(3).outerHTML
  42.                 Else
  43.                     GoTo Nn
  44.                 End If
  45. '                If InStr(Selection.Cells(3, 1), "查無") Then Selection.Delete Shift:=xlUp: GoTo Nn
  46.             End With
  47.         With Sheets(1)
  48.             aa = Selection.Range("a3")
  49.             If aa = "" Then aa = Selection.Range("a1")    '會出錯才加入這段
  50.             If aa + 1911 <> X Then GoTo MR
  51.         End With
  52.         Next X
  53. Nn:
  54.         If Sheets(1).Range("a1") = "" Then GoTo KK
  55.         xFile = xPath & "\" & E & "\HPM.txt"
  56.         MkDir_Sub xFile
  57.         Maketxt xFile, Sheets(1).Range("A1").CurrentRegion, E.Value
  58.         ii = ii + 1
  59.         Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 匯入上市月成交 " & E & "共" & ii & " 文字檔"
  60. KK:
  61.     Next E
  62.     IE.Quit
  63.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔,  讀取完畢 !! "
  64.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  65. '    ThisWorkbook.Save
  66. End Sub
  67. Sub Ep(S As String)
  68.     Dim D As New DataObject, i As Integer, FormDLL As String, Rng As Range
  69.     'DataObject 物件 在進行轉換動作時,做為格式化文字資料的暫存區域。其也可以暫存和儲存在 DataObject 的文字片段相關的格式。
  70.     '宣告 Dim D As New DataObject '須在工具-> 設定引用項目加入 新增引用 Microsoft Forms 2.0 Object Library ,專案 加入一表單即可
  71.     On Error GoTo ER
  72.     With D
  73.         .SetText S
  74.         .PutInClipboard
  75.         With Sheets(1)
  76.             With .Range("a" & .Rows.Count).End(xlUp)
  77.                 If .Row = 1 Then
  78.                     Set Rng = .Cells
  79.                 Else
  80.                     Set Rng = .Offset(1)
  81.                 End If
  82.                 Rng.Select
  83.                 .Parent.PasteSpecial Format:="Unicode 文字"
  84.                 Set Rng = Rng.Range("A3", Rng.Range("A3").End(xlDown)).Resize(, 9)
  85.                 With Sheets(1).Sort
  86.                     .SetRange Rng
  87.                     .Header = xlGuess
  88.                     .MatchCase = False
  89.                     .Orientation = xlTopToBottom
  90.                     .SortMethod = xlPinYin
  91.                     .Apply
  92.                 End With
  93.                 'Sort :資料排序
  94. '                Rng.Sort Key1:=Rng.Range("B2"), Order1:=xlDescending, Header:=xlYes ', _
  95.                 OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod _
  96.                 :=xlStroke, DataOption1:=xlSortNorma
  97. '                If .Row = 1 Then
  98. '                    .Range("A2").EntireRow.Delete
  99. '                Else
  100. '                    .Range("A2:A4").EntireRow.Delete
  101. '                End If
  102.             End With
  103.         End With
  104.     End With
  105.     Exit Sub
  106. ER:
  107.     ThisWorkbook.VBProject.References.AddFromFile "C:\windows\system32\FM20.DLL"
  108.     Resume
  109. End Sub
  110. Sub Maketxt(xF As String, Q As Range, Code As String)     '將匯入資料存入指定的txt
  111.     Dim fs As Object, E As Range, C As Variant, A As String, B As Integer, D As String
  112.     Set fs = CreateObject("Scripting.FileSystemObject")
  113.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  114.     A = Q.Cells(1)
  115.     B = Len(A)
  116.         If B >= 25 Then
  117.             D = Mid(A, 11, 4)
  118.         Else
  119.             D = Mid(A, 11, 2)
  120.         End If
  121.     Q.Cells(1) = Code & "-" & D & "" & " 月成交資料"   '加入股票代號
  122.     If Q.Cells(3, 1).Offset(1) = "" Then GoTo EE
  123.     Q.Range("a3", Q.Range("a3").End(xlDown)).Replace "年度", ""
  124.     Q.Columns(1).SpecialCells(xlCellTypeBlanks).Offset(-1).EntireRow.Delete
  125.     Q.Columns(1).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
  126. EE:
  127.     For Each E In Q.Rows
  128.         C = Application.Transpose(Application.Transpose(E.Value))
  129.         C = Join(C, vbTab)
  130.         fs.Write C
  131.     Next
  132.     fs.Close
  133. End Sub
  134. Sub MkDir_Sub(S As String)
  135.     Dim ar, i As Integer, xPath As String
  136.     If Dir(S) = "" Then
  137.         ar = Split(S, "\")
  138.         xPath = ar(0)
  139.         For i = 1 To UBound(ar) - 1
  140.             xPath = xPath & "\" & ar(i)
  141.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  142.         Next
  143.     End If
  144. End Sub
複製代碼

作者: GBKEE    時間: 2017-6-15 15:10

本帖最後由 GBKEE 於 2017-6-15 15:14 編輯

[attach]27341[/attach]
  1. For Each X In Rng1
  2.             With IE
  3.                 .Document.getElementsByTagName("select")("Yy").Value = X
  4.                 'yy -> 年度,mm -> 月份, dd -> 日期
  5.                 .Document.getelementsbyname("stockNo")(0).Value = E
  6.                 '股票代碼  stockNo  '**大小寫要一致**
  7.               '  .Document.getelementsbyname("query-button")(0).Click  '按下查詢
  8.                 For Each Ea In .Document.body.all.tags("a")
  9.                     If Ea.classname = "button search" Then
  10.                         Ea.Click: Exit For  '按下查詢
  11.                     End If
  12.                 Next
  13.                 Do While .Busy Or .readyState <> 4:    Loop
  14.                 On Error Resume Next
複製代碼
回復 84# smart3135
作者: smart3135    時間: 2017-6-15 22:01

回復 85# GBKEE
不好意思,我執行後似乎會卡在圖中的迴圈,不知能否請您執行看看是否有一樣情形呢?

[attach]27344[/attach]
  1. Option Explicit
  2. Dim IE As Object
  3. Sub IE_Application()
  4.     Set IE = CreateObject("InternetExplorer.Application")
  5.     With IE
  6.         .Navigate "http://www.twse.com.tw/ch/trading/exchange/FMSRFK/FMSRFKMAIN.php"
  7. '        .Visible = True   '不顯示ie
  8.         Do While .Busy Or .readyState <> 4: DoEvents: Loop
  9.   End With
  10. End Sub
  11. Sub 上市月成交資訊()
  12.     Dim Rng As Range, Rng1 As Range, E As Range, X As Range, T As Date, xPath As String, xFile As String
  13.     Dim Ea As Variant, ar(), ii, aa As Integer
  14.     T = Time
  15.     Application.DisplayStatusBar = True
  16.     '請將上市的股票代號,在 Sheets(3).Range("A1")往下Key上,迴圈依這裡的股票代號匯入
  17.     Set Rng = ThisWorkbook.Sheets(3).Range("A:A")
  18.     Set Rng1 = ThisWorkbook.Sheets(3).Range("b:b")
  19.     If Application.Count(Rng) = 0 Then MsgBox "沒有股票代號": Exit Sub
  20.     If Application.Count(Rng1) = 0 Then MsgBox "沒有股票代號": Exit Sub
  21.     Set Rng = Rng.SpecialCells(xlCellTypeConstants)
  22.     Set Rng1 = Rng1.SpecialCells(xlCellTypeConstants)
  23.     xPath = "F:\財報資料"
  24.     IE_Application    '
  25.     Application.StatusBar = " "
  26.     For Each E In Rng
  27. MR:
  28.         With Sheets(1)
  29.             .Activate
  30.             .Cells.Clear  '下載資料置於此工作表,變換股票時:清空
  31.         End With
  32.         For Each X In Rng1
  33.             With IE
  34.                 .Document.getElementsByTagName("select")("Yy").Value = X
  35.                 'yy -> 年度,mm -> 月份, dd -> 日期
  36.                 .Document.getelementsbyname("stockNo")(0).Value = E
  37.                 '股票代碼  stockNo  '**大小寫要一致**
  38. '                .Document.getelementsbyname("query-button")(0).Click  '按下查詢
  39.                 For Each Ea In .Document.body.all.tags("a")
  40.                     If Ea.classname = "button search" Then
  41.                         Ea.Click: Exit For  '按下查詢
  42.                     End If
  43.                 Next
  44.                 Do While .Busy Or .readyState <> 4:    Loop
  45.                 On Error Resume Next
  46.                 If InStr(.Document.getElementsByTagName("TABLE")(3).outerHTML, "查無") Then GoTo Nn
  47.                 If .Document.getElementsByTagName("TABLE")(3).Rows.Length > 1 Then
  48.                     Ep .Document.getElementsByTagName("TABLE")(3).outerHTML
  49.                 Else
  50.                     GoTo Nn
  51.                 End If
  52. '                If InStr(Selection.Cells(3, 1), "查無") Then Selection.Delete Shift:=xlUp: GoTo Nn
  53.             End With
  54.         With Sheets(1)
  55.             aa = Selection.Range("a3")
  56. '            If aa = "" Then aa = Selection.Range("a1")    '會出錯才加入這段
  57.             If aa + 1911 <> X Then GoTo MR
  58.         End With
  59.         Next X
  60. Nn:
  61.         If Sheets(1).Range("a1") = "" Then GoTo KK
  62.         xFile = xPath & "\" & E & "\HPM.txt"
  63.         MkDir_Sub xFile
  64.         Maketxt xFile, Sheets(1).Range("A1").CurrentRegion, E.Value
  65.         ii = ii + 1
  66.         Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 匯入上市月成交 " & E & "共" & ii & " 文字檔"
  67. KK:
  68.     Next E
  69.     IE.Quit
  70.     Application.StatusBar = Application.Text(Time - T, ["MM分SS秒"]) & " 共匯入上市月成交 " & ii & " 文字檔,  讀取完畢 !! "
  71.     MsgBox "匯入 文字檔" & ii & " 費時 " & Application.Text(Time - T, ["MM分SS秒"])
  72. '    ThisWorkbook.Save
  73. End Sub
  74. Sub Ep(S As String)
  75.     Dim D As New DataObject, i As Integer, FormDLL As String, Rng As Range
  76.     'DataObject 物件 在進行轉換動作時,做為格式化文字資料的暫存區域。其也可以暫存和儲存在 DataObject 的文字片段相關的格式。
  77.     '宣告 Dim D As New DataObject '須在工具-> 設定引用項目加入 新增引用 Microsoft Forms 2.0 Object Library ,專案 加入一表單即可
  78.     On Error GoTo ER
  79.     With D
  80.         .SetText S
  81.         .PutInClipboard
  82.         With Sheets(1)
  83.             With .Range("a" & .Rows.Count).End(xlUp)
  84.                 If .Row = 1 Then
  85.                     Set Rng = .Cells
  86.                 Else
  87.                     Set Rng = .Offset(1)
  88.                 End If
  89.                 Rng.Select
  90.                 .Parent.PasteSpecial Format:="Unicode 文字"
  91.                 Set Rng = Rng.Range("A3", Rng.Range("A3").End(xlDown)).Resize(, 9)
  92.                 With Sheets(1).Sort
  93.                     .SetRange Rng
  94.                     .Header = xlGuess
  95.                     .MatchCase = False
  96.                     .Orientation = xlTopToBottom
  97.                     .SortMethod = xlPinYin
  98.                     .Apply
  99.                 End With
  100.                 'Sort :資料排序
  101. '                Rng.Sort Key1:=Rng.Range("B2"), Order1:=xlDescending, Header:=xlYes ', _
  102.                 OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod _
  103.                 :=xlStroke, DataOption1:=xlSortNorma
  104. '                If .Row = 1 Then
  105. '                    .Range("A2").EntireRow.Delete
  106. '                Else
  107. '                    .Range("A2:A4").EntireRow.Delete
  108. '                End If
  109.             End With
  110.         End With
  111.     End With
  112.     Exit Sub
  113. ER:
  114.     ThisWorkbook.VBProject.References.AddFromFile "C:\windows\system32\FM20.DLL"
  115.     Resume
  116. End Sub
  117. Sub Maketxt(xF As String, Q As Range, Code As String)     '將匯入資料存入指定的txt
  118.     Dim fs As Object, E As Range, C As Variant, A As String, B As Integer, D As String
  119.     Set fs = CreateObject("Scripting.FileSystemObject")
  120.     Set fs = fs.CreateTextFile(xF, True)  '創見一個檔案,如檔案存在可覆蓋掉
  121.     A = Q.Cells(1)
  122.     B = Len(A)
  123.         If B >= 25 Then
  124.             D = Mid(A, 11, 4)
  125.         Else
  126.             D = Mid(A, 11, 2)
  127.         End If
  128.     Q.Cells(1) = Code & "-" & D & "" & " 月成交資料"   '加入股票代號
  129.     If Q.Cells(3, 1).Offset(1) = "" Then GoTo EE
  130.     Q.Range("a3", Q.Range("a3").End(xlDown)).Replace "年度", ""
  131.     Q.Columns(1).SpecialCells(xlCellTypeBlanks).Offset(-1).EntireRow.Delete
  132.     Q.Columns(1).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
  133. EE:
  134.     For Each E In Q.Rows
  135.         C = Application.Transpose(Application.Transpose(E.Value))
  136.         C = Join(C, vbTab)
  137.         fs.Write C
  138.     Next
  139.     fs.Close
  140. End Sub
  141. Sub MkDir_Sub(S As String)
  142.     Dim ar, i As Integer, xPath As String
  143.     If Dir(S) = "" Then
  144.         ar = Split(S, "\")
  145.         xPath = ar(0)
  146.         For i = 1 To UBound(ar) - 1
  147.             xPath = xPath & "\" & ar(i)
  148.             If Dir(xPath, vbDirectory) = "" Then MkDir xPath
  149.         Next
  150.     End If
  151. End Sub
複製代碼
[attach]27345[/attach]
作者: GBKEE    時間: 2017-6-19 16:47

回復 86# smart3135

證交所網頁有流量管制.附檔有重新修改一些地方.

[attach]27356[/attach]
作者: smart3135    時間: 2017-6-20 18:41

回復 87# GBKEE
感謝版主阿,真的太實用了,我還有自己修改一些內容符合我想要的格式
另外上市年成交資訊是依您前一篇回覆的內容我也稍作修改,一樣可以正常抓資料了
真是受教了:handshake
作者: smart3135    時間: 2018-2-12 12:55

回復 87# GBKEE
版主您好,又來請教您了,半年前證交所改版後有請您幫忙,後來確實可以抓資料了
但今年測試,下載沒幾個就會卡住,我再去開證交所網頁就會開不起來
有請朋友幫忙測試,他們的電腦是可以開的,這是不是表示因為我在抓大量資料
所以會有流量或頻寬的限制?連結中的文章似乎也是說明如此
不知道程式碼還有沒有能修正的地方讓它可以正常抓資料,謝謝
https://www.wearn.com/bbs/t911387.html
[attach]28361[/attach]
[attach]28362[/attach]
作者: smart3135    時間: 2018-2-12 19:37

回復 89# smart3135
感謝版主回覆,找了一下,找不到相關的網頁,目前可以使用的方式就是用一樣的程式每次資料只能抓25筆左右
當無法抓的時候就將數據機關掉重開,等網路連線就可以再抓25筆,900多筆資料要慢慢抓,哈
作者: joey0415    時間: 2018-2-12 22:14

回復 90# smart3135

速度只能每三秒抓一次就不會鎖ip

慢一點當然更好

目前我也是這樣試出來的
作者: smart3135    時間: 2018-2-12 22:42

本帖最後由 smart3135 於 2018-2-12 22:57 編輯

回復 91# joey0415
不好意思 請問要怎麼設定三秒抓一次 不是很懂這個語法
我目前是暫時把IE.Applictation放在迴圈中,等抓完一檔後再跳下一檔前再將IE.Quit
鎖IP的情形有大幅改善,偶有發生,但仍比原來最多只抓25檔好很多了
[attach]28369[/attach]
作者: smart3135    時間: 2018-2-12 22:53

回復 87# GBKEE
版主,再請教一下,我有重新寫了一個VBA,和原來抓的方式不一樣,是用HTML網址下去抓
可以直接帶入變數股票號碼直接抓,問題是抓下來的日期格式在寫入文字檔時,就會自己轉換成2018/X/X
有我試著在寫進文字檔前將儲存格格式變更成文字,但卻會顯示成另一個數字(圖片綠框處)
不知道該怎麼寫才能讓日期顯示在excel的結果和網頁一樣,並且設定成文字格式,寫進文字檔時才不會又轉換成日期格式
再請您指導一下,謝謝。
[attach]28368[/attach]
[attach]28367[/attach]
作者: smart3135    時間: 2018-2-13 06:47

回復 93# smart3135
測試了一下,用新網頁去抓資料還是有流量限制,一樣到約25檔就抓不了了
語法中也未加入IE.Application,沒辦法做 IE.Quit,所以看來這個VBA還是沒辦法破解流量限制
作者: joey0415    時間: 2018-2-13 13:53

回復 94# smart3135

不是不行而是你沒有認真想

這是只其中一種等待的方法

for i=XXX to XXX
Application.Wait Now + TimeValue("00:00:03")

next





歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)