HTTP通信、RSS解析を行うVBAを記述する
外部ユーザ関数getFeedを定義します。
[リスト3]HTTP通信、RSS解析を行う
Private Function getFeed(url As String, genre As String) As String
'(1)URLの入力チェック
If Len(url) = 0 Then
getFeed = "URL未入力"
Exit Function
End If
'(2)HTTP通信によるリクエスト送信
Dim xmlhttp As MSXML2.xmlhttp 'HTTP通信用オブジェクトを格納
Set xmlhttp = New MSXML2.xmlhttp 'HTTP通信用オブジェクトの生成
Dim status As String 'HTTPリクエストの成否を格納
Dim resText As String 'HTTPレスポンスを格納(テキスト)
xmlhttp.Open "GET", url, False 'GETメソッド、非同期通信で接続
xmlhttp.send 'HTTPリクエストを実送信
status = xmlhttp.statusText 'リクエスト成否の状態を取得
If status <> "OK" Then
Set xmlhttp = Nothing 'HTTP通信用オブジェクトを解放
getFeed = "リクエスト失敗"
Exit Function
End If
resText = xmlhttp.responseText 'レスポンスを格納
Set xmlhttp = Nothing 'HTTP通信用オブジェクトを解放
'(3)XMLデータの解析
Dim xmldata As MSXML2.DOMDocument
Dim rss As MSXML2.IXMLDOMElement
Dim itemList As MSXML2.IXMLDOMNodeList
Dim item As MSXML2.IXMLDOMNode
Set xmldata = New MSXML2.DOMDocument
xmldata.LoadXML resText 'レスポンスをXML文書として格納
'(4)XML文書のrss要素にアクセス
Set rss = xmldata.DocumentElement
If rss.tagName <> "rss" Or rss.getAttribute("version") <> "2.0" Then
getFeed = "非RSS2.0形式"
Exit Function
End If
'(5)記事を「item」要素のリストとして取得し、一旦配列変数に格納
Set itemList = rss.getElementsByTagName("item")
'(6)itemListの件数だけ、記事リストのサイズを広げる(既存データは保持)
ReDim Preserve artList(nofList + itemList.Length - 1)
Dim value As String
For i = 0 To itemList.Length - 1
Set item = itemList(i)
For j = 0 To item.ChildNodes.Length - 1
value = item.ChildNodes(j).Text
Select Case item.ChildNodes(j).nodeName
Case "title"
artList(nofList + i).title = value
Case "link"
artList(nofList + i).link = value
Case "description"
artList(nofList + i).description = cdataConv(value)
Case "pubDate"
If value <> "" Then
artList(nofList + i).pubDate = timeConv(value)
End If
End Select
Next j
artList(nofList + i).genre = genre
Next i
nofList = nofList + itemList.Length
Set xmldata = Nothing 'XMLオブジェクトを解放
getFeed = "OK"
End Function
(1)受け取った引数urlが空文字の場合は、「URL未入力」を返して終了します。
(2)HTTP通信用オブジェクトを生成し、セルに入力されたURLに対して、リクエストを送信します。成功したら、レスポンスをstatusに格納して、オブジェクトは解放します。
(3)オブジェクト変数xmldataにデータを読み込みます。
(4)ルート要素のタグ名が「rss」でない場合、またはversion属性が「2.0」でない場合は、「非RSS2.0形式」を返して終了します。
(5)記事を取り出す処理です。rss配下のitem要素をgetElementsByTagNameメソッドにより取り出し、itemListオブジェクトに格納します。
これを一旦、構造型配列artListに格納するため、ReDim Preserve命令により件数をitemListに合わせて拡張(既存データは保持)します。
itemListからインデックスを使って、item要素ごとにその子要素の配列を取得します。この中に<title>
などがあるはずですが、要素の有無、順序はサイトによって異なります。このため子要素すべてを走査し、名称が一致すれば、要素ごとに必要な処理を行った上で、artListに格納します。
description要素には、HTMLタグが含まれる可能性があるため、ユーザ定義関数cdataConvにより、<~>
の形の文字列を空文字に置換します。またpubDate要素は、RFC822形式(Tue, 01 Nov 2011 10:43:01 +0900)になっているため、ユーザ定義関数timeConvを使って、「年/月/日 時:分:秒」の形に組み立てます。いずれのユーザ定義関数も、JScriptの力を借りています(コードの説明は省略)。
nofListは、フィードの記事数itemList.lengthだけ加算し、xmldataオブジェクトを解放し、「OK」を返して終了します。
以上で完成です。「更新する」ボタンをクリックして、更新データが表示されれば成功です(完全なコードは、ここからダウンロードしてください)。
まとめ
Excelによるニュースの読み込みはいかがでしたか。RSS2.0形式であれば、URLを変更することにより、様々なニュース配信サイトの情報を収集できます。
WINGSプロジェクト 遠藤 存著/山田祥寛監修
WINGS プロジェクトについて
テクニカル執筆プロジェクト(代表山田祥寛)。海外記事の翻訳から、主にWeb開発分野の書籍・雑誌/Web記事の執筆、講演等を幅広く手がける。2011年5月時点での登録メンバは35名で、現在も一緒に執筆をできる有志を募集中。