半角チルダ

ExcelVBA、その他。
覚え書きや、補足資料などのスクラップブック。
end-u(1037781)

■XPエクスプローラ風「数値順」ソート

2013-03-29 22:00:00 | scrap
# ちと古い話題ですが

ファイル名「1.jpg ~10.jpg~」のソート
ここで教えて頂きました。:)

しばらく前のmoug.net給湯室でも出てたお題です。
「数値混じり文字列を文字部分と数値部分に分けてソートしたい」

Sub test1()
  Dim i  As Long
  Dim j  As Long
  Dim mx As Long
  Dim tmp As String
  Dim ary

  ary = VBA.Array("X10Y1", "X10Y10", "X10Y2", "X1Y1", _
          "X1Y10", "X1Y2", "X2Y1", "X2Y10", "X2Y2")
  mx = UBound(ary)
  For i = 0 To mx - 1
    For j = i + 1 To mx
      If ary(j) < ary(i) Then
        tmp = ary(i)
        ary(i) = ary(j)
        ary(j) = tmp
      End If
    Next
  Next
  Debug.Print Join(ary, vbLf)
End Sub

普通にSortすると

 X10Y1
 X10Y10
 X10Y2
 X1Y1
 X1Y10
 X1Y2
 X2Y1
 X2Y10
 X2Y2

こうなので

Option Explicit

Private Declare Function StrCmpLogicalW Lib "SHLWAPI.DLL" ( _
                    ByVal lpStr1 As Long, _
                    ByVal lpStr2 As Long) As Long

Sub test2()
  Dim i  As Long
  Dim j  As Long
  Dim mx As Long
  Dim tmp As String
  Dim ary

  ary = VBA.Array("X10Y1", "X10Y10", "X10Y2", "X1Y1", _
          "X1Y10", "X1Y2", "X2Y1", "X2Y10", "X2Y2")
  mx = UBound(ary)
  For i = 0 To mx - 1
    For j = i + 1 To mx
      If StrCmpLogicalW(StrPtr(ary(j)), _
               StrPtr(ary(i))) < 0 Then
        tmp = ary(i)
        ary(i) = ary(j)
        ary(j) = tmp
      End If
    Next
  Next
  Debug.Print Join(ary, vbLf)
End Sub

結果。

 X1Y1
 X1Y2
 X1Y10
 X2Y1
 X2Y2
 X2Y10
 X10Y1
 X10Y2
 X10Y10

参考:
『ファイル名の表示順序を変更する』
http://www.atmarkit.co.jp/fwin2k/win2ktips/342xpsort/xpsort.html
『StrCmpLogicalW function』
http://msdn.microsoft.com/en-us/library/bb759947%28VS.85%29.aspx
Comment
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする