- ベストアンサー
エクセルでXMLHTTPを用いて株の経常益を取得
- エクセルのマクロでXMLHTTPを用いて株の経常益を取得したい
- 株探の決算表から複数銘柄の経常益を取り込むと時間がかかるため、一部のデータのみを取得したい
- ウェブクエリでは不可能なため、XMLHTTPを利用して株の経常益を取得したい
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。こんな感じ? 以下【テスト条件】 ●新しいブックの ●Sheet1に ●以下のデータサンプルを作成 (1行め空行、2行め項目名、A3以下に[コード]) ーーーーー A列 B列 1| -(空行)- 2|コード 銘柄名 3|1301 極洋 4|1333 マ.. 5|1377 サ.. 6|1573 H.. 7|1853 森.. 8|1878 大.. 9|1959 九.. 10|2001 日.. 11|2032 ハ.. 12|2124 ジ.. 13|2212 山.. 14|2222 寿.. 15|2290 米.. 16|2317 シ.. 17|2337 い.. 18|2393 ケ.. ーーーーー ●VBEにて2件参照設定 Microsoft WinHTTP Services, version 5.1 Microsoft HTML Object Library ●標準モジュールを挿入して、 〓標準モジュール〓のスクリプトを貼付け ●クラスモジュールを挿入して(名前はClass1のまま)、 〓Class1(クラス)モジュール〓のスクリプトを貼付け ●スクリプト内の■マークの行にて 動作条件の指定変更または確認を済ませる ●ブック保存 ●実行 Sub StartWinHttpRequest() ●出力結果は上記Sheet1のサンプル右の空いている列(C列→) ' ' /// ' ' 〓〓〓 標準モジュール 〓〓〓 Option Explicit Public Const STBL As String = "今期*" ' ■テーブル名? Public Const SFLD As String = "経常益" ' ■フィールド名? Private Const SSHT As String = "Sheet1" ' ■シート名? Private Const TRACKS As Long = 24& ' ■Collectionの基準サイズ? Public mtxSrc ' 読込用二次元配列 Public mtxPrt ' 出力用〃 Public tnThreads As Long ' Thread 総件数 Public cnSent As Long ' Request/Send済のThread数 Public cnThRest As Long ' 未処理残件数( <> tnThreads - cnSent ) Private colCls As VBA.Collection ' Class1クラスコレクション Sub StartWinHttpRequest() Dim tnCol As Long ' Collectionの実行時サイズ Dim i As Long Application.Cursor = xlWait With Sheets(SSHT) If .FilterMode Then .ShowAllData mtxSrc = .Range("A3:A" & .Cells(Rows.Count, 1).End(xlUp).Row).Value ' ■[コード]データ先頭は A3 ? End With tnThreads = UBound(mtxSrc) ReDim mtxPrt(1 To tnThreads, 1 To 2) tnCol = TRACKS If tnThreads < TRACKS Then tnCol = tnThreads cnSent = 0& cnThRest = tnThreads Set colCls = New Collection For i = 1 To tnCol colCls.Add New Class1, CStr(i) Next i End Sub Private Sub ResPrint() Dim nColPos As Long If colCls Is Nothing Then Exit Sub Set colCls = Nothing If ActiveSheet.Name <> SSHT Then Sheets(SSHT).Select nColPos = Cells(2, Columns.Count).End(xlToLeft).Column + 1 ' ■出力位置・内容は適宜 Cells(1, nColPos).Resize(, 2).Value = Array(STBL, "予想") ' ■ 〃 Cells(2, nColPos).Resize(, 2).Value = Array(SFLD, Date) ' ■ 〃 Cells(3, nColPos).Resize(tnThreads, 2).Value = mtxPrt ' ■ 〃 Erase mtxSrc, mtxPrt Application.Cursor = xlDefault End Sub ' ' 〓〓〓 Class1(クラス)モジュール 〓〓〓 Option Explicit Private Const URL1 As String = "http://kabutan.jp/stock/finance?code=" ' ■ Private Declare PtrSafe Sub Sleep Lib "KERNEL32.dll" (ByVal dwMilliseconds As Long) Private WithEvents oWinReq As WinHttpRequest Private oDoc As HTMLDocument Private nThrdIdx As Long ' 「今このクラスでは何番目を処理しているのか」 Private Sub Class_Initialize() Set oWinReq = New WinHttpRequest Me.RequestAsync Set oDoc = New HTMLDocument End Sub Private Sub oWinReq_OnResponseFinished() Dim oElm As IHTMLElement Dim oTable As HTMLTable Dim oCell As HTMLTableCell Dim oRow As HTMLTableRow Dim sHTML As String Dim nFld As Long On Error GoTo Rep_ sHTML = oWinReq.responseText oDoc.body.innerHTML = sHTML Sleep (10) Set oElm = oDoc.getElementById("finance_box") For Each oTable In oElm.getElementsByTagName("table") If oTable.PreviousSibling.innerText Like STBL Then Exit For Next Set oElm = Nothing For Each oCell In oTable.Rows(0).Cells If oCell.innerText = SFLD Then Exit For Next nFld = oCell.cellIndex Set oCell = Nothing For Each oRow In oTable.Rows If Trim$(oRow.Cells(0).innerText) Like "予*" Then Exit For Next Rep_: Err.Clear If oRow Is Nothing Then mtxPrt(nThrdIdx, 1) = "-" ' ■ 無効なデータだった場合 Empty ? mtxPrt(nThrdIdx, 2) = "-" ' ■ 〃 Else mtxPrt(nThrdIdx, 1) = oRow.Cells(nFld).innerText mtxPrt(nThrdIdx, 2) = Replace$(Right$(Trim$(oRow.Cells(0).innerText), 7), ".", "-") End If Set oRow = Nothing ' ' ▼未処理スレ数 減算▼ cnThRest = cnThRest - 1& If cnSent < tnThreads Then Me.RequestAsync Else oWinReq.abort: Set oWinReq = Nothing: Set oDoc = Nothing ' ' ▼未処理スレ数 = 0& ならば▼最終出力処理 If cnThRest = 0& Then Application.OnTime Now, "ResPrint" End If End If End Sub Sub RequestAsync() cnSent = cnSent + 1& nThrdIdx = cnSent With oWinReq ' ' WinHttp非同期リクエスト .Open Method:="GET", URL:=URL1 & CStr(mtxSrc(nThrdIdx, 1)), Async:=True .Send End With End Sub ' ' ///
お礼
ありがとうございます。 出来ました! ウェブクエリでも四苦八苦する私にはXMLHTTPはとてつもなくハードルが高かったので、本当に助かりました。