aodama.gif(0.97KB) 文字列を特定の区切り文字で分割する(Split)

 「特定の区切り文字で分割する」とは、

ねずみ,牛,虎,うさぎ,竜,へび,馬,羊,さる,にわとり,犬,いのしし
みたいに、特定の区切り文字(この場合はカンマ)で区切られた文字列を、 その区切り文字で分割し、項目ごとに変数などに代入したりする処理のことを言ってます。 何かと需要が多いですね。
 ところが VB にはなぜか今までそのような関数が標準装備されていませんでした。 VB6 からようやく Split 関数が追加されましたが、 私のような VB5 以前のユーザーは結局自分で作るしかありません(^^;

 以下は私が自作した、文字列を特定の区切り文字で分割し、配列に代入する StrSplit 関数です。 この関数は戻り値として項目数(配列要素数)を返すので、 UBound で配列個数を調べる必要がないので便利かも(^^;

※以下のサンプルは、VB5 用です。VB4 の方はこちらをお使い下さい。

Option Explicit

'===== StrSplit Module =====
'(C)1999-2001 けるべ
'MAIL : NULL
'HOME : http://www.geocities.co.jp/SilkRoad/4511/

'引数 lngDefaultMaxArray を省略した場合に使用される値です。
'詳しくは下の StrSplit 関数仕様をご覧下さい。
Public Const STRSPLIT_DAFAULT_MAXARRAY = 255

'----- StrSplit 関数 Ver 1.05 -----
'
'文字列を特定の区切り文字で分割し、その結果を引数 strArray() で
'指定された文字列変数配列に格納します。詳しくはサンプルフォーム参照。
'
'引数 strExpression
'   必ず指定します。文字列と区切り文字を含んだ文字列式を指定します。
'   引数 strExpression が長さ 0 の文字列 ("") である場合、
'   StrSplit 関数は 0 を返します。
'
'引数 strDelimiter
'   文字列の区切りを識別する文字を指定します。引数 strDelimiter が
'   長さ 0 の文字列 ("") である場合は、引数 strExpression 全体の
'   文字列を含む単一の要素の配列を返します。指定された区切り文字が
'   存在しない場合も同様です。
'
'引数 strArray()
'   分割結果が格納される文字列型変数配列を指定します。StrSplit 関数を
'   呼び出すプロシージャ内で動的配列として宣言して渡して下さい。
'   配列サイズは関数内で初期化されるため、あらかじめ確保しておく
'   必要はありません。
'
'引数 lngCompare
'   省略可能です。文字列式を評価するときに使用する文字列比較の
'   モードを表す数値を指定します。省略した場合、バイナリ モードで
'   比較が行われます。
'
'   vbBinaryCompare : バイナリ モードで比較を行います。(0)
'   vbTextCompare   : テキスト モードで比較を行います。(1)
'
'引数 lngDefaultMaxArray
'   省略可能です。配列要素最大数の初期値を設定します。
'   もし配列サイズがここで設定した値では足りない場合、ここで設定した
'   個数ずつ配列サイズを増加させてゆきます。そのため分割項目数が
'   多い場合、この値を大きくすれば処理速度は向上しますが、
'   その分メモリを多く食います。予想される分割項目数に合わせて
'   調節して下さい。省略した場合、STRSPLIT_DAFAULT_MAXARRAY 定数の
'   値が使用されます。
'
'戻り値
'   成功した場合、配列 strArray() に格納した配列要素の
'   個数(要素最大値 + 1)を返します。
'   引数 strExpression に空の文字列を渡した場合、0 を返します。
'
'☆ StrSplit 関数と、VB6 の Split 関数との相違点
'
'   1.戻り値は配列の個数である。
'   2.デリミタ(区切り文字)は省略できない。
'   3.第 3 引数に宣言済み文字列変数配列を渡す。
'     (ここに分割結果が格納される)
'   4.count 引数はない。
'   5.配列個数初期値が設定できる。意味ねー(笑)
'
'戻り値が配列の個数となるため、Split 関数のように配列個数を
'UBound 関数で調べる必要もないため使いやすいと思います。
'処理速度はどっちが速いのかわかりません(^^;
'
'☆仕様変更
'
'Ver 1.03 より、返値を「配列の個数」に変更しました。
'Ver 1.02 以前のバージョンから使用されている方は注意して下さい。
'
'Ver 1.05 より、引数 strDelimiter で指定された区切り文字が
'存在しない場合は、引数 strExpression 全体の文字列を含む単一の要素の
'配列を返すように変更しました。(strArray(0) = strExpression)
'
'Ver 1.05 より、配列要素最大値の初期値を設定できるようにしました。
'末尾のオプション引数なので、省略しても何ら問題ありません。
'
Public Function StrSplit _
    (ByRef strExpression As String, _
     ByRef strDelimiter As String, _
     ByRef strArray() As String, _
     Optional ByVal lngCompare As Long = vbBinaryCompare, _
     Optional ByVal lngDefaultMaxArray As Long = STRSPLIT_DAFAULT_MAXARRAY) As Long

 Dim lngPos1 As Long     'InStr関数用検索開始位置
 Dim lngPos2 As Long     'InStr関数用文字検出位置
 Dim lngStrLen As Long   '検索される文字列のサイズ
 Dim lngDivLen As Long   '区切り文字のサイズ
 Dim lngCnt As Long      '項目数(=配列要素数)をあらわすカウンタ
 Dim lngMaxArray As Long '配列要素の最大数

    lngStrLen = Len(strExpression)  '元の文字列 strExpression の文字数を取得
    lngDivLen = Len(strDelimiter)   '区切り文字 strDelimiter の文字数を取得
    
    If lngStrLen = 0 Then           '引数 strExpression に空の文字列を渡した場合
        StrSplit = 0                '0 を返す
        Exit Function
    ElseIf lngDivLen = 0 Then       '引数 strDelimiter に空の文字列を渡した場合
        ReDim strArray(0)
        strArray(0) = strExpression '引数 strExpression を単一要素の配列として返す
        StrSplit = 1
        Exit Function
    End If
    
    lngMaxArray = lngDefaultMaxArray
    ReDim strArray(lngMaxArray)     '配列最大要素数を初期値にセット
    lngPos1 = 1                     '初期検索開始点を設定

    Do                                                                             '区切り文字が検出されなくなるまでループ
        If lngCnt > lngMaxArray Then                                               '項目数が配列要素最大数を超えてしまった場合
            lngMaxArray = lngMaxArray + lngDefaultMaxArray                         '配列要素最大数を lngDefaultMaxArray 増やす
            ReDim Preserve strArray(lngMaxArray)
        End If
        lngPos2 = InStr(lngPos1, strExpression, strDelimiter, lngCompare)          '区切り文字を検索しその位置を返す
        If lngPos2 Then                                                            '区切り文字が存在した場合
            strArray(lngCnt) = Mid$(strExpression, lngPos1, lngPos2 - lngPos1)     '検索開始点から(区切り文字位置 - 1)までの文字列をを配列に代入
            lngPos1 = lngPos2 + lngDivLen                                          '次回の検索開始点を設定
            lngCnt = lngCnt + 1                                                    '次回のため項目数を一つ増やす
        Else                                                                       '区切り文字が存在しない場合
            If lngCnt Then                                                         '最後の要素である場合
                strArray(lngCnt) = Right$(strExpression, lngStrLen - lngPos1 + 1)  '文字列の最後から検索開始点までの文字列を配列に代入
            Else                                                                   '区切り文字が全く存在しない場合
                strArray(lngCnt) = strExpression                                   '引数 strExpression を単一要素の配列として返す
                Exit Do
            End If
        End If
    Loop Until lngPos2 = 0

    ReDim Preserve strArray(lngCnt) '配列の余分な要素を削る
    StrSplit = lngCnt + 1           '配列の個数を返す

End Function

サンプル : ダウンロード strsplit.lzh(3.82KB)

 この関数で先ほどの文字列を処理してみます。

lngRet = StrSplit("ねずみ,牛,虎,うさぎ,竜,へび,馬,羊,さる,にわとり,犬,いのしし", ",", strRetArray())
とすれば、
strRetArray(0) = "ねずみ"
strRetArray(1) = "牛"
strRetArray(2) = "虎"
strRetArray(3) = "うさぎ"
strRetArray(4) = "竜"
strRetArray(5) = "へび"
strRetArray(6) = "馬"
strRetArray(7) = "羊"
strRetArray(8) = "さる"
strRetArray(9) = "にわとり"
strRetArray(10) = "犬"
strRetArray(11) = "いのしし"
のように格納され、戻り値(lngRet)は配列項目数の 12 になります。


VBコーナーにもどる   トップページにもどる