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

求集保庫 2014年4月~2018年8月的 Excel檔
請教樓主
https://histock.tw/stock/branch.aspx?no=1101&from=20180905&to=20180905

網頁中看到Jsondata 如下,所以用chrome 按F12 , response就如下,而非出現標準jsondata
這種的該如何處理?


<script>
$(document).ready(function () {
var jsonDatas = eval({
"Buy": [
{
"Index": 1,
"Number": "1380",
"Name": "台灣匯立",
"BSSum": "1,571",
"BuySum": "1,577",

yuhuahsiao wrote:
請教樓主
https://histock.tw/stock/branch.aspx?no=1101&from=20180905&to=20180905

網頁中看到Jsondata 如下,所以用chrome 按F12 , response就如下,而非出現標準jsondata
這種的該如何處理?...(恕刪)


這個網頁,您想得太複雜了

請用21樓範例,就可以簡單處理

提示:table(0)



謝謝樓主
的確想得太複雜
後來再去看原始碼,是我看錯了

Snare 大 : 你好! 中秋佳節快樂! 我用下列程式 抓資料 結果多變為文字格式 如何將資料改為數值
不知哪裡寫錯 煩請抽空 指導 謝謝 !

Sub GETdata()
Application.ScreenUpdating = False
On Error Resume Next

Dim Xmlhttp As Object, Clipboard As Object
Dim URL

URL="http://phs.nsc.com.tw/z/zg/zg_F_0_1.djhtm"
Sheets("工作表1").Range("a1:t300").ClearContents
Set Clipboard = CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
Set Xmlhttp = CreateObject("Microsoft.XMLHTTP")
With Xmlhttp
.Open "GET", URL, False
.send
End With

With Clipboard
.SetText Xmlhttp.responseText
.PutInClipboard
End With

With Sheets("工作表1")
.Select
.Cells(1, 1).Select
.PasteSpecial NoHTMLFormatting:=True
.Columns.AutoFit
End With
Set Xmlhttp = Nothing
Set Clipboard = Nothing
End Sub
alantsai5840 wrote:
抓資料 結果多變為文字格式 如何將資料改為數值
不知哪裡寫錯...(恕刪)


沒有寫錯
網頁上的資料,本來就是文字,所以貼上excel後,就是文字格式

直接在excel表格裡面,“手動輸入”的資料要改類型很簡單,就儲存格格式選一選就行

外部資料匯入、複製貼上,很容易就自動判斷為文字

就算儲存格格式是數字(顯示類型也是數字),貼上後還是會變文字

您可以開筆記本,先打一些數字,例如: 1 => 2.22(小數點) => 3,333 (千分位)
分別複製再貼上excel,您就會發現會變文字格式是正常的


所以要改格式,需要另外寫副程式處理,方法有很多
簡單一點的就是用 CDbl()
(CDbl()也可以配合21樓逐格寫入的範例,這樣就不用另外多寫一個副程式)






詳細請參考(類型轉換函數)
https://support.office.com/zh-tw/article/%E9%A1%9E%E5%9E%8B%E8%BD%89%E6%8F%9B%E5%87%BD%E6%95%B8-8ebb0e94-2d43-4975-bb13-87ac8d1a2202
感謝 Snare 大 抽空指導 我會依指導做 謝謝!

我有試cdbl 函數 對儲存格如 CELLS(3,6)="+17.35%" 無法轉換

最後 我用replace 函數將第一位元 取代就可以 replace(cells(3,6),1,1,"")

Snare 大謝謝!
看了很長時間,終於將樓主的教學看過一遍,收護良多,有些問題想請教一下

(1) #41
理論上方法1標準寫法能釋放記憶體。
請問方法2將AAA放進SubFun內執行完後回到MainFun,請問會釋放記憶體嗎?或僅僅是AAA失去記憶體的資料連結而以,記憶體的資料還在,只是已沒有被標記為是屬於AAA。

方法一
Sub MainFun()

SubFun()

End Sub

Sub SubFun()
dim AAA as object
set AAA = object

set AAA = nothing

End Sub


方法二
Sub MainFun()

SubFun()

End Sub

Sub SubFun()
dim AAA as object
set AAA = object

End Sub


(2) #120

120樓,樓主的寫法非常的不同,差異如下圖


如果照著樓主提供得學習,應該是會如下圖



原始碼的Source 分頁,查到的
encodeURIComponent=1&run=Y&step=1&TYPEK=sii&year=107&smonth=06&emonth=07&sstep=1&firstin=true



請教是如何查出能寫出這樣的指令,而且連 table 也要另外改,應該是另一個網頁的原始碼。



另一是在Newtwork的Request Headers有很多項,
是否因上圖的原始碼上有這一段,
xmlDoc[index].setRequestHeader("Content-Type","application/x-www-form-urlencoded");

所以VBA的指令上只有特別加上這一段,是嗎?


(因為是使用樓主的檔案稍為修改,所以指令就只貼圖比較明顯)
justinyutw wrote:
看了很長時間,終於將樓主的教學看過一遍,收護良多,有些問題想請教一下...(恕刪)


過了這麼多年,總算有人認真看了,感動


第一個問題:

是連結,也是釋放記憶體,2個都對
記憶體資料還在,也對,但是在end sub後,該記憶體區塊會變成可使用空間
所以等於釋放了
(請參考網頁說明)
http://yes.nctu.edu.tw/VB/1_Stat/Set.htm


至於為什麼我說是標準寫法,是因為現在程式太聰明了
end sub 後會自動處理掉

所以nothing,被放在"選擇性引數",可加上,也可不加上
可看41樓的記憶體使用量測試


第二個問題:
……120樓,一年5個月前寫的範例
好久沒打開來檢查了,有空我再看看……



第三個問題:
關於 .setRequestHeader
其實很多都可以省略,網站後端會處理,沒那麼嚴格,多加上也不會怎麼樣
所以大部份的網站
open (post or get),url
.send
2行,就可以拿到.responsetext了


但建議習慣上,需即時更新資料的,加上這3行(在不改變原始網址的情況下)
.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)"

有些網站會檢查referer,那就要特別再加上一行
.setRequestHeader "Referer", 網址

snare wrote:
過了這麼多年,總算...(恕刪)


由繁體、簡體字、英文網頁,過去要查到這些資料真的很少,而且很多都是 Try & Error,且即使語法最後很莫名奇秒的對了。
幾個月前查到這討論,沒有Try & Error 且又合邏輯的寫法,且範例一個比一個難且真的很有料。不需要像以前如淘金般,花很多時間去蕪存菁,就為了得到那一點經驗和知識。花了兩個月多的六日,趕快確認範例和網頁原始碼了解是如何寫,在網頁還沒被修改前且範例還可執行前,不然就浪廢了這些範例了。

無論如何,真的很感謝樓主的回覆。
之後還請多多指教,謝謝


(1) #41

所以如這討論串使用 Query Table 的族群,
善用將 Query Table 放入 SubFun 內,或甚至多加一句 Nothing (雙重保障),
應該對記憶體不足,應該明顯有幫助吧?

或者說如果有過多會重複呼叫(例如 For loop)且會佔資源的的物件(例如 Query Table),如方法一寫法,是否會很有幫助;或其實與方法二差不多而以。
如果可行的話,也許使用 Query Table 的族群藉由此類寫法,也可以多多少少增加一點效能。

方法一
Sub MainFun()

For
SubFunQueryTable()
Nest i

End Sub

Sub SubFunQueryTable()
dim AAA as object
set AAA = object

set AAA = nothing

End Sub

方法二
Sub MainFun()

For
dim AAA as object
set AAA = object

set AAA = nothing
Nest i

End Sub



(2) #120

.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
樓主在過去討論串,已有解釋這三行的應用。不過對於這一行,是如何或基於什麼了解要設定這時間?
是因為千禧年的關係嗎?雖然可以直接Copy Paste,但這行很特別,怎會知道要這麼寫?


.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
在71樓時首度需要使用這一行,第一次使用到。
當初想了很久,最後覺得伺服器回傳得訊息是不是想告訴我什麼。如果沒這訊息,應該要等到討論到30多頁後的樓主解答吧。




.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
忘了哪一樓開始,一開始覺得是先GET(POST)取得網址當頁的一些訊息後。
第二次GET(POST)會引用到這些訊息,當然是要說明這些訊息是 Referer 哪個網頁取得的。
就如同寫研究所寫論文引用數據時,要說明是從哪篇期刊等等取得的資料。

不知道是否是這樣的想法?雖然之後的範例即使沒有二次的GET(POST), 依然會寫上這一行,如同標準配備一般。
關閉廣告
文章分享
評分
評分
複製連結
請輸入您要前往的頁數(1 ~ 144)

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