WIZARDを利用したエクスプローラ
スタイルのDBアプリケーション開発秋月巌 AKIZUKI,Iwao
はじめに
図1:今回作成するエクスプローラスタイルのDBアプリケーション
![]()
豊富に用意されたウィザードは,Visual Basic 5.0のひとつの特徴である. なかでもアプリケーションウィザードは,Visual Basicで開発するアプリケーションのテンプレートを自動的に生成する興味深い開発支援機能である.
このエキスパートシステムは,生成するアプリケーションのスタイルを選択するときに,エクスプローラスタイルを選択することができる.
本稿では,ウィザードの生成したアプリケーションにコードを追加することで,データベースの内容をエクスプローラスタイルで表示するサンプルを作成する.
パーソナルコンピュータの時代
よい時代である.超高速のCPUを搭載したコンピュータが20万円で手に入り,しかも,プロ仕様のスペックを持つソフトウェアが,その半分の価格で買えたりする.数万円のプリンタで写真クォリティの印刷が可能であり,また1万円のソフトウェア音源がオーケストラの音色を再現する.
昔ならば,一部の貴族にしか実現できなかったことを1台のパーソナルコンピュータが可能にする.これこそが,テクノロジーの勝利であり,民主主義?である.開かれた可能性は新しい才能を発見するだろう.
業務とコンピュータ
もちろん,革新は利点のみを社会に提供するとはかぎらない.問題なのは,その低価格コンピュータを業務に使おうとする動きが顕著なことである.この潮流は,ある一面では正しいし,別の一面では間違っている.
ある一面とは「コスト」のことであり,別の一面とは「業務の遂行」という,ある意味ではコスト以上に重要な問題である.しかも,困ったことに,ちょうど私はこの分野の仕事に従事している.
大切なのはユーザーの認識である.私のところに訪れるユーザーに,私は次のように尋ねることにしている.「95%稼動するシステムならは500万円ですが,99%稼動するシステムだと5000万円になります.どちらにしますか?」
大抵のユーザーは前者を選択する.これは私にとって都合のよい選択である.なぜなら,10倍のコストをかけたとしても99%の可用性を持つシステムを作ることは難しいからである.ちなみにこれを99.9%に引き上げるには,さらに一桁高いコストの提示が必要になることはいうまでもない.
低コストシステムと開発ツール
低コストのシステムを導入するには,開発コストを下げることが重要な要素となる.そのためにRADツールが発展してきたのは,ご存知の通りである.RADツールと非RADツールの優位性を比較することにはあまり意味がない.それぞれのツールには適所があり,クロスオーバーする場面は少ない.予算と時間が豊富にあり,優秀なエンジニアが存分に確保できる場合は,非RADツールの方がクォリティの高いプロダクトを開発することができるが,そのようなプロジェクトは多くない.また,Borland C++ BuilderやPowersoft Power++のように非RAD系のコンパイラにRADのインターフェイスを被せたものもあるし,Delphiのように最初から完全に両方に属するツールもある.
Visual Basicとウィザード
さてRADツールの雄であるVisual Basicも,ver.5.0においてAPIの使用範囲を拡大するなど,低水準な処理を可能な方向に拡張している.ひとつのツールがカバーする領域が拡大することは,単一スキルのエンジニアの可能性拡張につながる.
Visual Basicは低水準の開発能力を高める一方で,豊富なウィザードの搭載により,RADツールとしての側面も強化している.大抵のMicrosoft製品に搭載されているウィザードとは,ソフトウェアの操作などをユーザーに指示するエキスパートシステムの一種である.開発ツールに搭載されたウィザードの多くは,プログラムのソースコードを自動的に生成する機能を持つ.Visual Basicには多くのウィザードが装備されており,開発者がソースコードを作成する作業を軽減するというのが触れ込みである.しかし,概してウィザードが生成するコードは猥雑で拡張性に乏しく,また,変数の命名を既定の方式で統一できないなどの問題点もある.結局は自分でコーディングをしなおすことになるケースが多い.本誌9月号で真崎理人氏は,アプリケーションウィザードの有用性について,Microsoftが既定する標準が確認できることをあげているが,ウィザードが生成するアプリケーションについては批判的である.
おそらく,ウィザードのアプリケーション開発における最大の効用は,その学習効果だろう.自分が目的とする処理に合致するウィザードがあれば,まず,それを使ってコードを出力してみる.次にそのコードを確認し,自分なりに記述しなおす.テンプレートが何もない“白紙”の状態からコードを書くことを考えれば,メソッドやプロパティの調査時間を節約できるだろう.それでは,サンプルアプリケーションと同じではないかと考える方もあるかもしれない.その通り.ウィザードはカスタマイズ可能なサンプルコード生成ツールなのである.
第3のユーザーインターフェイススタイル
MicrosoftはWindowsが普及する初期のころ,MDIインターフェイスを持つアプリケーションをWindowsの標準インターフェイスとして推奨していた.各開発ツールベンダーはMDIアプリケーションの開発に対応していることを自社製品の売りとして,最新のリリースをおこなった.それが一段落したころ,Microsoftは前言を翻し,次の標準インターフェイスはSDIだと強調した.しかし,なぜかOffice製品はいまだにMDIだし,Microsoft AccessにいたってはMDIアプリケーションしか作成できない.
結局はダブルスタンダードとしてWindowsにはMDIとSDIアプリケーションが混在することになった.そして,このたび,Microsoftはエクスプローラスタイルのアプリケーションを,標準的なユーザーインターフェイスとして新たに追加しようとしている(図1).
エクスプローラスタイルは,構造を持った構造を表現するのに適しているということができる.また,アイコンを使用することで直感的なインターフェイスを実現する.これらの長所はGUIとデータを結び付ける洗練されたスタイルだということがいえるだろう.
サンプルアプリケーション
の生成今回はウィザードが生成したアプリケーションテンプレートにコードを追加し,データベースのフロントエンドとして活用してみた.作成するサンプルプログラムはツールバー右側のボタンをクリックすることで,フォーム右側の表示形式を変更することができる(図2).フォームには2つのテーブルのデータがデータベースより表示される.ひとつは「取引先」テーブル(Torihikisaki)であり,もうひとつは「商品」テーブル(Syohin)である. 左側のTreeViewコントロールのトップには「取引先」があり,各取引先をクリックすると,その取引先が扱っている製品が表示される構造である. 記事末にソースコードの全文を掲載する.ひとつのモジュールとひとつのフォームからなるシンプルなプログラムである.網掛けの部分が追記したコード,斜体がコメントアウトした部分,それ以外がアプリケーションウィザードが生成したコードである.
アブリケーションウィザード
の利用アプリケーションウィザードの使用法は他のウィザードの例にもれず,難しいものではない.
Visual Basic 5.0の開発環境の[ファイル]メニューから[新しいプロジェクト]を選択すると,「新しいプロジェクト」ダイアログが表示される(図3).「アプリケーションウィザード」アイコンを選択するとウィザードが開始する(図4).
次の「インターフェイスの種類」ダイアログで,エクスプローラスタイルを選択する(図5).サンプルアプリケーションでは「メニュー」ダイアログの「すべての選択を解除」ボタンをクリックして選択を解除しておく(図6).ここでチェックボックスをチェックした場合は,指定した項目のメニューが実装される.「リソース」ダイアログと「インターネット接続」ダイアログでは,両方とも「いいえ」を選択する(図7・8).図9「標準フォーム」の「以下の標準フォームをアプリケーションに組み込みますか?」という問いに対して「いいえ」を選択.さらに,図10の「データアクセスフォーム」ダイアログでは「いいえ」を選択する.ここで「はい」を選択してテーブルを指定すると,ウィザードはデータを操作するための一般的なフォームをエクスプローラスタイルのフォームとは別に作成する.
最後に「完了」ダイアログ(図11)にアプリケーションの名前を入力し,「完了」ボタンをクリックすると,サマリーレポート(図12)が表示され,エクスプローラスタイルのアプリケーションが生成される. 図13はウィザードが生成したアプリケーションのプロジェクトウィンドウである.それぞれひとつのモジュールとフォームから構成されている.モジュールとはいっても,リスト1のコードをみてもらえばわかるように,メインフォームを呼び出すコードが記述されているだけで,実質的には何の処理もおこなっていない.
完成したアプリケーション 図14・15が完成したフォームのデザイン時と実行時である.フォームにはToolBarコントロール(tbToolBar),TreeViewコントロール(tvTreeView),ListViewコントロール(lvListView)と,それらを区切るためのImageコントロール(imgSplitter)およびPictureBoxコントロール(picSplitter)が配置されている.ListViewコントロールの背後に隠れて見えないが,CommonDialogコントロールとImageListコントロールもフォームに配置されている.このImageListコントロールはツールバーに表示するボタンのイメージを格納している.
処理が何も記述されていないため,実行してみても左右のリストには何も表示されない(図15).それでもノードの区切りをドラッグするとノードのサイズが変更される.
サイズ変更のためのドラッグ時の境界線表示
まずはウィザードが作成したユーザーインターフェイスから調べてみよう.
ウィザードが生成したイベントプロシージャには,ツリービューとリストビューの境界でマウスボタンが押されてドラッグしたときに,境界線の色が変り移動する様子が記述されている(リスト1).Imageコントロール(imgSplitter)のMouseDown,MouseMove,MouseUpの各イベントプロシージャにおいて,PictureBoxコントロール(picSplitter)の位置調整と表示,非表示の切り替えをおこなう.
リスト1:サイズ変更のためのドラッグ時の境界線表示処理
Private Sub imgSplitter_MouseDown _ (Button As Integer, Shift As Integer, X As Single, Y As Single) With imgSplitter picSplitter.Move .Left, .Top, .Width \ 2, .Height - 20 End With picSplitter.Visible = True mbMoving = True End Sub Private Sub imgSplitter_MouseMove _ (Button As Integer, Shift As Integer, X As Single, Y As Single) Dim sglPos As Single If mbMoving Then sglPos = X + imgSplitter.Left If sglPos < sglSplitLimit Then picSplitter.Left = sglSplitLimit ElseIf sglPos > Me.Width - sglSplitLimit Then picSplitter.Left = Me.Width - sglSplitLimit Else picSplitter.Left = sglPos End If End If End Sub Private Sub imgSplitter_MouseUp _ (Button As Integer, Shift As Integer, X As Single, Y As Single) SizeControls picSplitter.Left picSplitter.Visible = False mbMoving = False End Subツリービューとリストビューのサイズ変更処理
ツリービューとリストビューのサイズ変更をおこなうのは,Imageコントロール(imgSplitter)のMouseUpイベントプロシージャの一行目で呼び出されているSizeControlsサブプロシージャである(リスト2).このプロシージャではフォームのサイズとImageコントロール(imgSplitter)の位置によって,ツリービューとリストビューのサイズの変更をおこなう.
リスト2:ツリービューとリストビューのサイズ変更をするためのサブプロシージャ
Sub SizeControls(X As Single) On Error Resume Next '幅を設定します. If X < 1500 Then X = 1500 If X > (Me.Width - 1500) Then X = Me.Width - 1500 tvTreeView.Width = X imgSplitter.Left = X lvListView.Left = X + 40 lvListView.Width = Me.Width - (tvTreeView.Width + 140) lblTitle(0).Width = tvTreeView.Width lblTitle(1).Left = lvListView.Left + 20 lblTitle(1).Width = lvListView.Width - 40 '上辺を設定します. If tbToolBar.Visible Then tvTreeView.Top = tbToolBar.Height + picTitles.Height Else tvTreeView.Top = picTitles.Height End If lvListView.Top = tvTreeView.Top '高さを設定します. If sbStatusBar.Visible Then tvTreeView.Height = Me.ScaleHeight - _ (picTitles.Top + picTitles.Height + sbStatusBar.Height) Else tvTreeView.Height = Me.ScaleHeight - _ (picTitles.Top + picTitles.Height) End If lvListView.Height = tvTreeView.Height imgSplitter.Top = tvTreeView.Top imgSplitter.Height = tvTreeView.Height End Subイメージリストコントロールの配置
図16:ImageListコントロールを2つ配置
![]()
ツリービューやリストビューにアイコンを表示するためには,表示するアイコンのイメージをImageListコントロールに格納しておく必要がある.ImageListコントロールには複数のイメージをインデックス付きで格納することができるが,このコントロール自身はイメージを表示する機能を持たない.他のコントロールから要求されたときにイメージを提供するのである.プログラムコードからはイメージを配列として扱えることがメリットになる.
フォームにはすでにImageListコントロールがひとつ配置されているが,これはツールバー用のイメージリストなので,新しくImageListコントロールを2つ(ImageList1,ImageList2)追加する(図16).2つ追加するのは,大きいアイコン用と小さいアイコン用がひとつずつである.ひとつのImageListコントロールでは,たとえ元イメージのサイズが違っていても,他のコントロールに提供するときは同じサイズで提供する.そのため,表示方法によってアイコンのサイズを変更するためには,ImageListコントロールを2つ割り当てる必要がある.
イメージリストにアイコンを設定
図17:小さいアイコン用のImageListコントロール(ImageList1) 図18:大きいアイコン用のImageListコントロール(ImageList2) 図17・18は,ImageListコントロールのプロパティにイメージを設定した画面である.BMPファイルかアイコンファイルを取り込むことができる.左から順に1,2,3とインデックス番号が割り当てられる.「キー」として別名を割り当てることができるが,このサンプルでは割り当てずに番号で直接参照している.
図19:TreeViewコントロール(tvTreeView)のイメージリストプロパティにImageList1を指定 図20:ListViewコントロール(lvListView)のイメージリストプロパティにImageList1とImageList2を指定
イメージリストにイメージを割り当てたら,今度はTreeViewコントロールとListViewコントロールのプロパティに参照するイメージリストコントロールを関連づける必要がある.TreeViewコントロール(tvTreeView)にはImageList1,ListViewコントロール(lvListView)にはImageList1とImageList2を指定する(図19・20).ListViewコントロールは表示形式によってアイコンのサイズを変更するため2つのイメージリストを割り当てる必要があるが,TreeViewコントロールは常に小さいアイコンを表示するのでひとつしか指定することはできない.
ツリービューにイメージリストを指定すると,デザイン時にもアイコンが表示されるようになる(図21).
図21:イメージリストを指定するとデザイン時にアイコンが表示される
カスタムコードの記述
データの取得と表示
さて,ここからがカスタムコードを記述する作業である.
ツリービューに表示するデータは,フォームのLoadイベントプロシージャで一括して処理をおこなっている.フォームのサイズを指定する一連のコードをコメントアウトして,データベースにアクセスするコードを追加する(リスト3).
次の行は右側のリストビューを詳細表示させるよう指示している.しかし,この時点ではまだ,表示するデータは指定されていない.
lvListView.View = lvwReport
最上位ノードの作成
次の一連のコードは,ノードの設定をおこなっている.新しいノードを追加し,“取引先”と表示する.ノードの名前としてTagプロパティにデータベースの名前を設定している.Imageプロパティに設定している“1”という値は,図17のImageListコントロール(ImageList1)のプロパティに格納されている,左端のイメージを意味している.
Private mNode As Node | Set mNode = tvTreeView.Nodes.Add() mNode.Text = "取引先" mNode.Tag = dborder.Name mNode.Image = 1これらのコードによって作成されたのはツリービューの左上に表示される最上位のノードである(図22).表示(Textプロパティ)となっているが,プログラムが扱うIDとしてはTagプロパティが利用される.
図22:最上位のノード
![]()
子ノード(取引先名)の追加
以下のコードによって,「取引先」テーブル(Torihikisaki)のレコードセット(rsTorihikisaki)が作成される.
Dim rsTorihikisaki As Recordset Dim rsSyohin As Recordset Set rsTorihikisaki = dborder.OpenRecordset _ ("Torihikisaki", dbOpenSnapshot)さらに,以下のコードでは作成したレコードセットを元に,取引先のリストをノードに表示している.
Do Until rsTorihikisaki.EOF Set mNode = tvTreeView.Nodes.Add _ (1, tvwChild, "No" & _ rsTorihikisaki!torihiki_code,_ CStr(rsTorihikisaki!torihiki_mei), 1) mNode.Tag = "TORIHIKISAKI" | 中略 rsTorihikisaki.MoveNext Loopここでは,NodesコレクションのメソッドであるAddメソッドを利用して,最上位ノード(1)の子ノードとして新しいノードを追加する.固有のキーとして「取引先コード」(torihiki_code)を指定し,表示するテキストは「取引先名」(toruhiki_mei)である.アイコンには図16の左端のイメージが使用される.この処理をレコードを移動しながら「取引先」の数だけ繰り返して実行する.
これらの記述により,図23のように取引先を表示するノード(TORIHIKISAKI)が作成される.最上位ノードのアイコンが開いたものになっているのはTreeViewコントロール(tvTreeView)のExpandイベントプロシージャによって処理されている.
図23:最上位ノードの子ノードとして作成された「取引先」ノード
![]()
孫ノード(商品名)の追加
以下のコードは前述のループにネストしたループである.
Set rsSyohin = dborder.OpenRecordset _ ("select * from Syohin Where torihiki_code = " _ & rsTorihikisaki!torihiki_code) Dim NodeIndex As Integer NodeIndex = mNode.Index Do Until rsSyohin.EOF Set mNode = tvTreeView.Nodes.Add(NodeIndex, tvwChild) mNode.Tag = "SYOHIN" mNode.Key = rsSyohin!furigana mNode.Text = rsSyohin!syohin_mei mNode.Image = 3 rsSyohin.MoveNext Loop各取引先を表示するたびに,その取引先が扱う商品を抽出し,「取引先」ノード(TORIHIKISAKI)の子ノードとして作成する.ここでは固有のIDを保持するKeyプロパティや表示のためのTextプロパティを,Addメソッドの引数としてではなく,プロパティ値に代入することで設定している.
ノードのImageプロパティの値が3というのは,図17の左から3番目のイメージをアイコンとして設定することを意味している(図24).図24:取引先名が表示されているノードの子レコードとして「商品」ノードを作成
![]()
コードによるノードの展開
各ノードの作成が終わったら,最上位のノードを展開して取引先名を表示し,フォームのLoadイベントプロシージャを終了する.
リスト3:ツリービューにデータを表示
tvTreeView.Nodes(1).Expanded = True Private IListItem As ListItem Private dborder As Database Private mNode As Node Private Sub Form_Load() '-コメントにする-- 'Me.Left = GetSetting(App.Title, "Settings", "MainLeft", 1000) 'Me.Top = GetSetting(App.Title, "Settings", "MainTop", 1000) 'Me.Width = GetSetting(App.Title, "Settings", "MainWidth", 6500) 'Me.Height = GetSetting(App.Title, "Settings", "MainHeight", 6500) '------------------- lvListView.View = lvwReport Set dborder = DBEngine.OpenDatabase("order.mdb") tvTreeView.Sorted = True Set mNode = tvTreeView.Nodes.Add() mNode.Text = "取引先" mNode.Tag = dborder.Name mNode.Image = 1 Dim rsTorihikisaki As Recordset Dim rsSyohin As Recordset Set rsTorihikisaki = _ dborder.OpenRecordset("Torihikisaki", dbOpenSnapshot) Do Until rsTorihikisaki.EOF Set mNode = tvTreeView.Nodes.Add _ (1, tvwChild, "No" & rsTorihikisaki!torihiki_code, _ CStr(rsTorihikisaki!torihiki_mei), 1) mNode.Tag = "TORIHIKISAKI" Set rsSyohin = dborder.OpenRecordset _ ("select * from Syohin Where torihiki_code = " _ & rsTorihikisaki!torihiki_code) Dim NodeIndex As Integer NodeIndex = mNode.Index Do Until rsSyohin.EOF Set mNode = tvTreeView.Nodes.Add(NodeIndex, tvwChild) mNode.Tag = "SYOHIN" mNode.Key = rsSyohin!furigana mNode.Text = rsSyohin!syohin_mei mNode.Image = 3 rsSyohin.MoveNext Loop rsTorihikisaki.MoveNext ' 次の Publishers レコードに移動します. Loop tvTreeView.Nodes(1).Expanded = True End Subノード展開時のアイコン変更
図25:子ノードを表示するときには
「開いたフォルダ」アイコンに変更
![]()
ノードがクリックされて閉じられたり展開されたりした場合には,ノードのアイコンを変更する必要がある(図25).
なぜか,これらの処理は手動でおこなう必要がある.NodeオブジェクトのCollapseイベントとExpandイベントに記述したプロシージャが,これらのアイコンの変更を実現する.たとえば,Collapseイベントに記述された次のコードは,最上位ノードや「顧客名」ノードが閉じられたときに「閉じたフォルダ」アイコンを使用することを指定している.
If Node.Tag = "TORIHIKISAKI" Or Node.Index = 1 _ Then Node.Image = 1同様にExpandイベントプロシージャに記述された次のコードによって,ノードが展開したときに「開いたフォルダ」アイコンが使用される.
リスト4:ノードが展開されたり閉じられたときの処理
If Node.Tag = "TORIHIKISAKI" Or Node.Index = 1 Then Node.Image = 2 '"open" Node.Sorted = True End If Private Sub tvTreeView_Collapse _ (ByVal Node As ComctlLib.Node) If Node.Tag = "TORIHIKISAKI" Or Node.Index = 1 _ Then Node.Image = 1 '"closed" End Sub Private Sub tvTreeView_Expand _ (ByVal Node As ComctlLib.Node) If Node.Tag = "TORIHIKISAKI" Or Node.Index = 1 Then Node.Image = 2 '"open" Node.Sorted = True End If End Subリストビューへのアイテム登録
ノードがクリックされたときに,右側のリストビューにアイテムを表示するのがエクスプローラスタイルのアーキテクチャである.それらの処理はツリービューのNodeClickイベントプロシージャによりおこなわれている.このイベントは,ツリービュー内のノードがクリックしたときに呼び出される.
次のIf文で記述されているように,これらの処理はクリックしたノードが「取引先名」(TORIHIKISAKI)の場合だけ実行される.
If Node.Tag = "TORIHIKISAKI" Then本来,最上位のノードがクリックされた場合はリストビューに取引先を表示するべきなのだが,今回はサンプルなので商品を表示するだけにとどめる.
詳細表示時のヘッダ作成
次のコードでは,リストビューのヘッダを作成している(図26).これらの変更はリストビューのViewプロパティを詳細(lvwReport)に設定した場合にだけ表示される.
lvListView.ColumnHeaders.Clear lvListView.ColumnHeaders.Add , , "商品名", 2000 lvListView.ColumnHeaders.Add , , "フリガナ" lvListView.ColumnHeaders.Add , , "価格", 350 lvListView.ColumnHeaders.Add , , "在庫"図26:項目のヘッダを作成
![]()
リストビューのクリア
リストビューに表示されているアイテムをクリアするには,次のようにListItemsコレクションのClearメソッドを使用する.
lvListView.ListItems.Clearデータベースの内容をリストビューに表示
NodeオブジェクトのKeyプロパティの値を検索条件にして検索を実行し,該当する取引先の扱う商品のレコードセットを作成する.
Set rsISyohin = dborder.OpenRecordset _ ("select * from Syohin where torihiki_code = " _ & Val(Mid(Node.Key, 3)))ノードのアイコンを「開いたフォルダ」アイコンに変更し,ノードが展開した状態であることを視認できるようにする.
mNode.Image = 2次のループ内の処理によって,レコードセットに含まれる商品をリストビューに表示する.
Dim itm As ListItem Do Until rsISyohin.EOF Set itm = lvListView.ListItems.Add(, , CStr(rsISyohin!syohin_mei), 1, 3) itm.SubItems(1) = rsISyohin!furigana itm.SubItems(2) = CStr(rsISyohin!kouri_kakaku) itm.SubItems(3) = CStr(rsISyohin!zaiko) rsISyohin.MoveNext LoopこのListItemsコレクションのAddメソッドは,リストビューにアイテムを追加する機能を持つ.このケースでは「商品名」項目(syohin_mei)の値をテキストとして表示する.使用するアイコンは標準アイコンの場合は1(図18の1番目)であり,小さいアイコンの場合3(図1の左から3番目)を使用する.
SubItemsプロパティで追加しているのは,詳細表示時に表示するデータである.それ以外の場合にはリストビューにこれらの値は表示されない.リスト5:取引先名が表示されたノード(TORIHIKISAKI)がクリックされたとき,リストビューに商品のアイテムを表示
Private Sub tvTreeView_NodeClick(ByVal Node As ComctlLib.Node) If Node.Tag = "TORIHIKISAKI" Then lvListView.ColumnHeaders.Clear lvListView.ColumnHeaders.Add , , "商品名", 2000 lvListView.ColumnHeaders.Add , , "フリガナ" lvListView.ColumnHeaders.Add , , "価格", 350 lvListView.ColumnHeaders.Add , , "在庫" lvListView.ListItems.Clear Dim rsISyohin As Recordset Set rsISyohin = dborder.OpenRecordset _ ("select * from Syohin where torihiki_code = " _ & Val(Mid(Node.Key, 3))) mNode.Image = 2 '"open" Dim itm As ListItem Do Until rsISyohin.EOF Set itm = lvListView.ListItems.Add _ (, , CStr(rsISyohin!syohin_mei), 1, 3) itm.SubItems(1) = rsISyohin!furigana itm.SubItems(2) = CStr(rsISyohin!kouri_kakaku) itm.SubItems(3) = CStr(rsISyohin!zaiko) rsISyohin.MoveNext Loop End If End Sub
まとめ エクスプローラスタイルのユーザーインターフェイスアーキテクチャは,データベースのフロントエンドとしても親テーブルとの関連がわかりやすいなどのメリットを持つ.しかし,Visual Basic 5.0に付属してくるツリービューとリストビューの組み合わせでは,アプリケーションウィザードを使ったとしても猥雑なコーディングをする必要があり,日常的に使う気にはなれない.
このサンプルではフォームのオープン時にすべてのデータをロードしているが,この方法だとデータが多い場合にはフォームのロード時間が著しく遅くなる.これはVisual Basic 5.0のサンプルについてくるDataTreeアプリケーションを実行してみるとよくわかるはすである.
実用的なシステムをつくるには,ノードをクリックした瞬間に子ノードに表示するアイテムを抽出するクエリーを実行するべきである.しかし,この方法にも問題がある.エクスプローラスタイルのインターフェイスでは,ノードが子ノードを持つ場合には左側の四角形の中に+記号が表示される.動的に子ノードを作成するようにすると,この+記号が表示されない.この問題を回避するにはダミーで子ノードを作成しておいて,展開時に実データを追加する方法がよい.この方法は実際に有効だと思うが,実装にはやはり,余分なコードを記述する必要が生まれる.
日本の優秀なActiveXコントロールベンダーに,データ連結が可能なツリービューコントロールの開発を望みたい.
Visual Basic開発者の手引き | Visual Basicコースホームページ
int21 ホームページ | PCDN ホームページ
![]()