最近、このブログの記事数がかなりの数になってきまして過去記事を探すのに苦労するようになってきてしまいました。
そこで固定ページを作って簡単に記事を見つけられるようにしようと思ったのですが、なかなかいい方法が見つかりません。javascriptでサイトマップを作成するという方法もあるようなのですが、javascriptはあまり詳しくないので断念しました。
そこで、以前『Excel VBAでWebサービス - Excelでフィードを読もう(RSS2.0編)』というのがあったということを思い出しまして、この方法を利用して記事のリンクタグを作成するマクロを作ってみました。
シート構成
まずExcelのシートを次のように作成します。TOP

このシートにはURLと取得記事数の欄、そして「作成」ボタンがあります。
URLはBloggerのURL。セル名「URL」
取得記事数は、フィードで読み込むときの記事数になります。セル名「MAXRESULTS」
「作成」ボタン。これは図形を貼り付けています。
LIST

LISTシートは、作成した結果を表示するシートです。
1行目の各項目名のセルに名前を付けています。
タイトル・・・TITLE
投稿時間・・・PUBLISHED
ラベル・・・CATEGORY
件数・・・ENTRYCOUNT
タグ・・・TAG
このシート構成を踏まえて、以下のようにコードを書いていきます。
作成ボタンのクリックイベントハンドラ
作成ボタンを押したときのイベントハンドラです。入力されたURLや祝記事数をもとに取得したフィードからのデータをLISTシートに転記してソートしています。
Public Sub Create_Click()
On Error GoTo Err_Trap
Dim i As Integer
Dim url As String
Dim entryCnt As Integer
Dim maxResults As Integer
Dim setCnt As Integer
Dim feedUrl As String
Worksheets("TOP").Select
'URL
url = Range("URL").value
If Right(url, 1) <> "/" Then
url = url & "/"
End If
'取得記事数
maxResults = Range("MAXRESULTS").value
If Len(url) = 0 Then
MsgBox "URLが入力されていません。", vbExclamation, "注意"
Exit Sub
End If
ReDim EntryList(0)
EntryLinstIndex = 0
Dim remainCnt As Integer
Do
If remainCnt < 150 Then
feedUrl = url & "feeds/posts/default/?max-results=" & maxResults & "&start-index=" & (setCnt * 150) + 1
Else
feedUrl = url & "feeds/posts/default/?max-results=150" & "&start-index=" & (setCnt * 150) + 1
End If
'フィードの取得
entryCnt = GetAtomFeed(feedUrl)
setCnt = setCnt + 1
remainCnt = maxResults - (setCnt * 150)
Loop While (remainCnt > 0)
If entryCnt = 0 Then
'総件数が0の場合は、処理を中断
Exit Sub
End If
'最後の要素を削除
ReDim Preserve EntryList(EntryLinstIndex - 1)
'前回の記事をクリア
Dim startRow As Integer
Dim endRow As Integer
'LISTシートを選択
Worksheets("LIST").Select
Range("TITLE").Offset(1).Activate
startRow = ActiveCell.Row
endRow = ActiveCell.SpecialCells(xlCellTypeLastCell).Row
'対象範囲を削除
If startRow <= endRow Then
Rows(startRow & ":" & endRow).Delete
End If
endRow = entryCnt + 1
'記事リストから、ワークシートに転記
For i = 0 To UBound(EntryList)
'タイトル
ActiveSheet.Hyperlinks.Add _
anchor:=Range("TITLE").Offset(i + 1), _
Address:=EntryList(i).link, _
TextToDisplay:=EntryList(i).title
'投稿日時
Range("PUBLISHED").Offset(i + 1) = EntryList(i).published
'ラベル
Range("CATEGORY").Offset(i + 1) = EntryList(i).category
'タグ
Range("TAG").Offset(i + 1) = "<a href=""" & EntryList(i).link & """>" & EntryList(i).title & "</a>"
Next
'件数を出す
Range("ENTRYCOUNT").Offset(1).Activate
ActiveCell.value = "=IF(C2="""","""",COUNTIF(C:C,C2))"
Selection.AutoFill Destination:=Range("D" & startRow & ":D" & endRow), Type:=xlFillDefault
'ラベルの多い順、ラベル名昇順、タイトル名昇順にソートする
ActiveWorkbook.Worksheets("LIST").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("LIST").Sort.SortFields.Add Key:=Range("D" & startRow & ":D" & endRow), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("LIST").Sort.SortFields.Add Key:=Range("C" & startRow & ":C" & endRow), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("LIST").Sort.SortFields.Add Key:=Range("A" & startRow & ":A" & endRow), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("LIST").Sort
.SetRange Range("A1:E" & endRow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
'セル内を折り返して全体を表示
Selection.CurrentRegion.WrapText = True
Exit Sub
Err_Trap:
MsgBox Err.Number & " " & Err.description, vbCritical, "エラー"
End Sub
フィード取得
標準モジュールに下記のプロシージャを作成します。 実際のAtomフィードを取得する処理です。Public Function GetAtomFeed(url As String) As Integer
Dim i As Integer
Dim j As Integer
Dim k As Integer
'HTTP通信によるリクエスト送信
Dim xmlhttp As MSXML2.xmlhttp 'HTTP通信用オブジェクトを格納
Dim status As String 'HTTPリクエストの成否を格納
Dim resText As String 'HTTPレスポンスを格納(テキスト)
'HTTP通信用オブジェクトの生成
Set xmlhttp = New MSXML2.xmlhttp
'GETメソッド、非同期通信で接続
xmlhttp.Open "GET", url, False
'HTTPリクエストを実送信
xmlhttp.send
'リクエスト成否の状態を取得
status = xmlhttp.statusText
If status <> "OK" Then
Set xmlhttp = Nothing 'HTTP通信用オブジェクトを解放
GetAtomFeed = -1
Exit Function
End If
'レスポンスを格納
resText = xmlhttp.responseText
'HTTP通信用オブジェクトを解放
Set xmlhttp = Nothing
'XMLデータの解析
Dim xmlDoc As MSXML2.DOMDocument
Dim rss As MSXML2.IXMLDOMElement
Dim itemList As MSXML2.IXMLDOMNodeList
Dim item As MSXML2.IXMLDOMNode
Set xmlDoc = New MSXML2.DOMDocument
'レスポンスをXML文書として格納
xmlDoc.LoadXML (resText)
'XML文書のrss要素にアクセス
Set rss = xmlDoc.DocumentElement
'記事を「item」要素のリストとして取得し、一旦配列変数に格納
Set itemList = rss.getElementsByTagName("entry")
Dim value As String
Dim xmlAttr As MSXML2.IXMLDOMAttribute
Dim categoryCnt As Integer
Dim categoryList() As String
Dim workEntry As Entry
categoryCnt = 0
ReDim categoryList(0)
categoryList(0) = ""
'記事リスト分ループ
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" 'タイトル
workEntry.title = value
Case "link" 'リンクURL
Set xmlAttr = item.ChildNodes(j).Attributes.getNamedItem("rel")
If xmlAttr.value = "alternate" Then
Set xmlAttr = item.ChildNodes(j).Attributes.getNamedItem("href")
workEntry.link = xmlAttr.value
End If
Case "published" '投稿日時
If value <> "" Then
workEntry.published = TimeConvert(value)
End If
Case "category" 'ラベル
If categoryCnt > 0 Then
ReDim Preserve categoryList(categoryCnt)
End If
Set xmlAttr = item.ChildNodes(j).Attributes.getNamedItem("term")
categoryList(categoryCnt) = xmlAttr.value
categoryCnt = categoryCnt + 1
End Select
Next j
'配列に格納
For k = 0 To UBound(categoryList)
EntryList(EntryLinstIndex).title = workEntry.title
EntryList(EntryLinstIndex).link = workEntry.link
EntryList(EntryLinstIndex).published = workEntry.published
EntryList(EntryLinstIndex).category = categoryList(k)
EntryLinstIndex = EntryLinstIndex + 1
ReDim Preserve EntryList(EntryLinstIndex)
Next k
'初期化
categoryCnt = 0
ReDim categoryList(0)
workEntry.title = ""
workEntry.link = ""
workEntry.published = ""
Next i
Set xmlDoc = Nothing 'XMLオブジェクトを解放
GetAtomFeed = EntryLinstIndex
End Function
投稿日時の表示形式を変換
Atomフィードで取得した投稿日時は、「2017-03-18T22:27:00.001+09:00」というような形式をしているので、これを「yyyy/mm/dd hh:nn」形式に変換するプロシージャです。Private Function TimeConvert(published As String) As Date
Dim workStr As String
'"-"を"/"に変更
workStr = Replace(published, "-", "/")
'"T"を空白に変更
workStr = Replace(workStr, "T", " ")
'左から16桁分だけ取得
workStr = Left(workStr, 16)
TimeConvert = CDate(workStr)
End Function
構造体定義など
そのほかに、構造体定義とグローバル変数を下記のように定義しています。'記事を格納する構造体
Public Type Entry
title As String 'タイトル
link As String 'リンクURL
published As String '投稿日時
category As String 'ラベル
End Type
'記事リストを格納する配列
Public EntryList() As Entry
Public EntryLinstIndex As Integer
使い方
使い方は、URLにBloggerのURLを入力し、取得したい記事数を入力します。 そして、あとは作成ボタンを押すだけです。 実行されるとLISTシートのほうにリンクタグを作成されます。
<参考サイト>
Excel VBAでWebサービス - Excelでフィードを読もう(RSS2.0編) (1) フィードについて - マイナビニュース
クリボウの Blogger 入門- Blogger のフィード URL とパラメータ
[Excel VBA] XMLの読み込み- 遊び人の得意技はパルプンテ
スポンサーリンク