プログラム上でKEYを持つリスト構造を使う場合に利用するのがコレクションクラスです。 良く使うコレクションクラスには以下の様に3種類のものがあります。
クラス名 | KEY操作 | Index操作 | 備考 |
---|---|---|---|
ArrayList | × | ○ | Indexでの操作しかできないコレクション基本クラス 取り扱うデータ型は Object 型 |
Hashtable | ○ | × | 連想配列的なKEYを持つコレクションクラス KEY及び、取り扱うデータ型は Object 型 |
SortedList | ○ | ○ | ArrayList と Hashtable の性質を併せ持ったコレクションクラス Indexは指定されたKEY順にソートされた結果が割り振られます |
単なる Object 型の配列として使う場合は ArrayList でもいいのですが、 データ処理をする場合には何がしかのキーがあって、それに紐づくデータがあるものです。 そのためキーが扱える Hashtable SortedList を利用します。
これらのコレクションクラスはデータとして扱えるのは、 Object 型なので結果 データ型としてOKなものは何でもになります。 いろんなサイトで、データとして文字列が扱われているものはあるのですが、今回は少しだけ複雑にするため、 ユーザクラスをデータにもつものを示したいと思います。
以下のソースを見て下さい。ユーザクラスとしてTest を宣言しています。
このクラスを SortedList のデータとして追加等を行います。
このプログラムはモジュールファイルに Sub Main を作成しその中に処理を記述しています。 これをコンパイルする場合はプロジェクト・プロパティでスタートアップオブジェクトとして MdlMainSortList を指定して下さい。
クラスデータをリストする SortedList を宣言した後、 テストクラスのデータを4件生成しながら SortedList に追加を行います。 キーとしては4件とも同一の書式で文字列として処理しています。
その後確認の為に SortedList.Values から順次データを取得して、内容を表示しています。 (この時取得されるのはクラス型なので、いわゆる参照型です。)
さて、内部のデータの変更を行う為にキーを指定しデータを取得します。 ここでクラスのパブリック変数に直接値を入れることで内部データの変更が行われます。 (クラスの参照を SortedList はデータとして持っているだけで、その参照により実体データにアクセスします)
再度 SortedList の中身を全て確認するのですが、今回はIndexを使ってデータを取得しています。
SortedListでのクラスデータの使い方
Module MdlMainSortList 'テストクラス Private Class Test Public Key As String 'KEYとなる文字列 Public Name As String '名称の文字列 Public Data As Integer 'あるデータとしてのInteger型データ Public Flag As Boolean 'フラグ 'コンストラクタ Sub New(ByVal aKey As String, ByVal aName As String, ByVal aData As String) Me.Key = aKey Me.Name = aName Me.Data = aData Me.Flag = False End Sub End Class <STAThread()> _ Sub Main() 'クラスデータをリストするSortedList Dim SortTest As New SortedList Dim clsTest As Test '敢えてKEYの順番通りでは無い様に SortedList に追加 clsTest = New Test("KEY004", "NAME004", 444) SortTest.Add("KEY004", clsTest) clsTest = New Test("KEY001", "NAME001", 100) SortTest.Add("KEY001", clsTest) clsTest = New Test("KEY003", "NAME003", 333) SortTest.Add("KEY003", clsTest) clsTest = New Test("KEY002", "NAME002", 222) SortTest.Add("KEY002", clsTest) Debug.Print("**************************") 'SortedList のKEY順番に取り出す For Each clsTest In SortTest.Values '内容を確認 Debug.Print(clsTest.Key & " : " & clsTest.Name & " : " & clsTest.Data.ToString) Next '1個のデータをKEYで内容を取り出し、そのクラスの中身を変更する clsTest = SortTest.Item("KEY002") '取り出した clsTest はクラスデータの参照なので、以下の処理でクラスの中身を変更 clsTest.Name = "NAMEaaa" clsTest.Data = 555 clsTest.Flag = True Debug.Print("**************************") 'KEY順番に指標で取り出す For i As Integer = 0 To SortTest.Count - 1 'クラスの参照を取り出す clsTest = CType(SortTest.GetByIndex(i), Test) '内容を確認 Debug.Print(clsTest.Key & " : " & clsTest.Name & " : " & clsTest.Data.ToString & " : " & clsTest.Flag.ToString) Next End Sub End Module
結果の出力を開発環境の「出力」ウインドウに表示していますが、以下の様になります。
("KEY002"のデータが変更されていることが分かります。)
次に、 SortedList を Hashtable に変えてみた例を示します。 特に SortedList の場合と変わりはありませんが、 Indexを使ってのデータへのアクセスは出来ないので、キーを使うことになります。
ここでキーについての注意ですが、私はキーとしては文字列で設定する様にしています。 例えば扱うデータのキーとして「得意先コード(数値で5桁)」「商品コード(数値で8桁)」の2個があった場合は、 それぞれのコードを先頭ゼロ付きで桁数固定で文字列変換し連結したものをキーとしています。
もし「商品コード」等が文字列(漢字を含まないとする)の場合でしたら、 先頭に空白を補って桁数を揃えて連結します。そうしないと比較がうまくいかないからです。
Hashtableでのクラスデータの使い方
Module MdlMainHashList 'テストクラス Private Class Test Public Key As String 'KEYとなる文字列 Public Name As String '名称の文字列 Public Data As Integer 'あるデータとしてのInteger型データ Public Flag As Boolean 'フラグ 'コンストラクタ Sub New(ByVal aKey As String, ByVal aName As String, ByVal aData As String) Me.Key = aKey Me.Name = aName Me.Data = aData Me.Flag = False End Sub End Class <STAThread()> _ Sub Main() 'クラスデータをリストするHashtable Dim HashTest As New Hashtable Dim clsTest As Test '敢えてKEYの順番通りでは無い様に SortedList に追加 clsTest = New Test("KEY004", "NAME004", 444) HashTest.Add("KEY004", clsTest) clsTest = New Test("KEY001", "NAME001", 100) HashTest.Add("KEY001", clsTest) clsTest = New Test("KEY003", "NAME003", 333) HashTest.Add("KEY003", clsTest) clsTest = New Test("KEY002", "NAME002", 222) HashTest.Add("KEY002", clsTest) 'KEY順番に指標で取り出す Debug.Print("**************************") For Each clsTest In HashTest.Values '内容を確認 Debug.Print(clsTest.Key & " : " & clsTest.Name & " : " & clsTest.Data.ToString) Next '1このデータをKEYで内容を取り出し、そのクラスの中身を変更する clsTest = HashTest.Item("KEY002") '取り出した clsTest はクラスデータの参照なので、以下の処理でクラスの中身を変更 clsTest.Name = "NAMEaaa" clsTest.Data = 555 clsTest.Flag = True 'KEY順番に指標で取り出す Debug.Print("**************************") For Each clsTest In HashTest.Values '内容を確認 Debug.Print(clsTest.Key & " : " & clsTest.Name & " : " & clsTest.Data.ToString) Next End Sub End Module
コメント