はじめに

今回も引き続きTwitterを取り上げます。前回取得したアクセス・トークンを使って、いよいよTwitterでタイムラインを取得したり、ツイートを投稿したりできるようになります。動作確認は、Windows 7、Excel 2010、VBA 7.0およびWindows XP、Excel 2007、VBA 6.5で行っています。

図1.完成サンプル

完成サンプルはsample.lzhの中に収録しています。サンプルとしてご活用ください。
Excel VBAでWebサービス - 天気予報を取得してみよう
Excel VBAでWebサービス - MSNマネーから株価の推移を取得しよう
Excel VBAでWebサービス - Excelで書籍情報を検索・取得してみよう
Excel VBAでWebサービス - YouTube APIで動画を検索しよう
Excel VBAでWebサービス - ExcelでTwitterと連携する
Excel VBAでWebサービス - ExcelでTwitterと連携する2

Excel VBAによる開発

今回の開発は、(1)前回のOAuth認証の実装が済んでいること、(2)「認証する」ボタンをクリックして、アクセス・トークン、アクセス・シークレットの取得ができていること、以上を前提にして、Twitterの以下の操作を開発します。

  1. タイムラインを取得して表示する
  2. ツイートを投稿する

必要な情報の格納場所などを準備する

自分のツイートを入力するセルに「myTweet」、タイムラインの日時、ツイート、ハンドル名を表示するヘッダのセルにそれぞれ「datetime」、「tweet」、「handle」という名前を付けます。また、[開発]タブの[挿入]-[ActiveXコントロール]からコマンドボタンを2つ作成します。名前は「cbTimeline」と「cbTweet」、表示名は「タイムラインを表示する」と「投稿する」とします。 最終的に図2のような準備ができればOKです。

図2.ボタンと格納場所の準備

タイムラインを取得して表示するVBAの開発

タイムライン取得では、リクエストのHTTPメソッドは、GETを指定します。 また、タイムラインは、XML形式のレスポンスとして取得できます。ルート要素はです。

表1.タイムラインのXMLデータの主な要素

要素名 親要素 内容
status statuses 各ツイート情報
created_at status ツイートが投稿された日時
text status 投稿されたツイート本文
user status 投稿者情報
screen_name user 投稿者のハンドルネーム

ワークシートで、[開発]タブの[デザインモード]をONの状態で、コマンドボタン[cbTimeline]をダブルクリックします。VBエディタが開きますので、Private Sub cbTimeline_Click()の中に、コードを記述していきます。 前回作成したプロシージャSetParam、MakeSign、SendHttpを用いて、OAuth認証による通信を行い、タイムラインを取得します。

[リスト1]タイムラインを取得して表示するVBA

Private Sub cbTimeLine_Click()

    '受信したタイムラインのXML形式データを操作する変数
    Dim xmlTL As MSXML2.DOMDocument
    Dim statuses As MSXML2.IXMLDOMElement
    Dim status As MSXML2.IXMLDOMElement
    Dim createdAt As MSXML2.IXMLDOMElement
    Dim tweetText As MSXML2.IXMLDOMElement
    Dim screenName As MSXML2.IXMLDOMElement

    '(1)アクセス・トークンの存在チェック
    If Len(Range("access_token")) = 0 Then
        MsgBox "まず、認証してください"
        Exit Sub
    End If

    '(2)OAuth送信でリクエストを送信
    Set param = New Scripting.Dictionary '連想配列オブジェクトの生成
    SetParam 3 '(2-1)OAuth特有のパラメータ設定
    MakeSign 3, "GET", Range("urlTimeline") '(2-2)電子署名の作成
    Set xmlhttp = New MSXML2.xmlhttp 'HTTP通信用オブジェクトの生成
    SendHttp "GET", Range("urlTimeline") '(2-3)HTTP送信
    If Range("OAuthStatus") <> "OK" Then
        MsgBox ("リクエストが失敗しました。" & Range("OAuthStatus"))
        Set param = Nothing '連想配列オブジェクトの解放
        Set xmlhttp = Nothing 'HTTP通信用オブジェクトの解放
        Exit Sub
    End If
    Set xmlTL = xmlhttp.responseXML 'レスポンスを格納
    Set param = Nothing '連想配列オブジェクトの解放
    Set xmlhttp = Nothing 'HTTP通信用オブジェクトの解放

    '(3)XMLデータとして受信したデータを解析し、目的のデータを探索してワークシートに転記
    Sheets("Sheet1").Activate
    Set statuses = xmlTL.DocumentElement
    Dim i As Integer
    For i = 0 To statuses.ChildNodes.Length - 1
        Set status = statuses.ChildNodes.Item(i)
        Set createdAt = status.SelectSingleNode("created_at")
        ActiveSheet.Range("datetime").Offset(i + 1, 0) = TimeConv(createdAt.Text)
        Set tweetText = status.SelectSingleNode("text")
        ActiveSheet.Range("tweet").Offset(i + 1, 0) = tweetText.Text
        Set screenName = status.SelectSingleNode("user").SelectSingleNode("screen_name")
        ActiveSheet.Range("handle").Offset(i + 1, 0) = screenName.Text
    Next

End Sub

まず、タイムラインのXML形式データを操作するオブジェクト変数を用意します。XMLデータそのもの(変数名:xmlTL)はMSXML2.DOMDocument、各要素はMSXML.IXMLDOMElementとなります。
(1)最初に、アクセス・トークンが取得済みであることをチェックしています。
(2)まず、OAuth引数設定用の連想配列オブジェクトparamを生成し、プロシージャSetParamをフェーズ3として呼び出して、引数を設定しています(2-1)。
次に、プロシージャMakeSignをフェーズ3、GETメソッド、タイムラインの取得先URLを渡して呼び出して、電子署名を作成しています(2-2)。
そして、HTTP通信用オブジェクトxmlhttpを生成し、プロシージャSendHttpをGETメソッド、タイムラインの取得先URLを渡して呼び出し、リクエストを送信しています(2-3)。
SendHttpの中で「OAuthStatus」セルに設定された送信結果がOKでなかったら警告ダイアログを出して、終了します。
OKなら、xmlhttpオブジェクトのresponseXMLプロパティを参照して、xmlTL変数に格納し、用済みのオブジェクトparam、xmlhttpにNothingをセットして解放します。
(3)xmlTLからDocumentElementプロパティを参照し、ルート要素をstatuses変数に格納します。statuses要素の子要素statusがツイート情報になるので、これをstatusの数(statuses.ChildNodes.Length)だけ繰り返して取り出し、ワークシートに転記していきます。
ツイートの各要素(日時、本文、名前)へは、status要素のSelectSingleNodeメソッドで直接タグ名を指定してアクセスします。

図3.タイムラインのXML形式データへのアクセスイメージ

取得した各要素は、ワークシートの表題から下方向へインデックスだけずらした(Offset)セルに転記しています。

図4.Offsetの使い方

なお時刻は、「Wed Mar 02 07:28:35 +0000 2011」という形式になっていますので、Excelで日本標準時の日時として認識できるよう、ユーザ定義関数TimeConvを使って、変換しています(スクリプトの説明は省略)。 ワークシートに戻り、[開発]タブの[デザインモード]をOFFにし、[タイムラインを表示する]をクリックして、タイムラインが表示されれば成功です。

ツイートを投稿するVBAの開発

ワークシートで、[開発]タブの[デザインモード]をONの状態で、コマンドボタン[cbTweet]をダブルクリックします。VBエディタが開きますので、Private Sub cbTweet_Click()の中に、コードを記述していきます。

ツイートの投稿では、リクエストのHTTPメソッドは、POSTを指定します。 OAuth認証による通信部分で、ツイートを格納するstatus引数の扱いが若干イレギュラーなので注意してください。

ツイートを投稿するVBA

Private Sub cbTweet_Click()

    Dim urlEncodedTweet As String

    '(1)アクセス・トークンの存在チェック
    If Len(Range("access_token")) = 0 Then
        MsgBox "まず、認証してください": Exit Sub
    End If

    '(2)tweetの存在および文字数制限チェック
    Dim tweet As String
    tweet = Sheets("Sheet1").Range("myTweet")
    If Len(tweet) = 0 Then
        MsgBox "未入力です": Exit Sub
    End If
    If Len(tweet) > 140 Then
        MsgBox "文字数オーバーです": Exit Sub
    End If

    '(3)OAuth送信でリクエストを送信
    Set param = New Scripting.Dictionary '連想配列オブジェクトの生成
    SetParam 3 '(3-1)OAuth特有のパラメータ設定
    urlEncodedTweet = UrlEncode(Range("myTweet")) 'ツイートをURLエンコードしておく
    param("status") = urlEncodedTweet '投稿時は、ツイートもベース文字列の引数として含める
    MakeSign 3, "POST", Range("urlTweet") '(3-2)電子署名の作成
    param.Remove ("status") '電子署名作成後は、ツイートを引数から削除する
    Set xmlhttp = New MSXML2.xmlhttp 'HTTP通信用オブジェクトの生成
    SendHttp "POST", Range("urlTweet") & "?status=" & urlEncodedTweet '(3-3)HTTP送信
    If Range("OAuthStatus") <> "OK" Then
        MsgBox ("リクエストが失敗しました。" & Range("OAuthStatus"))
        Set param = Nothing '連想配列オブジェクトの解放
        Set xmlhttp = Nothing 'HTTP通信用オブジェクトの解放
        Exit Sub
    End If
    Set param = Nothing '連想配列オブジェクトの解放
    Set xmlhttp = Nothing 'HTTP通信用オブジェクトの解放

    Sheets("Sheet1").Range("myTweet") = "" 'ツイートをクリア
    Call cbTimeLine_Click 'タイムラインを取得

End Sub

(1)最初に、アクセス・トークンが取得済みであることをチェックしています。
(2)次に、ツイートの入力と文字数オーバーの有無を確認します。
(3)まず、OAuth引数設定用の連想配列オブジェクトparamを生成し、プロシージャSetParamをフェーズ3として呼び出して、引数を設定します(3-1)。電子認証を作成する前に、ツイートをURLエンコードしたものをstatus引数として連想配列に追加します。次に、プロシージャMakeSignをフェーズ3、POSTメソッド、ツイートの投稿先URLを渡して呼び出して、電子署名を作成します(3-2)。

HTTP通信を行う前に、status引数を連想配列から削除します。そして、HTTP通信用オブジェクトxmlhttpを生成し、プロシージャSendHttpを呼び出して、リクエストを送信します。その際、第1仮引数はPOSTメソッドでいいのですが、第2仮引数はツイートの投稿先URLだけではなく、URLエンコードされたツイートをクエリパラメータとして追加したものを設定します。具体的には「(ツイートの投稿先URL)?status=(URLエンコードされたツイート)」という形になります。(3-3)。
SendHttpの中で「OAuthStatus」セルに設定された送信結果を見て、OKでなかったら警告ダイアログを出して、終了します。OKなら、特に取得するデータはありませんので、用済みのオブジェクトparam、xmlhttpにNothingをセットして解放します。入力済みのツイートをクリアし、プロシージャcbTimeLine_Clickを呼び出して、タイムラインを取得しなおします。

ワークシートに戻り、[開発]タブの[デザインモード]をOFFにし、ツイートを入力後[Enter]キーを押してから、[投稿する]をクリックして、ツイートが追加されたタイムラインが表示されれば成功です。

まとめ

これで、Excel VBAからTwitterでツイートの投稿とタイムラインの取得ができるようになりました。いかがでしたか。 その他の操作をVBAから行いたい場合は、英語になりますが「REST API Resources」のページを参照してチャレンジしてみてください。

WINGSプロジェクト 遠藤 存著/山田祥寛監修
WINGS プロジェクトについて
テクニカル執筆プロジェクト(代表山田祥寛)。海外記事の翻訳から、主にWeb開発分野の書籍・雑誌/Web記事の執筆、講演等を幅広く手がける。2011年5月時点での登録メンバは35名で、現在も一緒に執筆をできる有志を募集中。