酒井 法雄 SAKAI,Norio
norio@int21.co.jp
| 書くことがない!? |
|---|
「久々の登場の酒井法雄です.みなさん,お元気だったでしょうか」
と,思わず書いてしまった.Visual Basic Magazine創刊号から,主として特集を連載(?)してきた私だが,ここ数ヶ月お休みさせていただいた(といっても本業であるソフトウェア開発はしていた).それでも,ちゃんと特集記事はあったし,むしろ本誌は厚くなったほどである.
「これならまだしばらく休んでもいいかな」とも思ったのだが,読者の皆様からは,「最近,酒井さんの記事がありませんが,どうしたのですか.さびしいです」といったハガキが届いたという.本当にありがたいことである.私のような者を気にかけてくださる方もいらっしゃるのかと胸を熱くしつつ,久々の登場とあいなった(とはいえ,相変わらず遅い原稿で,編集部の皆様にはご迷惑をおかけっぱなしである).
思えば,私がしばらく執筆しなくなったのは,これが初めてではない.Visual Basic Magazineが創刊される前,私は翔泳社のDr. Dobb's Journal JapanにVisual Basicの連載を長いあいだ執筆していた.そのときにも「もう書くことがない」という理由で,連載を中止したことがあった.当時の状況としては,長らく続いたVisual Basic 2.0を活用するためのほとんどあらゆることを書きまくり,日本では発売されなかったVisual Basic 3.0についても書きまくり,本当に書くことがなくなってしまったと感じたのである.そして,Visual Basic 4.0の発表が間近であり,いまさら古いことを書き連ねても意味がないと感じたのであった.
今回のお休みの原因は,前回と同じだったのである.もちろん,細かい部分で私が書いていないことはたくさんあったが,Visual Basic自体の特徴を生かすことや,DLLが煩雑に変わる開発環境を考えると,書かなかったことのほとんどは「Visual Basicらしくないもの」や「怪しい」ことであり,書く気になれなかったのである.またしても「書きつくした」と感じたのだ.もちろん,私が似たようなことを繰り返し書くよりも,本誌には優れた記事を書くことができるライターが増えてきたから,そういう方にお任せしたほうがよいのではないかとも感じたのである.
そして,そういうウマい時期に,MicrosoftはVisual Basic 6.0を発表してくれた.
また,復帰しなくてはならない.Visual Basic 6.0英語版は,9月2日にリリース予定である.しかし,日本語版のVisual Basic 6.0の詳細について述べるには,まだちょっとだけ時期が早いようだ.
| Windows Scripting Hostとは? |
|---|
そこで今回は,Visual Basic 6.0に搭載されるという,とっても便利なオブジェクトについて,ちょっと先取りして紹介することにしよう.大丈夫,Visual Basic 5.0からでもちゃんと使えるのである.というのも,このオブジェクトはすでにいろいろな形で配布されているのである.早い話が,そのオブジェクトが標準でVisual Basic 6.0のライブラリとして提供されることになったというワケである.
そのオブジェクトとは,File System Objectと呼ばれるものである.これは,WSHとよばれるものに含まれている.WSHは,Option PackにIIS 4.0のデバッグや拡張機能用として搭載されているほか,Windows 98にも標準でインストールされる.また,単体としてhttp://www.asia.microsoft.com/Japan/Developer/Scripting/からダウンロードすることもできる.このへんにサンプルプログラムなどもあるから,いっしょにダウンロードしておこう.
さて,ではWSHとは一体何なのだろうか?
誤解を覚悟でカンタンに言えば,これはMS-DOSのころにさんざんお世話になったBATファイルの拡張版である.つまりスクリプトを書いてカンタンなプログラムを動かせるというものだ.
BATファイルはcommand.comやcmd.exeといったコマンドインタープリタをベースに動くものだから,大したことはできない.だが,標準入出力をうまく使うような外部にあるコマンドを呼び出してやれば,かなりいろいろなことができるようになる.しかし,GUIの時代になっては,BATではどうにもならないことが出てきた.そこで,Windowsのもつ機能をスクリプトから呼び出せるようにした仕組みがWSHなのである.しかも,その言語仕様はVBScriptまたはJscriptである.
ここでピーンときたアナタは偉い.そう,実際には,ここで使われているのも例によってCOMのアーキテクチャ,つまりActiveX Scripting Engineなのである.ActiveX Scripting Engineは,Microsoftがインターネット恐怖症に陥っていた2年ほど前にひねり出されたもので,Netscape陣営のJava Scriptに対抗するためのIE用スクリプトエンジンであった.しかも,特定の言語仕様に依存しないものであり,あるのはあくまでも言語モジュールへのインターフェイスである.Microsoftは,そこにVBScriptとJava Script(最近ではイロイロあってJScriptとよんでいるようだ)の言語エンジンが搭載されている.したがって,このインターフェイスに沿ったエンジンを作れば,どんな言語でも動かすことができてしまうわけである.
しかし,せっかくこんな便利な機能を作ったものの,結局のところインターネットでVBScriptが流行ったなんて聞いたこともない.だが,このアーキテクチャ自体はとってもオモシロイ.そこで,私の会社(有限会社イント・ツーワン)では,コンソール周りを拡張すべくこのテクノロジーを作ったシステムを作ってしまった.題して,ASEXECである.
このコマンドは,ActiveX Scripting Engineを呼び出し,VBScriptあるいはJScriptで記述されたスクリプトをコマンドラインから実行可能であり,実行結果もすべてコンソールに出力できる.しかも,ちゃんとコンソール用の制御オブジェクトまでも完備していた.WindowsのようなGUIしか考えていないお間抜けOSでは,リモート管理をマトモにすることはできない.そこで,ログインシェルとASEXECを組み合わせて,なんでもできるようにしちゃおうという企画だったのである.
もちろん,皆様ご存じのように,GUIなんてものは初心者騙しに過ぎず,効率よい管理やオペレーションは,コマンドラインからやったほうが速いに決まっている.UNIXでtcshやbashを使っているときの,手が疲れないこと,オペレーションの効率がよいことといったら,Windowsなど比較すべくもない.本当にviを使っているときは心が安らぐ.で,そういうことができるようにしちゃおうと思ったのである.しかし,せっかく作ったものの,これを売り物にするでもなく,とりあえずはMS-DOSライクなしょうもないテキストベースのテニスゲームみたいなもんでも作って遊ぶ程度であった.
Windowsの弱点を一番よく知っているのは,もちろんMicrosoftである.「これからはGUIだっ」とか言っていたようなお偉いさんはどうだか知らないが,少なくともマトモな技術者だったら,Windowsの管理なんてやりたくないと社内の人でも思ったに違いない.そこで,そういったコトをなんとかしようというので,WSHができたのである.
はっきり言って,これは弊社製品をMicrosoftがマネっこしたに違いない.と思ったのだが,よくよく調べていくと,非公開ながらWSHのほうがちょっとだけ早くできていたらしい.ちっ.
だが,コンソールオブジェクトまでサポートしているから,ウチのASEXECのほうが管理ツールなどをマトモに作れるに違いない.などと負け惜しみを言っていても始まらないので,続きを行こう.
| WSHの使い方の例 |
|---|
図1:WSHスクリプトの実行画面例 (16KB) |
さて,上記URLからWSH10.EXEをダウンロードしたら,エクスプローラなどからダブルクリックする.そうすれば,あっけなくインストールが終了する.ついでにサンプルプログラムも同様にインストールしよう.
ここにはいくつかのファイルがあるが,拡張子が「.VBS」がVBScriptのもの,「.js」がJScriptのサンプルである.すでにWSHインストール時にファイルの関連付けができているので,そのままダブルクリックして実行することもできる.しかし,本来は,コマンドラインからcscript.exeを実行し,引数としてスクリプトファイルを指定するというのが本当だ.
例 >cscript network.vbs
また,GUI版としてwscript.exeも用意されている.
これらのEXEは内部的には,wshom.ocxをコールしており,このActiveXコントロールの内部には,いろいろと役に立つ便利なオブジェクトが含まれているのである.また,同時にインストールされるscrrun.dllにも,主としてファイル操作をするための便利なオブジェクトが含まれている.つまり,WSHは単なるActiveX Scripting Engineを使うためのフロントエンドではなく,そこに同時に用意された便利なメソッドなどを使えるシステムなのである.
ご存じの通り,VBScriptはいわゆるVBAのサブセットであり,外部にあるオブジェクトを操作することができる.ExcelでもAccessでも,Visual Basicで作ったコンポーネントでもOKだ.しかし,BAT処理みたいなことに役立つ関数がないことには意味がないのである.そこで,こういったオブジェクトが入っているというワケである.
cscript.exeおよびwscript.exeについての詳細は,次のURLを参照していただきたい.
http://www.asia.microsoft.com/Japan/Developer/Scripting/default.htm?/Japan/Developer/ Scripting/windowshost/docs/reference/whitepaper.htm
もっとも,VBScriptはVisual Basicなどと比較して効率的なコーディング環境が調っているわけではないので,Visual Basic 5.0のようなクイックヒントやデバッグ環境などに慣れた身にとっては,こんなことやってられないと思うのであった.
| WSHのオブジェクトモデル |
|---|
では,実際にはどのように便利な機能があるのだろうか.
まずは,wshom.ocxとscrrun.dllをクイックビューアで見てると,それぞれ図のように大量なWindows APIがインポートされていることが分かる.つまり,これらのAPIを使った処理が含まれているというワケである(図2).
ファイル関係やシェルAPI,ネットワークAPIなどが含まれており,いやがおうにも期待に胸は高鳴る.
図2:wshom.ocxとscrrun.dllをクイックビューアで見る![]() |
![]() |
実際にこれらのオブジェクトの内容を知るには,次のような方法で資料を得ることができる.
wshom.ocxに含まれるオブジェクト
wshom.ocxには,ShellとNetworkの2つのトップレベルオブジェクトが含まれている.これらのオブジェクトの詳細は,次のURLを参照していただきたい.
http://www.asia.microsoft.com/Japan/Developer/scripting/default.htm?/Japan/Developer/ Scripting/windowshost/docs/reference/objectmodel.htm
なお,Visual Basicからwshom.ocx(Windows Scripting Host Object Model(Ver 1.0)
)を参照設定しておけば,オブジェクトブラウザからその構造やメンバーを知ることができる.オブジェクト名は,IWshRuntimeLibraryがトップレベルである.
Shellオブジェクトには,レジストリ操作やショートカット作成などShell API周りの関数が含まれている.Networkオブジェクトには,ネットワーク周りの操作ができる関数が含まれている.従来であればVisual BasicでもWindows APIの助けを借りなければならないものばかりである.
scrrun.dllに含まれるオブジェクト
このオブジェクトについては,次のURLにある「VBScriptランゲージリファレンス」から検索することができる.
http://www.asia.microsoft.com/Japan/Developer/Scripting/default.htm?/Japan/Developer/ Scripting/VBScript/vbslang/vbstoc.htm
図3:Windows Scripting Hostのオブジェクトモデル (25KB) |
これと同じ内容のものはアーカイブされておらずダウンロードできないので,このURLから調べるしかない.
VB5の参照設定でMicrosoft Scripting Runtimeを選んでおくと,F2キーでオブジェクトブラウザを起動しオブジェクト構造を知ることができる.ただし,現状のWSHとは定数値などが異なっているし,実際に動かしてみると動かないものもある.VB6付属のWSHだと動くのかもしれない.
実際にこのオブジェクトに含まれるのは,FileSystemObjectである.ここにあるものは,ドライブ,フォルダ,ファイルに関する操作や情報取得の関数のほか,連想配列やテキストストリームなどの操作が含まれている.やはり,従来のVisual Basic単体ではできない機能が多く実現されている.
実は,このFileSystemObjectこそが,Visual Basic 6.0に標準で搭載されるものなのである.ただし,細かい仕様などが同じであるかどうかは,まだ確認できていない.
これらのオブジェクトの階層およびメンバーを図3に示す.
いずれのオブジェクトも,その下の階層で使われているオブジェクトがあることに注意してほしい.DAOやRDOなどと同様に,オブジェクトの階層モデルを理解していないと,ちょっと使いにくい.たとえば,FileSystemObjectのOpenTextFileメソッドの戻り値は,TextStreamオブジェクトであり,そのReadLineメソッドを使って1行読み込むといった処理をしてゆくことになる.
| 便利なオブジェクトをVisual Basicから使う |
|---|
このように,これらのオブジェクトがもっている機能は,標準のVisual Basicでは実現できないものが多く,同じようなことを実現するためには,従来であればWindows API使いまくりになってしまった.ところが,こんなオブジェクトがタダで提供されているのである.これを使わない手はないだろう.
しかも,VBScriptなどと違って,クイックヒントが装備されたエディタや,高機能なデバッガといった統合開発環境をもつVisual Basicから使えば,もっと効率的にプログラミングができる.逆に,Visual Basic環境を使って書いたソースをちょっとだけ書き直し,スクリプトとして保存して,cscript.exeから実行させるというワザさえあるのだ.これは便利そうである.
次に,それぞれのモジュールごとにVisual Basicから使うための方法を述べよう.
wshom.ocx
このモジュールを使うには,いきなりCreateObjectでインスタンシングしてしまえばよい.
Dim WSHShell As Object
Set WSHShell = CreateObject("WScript.Shell")
Set WSHnetwork = CreateObject("WScript.Network")
|
ただし,前に述べたようにCreateObjectできるのは,ShellとNetworkの2つのオブジェクトだけであることに注意してほしい. もうひとつの方法は,先に述べたように「Windows Scripting Host Object Model (Ver 1.0)」を参照設定する方法だ.こうすればオブジェクト構造も見られ,エディタ上でヒントを出すことができる(図4).
Dim WSHnetwork As New IWshShell_Class
Dim WSHnetwork As New IWshNetwork_Class
このほうが使いやすいが,オブジェクト名が気持ち悪い.
' 気持ち悪いけどクイックヒントが出るので便利
Private Sub cmdGet_Click()
Dim oNet As New IWshNetwork_Class
Dim oCol As IWshCollection_Class
Dim s As Variant
Set oCol = oNet.EnumPrinterConnections
Debug.Print oCol.Count
For Each s In oCol
lstPrt.AddItem s
Next
End Sub
' 気持ちよいけど不便
Private Sub cmdGet2_Click()
Dim oNet As Object
Dim oCol As Object
Dim s As Variant
Set oNet = CreateObject("WScript.Network")
Set oCol = oNet.EnumPrinterConnections
Debug.Print oCol.Count
For Each s In oCol
lstPrt.AddItem s
Next
End Sub
|
図4:WSHのオブジェクト構造を閲覧する (17KB) |
scrrun.dll
「Microsoft Scripting Runtime」を参照設定すればよい(図5).
オブジェクトブラウザでみると,「Scripting」にあるオブジェクトの内容を知ることができる(図6)
図5:「Microsoft Scripting Runtime」を参照設定する (10KB) |
図6:「Scripting」にあるオブジェクトを閲覧する (14KB) |
ここまで分かれば,Visual Basicプログラミングでのオブジェクト階層に慣れたあなたなら,もうスグにでも使うことができるだろう.実際にどのようなことができるかという例として,いくつか紹介していくことにしよう.
| ShellオブジェクトとNetworkオブジェクトの使用例 |
|---|
まずは,ShellオブジェクトとNetworkオブジェクトである.これはちょうどMicrosoftのサイトにWSH用のサンプルがあったので,これをVisual Basicで動くように書き直してみたものなので,著作権はMicrosoftにある.このサンプルは,もともと別れていた4つのサンプルをひとつのフォームにまとめたものである.
図7:ショートカット作成のサンプル![]() |
図8:ネットワーク情報を見るサンプル![]() |
図9:レジストリキーを操作するサンプル![]() |
ソースコードをリスト1に示す.大して難しいことはやっていないので,詳しくは,階層図を見ながら,ソースコードを眺めてほしい.しかしながら,このソースコードはきたない...
| FileSystemObjectの使用例1 |
|---|
次に,FileSystemObjectを使ってみた.このオブジェクトには大きく分けると,ドライブ・フォルダ・ファイル情報に関するものと,連想配列,テキストストリームの3つの機能に分けられる.
ここでは,最初のものについて,ひと通りの機能を使ってみた.次にそれぞれありがちな手法をプロシージャごとに紹介しよう.
まずは,最初にFileSystemObjectをインスタンシングしておく.
Dim oFs As New FileSystemObject
ドライブ一覧の取得
ひとつのドライブはDriveオブジェクトに,それらのコレクションとしてのドライブ全部はDrivesコレクションである.次のコードは,すでにインスタンシングされているFileSystemObjectから,Drivesコレクションを作成し,お決まりのコレクションからオブジェクトをひとつずつ取得するものである.
リストボックスには,ドライブ文字列Letterプロパティ,IsReadyプロパティの内容によって適切な文字列,そしてファイルシステムFileSystemプロパティを表示している.
Private Sub DispDrives()
Dim oDrive As Drive
Dim oDrives As Drives
Dim s As String
lstDrives.Clear
Set oDrives = oFs.Drives
On Error Resume Next
For Each oDrive In oDrives
With oDrive
s = .DriveLetter & vbTab
s = s & IIf(.IsReady, "Ready", "Not Ready") & vbTab
s = s & .FileSystem
lstDrives.AddItem s
End With
Next
End Sub
ドライブの詳細情報取得
ドライブ一覧のリストボックスから特定のドライブが選ばれたら,その詳細を表示し,さらにそのドライブ内のフォルダ一覧を取得する.
ここでは,それぞれを別のプロシージャとし,引数としてそれぞれドライブ文字列とルートフォルダのFolderオブジェクトを渡している.
Private Sub lstDrives_Click()
DispDriveDetails Left(lstDrives.Text, 1)
lstFolders.Clear
On Error Resume Next
DispFolders oFs.Drives.Item(Left(lstDrives, 1)).RootFolder
End Sub
ドライブレターをもとにして,Drivesコレクションの連想配列で選ばれたDriveオブジェクトを得る.そのあとは単純にDriveオブジェクトのプロパティを表示している.エラートラップは,準備できていないドライブなどの場合のエラーを防ぐためのものである.
Private Sub DispDriveDetails(DriveLetter As String)
Dim oDrive As Drive
lstDetail.Clear
Set oDrive = oFs.Drives.Item(DriveLetter)
On Error Resume Next
With oDrive
lstDetail.AddItem "DriveLetter:" & .DriveLetter
lstDetail.AddItem "RootFolder:" & .RootFolder
lstDetail.AddItem "Path:" & .Path
lstDetail.AddItem "VolumeName:" & .VolumeName
lstDetail.AddItem "DriveType:" & .DriveType
lstDetail.AddItem "FileSystem:" & .FileSystem
lstDetail.AddItem "IsReady:" & .IsReady
lstDetail.AddItem "SerialNumber:" & .SerialNumber
lstDetail.AddItem "ShareName:" & .ShareName
lstDetail.AddItem "TotalSize:" & .TotalSize
lstDetail.AddItem "FreeSpace:" & .FreeSpace
lstDetail.AddItem "AvailableSpace:" & .AvailableSpace
End With
End Sub
フォルダの一覧取得
引数であるフォルダを示すFolderオブジェクトから,フルパス名Pathプロパティを得て,リストボックスに追加している.その後,引数フォルダ下のサブフォルダSubFoldersコレクションから,その下にあるフォルダ一覧を得ている.
ここで注意してほしいのは,この関数DispFoldersはリカーシブ(再帰)して呼ばれていることだ.最初の引数oFolderは「C:\」のようなルートフォルダである.つまり,ルートフォルダ以下にあるフォルダをすべて得て,それぞれのフォルダについて再び自分自身を呼び出している.こうすれば,さらに下のフォルダまですべてをリストボックスに追加できるというわけだ.
従来のVisual BasicのDir関数でも同様のことができたが,ここまできれいに書くことはできなかった.きれいに書くことができるということは,プログラマにとって,とても嬉しいことである.
Private Sub DispFolders(oFolder As Folder)
Dim oSubFolder As Folder
On Error GoTo 0
lstFolders.AddItem oFolder.Path
For Each oSubFolder In oFolder.SubFolders
DispFolders oSubFolder
Next
End Sub
フォルダの詳細情報取得
フォルダ一覧のリストボックスから特定のフォルダが選ばれると,そのフォルダについての詳細情報を表示し,さらにそのフォルダに含まれるファイルの一覧を表示する.
先ほどと同様,それぞれはプロシージャとして作成されており,引数はFolder型およびFilesコレクションになっている.
Private Sub lstFolders_Click()
DispFolderDetails oFs.GetFolder(lstFolders.Text)
lstFiles.Clear
' On Error Resume Next
DispFiles oFs.GetFolder(lstFolders.Text).Files
End Sub
引数であるFolderオブジェクトについて,プロパティを表示している.どんなプロパティがあるかチェックしておこう.
Private Sub DispFolderDetails(oFolder As Folder)
lstDetail.Clear
On Error Resume Next
With oFolder
lstDetail.AddItem "ShortPath:" & .ShortPath
lstDetail.AddItem "Attributes:" & .Attributes
lstDetail.AddItem "DateCreated:" & .DateCreated
lstDetail.AddItem "DateLastAccessed:" & .DateLastAccessed
lstDetail.AddItem "DateLastModified:" & .DateLastModified
lstDetail.AddItem "Drive:" & .Drive
'lstDetail.AddItem .Files
lstDetail.AddItem "IsRootFolder:" & .IsRootFolder
lstDetail.AddItem "Name:" & .Name
lstDetail.AddItem "ParentFolder:" & .ParentFolder
lstDetail.AddItem "Path:" & .Path
lstDetail.AddItem "ShortName:" & .ShortName
lstDetail.AddItem "ShortPath:" & .ShortPath
lstDetail.AddItem "Size:" & .Size
'lstDetail.AddItem .SubFolders
lstDetail.AddItem "Type:" & .Type
'.Copy dst, overwriteflag
'.CreateTextFile filename, overwriteflag, unicodeflag
'.Delete forceflag
'.Move destfile
End With
End Sub
ファイルの一覧取得
ファイルの一覧は,引数であるFilesコレクションをもとにして,リストボックスに追加している.
Private Sub DispFiles(oFiles As Files)
Dim oFile As File
For Each oFile In oFiles
lstFiles.AddItem oFile.Path
Next
End Sub
ファイルの詳細情報取得
ファイルの詳細表示は,やはりプロパティを表示しているのみ.どんなプロパティがあるかチェックしておこう.
コメントにあるように,ファイルをコピー,削除,移動をするメソッドも用意されている.
Private Sub DispFileDetails(oFile As File)
lstDetail.Clear
With oFile
lstDetail.AddItem "Attributes:" & .Attributes
lstDetail.AddItem "DateCreated:" & .DateCreated
lstDetail.AddItem "DateLastAccessed:" & .DateLastAccessed
lstDetail.AddItem "DateLastModified:" & .DateLastModified
lstDetail.AddItem "Drive:" & .Drive
lstDetail.AddItem "Name:" & .Name
lstDetail.AddItem "ParentFolder:" & .ParentFolder
lstDetail.AddItem "Path:" & .Path
lstDetail.AddItem "ShortName:" & .ShortName
lstDetail.AddItem "ShortPath:" & .ShortPath
lstDetail.AddItem "Size:" & .Size
lstDetail.AddItem "Type:" & .Type
'.Copy dest, overwriteflag
'.Delete forceflag
'.Move dest
'.OpenAsTextStream IOMode, formatTristate
End With
End Sub
ファイルの作成・アクセス・修正日時の取得
|
ファイルおよびフォルダには,DateCreated,DateLastAccessed,DateLastModifiedの各プロパティがあり,それぞれファイルの作成日時,最後にアクセスされた日時,最後に修正された日時を知ることができる. したがって,特定フォルダ下にあるあまりアクセスされていないファイルを探し出して消すといったことができる.ここでは,指定されたドライブにあるこうしたファイルを探し出すコードを作成してみた(リスト2・図10). ただし,フォルダについて,これらのプロパティを正常に取得することはできなかった.もしかすると私のコーディングが悪いのかもしれないが,ほかにもいくつか正常に動作しないものがあった.これらがVisual Basic 6.0で改善されていることを望みたい. |
図10:指定されたドライブにあるファイルを探すサンプル (20KB) |
| FileSystemObjectの使用例2 |
|---|
最後は,連想配列とテキストストリームを使ってみよう.
連想配列は,すでにコレクションなどでおなじみのように,キーとなる文字列などから対応するアイテムを得るというものだ.配列などと違って,数値ではなく文字列から検索できることがウリである.
これは,それこそCollectionオブジェクトをうまく使えば実現することもできるが,FileSystemObjectのDictionaryオブジェクトを使えば,もっとカンタンに使いこなすことができる.
また,テキストファイルの読み書きをするTextStreamオブジェクトもある.そこで,ここではDictionaryオブジェクトに含まれた内容をTextStreamオブジェクトを使ってファイルに保存したり,読み込んだりするプログラムを作ってみた.
まずは,Dictionaryオブジェクトをインスタンシングしておく.
Const DICFILE = "DicFile.Txt" Dim oDic As New Dictionary
連想配列への追加
DictionaryオブジェクトoDicは,すでに汎用コレクションそのものである.追加は,Addメソッドを使い,引数としてキーと対応するアイテムを渡せばよい.
ここでは,テキストボックスに入力されたものを追加している.
Private Sub cmdAdd_Click()
On Error Resume Next
oDic.Add txtKey.Text, txtItem.Text
If Err Then
MsgBox Error$, vbCritical, "Error"
Else
DispAllKeys
End If
End Sub
いちいち文字列を入れるのも面倒なので,Form_Load時に月を表わす短い文字列,たとえば「Jan」をキー,長い文字列「January」をアイテムとしてDictionaryに追加するように,コードを書いてみた.
Private Sub Form_Load()
Dim i As Integer
Dim sShortName As String
Dim sLongName As String
oDic.Add "Zero", "ZoroZero"
For i = 1 To 12
sShortName = Format(DateSerial(0, i, 1), "mmm")
sLongName = Format(DateSerial(0, i, 1), "mmmm")
oDic.Add sShortName, sLongName
Next i
DispAllKeys
End Sub
キーおよびアイテムの変更
キーの内容を変更するには,Keyメソッドにキーを引数として指定し,代入してやればよい.アイテムについても同様にItemメソッドを使えばよい.
Private Sub cmdEdit_Click()
' Check Selected
If lstKey.ListIndex = -1 Then
MsgBox "Select one of Key from List!", vbCritical
Exit Sub
End If
' Item
oDic.Item(lstKey.Text) = txtItem.Text
' Key
oDic.Key(lstKey.Text) = txtKey.Text
DispAllKeys
End Sub
キーの存在を確認
指定されたキーがあるかどうかは,Existsメソッドを使って調べることができる.下のコードでは,リストボックスの選択も変更しているので長い処理になっているが,基本的には1行で済む簡潔なものである.
Private Sub cmdExist_Click()
Dim i As Integer
If oDic.Exists(txtKey.Text) Then
txtItem.Text = oDic.Item(txtKey.Text)
' Disp Listbox Item
For i = 0 To lstKey.ListCount - 1
If lstKey.List(i) = txtKey.Text Then
lstKey.ListIndex = i
End If
Next i
Else
MsgBox "Could not found!!", vbCritical
End If
End Sub
指定したキーを削除
キーの削除は,Removeメソッドの引数に,削除するキーを指定してやればよい.
Private Sub cmdRemove_Click()
' Check Selected
If lstKey.ListIndex = -1 Then
MsgBox "Select one of Key from List!", vbCritical
Exit Sub
End If
oDic.Remove lstKey.Text
DispAllKeys
End Sub
全件削除
全件の削除は単純にRemoveAllメソッドを実行すればよい.
Private Sub cmdRemoveAll_Click()
oDic.RemoveAll
DispAllKeys
End Sub
キー全体を取得して配列に
キー全件を取得して配列に入れることができる.これは,Variant型の変数にそのままKeysプロパティを代入してやればよい.Variant配列からは,下記のコードのようにそのひとつずつを得ることができる.これは定石である.
Private Function DispAllKeys()
Dim vKeys As Variant
Dim i As Integer
lstKey.Clear
vKeys = oDic.Keys
For i = 0 To oDic.Count - 1
lstKey.AddItem vKeys(i)
Next i
lblCount.Caption = CStr(oDic.Count)
End Function
アイテム全体を取得して配列に
アイテム全体についても,キーのとき同様にItemsプロパティで得ることができる.
Private Sub cmdItems_Click()
Dim vItems As Variant
Dim i As Integer
vItems = oDic.Items
For i = 0 To oDic.Count - 1
lstItem.AddItem vItems(i)
Next i
End Sub
テキストストリームへの書き込み
| Visual Basicの未来は明るい |
|---|
さて,WSHに含まれる各種のオブジェクトの使い方を見てきたが,いかがだっただろうか.従来はWindows APIバリバリでないと使えなかった機能が,実にカンタンに使うことができ,非常に便利である.
実は,このような便利なオブジェクトは,Internet Explorerをインストールしたときに同時にインストールされるActiveXコントロールやオブジェクトにも,いろいろなものがある.しかし,IEはセキュリティ上問題があることから使用禁止になっている企業も多く,そういったものがあることを前提にしてプログラムを作ることには問題がある.その点,WSHであれば安心であり,今後はWindows上の標準的なオブジェクトとなっていくハズだ.
私はこの時を待っていたのだ.「いずれは,Windows APIを使わなくても,Visual Basicからすべての処理を書くことができるようになる日が来るハズだ」と,Visual Basic 4.0が発売される前から書いてきた.一時は,そんな日は本当に来るのかと疑問に思ったこともあったが,VB5での大幅な改良やこういったオブジェクトの登場で,少しは真実味を帯びてきたようである.
Visual BasicからWindows APIを使う意味が完全になくなる日は来ないだろうが,たいていの処理はオブジェクトを使って書くことができるようになりつつあるのは確かだ.そういう意味では,やはりVisual Basicの未来は明るいと言えるのではないだろうか.
|
サンプルプログラムのダウンロード |