[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

scbs29

7/15/2012 8:28:00 PM

Hello all
Can anyone advise me of a sort array for the following.
I have files in a folder, the names of whic I pick up within my
program using the Dir() function, eg
Dim intFiles As Integer
Dim strFile As String
intFiles = 0
strFile = Dir(strFolder)
Do While strFile <> vbNullString
If strFile <> "." And strFile <> ".." Then
intFiles = intFiles + 1
ReDim Preserve strFileNames(intFiles)
strFileNames(intFiles - 1) = strFolder &
strFile
End If
strFile = Dir
Loop

In explorer the filenames are listed as
box1
box1_1
box2
box2_1
box3
box3_1
.
.
.
box9
box9_1
box10
box10_1
box11
box11_1
etc

but when I retrieve and display the filenames they are listed as
box1
box10
box10_1
box11
box11_1
.
.
.
box19
box19_1
box1_1
box2
box20
box20_1
box2_1

How can I sort these names so that they are in the same order as sjown
in explorer ?
I have tried a lot of sort algorithms I have found through DuckDuckGo
but none of them do the job.
Can anyone help ?
Will I have to write my own sort algorithm ?

ANy advice gratefully received.
TIA




remove fred before emailing
Registered Linux User 490858
19 Answers

Larry Serflaten

7/15/2012 9:54:00 PM

0

scbs29 wrote:

> How can I sort these names so that they are in the same order as sjown
> in explorer ?


Is explorer sorting the files by their creation date? Just something to check,
which you can also do if that is the case.

LFS

Mike Williams

7/15/2012 10:34:00 PM

0

"Larry Serflaten" <serflaten@gmail.com> wrote in message
news:dbdabf22-bbe2-476a-87f1-04105619c706@googlegroups.com...
> scbs29 wrote:
>
>> How can I sort these names so that they are in the same
>> order as sjown in explorer ?
>
> Is explorer sorting the files by their creation date? Just something
> to check, which you can also do if that is the case.

Actually this behaviour is something I have noticed only since reading the
OP's question. In Vista if I create the following files and if I open the
folder in Explorer and select sort alphabetically I see them in the
following order:

box2.txt
box2a.txt
box2a4.txt
box2a30.txt
box19.txt

So it seems that the Explorer sort is performed alphabetically until a
numeric digit is reached and then that numeric digit together with all
contiguous numeric digits thereafter are sorted as a number, and then
alphabetically again until (perhaps) some other numeric digits are
encountered. I think it will be necessary to write a custom compare function
to sort in such a manner. I had a little go myself but I got a bit "tongue
tied" after about 15 minutes of partial success and partial failure and it
really is time for bed here!

Mike


Ralph

7/15/2012 11:16:00 PM

0

On Sun, 15 Jul 2012 23:34:21 +0100, "Mike Williams"
<Mike@WhiskyAndCoke.com> wrote:

>"Larry Serflaten" <serflaten@gmail.com> wrote in message
>news:dbdabf22-bbe2-476a-87f1-04105619c706@googlegroups.com...
>> scbs29 wrote:
>>
>>> How can I sort these names so that they are in the same
>>> order as sjown in explorer ?
>>
>> Is explorer sorting the files by their creation date? Just something
>> to check, which you can also do if that is the case.
>
>Actually this behaviour is something I have noticed only since reading the
>OP's question. In Vista if I create the following files and if I open the
>folder in Explorer and select sort alphabetically I see them in the
>following order:
>
> box2.txt
> box2a.txt
> box2a4.txt
> box2a30.txt
> box19.txt
>
>So it seems that the Explorer sort is performed alphabetically until a
>numeric digit is reached and then that numeric digit together with all
>contiguous numeric digits thereafter are sorted as a number, and then
>alphabetically again until (perhaps) some other numeric digits are
>encountered. I think it will be necessary to write a custom compare function
>to sort in such a manner. I had a little go myself but I got a bit "tongue
>tied" after about 15 minutes of partial success and partial failure and it
>really is time for bed here!
>
>Mike
>

For better sleep, and Windows XP and later, check out the
StrCmpLogicalW API.
http://msdn.microsoft.com/en-us/library/windows/deskto...(v=vs.85).aspx

Private Declare Function StrCmpLogicalW Lib "shlwapi" (ByVal lpStr1 As
Long, ByVal lpStr2 As Long) As Long

-ralph

Auric__

7/16/2012 12:29:00 AM

0

scbs29 wrote:

> Can anyone advise me of a sort array for the following.
> I have files in a folder, the names of whic I pick up within my
> program using the Dir() function, eg
> Dim intFiles As Integer
> Dim strFile As String
> intFiles = 0
> strFile = Dir(strFolder)
> Do While strFile <> vbNullString
> If strFile <> "." And strFile <> ".." Then
> intFiles = intFiles + 1
> ReDim Preserve strFileNames(intFiles)
> strFileNames(intFiles - 1) = strFolder &
> strFile
> End If
> strFile = Dir
> Loop
>
> In explorer the filenames are listed as
[snip]
> but when I retrieve and display the filenames they are listed as
[snip]
> How can I sort these names so that they are in the same order as sjown
> in explorer ?
> I have tried a lot of sort algorithms I have found through DuckDuckGo
> but none of them do the job.
> Can anyone help ?
> Will I have to write my own sort algorithm ?

Short version: yes.

Long version: For pretty much all generic sorting algorithms, "10" < "2"
because the leftmost character of the strings are "1" and "2". With Windows
XP, Microsoft altered Explorer's sort algorithm to recognize numbers and
sort them appropriately, so it recognizes that "10" > "2". (Windows 2000
and older sort the way you don't want.)

To sort appropriately, your sorter would need to do something like this:

Sub custom_sorter(ByRef what() As String)
'variation of bubble sort
Dim L0 As Long, L1 As Long, f1 As Long, f2 As Long
Dim n1 As Double, n2 As Double, altered As Boolean
Do
altered = False
For L0 = LBound(what) To UBound(what) - 1
If what(L0) <> what(L0 + 1) Then
f1 = InStrAny(1, what(L0), "0123456789")
f2 = InStrAny(1, what(L0 + 1), "0123456789")
If f1 <> f2 Then
'numbers not in same position
If what(L0) > what(L0 + 1) Then
Swap what(L0), what(L0 + 1)
altered = True
End If
Else
'numbers in the same position;
'is the part before the numbers the same?
If Left(what(L0), f1 - 1) <> Left(what(L0 + 1), f1 - 1) Then
'left parts don't match; numbers don't matter
If what(L0) > what(L0 + 1) Then
Swap what(L0), what(L0 + 1)
altered = True
End If
Else
'text matches; numbers matter now
For L1 = f1 + 1 To Len(what(L0))
Select Case Mid(what(L0), L1, 1)
Case "0" To "9", "."
'do nothing
Case Else
n1 = Val(Mid(what(L0), f1, L1 - f1))
Exit For
End Select
Next
For L1 = f1 + 1 To Len(what(L0 + 1))
Select Case Mid(what(L0 + 1), L1, 1)
Case "0" To "9", "."
'do nothing
Case Else
n2 = Val(Mid(what(L0 + 1), f1, L1 - f1))
Exit For
End Select
Next
If n1 > n2 Then
Swap what(L0), what(L0 + 1)
altered = True
End If
End If
End If
End If
Next
Loop While altered
End Sub

'-----support functions-----

Function InStrAny(start As Integer, lookin As String, _
lookfor As String) As Long
Dim tmp1 As Long, L0 As Long

For L0 = start To Len(lookin)
tmp1 = InStr(lookfor, Mid$(lookin, L0, 1))
If tmp1 Then
InStrAny = L0
Exit Function
End If
Next
End Function

Sub Swap(ByRef var1, ByRef var2)
If VarType(var1) <> VarType(var2) Then Exit Sub
Dim tmp
tmp = var1
var1 = var2
var2 = tmp
End Sub

You're welcome to use the above in your project if you want, but you should
make sure it actually does what you want. (You should also note that bubble
sort is just about the slowest sort algorithm, and my code is slower than a
"normal" bubble sort.)

--
Hallo. My nem eez Inigo Montoya. You keel my father. Prepare to die.

Mike Williams

7/16/2012 5:48:00 AM

0

"ralph" <nt_consulting64@yahoo.com> wrote in message
news:nhj608hdmj30pr8jtbbp8qgc85ubpkbfup@4ax.com...

> For better sleep, and Windows XP and later, check out the
> StrCmpLogicalW API.
> http://msdn.microsoft.com/en-us/library/windows/deskto...(v=vs.85).aspx

Aha! I had an idea that Win Explorer must be using an API function to sort
in that specific way and I looked at the various StrCmp functions in MSDN
but I missed that one. Thanks a lot. I will sleep a lot easier tonight ;-)

Mike


Norm Cook

7/16/2012 12:57:00 PM

0

"ralph" <nt_consulting64@yahoo.com> wrote in message
news:nhj608hdmj30pr8jtbbp8qgc85ubpkbfup@4ax.com...
> On Sun, 15 Jul 2012 23:34:21 +0100, "Mike Williams"
> <Mike@WhiskyAndCoke.com> wrote:
>
>>"Larry Serflaten" <serflaten@gmail.com> wrote in message
>>news:dbdabf22-bbe2-476a-87f1-04105619c706@googlegroups.com...
>>> scbs29 wrote:
>>>
>>>> How can I sort these names so that they are in the same
>>>> order as sjown in explorer ?
>>>
>>> Is explorer sorting the files by their creation date? Just something
>>> to check, which you can also do if that is the case.
>>
>>Actually this behaviour is something I have noticed only since reading the
>>OP's question. In Vista if I create the following files and if I open the
>>folder in Explorer and select sort alphabetically I see them in the
>>following order:
>>
>> box2.txt
>> box2a.txt
>> box2a4.txt
>> box2a30.txt
>> box19.txt
>>
>>So it seems that the Explorer sort is performed alphabetically until a
>>numeric digit is reached and then that numeric digit together with all
>>contiguous numeric digits thereafter are sorted as a number, and then
>>alphabetically again until (perhaps) some other numeric digits are
>>encountered. I think it will be necessary to write a custom compare
>>function
>>to sort in such a manner. I had a little go myself but I got a bit "tongue
>>tied" after about 15 minutes of partial success and partial failure and it
>>really is time for bed here!
>>
>>Mike
>>
>
> For better sleep, and Windows XP and later, check out the
> StrCmpLogicalW API.
> http://msdn.microsoft.com/en-us/library/windows/deskto...(v=vs.85).aspx
>
> Private Declare Function StrCmpLogicalW Lib "shlwapi" (ByVal lpStr1 As
> Long, ByVal lpStr2 As Long) As Long
>
> -ralph

Ralph - thanks for sharing. Wanted to see it
in action, so:

Private Type StackType
Low As Long
Hi As Long
End Type
Private Declare Function StrCmpLogicalW Lib "shlwapi" (ByVal lpStr1 As Long,
ByVal lpStr2 As Long) As Long
'Modified HuthSort
Private Sub HuthSortLogical(Arr() As String)
Dim Compare As Long
Dim Temp As String
Dim aStack(1 To 128) As StackType
Dim i As Long, j As Long
Dim Low As Long, Hi As Long
Dim StackPtr As Long

aStack(1).Low = LBound(Arr)
aStack(1).Hi = UBound(Arr)
StackPtr = 2

Do
StackPtr = StackPtr - 1
Low = aStack(StackPtr).Low
Hi = aStack(StackPtr).Hi
Do
i = Low
j = Hi
Compare = StrPtr(Arr((Low + Hi) \ 2))
Do
Do While StrCmpLogicalW(StrPtr(Arr(i)), Compare) = -1
i = i + 1
Loop
Do While StrCmpLogicalW(StrPtr(Arr(j)), Compare) = 1
j = j - 1
Loop
If i <= j Then
Temp = Arr(i)
Arr(i) = Arr(j)
Arr(j) = Temp
i = i + 1
j = j - 1
End If
Loop While i <= j
If j - Low < Hi - i Then
If i < Hi Then
aStack(StackPtr).Low = i
aStack(StackPtr).Hi = Hi
StackPtr = StackPtr + 1
End If
Hi = j
Else
If Low < j Then
aStack(StackPtr).Low = Low
aStack(StackPtr).Hi = j
StackPtr = StackPtr + 1
End If
Low = i
End If
Loop While Low < Hi
Loop While StackPtr <> 1
End Sub

Private Sub Form_Load()
Dim a(1 To 10) As String
Dim i As Long
For i = 1 To 10
a(i) = "Item" & CStr(i)
Next
a(1) = "Item200"
a(2) = "Item4000"
a(3) = "Item6000"
HuthSortLogical a
For i = 1 To 10
Debug.Print i, a(i)
Next
End Sub

Output:
1 Item4
2 Item5
3 Item6
4 Item7
5 Item8
6 Item9
7 Item10
8 Item200
9 Item4000
10 Item6000


Mayayana

7/16/2012 1:34:00 PM

0


| Output:
| 1 Item4
| 2 Item5
| 3 Item6
| 4 Item7
| 5 Item8
| 6 Item9
| 7 Item10
| 8 Item200
| 9 Item4000
| 10 Item6000
|

It seems to be even more complicated than that.
I process my server web logs and format the file
names as daym-dd.txt. Ex.: mon7-16.txt.

On my XP system it works as follows:

tue7-10.txt comes before tue7-3.txt. thu7-12
comes before thu7-5. But sun7-1 comes before sun7-8.

In addition, at Ralph's link it says that one should not
count on the function remaining consistent. Which seems
to reaise a question: Why would anyone ever want/need
to sort names exactly as they show in Explorer?


Ralph

7/16/2012 1:54:00 PM

0

On Mon, 16 Jul 2012 09:33:56 -0400, "Mayayana"
<mayayana@invalid.nospam> wrote:

>
>| Output:
>| 1 Item4
>| 2 Item5
>| 3 Item6
>| 4 Item7
>| 5 Item8
>| 6 Item9
>| 7 Item10
>| 8 Item200
>| 9 Item4000
>| 10 Item6000
>|
>
> It seems to be even more complicated than that.
>I process my server web logs and format the file
>names as daym-dd.txt. Ex.: mon7-16.txt.
>
>On my XP system it works as follows:
>
>tue7-10.txt comes before tue7-3.txt. thu7-12
>comes before thu7-5. But sun7-1 comes before sun7-8.
>
> In addition, at Ralph's link it says that one should not
>count on the function remaining consistent. Which seems
>to reaise a question: Why would anyone ever want/need
>to sort names exactly as they show in Explorer?
>


Say you are taking wedding pictures and labeling the pictures by
subject and "take" ...
bm1.jpg
bm2.jpg
bm3.jpg
bride1.jpg
bride2.jpg
fob1.jpg
fob2.jpg
fob3.jpg
groom1.jpg
groom2.jpg
mob1.jpg
mob2.jpg

By the way there is a registery option to not sort "logically", found
under Explorer settings... can't remember exactly where. Will look it
up.

-ralph


Ralph

7/16/2012 2:07:00 PM

0

On Mon, 16 Jul 2012 08:53:46 -0500, ralph <nt_consulting64@yahoo.com>
wrote:

>On Mon, 16 Jul 2012 09:33:56 -0400, "Mayayana"
><mayayana@invalid.nospam> wrote:
>
>>
>>| Output:
>>| 1 Item4
>>| 2 Item5
>>| 3 Item6
>>| 4 Item7
>>| 5 Item8
>>| 6 Item9
>>| 7 Item10
>>| 8 Item200
>>| 9 Item4000
>>| 10 Item6000
>>|
>>
>> It seems to be even more complicated than that.
>>I process my server web logs and format the file
>>names as daym-dd.txt. Ex.: mon7-16.txt.
>>
>>On my XP system it works as follows:
>>
>>tue7-10.txt comes before tue7-3.txt. thu7-12
>>comes before thu7-5. But sun7-1 comes before sun7-8.
>>
>> In addition, at Ralph's link it says that one should not
>>count on the function remaining consistent. Which seems
>>to reaise a question: Why would anyone ever want/need
>>to sort names exactly as they show in Explorer?
>>
>
>
>Say you are taking wedding pictures and labeling the pictures by
>subject and "take" ...
>bm1.jpg
>bm2.jpg
>bm3.jpg
>bride1.jpg
>bride2.jpg
>fob1.jpg
>fob2.jpg
>fob3.jpg
>groom1.jpg
>groom2.jpg
>mob1.jpg
>mob2.jpg
>
>By the way there is a registery option to not sort "logically", found
>under Explorer settings... can't remember exactly where. Will look it
>up.
>
>-ralph
>

lol
That's a lousy example. Not enough coffee yet. Would sort the same.

The idea was to show that there are many situations where you would
like to see ...

<Subject><ordinal>

here are the keys ...
(For all users)
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curr
entVersion\policies\Explorer]
NoStrCmpLogical = DWORD: 1

(Per user)
[HKEY_CURRENT_USER\Software\Microsoft\Windows\Curre
ntVersion\Policies\Explorer]
NoStrCmpLogical = DWORD: 1

You can set it in Windows 7 using the group policy editor. Not sure of
earlier versions. Probably not there. Perhaps with service packs?
Can't check XP at the moment.

-ralph

Mayayana

7/16/2012 2:32:00 PM

0

| [HKEY_CURRENT_USER\Software\Microsoft\Windows\Curre
| ntVersion\Policies\Explorer]
| NoStrCmpLogical = DWORD: 1
|

Interesting. That's there on my XP system. Perhaps
it's the default? I certainly never set it.

It's hard for me to see the value of logical ordering.
I think I know what you mean. It makes sense
to have barn2.jpg come after barn1.jpg and not after
barn10.jpg. But once one starts down that road, where
does it end? It's getting into name intepretation --
guessing the purpose of a file name. If we start doing that
then why not date ordering for my logs? I'd much prefer
that Windows could do that:

wed7-4.txt
thu7-5.txt
fri7-6.txt