Yahoo股市又改code了~~ 請問兩年前您給我的程式該修改哪裡?
請原諒我對Json真的不懂, 謝謝!
-------------------------------------------------------------------------------
Sub Get_Yahoo_類股報價_Json()
Dim Xmlhttp As Object, Jsondata As Object, DecodeJson, Url As String, sectorId As String, exchange As String, p As Integer, Page As Integer, temp, i As Integer, ttt As Double
Sheets("工作表1").Cells.Clear
Sheets("工作表1").Range("a1:k1") = Array("股票名稱", "代號", "股價", "漲跌", "漲跌幅(%)", "開盤", "昨收", "最高", "最低", "成交量 (張)", "時間")
Application.ScreenUpdating = False
'sectorld、exchange,2個參數,同開啟網頁時,網址上的參數
'test
sectorId = "4"
exchange = "TAI"
'test
'sectorId = "33"
'exchange = "TAI"
'test
'sectorId = "123"
'exchange = "TWO"
'test
'sectorId = "167"
'exchange = "TWO"
'test
'sectorId = "166"
'exchange = "TWO"
ttt = Timer
Page = 1
p = 0
Do
Set Jsondata = CreateObject("HtmlFile")
Set Xmlhttp = CreateObject("WinHttp.WinHttpRequest.5.1")
'因語法關係無法正常顯示,Jsondata.write 這行程式碼,請手動輸入
Url = "https://tw.stock.yahoo.com/_td-stock/api/resource/StockServices.getClassQuotes;exchange=" & exchange & ";offset=" & p * 30 & ";sectorId=" & sectorId & "?bkt=tw-qsp-exp-no2-1&device=desktop&ecma=default&feature=ecmaModern&intl=tw⟪=zh-Hant-TW&partner=none®ion=TW&site=finance&tz=Asia/Taipei&returnMeta=true"
With Xmlhttp
.Open "GET", Url, False
.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
.setRequestHeader "Cache-Control", "no-cache"
.setRequestHeader "Pragma", "no-cache"
.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
.send
End With
Set DecodeJson = CallByName(Jsondata.JsonParse(Xmlhttp.responsetext), "data", VbGet)
If p = 0 Then
Page = CallByName(CallByName(DecodeJson, "pagination", VbGet), "resultsTotal", VbGet)
Debug.Print Page 'total
If Page = 0 Then
MsgBox "暫無資料", vbOKOnly, "Error"
Application.ScreenUpdating = True
Exit Sub
End If
Page = WorksheetFunction.RoundUp(Page / 30, 0)
End If
With Sheets("工作表1")
For i = 0 To CallByName(CallByName(DecodeJson, "list", VbGet), "length", VbGet) - 1
Set temp = CallByName(CallByName(DecodeJson, "list", VbGet), i, VbGet)
.Cells(i + 2 + (p * 30), 1) = temp.symbolName
.Cells(i + 2 + (p * 30), 2) = CallByName(temp, "symbol", VbGet)
.Cells(i + 2 + (p * 30), 3) = CallByName(temp, "price", VbGet)
.Cells(i + 2 + (p * 30), 4) = CallByName(temp, "change", VbGet)
.Cells(i + 2 + (p * 30), 5) = "'" & temp.changePercent
.Cells(i + 2 + (p * 30), 6) = temp.regularMarketOpen
.Cells(i + 2 + (p * 30), 7) = temp.regularMarketPreviousClose
.Cells(i + 2 + (p * 30), 8) = temp.regularMarketDayHigh
.Cells(i + 2 + (p * 30), 9) = temp.regularMarketDayLow
.Cells(i + 2 + (p * 30), 10) = temp.volumeK
.Cells(i + 2 + (p * 30), 11) = temp.regularMarketTime
Next i
End With
Set Xmlhttp = Nothing
Set Jsondata = Nothing
Set DecodeJson = Nothing
Set temp = Nothing
p = p + 1
'Delaytick(0.5)
Loop Until p = Page
Sheets("工作表1").Cells.EntireColumn.AutoFit
Application.ScreenUpdating = True
Debug.Print Timer - ttt & "s"
End Sub
Sub Delaytick(setdelay As Single)
Dim StartTime As Double, NowTime As Double
StartTime = Timer * 100
setdelay = setdelay * 100
Do
NowTime = Timer * 100
DoEvents
Loop Until NowTime - StartTime > setdelay
End Sub
------------------------------------------------------------------------------------------------------------
snare wrote:
1024樓
從...(恕刪)
yth0315 wrote:自回我的問題,順便回覆您的問題〜
snare 大,
Yahoo 股市又改 code 了~~請問兩年前您給我的程式該修改哪裡?
請原諒我對 Json 真的不懂,謝謝!
有幾個地方因為Yahoo多加了一層,所以我們要再多用一層CallByName()來抓。
像是
.Cells(i + 2 + (p * 30), 3) = CallByName(CallByName(temp, "price", VbGet), "raw", VbGet)
其它如
price, bid, ask, change, regularMarketOpen, regularMarketDayHigh, regularMarketDayLow, regularMarketPreviousClose
也都要再多加一層CallByName()
蔬食抗暖化,減碳救地球!
想請問這怎麼改,我是用之前的程式碼,謝謝
圖片

原始程式碼
Sub fake_Multiplex()
Call Get_Yahoo_Wtx_Json
Dim i As Integer, LastRow As Integer, t As Double
t = Timer
DownloadError = 0
LastRow = Sheets("stock").Range("a1").CurrentRegion.Rows.Count
Sheets("stock").Range("b3:l" & LastRow).Clear: Sheets("stock").Range("n1:n3") = ""
For i = 3 To LastRow
DoEvents
Sheets("stock").Range("n1") = "Loading " & Round((i / LastRow) * 100) & "%"
Call getstock(i, i)
Next i
With Sheets("stock")
If DownloadError > 0 Then Call Redownload
If DownloadError > 0 Then .Range("n2") = DownloadError & " 下載失敗"
.Range("n1") = LastRow - 1 - DownloadError & " stock loading ok"
.Cells.EntireColumn.AutoFit
End With
Debug.Print Timer - t
Sheets("股票").Select
'Call EX_停損停利通知
End Sub
--------------------------------------------------------------------------------------------------------------------------------------------
Sub Redownload()
If DownloadError = 0 Then Exit Sub
Dim i As Integer, LastRow As Integer
LastRow = Sheets("stock").Range("a1").CurrentRegion.Rows.Count
For i = 5 To 0 Step -1
Delaytick (1)
Sheets("stock").Range("n3") = DownloadError & "筆失敗=>" & i & "秒後,重新下載"
Next i
DownloadError = 0
Sheets("stock").Range("n3") = ""
For i = 2 To LastRow
If Sheets("stock").Cells(i, 2) = "下載失敗" Then
Sheets("stock").Cells(i, 2) = ""
Call getstock(i, i)
End If
Next i
End Sub
--------------------------------------------------------------------------------------------------------------------------
Sub getstock(Firstdata As Integer, Lastdata As Integer)
Dim UrL As String, GetXml As Object, Jsondata As Object, DecodeJson, temp As String, DataTime As String, i As Integer, j As Integer, k As Integer, changePercent As Double
On Error Resume Next
For k = Firstdata To Lastdata
DoEvents
UrL = "https://tw.stock.yahoo.com/q/q?s=" & Sheets("stock").Cells(k, 1)
Set GetXml = CreateObject("WinHttp.WinHttpRequest.5.1")
Set Jsondata = CreateObject("HtmlFile")
Jsondata.write ""
With GetXml
.Open "GET", UrL, False
.setRequestHeader "Cache-Control", "no-cache"
.setRequestHeader "Pragma", "no-cache"
.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
.send
DataTime = Split(Split(.responsetext, "datatime=""")(1), """>")(0)
temp = "{""quote"":{""data"":" & Split(Split(.responsetext, """quote"":{""data"":")(1), ",""orderbook"":")(0) & "}}}"
Set DecodeJson = CallByName(CallByName(Jsondata.JsonParse(temp), "quote", VbGet), "data", VbGet)
With Sheets("stock")
.Cells(k, 2) = CallByName(DecodeJson, "symbolName", VbGet)
.Cells(k, 3) = DataTime 'CallByName(DecodeJson, "regularMarketTime", VbGet)
.Cells(k, 4) = CallByName(DecodeJson, "price", VbGet)
.Cells(k, 5) = CallByName(DecodeJson, "bid", VbGet)
.Cells(k, 6) = CallByName(DecodeJson, "ask", VbGet)
'漲跌顯示方法,一、二,請自行替換
'==============================
'一、漲跌,使用正負號
'.Cells(k, 7) = CallByName(DecodeJson, "changePercent", VbGet)
'If .Cells(k, 7).Value > 0 Then .Cells(k, 7).Font.Color = -16776961 _
'Else If .Cells(k, 7).Value < 0 Then .Cells(k, 7).Font.Color = -11489280
'==============================
'==============================
'二、漲跌,使用▲▼
'debug.print vartype(CallByName(DecodeJson, "changePercent", VbGet)) ' 8 = string
.Cells(k, 7) = CallByName(DecodeJson, "changePercent", VbGet)
changePercent = .Cells(k, 7)
If changePercent > 0 Then
.Cells(k, 7).Value = "▲" & changePercent * 100 & "%"
.Cells(k, 7).Font.Color = -16776961
ElseIf changePercent < 0 Then
.Cells(k, 7).Value = Replace(changePercent * 100, "-", "▼") & "%"
.Cells(k, 7).Font.Color = -11489280
End If
'==============================
.Cells(k, 8) = CallByName(DecodeJson, "volume", VbGet) / 1000
.Cells(k, 9) = CallByName(DecodeJson, "regularMarketPreviousClose", VbGet)
.Cells(k, 10) = CallByName(DecodeJson, "regularMarketOpen", VbGet)
.Cells(k, 11) = CallByName(DecodeJson, "regularMarketDayHigh", VbGet)
.Cells(k, 12) = CallByName(DecodeJson, "regularMarketDayLow", VbGet)
If .Cells(k, 2) = "" Then
.Cells(k, 2) = "下載失敗"
DownloadError = DownloadError + 1
End If
End With
End With
Set GetXml = Nothing
Set Jsondata = Nothing
Set DecodeJson = Nothing
'Delaytick (0.3)
Next k
End Sub
-------------------------------------------------------------------------------------------------------------------------------------------
Sub Delaytick(setdelay As Single)
Dim StartTime As Double, NowTime As Double
StartTime = Timer * 100
setdelay = setdelay * 100
Do
NowTime = Timer * 100
DoEvents
Loop Until NowTime - StartTime > setdelay
End Sub
nijawang wrote:
有幾個地方因為Yahoo多加了一層,所以我們要再多用一層CallByName()來抓
感謝你幫忙找問題
最後一層的名稱,如果不會和vba語法衝突,可用另一種寫法
CallByName(CallByName(temp, "price", VbGet), "raw", VbGet)
CallByName(temp, "price", VbGet).raw
cji3cj6xu6 wrote:
"1157F" 對於層層剝開的詳細說明
如果無法用.length取得長度,或是最後一層沒有名稱可用
進階一點的方式
可參考(1168、1171、1281、1282)樓
g80860 wrote:
有沒有可以寫入vba處理或延緩幾秒再處理等方式,不用另裝軟體,直接在vba 寫入,下載慢點也可以.請教有這樣vba寫法嗎??
可用 Application.OnTime Now,延後副程式執行
或在迴圈中加入延遲
Sub test()
For t = 1 To 10
Delaytick (1) '秒數
Debug.Print t
Next t
End Sub
Sub Delaytick(setdelay As Single)
Dim StartTime As Double, NowTime As Double
StartTime = Timer * 100
setdelay = setdelay * 100
Do
NowTime = Timer * 100
DoEvents
Loop Until NowTime - StartTime > setdelay
End Sub
或是像1095樓範例中,把下載失敗的,直接在儲存格中做個註解
另外找時間再手動 or 自動下載
想關寫法文章內出現很多次了,請自行google































































































