わたろぐ

仕事、読書、ガジェット、グルメ、写真、旅行など雑多な備忘

【VB.NET】構造体の配列のソート

複数のメンバを持つ構造体の配列をソートする。

以下のような構造体を想定する。

Public Structure record
    ' 店コード
    Dim tencd As Integer
    ' 仕入先コード
    Dim siirecd As Integer
    ' 納品日
    Dim nouhindate As Integer
    ' 伝票番号
    Dim denno As Integer

    Public Sub record()
        ' 各メンバの初期化
        tencd = 0
        siirecd = 0
        nouhindate = 0
        denno = 0
    End Sub

End Structure

このとき、店コード、仕入先コード、納品日、伝票番号の順でソートを行うとする。

System.Collections.IComparer インターフェースを実装する。

Public Class recordCompare : Implements System.Collections.IComparer
    Public Function Compare(ByVal right As Object, ByVal left As Object) As Integer Implements IComparer.Compare
        ' right > left  : 正の値を返す。
        ' right == left    : 0を返す。
        ' right < left  : 負の値を返す。

        ' 店舗コード、仕入先、納品日、伝票番号の順に比較する

        ' 店舗コードで比較
        If (CType(right, record)).tencd - (CType(left, record)).tencd > 0 Then
            Return 1
        ElseIf ((CType(right, record)).tencd - (CType(left, record)).tencd < 0 Then
            Return -1
        Else
            ' 仕入先コードで比較
            If (CType(right, record)).siire - (CType(left, record)).siire > 0 Then
                Return 1
            ElseIf (CType(right, record)).siire - (CType(left, record)).siire < 0 Then
                Return -1
            Else
                    ' 納品日で比較
                If (CType(right, record)).nouhindate - (CType(left, record)).nouhindate > 0 Then
                    Return 1
                ElseIf (CType(right, record)).nouhindate - (CType(left, record)).nouhindate < 0 Then
                    Return -1
                Else
                    ' 伝票番号で比較
                    If (CType(right, record)).denno - (CType(left, record)).denno > 0 Then
                        Return 1
                    Else
                        Return -1
                    End If
                End If
            End If
        End If
    End Function
End Class

Compare メソッドでは、引数としている2つのオブジェクトの比較を行い、right の方が大きい(後ろに並ぶ)場合は 1left の方が大きいときは -1 を返す。 そこで、まず店舗コードで比較を行う。同じであれば仕入先コードで比較。と言った具合にソートしたい項目の順序で比較の定義を行う。

実際にソートを行うときは、 ArrayList クラスの Sort メソッドを利用する。 引数にインターフェースを定義した、 recordCompare を指定する。

Sub Main()

    ' レコードのオブジェクト
    Dim rec As record
    ' レコードオプジェクト配列
    Dim list As ArrayList = New ArrayList()

    '==============================
    ' 構造体の配列にデータを挿入(省略)
    '==============================
        
    '並び替え
    list.Sort(New recordCompare)

End Sub

こうすることで、ArrayLsit listは店舗、仕入先、納品日、伝票番号の順でソートされる。