-
Jan 27th, 2000, 08:52 PM
#1
Thread Starter
New Member
hello everyone
the listview control in visual basic can sort on any column simply. my problem is that it behaves like it is sorting strings. i cannot get it to correctly sort on numbers or dates.
eg. it sorts numbers 1 to 23 like this....
1
10
11
12
13
14
15
16
17
18
19
2
20
21
22
23
24
3
4
5
6
7
8
9
same problem with dates it thinks they are strings. i have investigated the following:
(*) the columnheader objet does not have a property where i can define the data type of the column values that it will hold
(*) you cannot create a hidden column to sort on. ie. somehow fake the sort
the windows explorer uses a similar or probably the same control. click on the size and see the column values are not sorted as if they were strings, they are actually sorted in correct order of file size.
ANY IDEAS/SOLUTION/ALTERNATIVE.
also see the control (listview) used by winzip. do you think these are the same as what we the vb-developers have been provided with.
[This message has been edited by badal (edited 01-28-2000).]
-
Jan 27th, 2000, 11:39 PM
#2
Hello badal,
The only way I was able to get around this was to format my numbers with 0.
1 = 01
2 = 02
That works out the sorting.
Good Luck
------------------
Boothman
There is a war out there and it is about who controls the information, it's all about the information.
-
Jan 28th, 2000, 01:30 AM
#3
Addicted Member
These are as good as you're going to get. Unfortunately, ListView uses a simple sort that doesn't take into account whether it's a date or an integer or a string. It just treats everything like a string.
-
Jan 28th, 2000, 12:08 PM
#4
Thread Starter
New Member
thanx guys,
that's exactly what i thought, vb listview cannot handle anything but strings. this does not solve my problem, i wonder how they have done in winzip and windows explorer or what control are they using. thanx anyway.
do you know of an equivalent control, anything but not the grid unless it has a columnclick event like listview does?
-
Jan 28th, 2000, 12:21 PM
#5
Fanatic Member
Greetings Badal.
As for Dates, if you format the values so that the years are first, then the months, then the days, I believe that ascending and descending sorts will be correct. I'm not sure about this, however, because I haven't tested it.
For example:
Code:
format(Date,"yyyy/mm/dd")
Hope this helps.
------------------
OneSource
The truth may be out there, but it's in here too!
.
[This message has been edited by OneSource (edited 01-28-2000).]
-
Jan 31st, 2000, 01:05 AM
#6
Here is an example of how to sort the ListView by Date or Number. Copy this code to a module:
VB Code:
Private Declare Function LockWindowUpdate Lib "user32" (ByVal hWndLock As Long) As Long
Public Enum eSortType
eByDate = 1
eByNumber = 2
eByString = 3
End Enum
Public Sub SortListView(pListView As ListView, pSortType As eSortType, pColumnHeaderIndex As Integer)
Dim l As Long
Dim strFormat As String
Dim strData() As String
Dim lngCursor As Long
Dim lngIndex As Long
On Error Resume Next
With pListView
' Display the hourglass cursor whilst sorting
lngCursor = .MousePointer
.MousePointer = vbHourglass
' Prevent the ListView control from updating on screen -
' this is to hide the changes being made to the listitems
' and also to speed up the sort
LockWindowUpdate .hWnd
lngIndex = pColumnHeaderIndex - 1
Select Case pSortType
Case eByDate
' Sort by date.
strFormat = "YYYYMMDDHhNnSs"
With .ListItems
If (lngIndex > 0) Then
For l = 1 To .Count
With .Item(l).ListSubItems(lngIndex)
.Tag = .Text & vbNullChar & .Tag
If IsDate(.Text) Then
.Text = Format(CDate(.Text), _
strFormat)
Else
.Text = ""
End If
End With
Next l
Else
For l = 1 To .Count
With .Item(l)
.Tag = .Text & vbNullChar & .Tag
If IsDate(.Text) Then
.Text = Format(CDate(.Text), _
strFormat)
Else
.Text = ""
End If
End With
Next l
End If
End With
With .ListItems
If (lngIndex > 0) Then
For l = 1 To .Count
With .Item(l).ListSubItems(lngIndex)
strData = Split(.Tag, vbNullChar)
.Text = strData(0)
.Tag = strData(1)
End With
Next l
Else
For l = 1 To .Count
With .Item(l)
strData = Split(.Tag, vbNullChar)
.Text = strData(0)
.Tag = strData(1)
End With
Next l
End If
End With
Case eByNumber
' Sort Numerically
strFormat = String(30, "0") & "." & String(30, "0")
With .ListItems
If (lngIndex > 0) Then
For l = 1 To .Count
With .Item(l).ListSubItems(lngIndex)
.Tag = .Text & vbNullChar & .Tag
If IsNumeric(.Text) Then
If CDbl(.Text) >= 0 Then
.Text = Format(CDbl(.Text), _
strFormat)
Else
.Text = "&" & InvertNumber( _
Format(0 - CDbl(.Text), _
strFormat))
End If
Else
.Text = ""
End If
End With
Next l
Else
For l = 1 To .Count
With .Item(l)
.Tag = .Text & vbNullChar & .Tag
If IsNumeric(.Text) Then
If CDbl(.Text) >= 0 Then
.Text = Format(CDbl(.Text), _
strFormat)
Else
.Text = "&" & InvertNumber( _
Format(0 - CDbl(.Text), _
strFormat))
End If
Else
.Text = ""
End If
End With
Next l
End If
End With
With .ListItems
If (lngIndex > 0) Then
For l = 1 To .Count
With .Item(l).ListSubItems(lngIndex)
strData = Split(.Tag, vbNullChar)
.Text = strData(0)
.Tag = strData(1)
End With
Next l
Else
For l = 1 To .Count
With .Item(l)
strData = Split(.Tag, vbNullChar)
.Text = strData(0)
.Tag = strData(1)
End With
Next l
End If
End With
Case Else
End Select
.SortOrder = (.SortOrder + 1) Mod 2
.SortKey = pColumnHeaderIndex - 1
.Sorted = True
' Unlock the list window so that the OCX can update it
LockWindowUpdate 0&
' Restore the previous cursor
.MousePointer = lngCursor
End With
End Sub
Private Function InvertNumber(ByVal pNumber As String) As String
Static i As Integer
For i = 1 To Len(pNumber)
Select Case Mid$(pNumber, i, 1)
Case "-": Mid$(pNumber, i, 1) = " "
Case "0": Mid$(pNumber, i, 1) = "9"
Case "1": Mid$(pNumber, i, 1) = "8"
Case "2": Mid$(pNumber, i, 1) = "7"
Case "3": Mid$(pNumber, i, 1) = "6"
Case "4": Mid$(pNumber, i, 1) = "5"
Case "5": Mid$(pNumber, i, 1) = "4"
Case "6": Mid$(pNumber, i, 1) = "3"
Case "7": Mid$(pNumber, i, 1) = "2"
Case "8": Mid$(pNumber, i, 1) = "1"
Case "9": Mid$(pNumber, i, 1) = "0"
End Select
Next
InvertNumber = pNumber
End Function
Usage: SortListView ListView, SortType, ColumnHeaderIndex
Exaple:
VB Code:
Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
Select Case ColumnHeader
Case "DATE"
SortListView ListView1, eByDate, ColumnHeader.Index
Case "NUMBER"
SortListView ListView1, eByNumber, ColumnHeader.Index
End Select
End Sub
-
Jan 31st, 2000, 01:05 AM
#7
Junior Member
-
Jan 18th, 2003, 06:12 AM
#8
Lively Member
I have done exactly what was in that sample, but it still does not sort by numbers even if I use "eByNumber".
What is wrong??
All I get is this:
1
11
2
Instead of:
1
2
11
Please help
Machine Language: You try to shoot yourself in
the foot only to discover you must first reinvent the
gun, gunpowder, the bullet, and your foot.
-
Jan 31st, 2003, 02:06 PM
#9
New Member
Not sure if you are getting your data from a database or not, but you can always write a method--er--sub(damn Java!) to requery the data with the ORDER BY clause on the numeric field and repopulate the listView based on that. This assumes, of course that there isn't a huge amount of data displayed in the listView. Also, this could be a big waste of time if you aren't populating with a database.
Anyway, good luck!
VB 5.0 Enterprise
VB 6.0 Enterprise
Sybase
MSAccess
Windows 98 SE
Windows 2000 SR1
-
Feb 5th, 2003, 10:47 AM
#10
Lively Member
I am using a database, but do not want to requery every time the user changes the sorting order. However I sorted it out!
Machine Language: You try to shoot yourself in
the foot only to discover you must first reinvent the
gun, gunpowder, the bullet, and your foot.
-
Feb 5th, 2003, 11:05 AM
#11
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|