(不定期更新)使用VBA解決 excel web 查詢無法匯入、匯入太慢的股市資料

如果使用
一、ieobject
二、CreateObject("InternetExplorer.Application")
三、web 查詢
四、直接用網址插入網頁圖片
五、其它…等等


常常會造成excel 停止回應一下子
匯入圖片反應很慢,速度不穩定,一張圖2秒~1分鐘
嚴重的話excel還會當掉
雖然簡單,但只適合“固定圖片名稱”的網頁
不適合用在一直在變動的圖片資料,名稱一變,連結就失效

但如果先下載再插入就可避免這個問題
這個範例就是使用 xmlhttp 快速取得網頁上所有的純圖片網址
下載全部圖片後再插入excel表格,不需開ie、不用ieobject
可以用非常快的速度在excel中插入網頁的圖片
這個網頁16張圖(如果google facebook那2張也算進來)
用這個方式,下載+插入圖片,大約只要 1.2秒


範例網站:
台灣股市資訊網 http://goodinfo.tw/StockInfo/index.asp
股票代號:2412 (紅圈內的所有圖片)
http://goodinfo.tw/StockInfo/StockDetail.asp?STOCK_ID=2412





'====程式碼要放在“模組”裡====

'使用urlmon函式庫
Private Declare Function URLDownloadToFile Lib "urlmon" _
Alias "URLDownloadToFileA" (ByVal pCaller As Long, ByVal szURL As String, _
ByVal szFileName As String, ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
Sub getimage()

ttt = Timer
Dim Url, Url_a, HTMLsourcecode, XMLGET, ImageLinks, links, ImageFiles, target, Del_Image As Shape

target = "c:\excel\"
If Dir(target, vbDirectory) = "" Then
'建立暫存目錄
MkDir target
Else
'刪除暫存目錄內所有檔案
'注意,目錄內所有檔案,會在無任何提示下刪除,請小心設定目錄名稱、位置
If Dir(target & "*.*") <> "" Then Kill target & "*.*"
'刪除sheet1裡面,已插入的所有圖片
For Each Del_Image In Sheets("sheet1").Shapes
If Del_Image.Type = 11 Then Del_Image.Delete
Next
End If


Set HTMLsourcecode = CreateObject("htmlfile")
Set XMLGET = CreateObject("WinHttp.WinHttpRequest.5.1")

Url = "http://goodinfo.tw/StockInfo/StockDetail.asp?STOCK_ID=2412"
Url_a = "http://goodinfo.tw/StockInfo/"

With XMLGET
.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"
.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
.send

HTMLsourcecode.body.innerhtml = convertraw(.responsebody)
'把所有圖片網址,設成一個物件
Set ImageLinks = HTMLsourcecode.all.tags("image")
For Each links In ImageLinks
i = i + 1
'下載網頁內所有的圖片
URLDownloadToFile 0, Url_a & Replace(links.href, "about:", ""), target & i & ".gif", 0, 0
Set ImageFiles = Sheets("sheet1").Pictures.Insert(target & i & ".gif")
'插入圖片,調整位置
With ImageFiles
.Left = ActiveSheet.Cells((i - 1) * 10 + 1, 2).Left
.Top = ActiveSheet.Cells((i - 1) * 10 + 1, 2).Top
End With
Next

End With

Set HTMLsourcecode = Nothing
Set XMLGET = Nothing
Set ImageLinks = Nothing
Set ImageFiles = Nothing

Debug.Print Timer - ttt

End Sub

Function convertraw(rawdata)
Dim rawstr
Set rawstr = CreateObject("adodb.stream")
With rawstr
.Type = 1
.Mode = 3
.Open
.Write rawdata
.Position = 0
.Type = 2
.Charset = "utf-8"
convertraw = .ReadText
.Close
End With
Set rawstr = Nothing
End Function


'===========================================
如果,不想下載全部圖片,只要把這9行程式碼刪掉
For Each links In ImageLinks
...
next
例如只要網頁中16張圖片的圖片3(google facebook 是圖片1、圖片2)

程式碼改成
URLDownloadToFile 0, Url_a & Replace(ImageLinks(3).href, "about:", ""), target & "temp.gif", 0, 0
Set ImageFiles = Sheets("sheet1").Pictures.Insert(target & "temp.gif")
With ImageFiles
.Left = ActiveSheet.Cells(2, 2).Left
.Top = ActiveSheet.Cells(2, 2).Top
End With

這個範例也可以合併到21樓的範例中
美觀方面請自行加程式碼處理


附加壓縮檔: 201804/mobile01-bc495fc8173a47886cb6c1869ac7a8fa.zip
謝謝Snare大的指導.
發文的內容,小弟再慢慢仔細的研讀,體會.
TKS!
snare wrote:
如果使用 一、ieo...(恕刪)


師傅
有狀況,有狀況
http://www.tse.com.tw/ch/index.php


我要抓這區塊的資料





結果連一開始定義都失敗了
師傅的招
HTMLsourcecode.body.innerhtml = .ResponseText
也無效化了

怎辦?!

怎麼會不能定義呢?

bioleon69 wrote:
HTMLsourcecode.body.innerhtml = .ResponseText
也無效化了...(恕刪)


一、
HTMLsourcecode.body.innerhtml = convertraw(.ResponseBody)

二、
.Charset = "utf-8"


不過您要的資料不在http://www.tse.com.tw/ch/index.php 這一頁喔
資料是另外產生的,抓下來也沒什麼用
需改用CreateObject("InternetExplorer.Application")
xmlhttp的方式,目前不想教
snare wrote:
一、HTMLsour...(恕刪)


改了,怎麼是這樣子?
師傅,而且您的即時運算視窗 列印出來的怎麼這麼漂亮


bioleon69 wrote:
您的即時運算視窗 列印出來的怎麼這麼漂亮...(恕刪)


Debug.Print HTMLsourcecode.body.innerhtml

這頁沒整體市場的資料,不用抓了

不過如果不要表格,只想要那些數字,用抓csv的方式改寫一下就行


不過網址會不會變,我就不知道了,臨時亂寫的

Sub 整體市場()

Dim Url, XMLget, csvrow As Variant, csvstring As String
Set XMLget = CreateObject("msxml2.xmlhttp")
'5/24修正一下錯誤網址
Url = "http://www.tse.com.tw/rsrc/data/zh/home/summary.json?_=1495560138601"

With XMLget
.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
Do Until .readyState = 4: DoEvents: Loop

csvstring = .responsetext
csvrow = Split(csvstring, ",")

i = 0
For Each csvc In csvrow
i = i + 1
Cells(i, 1) = Replace(csvc, """", "")
Next

End With

Set XMLget = Nothing


End Sub
snare wrote:
HTMLsourcecode.body.innerhtml


謝謝師傅 不好意思,原來可以print左邊的
問了一個那麼愚蠢的問題XD

另外,感謝師傅指點,這一次的XML程式碼似乎比較簡單一些
csvstring = .responsetext
csvrow = Split(csvstring, ",")

趕緊來研究看看
師傅您早:
依照師傅的指導,我下載到Goodinfo的股個資產負債表.
有二點還請師傅開示:
(1)Table:您的說明上有提到一個網頁上各個"表格"資料的順序,如Table 11 table 14...
昨天有試著以Chrome打開網頁的程式碼,"有字天書",不知網頁上的表格如何找到順序.
師傅之前的貼文:
是的,看不懂原始碼,只能一個一個找
正常情況下網頁不會有太多表格
如果是我的範例,只是改編號,程式不會出錯,除非表格不存在
像是yahoo股票網頁,只需要試到第7個(編號6),不會花太多時間
HTMLsourcecode.all.tags("table")(0).Rows
HTMLsourcecode.all.tags("table")(1).Rows
HTMLsourcecode.all.tags("table")(2).Rows


HTMLsourcecode.all.tags("table")(6).Rows
以小徒目前的功力,應該就是一個一個找.......吧?
(2)這個網站有二個下拉式選單.
1.報表種類:

2.報表最終期間:



不知這二個選單(變數)該如何處理?
Thank you!
akirachin wrote:
不知這二個選單(變數)該如何處理?...(恕刪)


簡單一點的用CreateObject("InternetExplorer.Application")
按下選單,再去抓資料( 這個範例很多,請自行google )

難一點的,要改用WinHttp post 方法
但這個方式,要看網頁原始碼、追踨網址
每個網站的寫法都不太一樣
沒辦法一個副程式通用大部份的網頁
寫出來的程式碼,只適合被 copy、抄 ,不適合教學
畢竟mobile01 不是程式論譠,不太適合po那種需要改來改去的程式碼

讓我考慮一下
要不要為這個網頁寫個範例,讓大家抄…
先謝謝師傅!
snare wrote:
如果使用 一、ieobject...(恕刪)
文章分享
評分
評分
複製連結
請輸入您要前往的頁數(1 ~ 158)

今日熱門文章 網友點擊推薦!