Form1にListview1を貼り付けます。
以下を実行すると、数字のプラスマイナスを考えて、並べ替えが出来ませんが数字のプラスマイナスをも考慮したソートが出来るようにするにはどうしたらいいでしょうか?
'******************************************************************
Public Class LVSort
'IComparerインターフェイス
Implements IComparer
Private mOrder As SortOrder = SortOrder.Ascending 'ソート順(昇順・降順)
Private mKey As Integer = 0 'ソート列
'ソート順(昇順・降順)プロパティ
Public Property Order() As SortOrder
Get
Return mOrder
End Get
Set(ByVal Value As SortOrder)
mOrder = Value
End Set
End Property
'ソート列プロパティ
Public Property Key() As Integer
Get
Return mKey
End Get
Set(ByVal Value As Integer)
mKey = Value
End Set
End Property
'比較結果を返す
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.Compare
Dim intRet As Integer
Try
'比較用リストアイテム格納変数
Dim sx As ListViewItem = CType(x, ListViewItem)
Dim sy As ListViewItem = CType(y, ListViewItem)
'文字列を比較し、値を格納
intRet = CompareString(sx.SubItems(mKey).Text, sy.SubItems(mKey).Text)
'降順のときは結果を逆転
If mOrder = SortOrder.Descending Then
intRet = -intRet
End If
Catch ex As Exception
Debug.WriteLine(ex.Message.ToString)
End Try
'結果を返す
Return intRet
End Function
'文字列内の数値として認識できる部位を検査し、比較した値を返す
Private Function CompareString(ByVal str1 As String, ByVal str2 As String) As Integer
Dim chrNum() As Char = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}
Dim i As Integer
Dim intPos As Integer
Dim intLength As Integer
Dim intNext1 As Integer
Dim intNext2 As Integer
Dim intRet As Integer
Dim idx As Integer
Dim idx1 As Integer
Dim idx2 As Integer
Dim lngNum1 As Long = -1
Dim lngNum2 As Long = -1
'はじめの文字列から数値として認識できる部分を探す
idx1 = str1.IndexOfAny(chrNum)
'見つかった場合
If idx1 <> -1 Then
'位置を格納
intPos = idx1
'長さの初期値
intLength = 1
'見つかった位置から文字列の終わりまで検査
For i = idx1 + 1 To str1.Length - 1
'数値として認識できるか検査
idx = str1.Substring(i, 1).IndexOfAny(chrNum)
'数値として認識できない場合は抜ける
If idx = -1 Then Exit For
'長さを格納
intLength += 1
Next
'数値をLong値として格納
lngNum1 = CType(str1.Substring(intPos, intLength), Long)
'文字列の途中で終了した場合
If intPos + intLength <> str1.Length Then
'ループを抜けたポイントを格納
intNext1 = intPos + intLength
End If
End If
'次の文字列から数値として認識できる部分を探す
idx2 = str2.IndexOfAny(chrNum)
'見つかった場合
If idx2 <> -1 Then
'位置を格納
intPos = idx2
'長さの初期値
intLength = 1
'見つかった位置から文字列の終わりまで検査
For i = idx2 + 1 To str2.Length - 1
'数値として認識できるか検査
idx = str2.Substring(i, 1).IndexOfAny(chrNum)
'数値として認識できない場合は抜ける
If idx = -1 Then Exit For
'長さを格納
intLength += 1
Next
'数値をLong値として格納
lngNum2 = CType(str2.Substring(intPos, intLength), Long)
'文字列の途中で終了した場合
If intPos + intLength <> str2.Length Then
'ループを抜けたポイントを格納
intNext2 = intPos + intLength
End If
End If
'数値が認識されなかったか、
'または同じ位置ではない場合
If idx1 = -1 Or idx2 = -1 Or (idx1 <> idx2) Then
'単純比較を行なう
intRet = String.Compare(str1, str2)
Else
'文字列の先頭が数値として認識されたか、
'または数値より前の文字列が同じ場合
If (idx1 = 0 And idx2 = 0) Or _
(str1.Substring(0, str1.Length - (str1.Length - idx1)) = _
str2.Substring(0, str2.Length - (str2.Length - idx2))) Then
'数値として認識でき、ひとつめが大きい場合
If lngNum1 <> -1 And lngNum2 <> -1 And lngNum1 > lngNum2 Then
'入れ替える値を格納
intRet = 1
ElseIf lngNum1 <> -1 And lngNum2 <> -1 And lngNum1 < lngNum2 Then
'数値として認識でき、ひとつめが小さい場合は
'入れ替えない値を格納
intRet = -1
ElseIf intNext1 <> 0 And intNext2 <> 0 Then
'文字列の最後まで調べていない場合は再帰
intRet = CompareString(str1.Substring(intNext1), str2.Substring(intNext2))
Else
'入れ替えない値を格納
intRet = -1
End If
Else
'数値より前の文字列が違う場合は単純比較
intRet = String.Compare(str1, str2)
End If
End If
'値を返す
Return intRet
End Function
End Class
'*********************************************************************
Public Class Form1
Inherits System.Windows.Forms.Form
#Region " Windows フォーム デザイナで生成されたコード "
Public Sub New()
MyBase.New()
InitializeComponent()
End Sub
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
Private components As System.ComponentModel.IContainer
Friend WithEvents ListView1 As System.Windows.Forms.ListView
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.ListView1 = New System.Windows.Forms.ListView
Me.SuspendLayout()
'
'ListView1
'
Me.ListView1.Font = New System.Drawing.Font("MS ゴシック", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(128, Byte))
Me.ListView1.HideSelection = False
Me.ListView1.Location = New System.Drawing.Point(12, 12)
Me.ListView1.Name = "ListView1"
Me.ListView1.Size = New System.Drawing.Size(404, 196)
Me.ListView1.TabIndex = 1
Me.ListView1.UseCompatibleStateImageBehavior = False
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 12)
Me.ClientSize = New System.Drawing.Size(426, 223)
Me.Controls.Add(Me.ListView1)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.MaximizeBox = False
Me.Name = "Form1"
Me.Text = "リストビューのソート"
Me.ResumeLayout(False)
End Sub
#End Region
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'リストビューの初期設定
ListView1.View = View.Details '詳細表示
ListView1.HeaderStyle = ColumnHeaderStyle.Clickable 'カラムヘッダのクリック可能
'リストビューの詳細表示用のヘッダ作成
ListView1.Columns.Add("アイテム", 100, HorizontalAlignment.Left)
ListView1.Columns.Add("サブ1", 100, HorizontalAlignment.Left)
ListView1.Columns.Add("サブ2", 100, HorizontalAlignment.Right)
ListView1.Items.Add("あああああ")
ListView1.Items(0).SubItems.Add("fffff")
ListView1.Items(0).SubItems.Add("33333")
ListView1.Items.Add("いいいいい")
ListView1.Items(1).SubItems.Add("ddddd")
ListView1.Items(1).SubItems.Add("44444")
ListView1.Items.Add("ううううう")
ListView1.Items(2).SubItems.Add("aaaaa")
ListView1.Items(2).SubItems.Add("-66666")
ListView1.Items.Add("えええええ")
ListView1.Items(3).SubItems.Add("eeeee")
ListView1.Items(3).SubItems.Add("88888")
ListView1.Items.Add("おおおおお")
ListView1.Items(4).SubItems.Add("bbbbb")
ListView1.Items(4).SubItems.Add("-77777")
ListView1.Items.Add("かかかかか")
ListView1.Items(5).SubItems.Add("hhhhh")
ListView1.Items(5).SubItems.Add("55555")
ListView1.Items.Add("ききききき")
ListView1.Items(6).SubItems.Add("ggggg")
ListView1.Items(6).SubItems.Add("-11111")
ListView1.Items.Add("くくくくく")
ListView1.Items(7).SubItems.Add("ccccc")
ListView1.Items(7).SubItems.Add("22222")
End Sub
'カラムヘッダのクリック
Private Sub ListView1_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles ListView1.ColumnClick
Static blnOrderFlg As Boolean
Dim ccLVSort As LVSort = New LVSort
With ccLVSort
If blnOrderFlg Then
'昇順
.Order = SortOrder.Ascending
Else
'降順
.Order = SortOrder.Descending
End If
'クリックされた列によりソートキーを指定
.Key = e.Column
End With
'ListViewItemSorterプロパティへ、ソートの比較演算子を表すカスタムクラスを指定
ListView1.ListViewItemSorter = ccLVSort
'フラグ変数を反転
blnOrderFlg = Not blnOrderFlg
End Sub
End Class
'*********************************************************************
あれ?これってVB.NETですよね?
ここは「VB2-VB6専用」の掲示板ですよ。
VB.NETはお隣の「VB.NET掲示板(.NET専用)」をご利用ください。
> 数字のプラスマイナスをも考慮したソート
> '文字列を比較し、値を格納
> intRet = CompareString(sx.SubItems(mKey).Text, sy.SubItems(mKey).Text)
文字列のままではなく、一度数値に直してから比較するとか・・・
移動先
http://madia.world.coocan.jp/cgi-bin/vbnet/wwwlng.cgi?print+200706/07060036.txt
とりあえず解決
ツイート | ![]() |