FC2ブログ

スポンサーサイト 


上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

--/--/--

Category: スポンサー広告

TB: --  /  CM: --

top △

文字の並べ替え 


"201-20 201-1  202-2 202-11 1011 235 20" という文字列があった時、
空白を区切りとして、各文字列を並べ替えたい・・・・

これ、単純に並べ替えると
"1011 20 201-1 201-20 202-11 202-2 235" の様になりますが
"20 201-1 201-20 202-2 202-11 235 1011" の様に数値として解釈した結果で並び替えたい。

数値として解釈する際、"-" の区切りが1つ存在する場合がある。
この時に、"-" がある場合には、左側のもの・・・  "-" がない場合は、そのままで・・・

また、"-" があった場合の右側についても数値として解釈する。
("202-11 202-2" の順ではなく "202-2 202-11")

これを実現しようとすると、
・空白区切りで分割して
・"-" の前/後を数値化して
・並べ替え・・・(ソート)
・・・・・ってな処理手順になるかと思います。

せっかく Access を使っているので、ソートの楽な インメモリレコードセットを使って・・・
 
ADODB のインメモリレコードセットを使うので、VBE での参照設定は忘れずにしておきます。
以下の様な感じの記述になりました。
Public Function NumSort(sS As String, Optional SEP As String = "-") As String
  Dim v As Variant
  Dim sAry() As String
  Dim sTmp As String
  Dim i As Long, j As Long

  On Error Resume Next
  NumSort = ""
  If (Len(sS) = 0) Then Exit Function

  With New ADODB.Recordset
    .Fields.Append "元", adVarChar, 255
    .Fields.Append "前", adInteger
    .Fields.Append "後", adInteger
    .CursorLocation = adUseClient
    .Open

    For Each v In Split(sS, " ")
      If (Len(v) > 0) Then
        sAry = Split(v & SEP, SEP)
        i = 0: j = 0
        i = CLng("0" & sAry(0))
        j = CLng("0" & sAry(1))
        .AddNew
        .Fields("元") = v
        .Fields("前") = i
        .Fields("後") = j
        .Update
      End If
    Next

    sTmp = ""
    If (.RecordCount > 0) Then
      .Sort = "前, 後, 元"
      While (Not .EOF)
        sTmp = sTmp & " " & .Fields("元")
        .MoveNext
      Wend
      sTmp = Mid(sTmp, 2)
    End If
    NumSort = sTmp
    .Close
  End With
End Function
 
用意した関数「NumSort」では、
文字列と、その有効文字列内の区切り「-」を指定できるように・・・
(空白についても指定できるようにした方が良いのかも)

    .CursorLocation = adUseClient
は、なくても動いた様な・・・・気も・・・・
これは、
      .Sort = "前, 後, 元"
の、「Sort」を使う時には CursorLocation は adUseClient で・・・・
というのを、どこかで見たような気がして・・・

    For Each v In Split(sS, " ")
      If (Len(v) > 0) Then
        sAry = Split(v & SEP, SEP)
        i = 0: j = 0
        i = CLng("0" & sAry(0))
        j = CLng("0" & sAry(1))
で、文字列を分解していきますが、
空白で区切ったものが文字列だったら、必ず "-" が存在するようにしてから Split を・・・
で、(0) と (1) を CLng で整数にしていきますが、空文字だった時に対処するように
"0" を先頭に付加してエラーにならない様に・・・
数値じゃなかった時には、CLng でエラーになるので、各初期値を事前に設定・・・
ってな流れになります。

数値にした時に整数を使うようにしましたが、データのパターンによっては実数が良かったり・・・

何か解釈して、配列的要素をソート(並び替える)なら、
インメモリレコードセットを使った方が楽かな・・・・という例でした。

※ 現状 "201-1" と、 "201-01" や "0201-001" は同じ数値になっています。
これを解消するには、フィールドを追加して・・・・云々処理増えますね。
実際に必要になったら、その時のデータパターンを見て改造していくのですかね・・・

他にもっと楽な方法があるのかもしれませんが・・・・・

今回、サンプルファイルの添付はありません。
関連記事

2011/12/18

Category: 関数を作ってみる

TB: 0  /  CM: 0

top △

この記事に対するコメント

top △

コメントの投稿

Secret

top △

トラックバック

トラックバックURL
→http://kikutips.blog13.fc2.com/tb.php/114-e4012f09
この記事にトラックバックする(FC2ブログユーザー)

top △


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。