ExcelVBAでランダムな文字列を生成する方法

2021年9月8日 2023年11月8日
カテゴリ: プログラミング
Excel ExcelVBA 乱数

ExcelVBAでランダムな整数を生成できるなら、次はランダムな文字列を生成したくなるものですよね?
たとえば自動生成される複雑なパスワードのようなランダムな文字列も Rnd 関数を使えば生成できるんです!

半角英数記号で構成されるランダムな文字列を生成する

方法としては
1. 使用したい文字をひとつずつ配列に格納する
2. 配列の要素数を元にランダムな整数を生成
3. 生成した整数を用いて配列から文字を取得する
4. 取得した文字をつなげていく
といった感じになります。

使用したい文字をひとつずつ配列に格納する

素直にやるとこんな感じになるでしょうか。

Sub example1()
    Dim arr as String
    arr = Aarray("a","b","c", ... (中略) ... ,"z")
End Sub

この方法は確実だけど、正直とってもめんどくさいですよね。
簡単なやり方として、文字コードを使用する方法を紹介します。

文字にはそれぞれ文字コード(または文字セット)というものが割り当てられていて、 a は 97 、 b は 98 … z は 122 という風になっています。
つまり 97 から 122 までの数値を For で配列に格納していけばよいのです。

文字コードについてはMicrosoftのドキュメントを参照しました。
https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/character-set-0127

Sub example2()
    Dim arr() As Integer
    Dim i As Integer
    Dim count As Integer

    count = 0

    For i = 97 To 122
        ReDim Preserve arr(count)
        arr(count) = i
        count = count + 1
    Next i
End Sub

これだけで配列 arr には 97 から 122 までの整数値が格納されます。
文字コードは Chr 関数で文字に変換できるので、後々配列から取り出したときに変換するという手順にします。

ついでに、大文字の A から Z は 65 から 90 、数字の 0 から 9 は 48 から 57 が割り当てられているのでこれも追加しましょう。
また、記号もいくつか追加してみましょう。今回は「 # $ % & 」の 4 つの記号を使うことにします。文字コードは 35 から 38 です。

Sub example3()
    Dim arr() As Integer
    Dim i As Integer
    Dim count As Integer

    count = 0

    '# $ % & の文字コードを格納
    For i = 35 To 38
        ReDim Preserve arr(count)
        arr(count) = i
        count = count + 1
    Next i

    '0 から 9 の文字コードを格納
    For i = 48 To 57
        ReDim Preserve arr(count)
        arr(count) = i
        count = count + 1
    Next i

    'A から Z の文字コードを格納
    For i = 65 To 90
        ReDim Preserve arr(count)
        arr(count) = i
        count = count + 1
    Next i

    'a から z の文字コードを格納
    For i = 97 To 122
        ReDim Preserve arr(count)
        arr(count) = i
        count = count + 1
    Next i
End Sub

配列の要素数を元にランダムな整数を生成

配列に要素番号を渡すと、対応する要素が返ってきます。
この要素番号をランダムに決めることでランダムな文字列を生成することができます。

ランダムな要素番号を生成するには、次のコードを応用します。

n から m までのランダムな整数を生成する

Sub example4()
    Dim n As Integer
    Dim m As Integer
    Dim randomNumber As Integer

    n = 10
    m = 150

    Randomize
    randomNumber = Int(Rnd * (m - n + 1) + n)
    Debug.Print randomNumber
End Sub

n を配列の要素数の最小値、 m を配列の要素数の最大値とすればよいのです。
配列の要素数の最小値と最大値はそれぞれ LBound 関数と UBound 関数で取得できます。

Sub example5()
    Dim arr() As Integer

    ...

    (中略)

    ...

    Dim randomNumber As Integer

    Randomize
    randomNumber = Int(Rnd * (UBound(arr) - LBound(arr) + 1) + LBound(arr))
    Debug.Print randomNumber
End Sub

生成した整数を用いて配列から文字を取得する

配列から要素を取得するには要素番号を指定するだけです。
要素番号は 0 から始まります。(先頭は 0 、次は 1 ...という感じ)

Sub example6()
    Dim arr As Integer
    arr = Aarray(10, 20, 30, 40, 50)

    Debug.Print arr(0)
End Sub

配列 arr には文字コードが格納されているので、 Chr 関数で文字に変換します。

Sub example7()
    Dim arr() As Integer
    Dim randomNumber As Integer

    ...

    (中略)

    ...

    Dim randomCharacter As String
    randomCharacter = Chr(arr(randomNumber))

End Sub

取得した文字をつなげていく

文字をつなげるには & を使用します。
ランダムな文字を一文字ずつ生成して、 For で任意の回数繰り返してつないでいけばいいのです。

これまでのコードをまとめると次のようになります。

Sub example8()
    Dim arr() As Integer
    Dim i As Integer
    Dim count As Integer

    count = 0

    '# $ % & の文字コードを格納
    For i = 35 To 38
        ReDim Preserve arr(count)
        arr(count) = i
        count = count + 1
    Next i

    '0 から 9 の文字コードを格納
    For i = 48 To 57
        ReDim Preserve arr(count)
        arr(count) = i
        count = count + 1
    Next i

    'A から Z の文字コードを格納
    For i = 65 To 90
        ReDim Preserve arr(count)
        arr(count) = i
        count = count + 1
    Next i

    'a から z の文字コードを格納
    For i = 97 To 122
        ReDim Preserve arr(count)
        arr(count) = i
        count = count + 1
    Next i


    Dim length As Integer
    Dim randomString As String

    Dim randomNumber As Integer
    Dim randomCharacter As String

    length = 50
    Randomize
    For i = 1 To length
        randomNumber = Int(Rnd * (UBound(arr) - LBound(arr) + 1) + LBound(arr))
        randomCharacter = Chr(arr(randomNumber))
        randomString = randomString & randomCharacter
    Next i

    Debug.Print randomString
End Sub

なんだかすごくそれっぽくなりましたね。

任意の長さのランダムな文字列を生成する関数を作ろう

文字列の長さを引数として渡すと、指定した長さのランダムな文字列を返す関数を作ってみましょう。
ついでにアルファベット小文字・大文字・数字・記号を使用するかオプションで決めれるようにしましょう。

Function randomString(length As Integer, Optional useLowerAlphabet As Boolean = True, Optional useUpperAlphabet As Boolean = True, Optional useDigits As Boolean = True, Optional useSymbol As Boolean = True) As String
    '引数
    '   length 生成する文字列の文字数

    'オプション引数(True : 使用する(デフォルト値) / False : 使用しない)
    '   useLowerAlphabet 小文字アルファベット
    '   useUpperAlphabet 大文字アルファベット
    '   useDigits 数字
    '   useSymbol 記号

    'オプション引数がすべて False の場合何もせずに関数を終了する。
    If Not useLowerAlphabet And Not useUpperAlphabet And Not useDigits And Not useSymbol Then
        Exit Function
    End If

    Dim arr() As Integer
    Dim i As Integer
    Dim count As Integer

    Dim randomNumber As Integer
    Dim randomCharacter As String

    count = 0

    If useSymbol Then
        '# $ % & の文字コードを格納
        For i = 35 To 38
            ReDim Preserve arr(count)
            arr(count) = i
            count = count + 1
        Next i
    End If

    If useDigits Then
        '0 から 9 の文字コードを格納
        For i = 48 To 57
            ReDim Preserve arr(count)
            arr(count) = i
            count = count + 1
        Next i
    End If

    If useUpperAlphabet Then
        'A から Z の文字コードを格納
        For i = 65 To 90
            ReDim Preserve arr(count)
            arr(count) = i
            count = count + 1
        Next i
    End If

    If useLowerAlphabet Then
        'a から z の文字コードを格納
        For i = 97 To 122
            ReDim Preserve arr(count)
            arr(count) = i
            count = count + 1
        Next i
    End If

    Randomize
    For i = 1 To length
        randomNumber = Int(Rnd * (UBound(arr) - LBound(arr) + 1) + LBound(arr))
        randomCharacter = Chr(arr(randomNumber))
        randomString = randomString & randomCharacter
    Next i

End Function

こんな感じで使用します。

たとえば大文字アルファベット + 数字のみで 8 文字のランダムな文字列を生成する場合は次のようにします。

=randomString(8, FALSE, , , FALSE)

関連の記事

ExcelVBA でランダムな整数を生成する方法

ExcelVBA で時間が正しく変換されない

Excel のセルに名前を付けよう

OpenPyXl でチェックボックスを押したい