連載:VB 6ユーザーのための
これならマスターできるVB 2005超入門

第2回 コントロール配列がなくても大丈夫!

羽山 博
2006/09/23
Page1 Page2 Page3 Page4

■デザートも豪華 〜 XML文書を読み込んで表示する

 コントロール配列に代わる仕組みについて、一通りの説明は終わった。が、まだプログラムは終わりではない。さすがに、実際のシステムでデータの値をプログラム中にハード・コーディングすることはないだろう。ログの表示用プログラムであれば、ログ・データをどこからかもらってくるはずだ。

 今回扱っているのは、かなり加工された、しかも単純なログ・データだが、例えば、以下に示すようなXML文書としてデータが渡されてくるかもしれない(図17)。


図17 ログ・データを記録したXML文書
logdate.xmlという名前のサンプル・ファイルを表示したところ。「ログ管理表」というルート要素の下に「項目」という要素が複数あり、「項目」の下には「IP」「アクセス回数」「最終アクセス日付」という要素がある。単純化し、見やすくするためにタグに日本語を使ったが、プログラムで取り扱うなら半角英数字の方がいいかもしれない。

 XML文書を開くには、コードの先頭に

Imports System.XML

と記述し、フォームのLoadイベント・ハンドラを以下のように書き換えればよい。ここではXML文書のファイル名はlogdata.xmlとする。以下の例ではLoadメソッドの引数にローカルなファイルを指定しているが、URLを指定すればXML文書が自動的にダウンロードされる。コードはちょっと長いが、図解しながら少しずつ見ていくので、コードにざっと目を通してから(最初は理解できなくても構わない)、解説に進むといいだろう。

Private Sub initProc(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

  Dim docLog As New XmlDocument()
  Dim nodesLog As XmlNodeList
  Dim i As Integer
  docLog.Load("c:\home\logdata.xml") ' ここまではおまじない

  ' 「項目」というタグ名を持つ要素を取得し、
  ' nodesLogで参照できるようにする
  nodesLog = docLog.GetElementsByTagName("項目")

  For i = 0 To nodesLog.Count - 1
    dgvLog.Rows.Add()
    dgvLog.Rows(i).Cells(0).Value = i + 1

    ' nodesLogのi番目の要素の下にある「IP」という
    ' 項目のテキストをセルに入れる
    dgvLog.Rows(i).Cells(1).Value = nodesLog(i).Item("IP").InnerText

    ' nodesLogのi番目の要素の下にある「アクセス回数」という
    ' 項目のテキストをセルに入れる
    dgvLog.Rows(i).Cells(2).Value = _
        nodesLog(i).Item("アクセス回数").InnerText

    ' nodesLogのi番目の要素の下にある「最終アクセス日付」という
    ' 項目のテキストをセルに入れる
    dgvLog.Rows(i).Cells(3).Value = _
        nodesLog(i).Item("最終アクセス日付").InnerText

  Next i
End Sub
リスト2 XML文書を読み込むフォームのLoadイベント・ハンドラ

 では、解説しよう。現時点では「docLog.Load〜」の行までは、おまじないだと思ってそのまま書けばよい。……というと、いきなり解説になっていないのだが、ここは変数名を好きなものに変える程度で、いつも同じような記述になるため、そのまま書くものとしておく(近いうちに、これらのおまじないの意味を説明しようとは思うが……)。そうすれば、指定されたXML文書が読み込まれ、docLogという名前で利用できるようになる(図18)。


図18 docLog.Load("c:\home\logdata.xml")の動作
docLogはXmlDocumentオブジェクトと呼ばれるもので、XML文書そのものを表す。そのLoadメソッドを使ってXML文書を読み込む。LoadメソッドにはXML文書のあるURLを指定しても構わない。例えば、http://www.rogue.co.jp/logdata.xmlという指定もオーケー(サンプル・データとして実際に使えるようにしてあるので、試してみてもらってもいい)。

 XML文書の取り扱い方は単純そのもの。階層になっている要素を順に取り出せばよい。ここではまず「項目」という名前の要素を取得する。次に、その下の「IP」や「アクセス回数」、「最終アクセス日付」を取得するというわけだ。

 では、「項目」という名前の要素を取得しよう。GetElementsByTagNameメソッドを使えばタグ名を指定して要素(ノード)を取得することができるので、

nodesLog = docLog.GetElementsByTagName("項目")

と書く。「項目」という名前の要素は複数あるので、返されるのはコレクションへの参照となる。これで、nodesLogを使って「項目」という名前の要素が利用できるようになった。図19のようなイメージでとらえるといいだろう。


図19 要素のコレクションを取得する
docLogには図18で見たようにXML文書が読み込まれている。GetElementByTagNameメソッドを使って「項目」という要素を取得し、nodesLogという変数で参照できるようにした。

 これで例えばnodesLog(0)であれば、最初の「項目」を参照できる。従って、インデックスの部分を変数にしてやれば、すべての「項目」を参照できることが分かる。実際、initProcの内容の骨格部分だけを見てみると、

For i = 0 To nodesLog.Count - 1
  データグリッドビューに行を追加する
  データグリッドビューのセルに、nodesLog(i)の「あれやこれや」を入れる
Next i

というループになっていることが分かる。

 続いては、その「あれやこれや」の部分だ。「項目」の中の「IP」「アクセス回数」「最終アクセス日付」の各要素を取り出せばよい。1つ分かればあとは同じなので「IP」について見てみよう。「IP」という子要素を取り出すには、

nodesLog(i).Item("IP")

とすればよい。これもイメージを図で表すと、図20のようになる。XML文書の細かいところに入っていくので、図をズームアップして見てみよう。


図20 名前を指定して子要素を取得する
nodesLog(0)は「項目」という名前の最初の要素を表す。そこにある「IP」という名前の子要素を取り出すにはnodesLog(0).Item("IP")とすればよい。

 なお、「IP」という要素は、「項目」の最初の子要素なので、すべての子要素を表すChildNodesプロパティにインデックスを指定して、

nodesLog(i).ChildNodes(0)

のように表すこともできる。

 innerTextプロパティは、要素の中にあるすべてのテキストを表す。従って、

nodesLog(0).Item("IP").InnerText

であれば「192.168.1.2」という文字列が取り出せる。ちなみに、

nodesLog(0).InnerText

なら、どういう文字列が取り出せるか分かるだろうか? この場合は、「192.168.1.2482006/09/16」となる。

 これで、リスト2の繰り返し処理の中にあった、

dgvLog.Rows(i).Cells(1).Value = nodesLog(i).Item("IP").InnerText

の意味もスッキリ分かるだろう。dgvLogのi行1列目のセルに、「nodesLogのi番目の『IP』という名前の子要素の中にあるテキスト」を入れるということだ。

 最後の最後におまけ。ChildNodesプロパティを使えば、インデックスで子要素が指定できるので、For文の部分を次のように表すことができる。

For i = 0 To nodesLog.Count - 1
  grdLog.Rows.Add()
  grdLog.Rows(i).Cells(0).Value = i + 1
  For j = 0 To nodesLog(i).ChildNodes.Count - 1
    grdLog.Rows(i).Cells(j + 1).Value = _
        nodesLog(i).ChildNodes(j).InnerText
  Next j
Next i
リスト3 ChildNodesプロパティを使用したセルへの値の設定

 実行結果はいずれも図16とまったく同じなので省略する。

結び ― お腹いっぱい。でも、お品書きにはまだまだおいしいものが!

 第2回目ということで、最初の方は復習を兼ねてプロパティの設定方法をかなり丁寧に追いかけた。次回からは、設定内容の一覧だけにするので、不安のある方はいまのうちに一通り操作しておくといいだろう(VB 6の経験があれば、戸惑うことはほとんどないと思う)。

 VB 6のコントロール配列は古き良きBASICという印象のある機能だが、VB 2005で見たイベント・ハンドラの共有は洗練された美しい機能といった印象がある。後半、XML文書の取り扱い方法を見て、一気に高みまで上り詰めた。頂上から景色を眺め渡すと、すがすがしい気分になることと思う。XML文書が取り扱えるようになればRSSフィードを扱ったり、GoogleやAmazonなどのWebサービスを利用したりすることもできる。

 だが、ほかにも眺めのいい山や丘はたくさんある。メニューをはじめとする数多くのコントロールの使い方についてもまだ見ていないし、XMLのところで見た「New何とかかんとか」も気になる。ものすごく便利なのだが謎めいた「My」という存在、Windows APIのほとんどに取って代わる.NET Frameworkなどもこれからだ。

 次回の謎解きは、そのあたりのトピックから1つを選ぶこととしよう。End of Article


 INDEX
  連載:VB 6ユーザーのためのこれならマスターできるVB 2005超入門
  第2回 コントロール配列がなくても大丈夫!
    1.サンプル・プログラム2 − XML文書を表示する
    2.データグリッドビューに列を追加する/イベント・ハンドラを書く
    3.本筋に戻って 〜 イベント・ハンドラを共有する
  4.デザートも豪華 〜 XML文書を読み込んで表示する
 
インデックス・ページヘ  「これならマスターできるVB 2005超入門」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH