zz log

zaininnari Blog

エクセル・アクセスで自然順ソート

概要

excel や Access では自然順ソート(natsort) が提供されていません。(PHP では提供されています!) 自然順ソートを真面目に実装するのは意外に大変です。

大変なポイントとして、以下の3点があります。

  • 数字とそれ以外に分割を行い、個別に比較しないといけないので、ワークシート関数のみではほぼ不可能
  • 01, 001, 0001 のような0の桁埋めされたものとされてないものを区別するかで処理が分岐
  • 空白文字の扱い

仕様

今回のコードは、住所の並び替えを念頭においた仕様です。

  • エクセル上で並び替える必要上、手軽に並び替えを行いたいので、1セルにまとめるため、数字の桁埋めの上限に制限がある(truncateLen = 5)
  • 全角数字は、事前に半角数字に変換
  • 全角空白は、事前に半角数字に変換
  • 漢数字の地番は考慮しない
  • 環境依存文字が含まれると、処理できない(Unicodeで処理しないといけないが、手抜き)
  • 0の桁埋めを考慮しない

参考URL

Function formatNatsort(ByVal text As String) As String

    Dim i As Long, length As Long, ascii As Long
    Dim char As String, bufferString As String, padding As String
    Dim beforeState As Long, currentState As Long, truncateLen As Long

    length = Len(text)
    padding = "0000000000000000"
    beforeState = -1
    currentState = 0
    bufferString = ""
    truncateLen = 5

    If length = 0 Then
        formatNatsort = ""
        Exit Function
    End If

    For i = 1 To length
        char = Mid(text, i, 1)
        ascii = Asc(char)
        If ascii = 32 Then
            currentState = 0
        ElseIf ascii >= 48 And ascii <= 57 Then
            currentState = 1
        Else
            currentState = 2
        End If

        If i = 1 Then
            beforeState = currentState
        End If
        If currentState <> 0 Then
            If currentState = beforeState Then
                bufferString = bufferString & char
            Else
                If currentState = 1 Then
                    formatNatsort = formatNatsort & bufferString
                Else
                    formatNatsort = formatNatsort & Right(padding & bufferString, truncateLen)
                End If
                bufferString = char
            End If
            beforeState = currentState
        End If

    Next i

    If currentState = 1 Then
        formatNatsort = formatNatsort & Right(padding & bufferString, truncateLen)
    Else
        formatNatsort = formatNatsort & bufferString
    End If
End Function

使い方

モジュールを新規に追加して、コードをコピペしてください。

オリジナル 処理後
東京都千代田区永田町2丁目3−1 東京都千代田区永田町00002丁目00003−00001
東京都千代田区永田町1−7−1 東京都千代田区永田町00001−00007−00001

後は、処理後のフィールドをキーにして並び替えを実行してください。