【源码分享】ListView的数字排序
vb吧
全部回复
仅看楼主
吧务
level 15
ListView的默认的排序功能都是按照字符串顺序排的,那样对数字顺序时,如果升序排列,9会排在10的后面。如何让数字或日期正确排序,用API和循环语句可以实现。代码如下:
Option Explicit
Private Declare Function LockWindowUpdate Lib "user32" (ByVal hWndLock As Long) As Long
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Sub Form_Load()
     '向ListView注入三列数据,第二列为数字,第三列为日期。
     With ListView1
         .View = lvwReport
    
         .ColumnHeaders.Add(, , "String").Tag = "STRING"
         .ColumnHeaders.Add(, , "Number").Tag = "NUMBER"
         .ColumnHeaders.Add(, , "Date").Tag = "DATE"
        
        
         .ColumnHeaders(1).Alignment = lvwColumnLeft
         .ColumnHeaders(2).Alignment = lvwColumnRight
         .ColumnHeaders(3).Alignment = lvwColumnCenter
        
         Dim l As Long
         Dim dblRnd As Double
         Dim dteRnd As Date
        
         With .ListItems
             For l = 1 To 1000
                 With .Add(, , "ListItem " & l)
                     dblRnd = (Rnd() * 10000) - 5000
                     dteRnd = (Rnd() * 1000) + Date
                     .ListSubItems.Add , , Format(dblRnd, "0.00")
                     .ListSubItems.Add , , Format(dteRnd, "yyyy-m-d")
                 End With
             Next l
         End With
     End With
End Sub
Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
     On Error Resume Next
    
     Dim lngStart As Long
     lngStart = GetTickCount

2011年05月10日 23点05分 1
吧务
level 15
    
     With ListView1
         Dim lngCursor As Long
         lngCursor = .MousePointer
         .MousePointer = vbHourglass
        
         LockWindowUpdate .hWnd
        
         Dim l As Long
         Dim strFormat As String
         Dim strData() As String
        
         Dim lngIndex As Long
         lngIndex = ColumnHeader.Index - 1
    
         Select Case UCase$(ColumnHeader.Tag)
             Case "DATE"
            
                 strFormat = "YYYYMMDDHhMmSs"
        
                 With .ListItems
                     If (lngIndex > 0) Then
                         For l = 1 To .Count
                             With .Item(l).ListSubIte***ngIndex)
                                 .Tag = .Text & Chr$(0) & .Tag
                                 If IsDate(.Text) Then
                                     .Text = Format(CDate(.Text), strFormat)
                                 Else
                                     .Text = ""

2011年05月10日 23点05分 2
吧务
level 15
                                 End If
                             End With
                         Next l
                     Else
                         For l = 1 To .Count
                             With .Item(l)
                                 .Tag = .Text & Chr$(0) & .Tag
                                 If IsDate(.Text) Then
                                     .Text = Format(CDate(.Text), strFormat)
                                 Else
                                     .Text = ""
                                 End If
                             End With
                         Next l
                     End If
                 End With
                
                

2011年05月10日 23点05分 3
吧务
level 15
                 .SortOrder = .SortOrder Xor 1
                 .SortKey = ColumnHeader.Index - 1
                 .Sorted = True
                
                 With .ListItems
                     If (lngIndex > 0) Then
                         For l = 1 To .Count
                             With .Item(l).ListSubIte***ngIndex)
                                 strData = Split(.Tag, Chr$(0))
                                 .Text = strData(0)
                                 .Tag = strData(1)
                             End With
                         Next l
                     Else
                         For l = 1 To .Count
                             With .Item(l)
                                 strData = Split(.Tag, Chr$(0))
                                 .Text = strData(0)
                                 .Tag = strData(1)

2011年05月10日 23点05分 4
吧务
level 15
                             End With
                         Next l
                     End If
                 End With
                
             Case "NUMBER"
            
                 strFormat = String(30, "0") & "." & String(30, "0")
            
                 With .ListItems
                     If (lngIndex > 0) Then
                         For l = 1 To .Count
                             With .Item(l).ListSubIte***ngIndex)
                                 .Tag = .Text & Chr$(0) & .Tag
                                 If IsNumeric(.Text) Then
                                     If CDbl(.Text) >= 0 Then
                                         .Text = Format(CDbl(.Text), strFormat)
                                     Else
                                         .Text = "&" & InvNumber(Format(0 - CDbl(.Text), strFormat))

2011年05月10日 23点05分 5
吧务
level 15
                                     End If
                                 Else
                                     .Text = ""
                                 End If
                             End With
                         Next l
                     Else
                         For l = 1 To .Count
                             With .Item(l)
                                 .Tag = .Text & Chr$(0) & .Tag
                                 If IsNumeric(.Text) Then
                                     If CDbl(.Text) >= 0 Then
                                         .Text = Format(CDbl(.Text), strFormat)
                                     Else
                                         .Text = "&" & InvNumber(Format(0 - CDbl(.Text), strFormat))

2011年05月10日 23点05分 6
吧务
level 15
                                     End If
                                 Else
                                     .Text = ""
                                 End If
                             End With
                         Next l
                     End If
                 End With
                
                 .SortOrder = .SortOrder Xor 1
                 .SortKey = ColumnHeader.Index - 1
                 .Sorted = True
                
                 With .ListItems
                     If (lngIndex > 0) Then
                         For l = 1 To .Count
                             With .Item(l).ListSubIte***ngIndex)
                                 strData = Split(.Tag, Chr$(0))
                                 .Text = strData(0)

2011年05月10日 23点05分 7
吧务
level 15
                                 .Tag = strData(1)
                             End With
                         Next l
                     Else
                         For l = 1 To .Count
                             With .Item(l)
                                 strData = Split(.Tag, Chr$(0))
                                 .Text = strData(0)
                                 .Tag = strData(1)
                             End With
                         Next l
                     End If
                 End With
            
             Case Else
            
                 .SortOrder = .SortOrder Xor 1
                 .SortKey = ColumnHeader.Index - 1
                 .Sorted = True
                
         End Select
            
         LockWindowUpdate 0&
        
         .MousePointer = lngCursor
        
     End With
     'MsgBox "行数: " & ListView1.ListItems.Count & " 用时: " & GetTickCount - lngStart & "ms"
End Sub
Private Function InvNumber(ByVal Number As String) As String
     Static i As Integer
     For i = 1 To Len(Number)
         Select Case Mid$(Number, i, 1)
         Case "-": Mid$(Number, i, 1) = " "
         Case "0": Mid$(Number, i, 1) = "9"
         Case "1": Mid$(Number, i, 1) = "8"
         Case "2": Mid$(Number, i, 1) = "7"
         Case "3": Mid$(Number, i, 1) = "6"
         Case "4": Mid$(Number, i, 1) = "5"
         Case "5": Mid$(Number, i, 1) = "4"
         Case "6": Mid$(Number, i, 1) = "3"
         Case "7": Mid$(Number, i, 1) = "2"
         Case "8": Mid$(Number, i, 1) = "1"
         Case "9": Mid$(Number, i, 1) = "0"
         End Select
     Next
     InvNumber = Number
End Function
2011年05月10日 23点05分 8
吧务
level 15
百度啊,怎么连代码也屏蔽,
                              With .Item(l).ListSubIte***ngIndex)
里面的*号是 ***
.Item(l).ListSubIte***ngIndex)
2011年05月11日 00点05分 9
吧务
level 15
需要的留邮箱吧,百度把代码屏蔽了
*号里面的文字是 .Item(l).ListSubIte 和谐 m 和谐 s( 和谐 l 和谐 ngIndex)
2011年05月11日 00点05分 10
level 1
2011年05月11日 00点05分 11
吧务
level 12
2011年05月11日 01点05分 13
level 13
好像有点繁琐了,思路还是一样,通过format把数字格式化成一样的格式然后排序
但是这个方法只能针对统一的正数或者统一的负数,如果正负混合,就没用了的
2011年05月11日 02点05分 14
吧务
level 15
你可以下载下来试试,对正负数混合同样有用
2011年05月11日 02点05分 15
吧务
level 15
我就让你看看排序的结果。你在我代码中能看到dblRnd = (Rnd() * 10000) - 5000这条语句吧,这是在向表中随机添加数字来看一下排序效果的,为什么要减5000?就是为了能正负混合。能生成-5000到5000之间的数。下图是按数字顺序升序排列的。

2011年05月11日 02点05分 16
吧务
level 12
***是啥
2011年05月11日 03点05分 17
吧务
level 15
被百度屏蔽了,你可以去http://u.115.com/file/cli9zi2c下载
2011年05月11日 03点05分 18
level 1
2011年05月11日 03点05分 19
吧务
level 15
不用留邮箱,自己去http://u.115.com/file/cli9zi2c下载。
2011年05月11日 03点05分 20
level 7
2011年05月11日 05点05分 21
1 2 尾页