概要
excel や Access では自然順ソート(natsort) が提供されていません。(PHP では提供されています!) 自然順ソートを真面目に実装するのは意外に大変です。
大変なポイントとして、以下の3点があります。
- 数字とそれ以外に分割を行い、個別に比較しないといけないので、ワークシート関数のみではほぼ不可能
- 01, 001, 0001 のような0の桁埋めされたものとされてないものを区別するかで処理が分岐
- 空白文字の扱い
仕様
今回のコードは、住所の並び替えを念頭においた仕様です。
- エクセル上で並び替える必要上、手軽に並び替えを行いたいので、1セルにまとめるため、数字の桁埋めの上限に制限がある(truncateLen = 5)
- 全角数字は、事前に半角数字に変換
- 全角空白は、事前に半角数字に変換
- 漢数字の地番は考慮しない
- 環境依存文字が含まれると、処理できない(Unicodeで処理しないといけないが、手抜き)
- 0の桁埋めを考慮しない
参考URL
- JavaScriptでオレオレnatsortを実装してみました - latest log
- シンプルな記述のため、処理を理解する手助けになりました。
- pythonでnatsort(自然順ソート) - Python仲間募集中
- python だけど、処理毎の詳しい解説
- Natural Order String Comparison
- 仕様が書かれているページ
- sourcefrog.net/projects/natsort/natcompare.js
- 仕様に沿った JavaScript による実装。
コード
- 仕様に沿った JavaScript による実装。
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 |
後は、処理後のフィールドをキーにして並び替えを実行してください。