「~」や「, 」で連結された数字を元の数字に戻す

先日は、連続する数字を「~」で、不連続な数字は「, 」で連結する
ユーザー定義関数の作成に挑戦した。
infoment.hatenablog.com

すると、この逆を行う処理についてのコメントが寄せられた。
そこで今回は、これについて挑戦してみた。
f:id:Infoment:20191123225913p:plain

今回の解説については、コード内のコメントで行ったので前置きを割愛する。

Public Function UnmargeNumber(ByVal source As String, _
                           Optional JoinFlag As Boolean = True) As Variant
    If source = vbNullString Then
        UnmargeNumber = vbNullString
        Exit Function
    End If
                     
    ' 全角と半角の混在を想定し、一旦全て半角化する。
        source = StrConv(source, vbNarrow)
    ' 余分な半角スペースを除去しておく。
        source = Replace(source, " ", vbNullString)

    ' 桁数取得のために、「~」を「,」に置き換えて一旦分割。
    Dim arr As Variant
        arr = Split(Replace(source, "~", ","), ",")
    ' 個別部位桁数。
    Dim RemainDigitNumber As Long
        RemainDigitNumber = Len(arr(UBound(arr)))
    ' 共通部位桁数。
    Dim CommonDigitNumber As Long
        CommonDigitNumber = Len(arr(0)) - RemainDigitNumber
    Dim CommonCharacter As String
        CommonCharacter = Left(source, CommonDigitNumber)
        
    ' 改めて、引数の文字を「,」で分割する。この時点で、未だ「~」は
    ' そのまま残しておく。また、共通部位は取り除いておく。
        arr = Split(Mid(source, CommonDigitNumber + 1), ",")
        
    ' 分割した総数は、「~」が存在するため現時点で不明。そのため、
    ' とりあえずまずコレクションに格納する。
    Dim col As Collection
    Set col = New Collection
    Dim i As Long
    Dim j As Long
    Dim TempCharacter As String
    Dim TempArray As Variant
        For i = 0 To UBound(arr)
            TempCharacter = arr(i)
            ' 「~」を含む場合は、これを展開してコレクションに格納する。
            If TempCharacter Like "*~*" Then
                TempArray = Split(TempCharacter, "~")
                For j = 0 To TempArray(1) - TempArray(0)
                    col.Add CommonCharacter & _
                            Format(TempArray(0) + j, _
                                   WorksheetFunction.Rept(0, RemainDigitNumber))
                Next
            Else
                col.Add CommonCharacter & Format(arr(i), WorksheetFunction.Rept(0, RemainDigitNumber))
            End If
        Next
    
    ' コレクションを配列に変換する。
    ReDim arr(0 To col.Count - 1)
        For i = 1 To col.Count
            arr(i - 1) = col.Item(i)
        Next
        
    ' JoinFlagによって、戻り値を変更する。
    '  True の場合、「,」で結合して文字列として返す。
    '  Falseの場合、配列として返す。
    ' ※ワークシートで使用する場合を想定し、初期値は文字で返している。
        Select Case JoinFlag
            Case True
                UnmargeNumber = Join(arr, ", ")
            Case False
                UnmargeNumber = arr
        End Select    
End Function

テスト結果はこちら。
f:id:Infoment:20191123231252g:plain

数字を含まない場合など、細かいエラー処理は未だ尽くしきれていない。しかし、先日作成した連結する関数とセットで、何かと使えそうです。

参考まで。