 
       
  
  在現代投資管理中,定期更新基金淨值(NAV)是非常重要的一環。手動查詢和輸入淨值數據不僅耗時,而且容易出錯。為此,本腳本旨在通過VBA自動化,根據Excel中的基金代碼、查詢日期和區域,從指定的網頁中抓取當天的淨值並填入相應的單元格。
腳本的主要流程包括:
在開始編寫VBA腳本之前,確保Excel中已經啟用了必要的參考庫。這些參考庫包括:
可以通過VBA編輯器中的「工具」->「參考設定」來啟用這些庫。
以下是完整的VBA腳本,實現根據基金代碼和日期自動查詢淨值並填充到Excel中的C欄:
Sub 查詢基金淨值()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.ActiveSheet
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    
    Dim i As Long
    For i = 2 To lastRow
        Dim fundCode As String
        Dim queryDate As String
        Dim region As String
        Dim baseUrl As String
        Dim url As String
        Dim netValue As String
        
        ' 讀取A欄標的代碼,B欄查詢日期,F欄區域,H欄基礎網址
        fundCode = Trim(ws.Cells(i, "A").Value)
        queryDate = Format(ws.Cells(i, "B").Value, "yyyy/mm/dd")
        region = Trim(ws.Cells(i, "F").Value)
        baseUrl = Trim(ws.Cells(i, "H").Value)
        
        ' 根據區域動態構建URL
        If region = "境內" Then
            url = Replace(baseUrl, "{code}", fundCode)
        ElseIf region = "境外" Then
            url = Replace(baseUrl, "{code}", fundCode)
        Else
            ws.Cells(i, "C").Value = "區域錯誤"
            GoTo NextIteration
        End If
        
        ' 發送HTTP請求
        Dim http As Object
        Set http = CreateObject("MSXML2.XMLHTTP.6.0")
        On Error GoTo ErrorHandler
        http.Open "GET", url, False
        http.send
        
        If http.Status = 200 Then
            ' 解析HTML內容
            Dim htmlDoc As Object
            Set htmlDoc = CreateObject("HTMLFile")
            htmlDoc.body.innerHTML = http.responseText
            
            ' 提取淨值
            netValue = ExtractNetValue(htmlDoc, queryDate)
            
            If netValue <> "" Then
                ws.Cells(i, "C").Value = netValue
            Else
                ws.Cells(i, "C").Value = "無資料"
            End If
        Else
            ws.Cells(i, "C").Value = "連線錯誤"
        End If
        
        ' 延遲以防止過快請求被封鎖
        Application.Wait Now + TimeValue("0:00:01")
        
NextIteration:
        On Error GoTo 0
    Next i
    
    MsgBox "所有淨值查詢完成!", vbInformation
    Exit Sub
    
ErrorHandler:
    ws.Cells(i, "C").Value = "查詢失敗"
    Resume NextIteration
End Sub
Function ExtractNetValue(htmlDoc As Object, queryDate As String) As String
    Dim tables As Object
    Set tables = htmlDoc.getElementsByTagName("table")
    
    Dim tbl As Object
    Dim tr As Object
    Dim td As Object
    Dim found As Boolean
    found = False
    
    For Each tbl In tables
        For Each tr In tbl.getElementsByTagName("tr")
            Dim cells As Object
            Set cells = tr.getElementsByTagName("td")
            If cells.Length >= 2 Then
                Dim dateText As String
                dateText = Trim(cells(0).innerText)
                If dateText = queryDate Then
                    ExtractNetValue = Trim(cells(1).innerText)
                    found = True
                    Exit Function
                End If
            End If
        Next tr
        If found Then Exit For
    Next tbl
    
    ExtractNetValue = ""
End Function
  在腳本中,根據F欄的區域(境內或境外),需要動態調整查詢URL的構建方式。例如:
| 區域 | URL範例 | 
|---|---|
| 境內 | http://fundf10.eastmoney.com/jbgk_{code}.html | 
| 境外 | http://example.com/fund/{code}/nav | 
在這些URL中,`{code}`是需要被替換為具體的基金代碼的占位符。腳本通過`Replace`函數將`{code}`替換為A欄的基金代碼,從而生成具體的查詢URL。
設計URL模板時,需要確保模板能夠靈活應對不同區域和基金代碼的組合。例如:
通過這種模板設計,腳本可以適應不同的URL結構,確保查詢的靈活性和可擴展性。
為了準確提取指定日期的淨值,需要分析目標網頁的HTML結構。通常,基金淨值會以表格(`
| A欄:標的代碼 | B欄:查詢日期 | F欄:區域 | H欄:查詢網址 | C欄:淨值 | 
|---|---|---|---|---|
| BCAAB002 | 2025/01/21 | 境外 | http://example.com/fund/{code}/nav | 10.42 | 
| BCAAB003 | 2025/01/22 | 境內 | http://fundf10.eastmoney.com/jbgk_{code}.html | 未填 | 
運行腳本後,C欄將自動填充對應的淨值,如下所示:
| A欄:標的代碼 | B欄:查詢日期 | F欄:區域 | H欄:查詢網址 | C欄:淨值 | 
|---|---|---|---|---|
| BCAAB002 | 2025/01/21 | 境外 | http://example.com/fund/{code}/nav | 10.42 | 
| BCAAB003 | 2025/01/22 | 境內 | http://fundf10.eastmoney.com/jbgk_{code}.html | 15.30 | 
通過本詳細指南,您可以輕鬆地編寫並運行VBA腳本,自動化查詢並填充Excel中的基金淨值數據。這不僅提高了工作效率,還減少了手動輸入可能帶來的錯誤。隨著財務數據的不斷變化,這樣的自動化工具將成為現代投資管理中不可或缺的一部分。