Public code AsString'股票代码 Public name AsString'股票名称 Public lastClosePrice AsDouble'昨收 Public openPrice AsDouble'今开 Public currPrice AsDouble'最新价格 Public maxPrice AsDouble'最高 Public minPrice AsDouble'最低
Public volume AsDouble' Public turnover AsDouble Public lastUpdateDate AsString Public lastUpdateTime AsString
Function GetStockDataByCode(stockCode AsString) As Collection OnErrorGoTo Oops
Dim url AsString url = "http://hq.sinajs.cn/list=" + stockCode ' define stock Dim stocks As Collection Set stocks = New Collection Dim stock As CStock ' request stock data Dim http AsObject Set http = CreateObject("Microsoft.XMLHTTP") http.Open "POST", url, False http.send "" If http.Status = 200Then ' split by ";" Dim stockList As Variant stockList = Split(http.responseText, ";") Dim item As Variant Dim stockDataStr AsString ForEach item In stockList stockDataStr = item If Len(stockDataStr) > 6Then Set stock = ParseSingleLine(stockDataStr) stocks.Add stock EndIf 'release control to OS DoEvents Next EndIf Set GetStockDataByCode = stocks Oops: ' Debug.Print "[GetStockDataByCode] Error when handling stock: " & stockCode ' 释放内存 Set stock = Nothing Set stocks = Nothing EndFunction
Function ParseSingleLine(stockData AsString) As CStock Dim Data As Variant Data = Split(stockData, ",") 'check data length Dim dataLength AsInteger dataLength = UBound(Data) - LBound(Data) If dataLength < 3Then '如果数据长度小于3,直接返回 Set ParseSingleLine = Nothing GoTo Oops EndIf Dim stock As CStock Dim mkt As STOCK_MKT Dim stockCode AsString ' get stockCode stockCode = Split(Split(Data(0), "=")(0), "_")(2) Set stock = New CStock 'check whether it's hk code mkt = GetMarketType(stockCode) If mkt = MKT_HK Then stock.code = stockCode stock.name = Data(1) stock.openPrice = Data(2) stock.lastClosePrice = Data(3) stock.maxPrice = Data(4) stock.minPrice = Data(5) stock.currPrice = Data(6)
'Write stock data to the right columns of the code column Function WriteSingleStockDataToTable(stock As CStock, codeRow AsInteger, codeCol AsInteger, Optional IncludeDetails AsBoolean = False)
'Write multiple stock data to the right columns of code Function WriteStockListDataToTable(codeCol AsInteger, codeDict AsObject, stocks As Collection, Optional IncludeDetails AsBoolean = False) Dim item As CStock Dim codeRow AsInteger ForEach item In stocks codeRow = codeDict.item(item.code) Call WriteSingleStockDataToTable(item, codeRow, codeCol, IncludeDetails) Next EndFunction
' Sub RefreshBtnClicked() ' Debug.Print "Start Refresh()..." Dim sngStart AsSingle sngStart = Timer Dim codeColumn AsInteger Dim startRow AsInteger Dim endRow AsInteger Dim batchSize AsInteger Dim getDetails AsBoolean ' update settings codeColumn = 4'股票代码列 startRow = 5'起始行 endRow = 100'结束行 batchSize = 5'一次获取股票个数 getDetails = True'是否更新详情,否则只更新当前涨幅(注意:更新的字段越多,耗时越长) Call RefreshStockListByBatch(codeColumn, startRow, endRow, batchSize, getDetails) MsgBox "Refresh done, " & Timer - sngStart & "s used."
EndSub
Sub RefreshStockListByBatch(codeColumn AsInteger, startRow AsInteger, endRow AsInteger, batchSize AsInteger, Optional IncludeDetails AsBoolean = False) 'refresh my list using one single request Dim row AsInteger Dim longCode AsString Dim mkt As STOCK_MKT Dim stockCount AsInteger Dim stockListData As Collection Dim columnCode AsString Dim code AsString 'crete dict to record stock position Dim codeDict AsObject Set codeDict = CreateObject("Scripting.Dictionary") 'initialize longCode = "" stockCount = 0 Set stockListData = New Collection For row = startRow To endRow 'convert to lower case code = LCase(Cells(row, codeColumn).Value) 'construct the long code by ",", e.g. sh000001,sz300012,sh... mkt = GetMarketType(code) If mkt <> MKT_INVALID Then If Len(longCode) > 0Then longCode = longCode & "," EndIf longCode = longCode & code 'record stock position IfNot codeDict.exists(code) Then codeDict.Add code, row EndIf ' stockCount = stockCount + 1 EndIf 'check and request stock data by longCode If stockCount + 1 > batchSize Then ' Set stockListData = GetStockDataByCode(longCode) Call WriteStockListDataToTable(codeColumn, codeDict, stockListData, IncludeDetails) ' reset Set stockListData = Nothing Set stockListData = New Collection stockCount = 0 longCode = "" 'release control to OS DoEvents EndIf Next row ' Set stockListData = GetStockDataByCode(longCode) Call WriteStockListDataToTable(codeColumn, codeDict, stockListData, IncludeDetails) Set codeDict = Nothing Set stockListData = Nothing EndSub