忍者ブログ

VB.NET-TIPS などプログラミングについて

VB.NETのTIPS(小技集)を中心に、Javascript、PHP その他のプログラミングについて少し役に立つ情報を発信します。いわゆる個人的な忘備録ですが、みなさんのお役に立てれば幸いです。

コレクションクラス(SortedList , Hashtable)でのクラスデータの使い方

プログラム上でKEYを持つリスト構造を使う場合に利用するのがコレクションクラスです。 良く使うコレクションクラスには以下の様に3種類のものがあります。

クラス名KEY操作Index操作備考
ArrayList × Indexでの操作しかできないコレクション基本クラス
取り扱うデータ型は Object
Hashtable × 連想配列的なKEYを持つコレクションクラス
KEY及び、取り扱うデータ型は Object
SortedList ArrayListHashtable の性質を併せ持ったコレクションクラス
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"のデータが変更されていることが分かります。)


次に、 SortedListHashtable に変えてみた例を示します。 特に 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











PR

コメント

コメントを書く