Board logo

標題: [發問] 股票歷史價格表 [打印本頁]

作者: Scott090    時間: 2017-10-13 15:46     標題: 股票歷史價格表

進入這個網站取得個股歷史價:
http://www.cnyes.com/twstock/ps_historyprice/2330.htm

[attach]27803[/attach]
它只有固定的日期區間資料

請教導 :
              VBA 如何用 選用其中的"開始日期"及"結束日期"及 "查詢" 而取得更長區間的資料表

謝謝
作者: Scott090    時間: 2017-10-20 15:12

回復 1# Scott090

參考以下程式碼可以設定日期區間
繼續尋求更佳的方法
  1. '從鉅亨網取得歷史股價
  2. '使用 IE 物件
  3. 'option explicit
  4. 'option base 1

  5. Sub TestCNYES()

  6.     Dim Price(0 To 20, 0 To 9)
  7.     Dim Code
  8.     Code = "2330"
  9.    
  10.     Dim IE As Object, URL$
  11.     Dim date0 As Date, StartDate$, EndDate$, timer, time0 As Date
  12.     Dim Table As Object, oDoc As Object, E
  13.     Dim Re%, Ce%, i%, k%, ColName$
  14.    
  15.     ActiveSheet.Cells.Clear
  16.    
  17.     '設定資料開始及結束日期
  18.     StartDate = Format(DateAdd("m", -2, Date), "yyyy/mm/dd")   '取2個月的資料,約40筆
  19.     EndDate = Format(Date, "yyyy/mm/dd")
  20.    
  21.     k = 0
  22. Again:
  23.     Set IE = CreateObject("InternetExplorer.Application")
  24.     With IE
  25.             URL = "http://www.cnyes.com/twstock/ps_historyprice/" & Code & ".htm"
  26.             .Visible = False                '不顯示 IE
  27.             .navigate URL
  28.             
  29.             time0 = Now() + #12:00:05 AM#   '設定時間控制計時5秒鐘
  30.             Do
  31.                 DoEvents
  32.             Loop While (.Busy Or .readystate <> 4) And Time < time0
  33.            
  34.            '網頁未準備好,關閉重啟
  35.             If .readystate <> 4 Then
  36.                 .Quit
  37.                 k = k + 1
  38.                 If k <= 2 Then GoTo Again
  39.                 GoTo GiveUp                   '開啟3次都失敗就放棄
  40.             End If
  41.             
  42.             Set oDoc = .Document.getElementsByTagName("input")
  43.             With oDoc
  44.                  .Item("ctl00$ContentPlaceHolder1$startText").Value = StartDate ' 開始日期 input name
  45.                  .Item("ctl00$ContentPlaceHolder1$endText").Value = EndDate     ' 結束日期 input name
  46.             
  47.                  Set E = .Item("ctl00$ContentPlaceHolder1$submitBut")           '查詢鍵名稱
  48.                     E.Click                                                     '按查詢鍵
  49.             End With
  50.             
  51.             k = 0
  52.             time0 = Now() + #12:00:05 AM#   '設定時間控制計時5秒鐘
  53.             Do
  54.                 DoEvents
  55.             Loop While (.Busy Or .readystate <> 4) And Now() < time0
  56.             
  57.             Application.Wait Time + #12:00:03 AM#
  58.             
  59.             Set E = .Document.getElementsByTagName("TABLE")(1)
  60.             If E Is Nothing Then IE.Quit: GoTo Again
  61.             
  62.             For Re = 0 To 19          '取19天的歷史紀錄
  63.                 For Ce = 0 To 8
  64.                     Price(Re, Ce) = E.Rows(Re).Cells(Ce).innertext   '日期、開、高、低、收、漲跌  漲% 成交量  成交金額
  65.                 Next
  66.             Next
  67.             
  68.             ActiveSheet.Cells(1, "A").Resize(20, 9).Value = Price
  69. GiveUp:
  70.         
  71.         .Quit
  72.     End With

  73. End Sub
複製代碼

作者: iamaraymond    時間: 2018-1-29 01:15

回復 2# Scott090

幫大大補充一下,
1.44~51行那邊應該可以用document.all(name)取代會比較簡單
2.可以透過修改
https://www.cnyes.com/twstock/ps_historyprice.aspx?code=2330&ctl00$ContentPlaceHolder1$startText=2001/10/05&ctl00$ContentPlaceHolder1$endText=2018/01/09
然後用外部匯入,會比較快,也比較簡單
個人小小想法,參考一下
作者: Scott090    時間: 2018-1-29 06:19

回復 3# iamaraymond


    謝謝,我將試試看。
另,請教 Excel 2013 及它的 VBA 說明的查詢 是:
1.連線透過網路,
還是
2. 離線,已具備崁入(Built in)說明,只要按 F1 就可以
作者: Scott090    時間: 2018-1-29 18:05

回復 3# iamaraymond

依據大大的指導,修改如下,請看看是不是這樣子。
謝謝
  1. '從鉅亨網取得歷史股價
  2. '使用 IE 物件
  3. 'option explicit
  4. 'option base 1

  5. Sub TestCNYES1()

  6.     Dim Price()
  7.     Dim Code
  8.     Code = "2330"
  9.    
  10.     Dim IE As Object, URL$
  11.     Dim date0 As Date, StartDate$, EndDate$, submitBTN$, timer, time0 As Date
  12.     Dim Table As Object, oDoc As Object, E
  13.     Dim Re%, Ce%, i%, k%, ColName$
  14.    
  15.     ActiveSheet.Cells.Clear
  16.    
  17.     '設定資料開始及結束日期
  18.     StartDate = Format(DateAdd("m", -2, Date), "yyyy/mm/dd")    '取2個月的資料,約40筆
  19.     EndDate = Format(Date, "yyyy/mm/dd")
  20.    
  21.     StartDate = "&ctl00$ContentPlaceHolder1$startText=" & StartDate           '開始日期 input name
  22.     EndDate = "&ctl00$ContentPlaceHolder1$endText=" & EndDate                  ' 結束日期 input name
  23. '    submitBTN = "&ctl00$ContentPlaceHolder1$submitBut=查詢"
  24.    
  25.     k = 0
  26. Again:
  27.     Set IE = CreateObject("InternetExplorer.Application")
  28.    
  29.     With IE
  30.             URL = "https://www.cnyes.com/twstock/ps_historyprice.aspx?code=" & Code & StartDate & EndDate
  31.             .Visible = False                '不顯示 IE
  32.             .navigate URL
  33.             
  34.             time0 = Now() + #12:00:05 AM#   '設定時間控制計時5秒鐘
  35.             Do
  36.                 DoEvents
  37.             Loop While (.Busy Or .readystate <> 4) And Time < time0
  38.            
  39.            '計時時間到了網頁未準備好,關閉重啟
  40.             If .readystate <> 4 Then
  41.                 .Quit
  42.                 k = k + 1
  43.                 If k <= 2 Then GoTo Again
  44.                 GoTo GiveUp                   '開啟3次都失敗就放棄
  45.             End If
  46.                         
  47. '            Set E = .Document.getElementsByTagName("TABLE")(0)
  48.             Set E = .Document.all.tags("TABLE")(0)          '這個網頁的資料表有變動
  49.             If E Is Nothing Then IE.Quit: GoTo Again
  50.             
  51.             i = E.Rows.Length - 1: k = E.Rows(1).Cells.Length - 1
  52.             ReDim Price(0 To i, 0 To k)
  53.             
  54.             For Re = 0 To i         '取19天的歷史紀錄
  55.                 For Ce = 0 To k
  56.                     Price(Re, Ce) = E.Rows(Re).Cells(Ce).innertext   '日期、開、高、低、收、漲跌  漲% 成交量  成交金額
  57.                 Next
  58.             Next
  59.             
  60.             ActiveSheet.Cells(1, "A").Resize(i + 1, k + 1).Value = Price
  61. GiveUp:
  62.         
  63.         .Quit
  64.     End With

  65. End Sub
複製代碼

作者: iamaraymond    時間: 2018-1-29 19:49

回復 5# Scott090


  我的是按F1之後會上網找說明

另外我的想法是用QueryTable的方式
  1. Sub 股價()

  2. [A10].CurrentRegion.Clear

  3. stockno = [B3]
  4. mydate1 = Format([B4], "YYYY/MM/DD")
  5. mydate2 = Format([B5], "YYYY/MM/DD")
  6. myurl = "https://www.cnyes.com/twstock/ps_historyprice.aspx?code=" & stockno & "&ctl00$ContentPlaceHolder1$startText=" & mydate1 & "&ctl00$ContentPlaceHolder1$endText=" & mydate2

  7. With ActiveSheet.QueryTables.Add(Connection:= _
  8.         "URL;" & myurl _
  9.         , Destination:=Range("$A$10"))
  10.         .RowNumbers = False
  11.         .FillAdjacentFormulas = False
  12.         .PreserveFormatting = False
  13.         .RefreshOnFileOpen = False
  14.         .BackgroundQuery = False
  15.         .RefreshStyle = xlOverwriteCells
  16.         .SavePassword = False
  17.         .SaveData = True
  18.         .AdjustColumnWidth = False
  19.         .RefreshPeriod = 0
  20.         .WebSelectionType = xlSpecifiedTables
  21.         .WebFormatting = xlWebFormattingNone
  22.         .WebTables = "1"
  23.         .WebPreFormattedTextToColumns = True
  24.         .WebConsecutiveDelimitersAsOne = True
  25.         .WebSingleBlockTextImport = False
  26.         .WebDisableDateRecognition = False
  27.         .WebDisableRedirections = False
  28.         .Refresh BackgroundQuery:=False
  29.         .Delete
  30.     End With
  31. End Sub
複製代碼

作者: Scott090    時間: 2018-1-30 06:35

回復 6# iamaraymond


    " ..... F1上網找說明 ....  ",就因為需網路連結這麼不方便,放棄使用。

謝謝大大的 QueryTable 模式。
因有其他程式碼的連結使用所以我直接把資料放進陣列
作者: GBKEE    時間: 2018-1-30 12:46

本帖最後由 GBKEE 於 2018-1-30 12:47 編輯

回復 6# iamaraymond
這網頁用QueryTable 得取的資料有時起始日期會不準確,試試修改起始日期,看看資料是否正確

回復 7# Scott090
  1. Option Explicit
  2. Sub Ex_Ie_Copy()
  3.     Dim Code As String, Price()
  4.     Dim date0 As Date, StartDate$, EndDate$, timer, time0 As Date, IE_StartDate As String
  5.     Dim E As Object, IE As Object
  6.     Code = "2330"
  7.     time0 = Time
  8.     Application.StatusBar = "開啟網頁...."
  9.     '設定資料開始及結束日期
  10.     StartDate = Format(DateAdd("m", -12 * 10, Date), "yyyy/mm/dd") '取10年資料筆
  11.     If StartDate < CDate("1994/09/07") Then
  12.         MsgBox "StartDate  " & StartDate & vbLf & "不可小於" & "1994/09/07"
  13.         End
  14.     End If
  15.     EndDate = Format(Date, "yyyy/mm/dd")
  16. Set IE = CreateObject("InternetExplorer.Application")
  17.     With IE
  18.             .navigate "http://www.cnyes.com/twstock/ps_historyprice/" & Code & ".htm"
  19.             Do:          DoEvents:             Loop While .Busy Or .readystate <> 4

  20.             With .Document.getElementsByTagName("input")
  21.                  .Item("ctl00$ContentPlaceHolder1$startText").Value = StartDate ' 開始日期 input name
  22.                  .Item("ctl00$ContentPlaceHolder1$endText").Value = EndDate     ' 結束日期 input name
  23.                  .Item("ctl00$ContentPlaceHolder1$submitBut").Click
  24.             End With
  25.             Do:          DoEvents:             Loop While .Busy Or .readystate <> 4
  26.             On Error Resume Next
  27.             Do
  28.                 Err.Clear
  29.                 Set E = .Document.getElementsByTagName("TABLE")(0)
  30.                 If E.INNERTEXT <> "" Then
  31.                     If Err = 0 Then
  32.                         If Abs(DateValue(E.Rows(E.Rows.Length - 1).Cells(0).INNERTEXT) - DateValue(StartDate)) <= 15 Then
  33.                             If Err = 0 Then Exit Do
  34.                         End If
  35.                     End If
  36.                End If
  37.              DoEvents
  38.              Application.StatusBar = " 等候 網頁資料中 ... "
  39.             Loop
  40.             On Error GoTo 0
  41.             CopyToClipbox E.OUTERHTML
  42.             Application.StatusBar = StartDate & " - " & EndDate & " 資料共 " & E.Rows.Length - 1 & " 讀取.." & Application.Text(Time - time0, ["m分:S秒 ok"])
  43.             .Quit
  44.     End With
  45. End Sub
  46. Private Sub CopyToClipbox(strText As String)    '文本拷貝到剪貼板
  47.     With CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
  48.         .SetText strText
  49.         .PutInClipboard
  50.     End With
  51.     With ActiveSheet
  52.         .UsedRange.Clear
  53.         .[A1].Select
  54.         .Paste
  55.     End With
  56. End Sub
複製代碼
  1. Sub Ex_Ie()
  2.     Dim Code As String, Price()
  3.     Dim StartDate$, EndDate$, time0 As Date
  4.     Dim E As Object
  5.     Dim Re%, Ce%
  6.     Code = "2330"
  7.     time0 = Time
  8.     ActiveSheet.Cells.Clear
  9.     Cells(1).Activate
  10.     Application.StatusBar = "開啟網頁...."
  11.     '設定資料開始及結束日期
  12.     StartDate = Format(DateAdd("m", -12 * 10, Date), "yyyy/mm/dd") '取10年資料筆
  13.     If StartDate < CDate("1994/09/07") Then
  14.         MsgBox "StartDate  " & StartDate & vbLf & "不可小於" & "1994/09/07"
  15.         End
  16.     End If
  17.     EndDate = Format(Date, "yyyy/mm/dd")
  18.    
  19.     With CreateObject("InternetExplorer.Application")
  20.             .navigate "http://www.cnyes.com/twstock/ps_historyprice/" & Code & ".htm"
  21.             Do:          DoEvents:             Loop While .Busy Or .readystate <> 4
  22.             With .Document.getElementsByTagName("input")
  23.                  .Item("ctl00$ContentPlaceHolder1$startText").Value = StartDate ' 開始日期 input name
  24.                  .Item("ctl00$ContentPlaceHolder1$endText").Value = EndDate     ' 結束日期 input name
  25.                  .Item("ctl00$ContentPlaceHolder1$submitBut").Click
  26.             End With
  27.             Do:          DoEvents:             Loop While .Busy Or .readystate <> 4
  28.             On Error Resume Next
  29.             Do
  30.                 Err.Clear
  31.                 Set E = .Document.getElementsByTagName("TABLE")(0)
  32.                 If E.INNERTEXT <> "" Then
  33.                     If Err = 0 Then
  34.                         If Abs(DateValue(E.Rows(E.Rows.Length - 1).Cells(0).INNERTEXT) - DateValue(StartDate)) <= 15 Then
  35.                             If Err = 0 Then Exit Do
  36.                         End If
  37.                     End If
  38.                 End If
  39.                 DoEvents
  40.                 Application.StatusBar = " 等候 網頁資料中 ... "
  41.             Loop
  42.             On Error GoTo 0
  43.             'ReDim Price(0 To E.Rows.Length - 1, 0 To E.Rows(0).Cells.Length - 1)
  44.             Application.StatusBar = StartDate & " - " & EndDate & " 資料共 " & E.Rows.Length - 2 & " 讀取...... "
  45.             For Re = 0 To E.Rows.Length - 1 ' 19          '取19天的歷史紀錄
  46.                 For Ce = 0 To E.Rows(Re).Cells.Length - 1
  47.                     Cells(Re + 1, Ce + 1) = E.Rows(Re).Cells(Ce).INNERTEXT '日期、開、高、低、收、漲跌  漲% 成交量  成交金額
  48.                    ' Price(Re, Ce) = E.Rows(Re).Cells(Ce).innertext   '日期、開、高、低、收、漲跌  漲% 成交量  成交金額
  49.                 Next
  50.             Next
  51.             'ActiveSheet.Cells(1, "A").Resize(UBound(Price), UBound(Price, 2)).Value = Price
  52.         Application.StatusBar = StartDate & " - " & EndDate & " 資料共 " & E.Rows.Length - 2 & " 讀取.." & Application.Text(Time - time0, ["m分:S秒 ok"])
  53.         .Quit
  54.     End With
  55. End Sub
複製代碼

作者: Scott090    時間: 2018-1-31 07:22

回復 8# GBKEE


    謝謝 GBKEE 大大 提供的:
資料完整性的查檢機制、 Clip Board 的方法

另, Do
                 .......
                 Application.StatusBar = " 等候 網頁資料中 ... "
          Loop
中,有時不知甚麼狀況會有某些檔股票讀不到資料的情形,所以需要用時間計時來控制並放棄

再次感恩
作者: Scott090    時間: 2018-1-31 21:49

回復 8# GBKEE

   沒有記錄下來,不過好像不是一個特定的;有時用手動直接去檢查又會在網頁上出現資料
下次碰到把它們記下來送給參考。
我在懷疑是網路本身的傳輸也說不定

謝謝
作者: iamaraymond    時間: 2018-2-1 14:29

回復 8# GBKEE


   我記得會造成不一樣是因為如果輸入日期剛好碰到假日,那資料會以下一個工作日開始,例如輸入20180128(日),那就會抓到從20180129(一)開始的資料
作者: GBKEE    時間: 2018-2-1 20:37

本帖最後由 GBKEE 於 2018-2-1 20:39 編輯

回復 11# iamaraymond
這網頁可能也有流量管制
試試看
  1. Option Explicit
  2. Sub 股價()
  3.     Dim stockno As String, mydate1 As String, mydate2 As String, myurl As String
  4.     Dim Ar As Variant, i As Integer, xTime As Date
  5.     Ar = Array("2005/1/1", "2006/1/1", "2007/1/1", "2008/1/1")
  6.     [B3] = 2303
  7.     stockno = [B3]
  8.     [B5] = Date
  9.     For i = 0 To UBound(Ar)
  10.         [b4] = Ar(i)
  11.         [A10].CurrentRegion.Clear
  12.         mydate1 = Format([b4], "YYYY/MM/DD")
  13.         mydate2 = Format([B5], "YYYY/MM/DD")
  14.         myurl = "https://www.cnyes.com/twstock/ps_historyprice.aspx?code=" & stockno & "&ctl00$ContentPlaceHolder1$startText=" & mydate1 & "&ctl00$ContentPlaceHolder1$endText=" & mydate2
  15.         With ActiveSheet.QueryTables.Add(Connection:= _
  16.             "URL;" & myurl, Destination:=Range("$A$10"))
  17.             .RefreshStyle = xlOverwriteCells
  18.             .SaveData = True
  19.             .AdjustColumnWidth = False
  20.             .WebSelectionType = xlSpecifiedTables
  21.             .WebFormatting = xlWebFormattingNone
  22.             .WebTables = "1"
  23.             Application.StatusBar = "資料下載中 ... " & [b4]
  24.             .Refresh BackgroundQuery:=False
  25.             .Delete
  26.         End With
  27.         With [A10].End(xlDown)
  28.             .Select
  29.             If Abs(.Cells - [b4]) > 15 Then
  30.                 MsgBox "開始日期 " & [b4] & " <****> " & .Cells
  31.             End If
  32.         End With
  33.         If i < UBound(Ar) Then
  34.             xTime = Time
  35.             Do
  36.                 DoEvents
  37.                 Application.StatusBar = xTime + #12:00:20 AM# & " - 等候 20秒 ..." & Time
  38.             Loop While xTime + #12:00:20 AM# > Time
  39.         Else
  40.             MsgBox "程式 完畢 "
  41.         End If
  42.     Next
  43. End Sub
複製代碼

作者: Scott090    時間: 2018-2-2 08:58

回復 11# iamaraymond

我想是資料的完整性問題,不是起始日期是否與資料日期一致
在下列位址有討論,請參考  
  http://forum.twbts.com/thread-20288-1-1.html
作者: jackyq    時間: 2018-2-2 11:15

IE , ActiveX.EXE 最大特點是什?  善用之
作者: Scott090    時間: 2018-2-3 06:48

回復 14# jackyq


    請 jackyq 大明示,以便學習

謝謝
作者: jackyq    時間: 2018-2-3 16:44

回復 15# Scott090

多工 ...




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