VBAで「数字のみ」を厳密に判定する関数

ISBN-10形式のASINを判定する場合、「10文字あるか」だけでは不十分です。

例えば、

1234567890

は数字10桁ですが、

12345678A0

は10文字あってもISBN-10形式ではありません。

そこで、文字列が0~9の数字だけで構成されているかを判定する専用の関数を使用します。

数字のみ判定関数

今回使用している関数は次のとおりです。

Private Function 数字のみ判定(ByVal s As String) As Boolean

    Dim i As Long
    Dim c As String

    If Len(s) = 0 Then
        数字のみ判定 = False
        Exit Function
    End If

    For i = 1 To Len(s)
        c = Mid(s, i, 1)

        If c < "0" Or c > "9" Then
            数字のみ判定 = False
            Exit Function
        End If
    Next i

    数字のみ判定 = True

End Function

この関数の役割

この関数は、引数として渡された文字列が、

0~9だけで構成されている

場合にTrueを返し、それ以外の場合はFalseを返します。

例えば、

文字列結果
"123456789"True
"123"True
"0"True
"12345678A"False
"12-345"False
"+123"False
"1.23"False
""False

となります。


なぜIsNumericを使わないのか?

VBAには、文字列が数値として扱えるかどうかを判定するIsNumericという組み込み関数があります。

例えば、

If IsNumeric(s) Then

と書くことができます。

しかし、今回の目的は「数値として計算できるか」ではありません。

文字列が0~9だけで構成されているかを確認したいのです。

IsNumericは、今回のような「純粋な数字だけ」という厳密な判定には適していません。

ISBNやASINの桁チェックでは、

123456789

はOKですが、

+12345678
123.45678
1E8

のような表記はNGです。

そのため、今回の処理ではIsNumericを使わず、1文字ずつ確認しています。


1.空文字列をチェックする

最初に、文字列が空でないか確認しています。

If Len(s) = 0 Then
    数字のみ判定 = False
    Exit Function
End If

Lenは文字列の長さを取得するVBAの組み込み関数です。

例えば、

Len("12345")

なら5が返ります。

空文字列の場合は0になります。

数字が1文字もない場合は「数字のみ」とは判定しないため、Falseを返します。


2.1文字ずつ確認する

次に、Forループを使って文字列を1文字ずつ確認します。

For i = 1 To Len(s)

例えば、

123456789

という文字列なら、

1文字目 → 1
2文字目 → 2
3文字目 → 3
...
9文字目 → 9

というように順番に確認します。


3.Mid関数で1文字取り出す

c = Mid(s, i, 1)

Midは、文字列の途中から指定した文字数を取り出す関数です。

例えば、

Mid("123456789", 3, 1)

とすると、

3

が返ります。

今回の処理では、iの値を変化させることで、文字列を1文字ずつ取り出しています。


4.0~9の範囲か確認する

この部分が、この関数の重要なポイントです。

If c < "0" Or c > "9" Then

取り出した1文字が、

"0" ~ "9"

の範囲にあるか確認しています。

例えば、

"5"

なら数字なので問題ありません。

一方、

"A"

や、

"-"

などが含まれていれば、

数字のみ判定 = False

として、その時点で処理を終了します。


5.すべて数字ならTrue

最後まで問題なくチェックできた場合、

数字のみ判定 = True

としてTrueを返します。

つまり、

1文字でも数字以外があれば → False

すべて0~9なら → True

というシンプルな仕組みです。


ISBN-10判定でどのように使われているか

この関数は、先ほどのISBN10形式判定から呼び出されています。

例えば、

If Not 数字のみ判定(Left(s, 9)) Then

では、ISBN-10の先頭9桁を取り出して、それがすべて数字か確認しています。

また、10桁目についても、

If 数字のみ判定(lastChar) Or UCase(lastChar) = "X" Then

として、

10桁目が数字
または
10桁目がX

であればISBN-10形式と判定しています。


今回の処理で使用している関数

今回の3つの自作関数を整理すると、次のようになります。

① 数字のみ判定

Private Function 数字のみ判定(ByVal s As String) As Boolean

役割:

文字列が0~9だけで構成されているかを判定します。


② ISBN10形式判定

Private Function ISBN10形式判定(ByVal asinVal As String) As Boolean

役割:

ASINがISBN-10として扱える形式か判定します。

判定条件は、

  • 10桁
  • 先頭9桁が数字
  • 10桁目が数字またはX

です。

この関数の中から①の数字のみ判定を呼び出しています。


③ ISBN10to13変換

Private Function ISBN10to13変換(ByVal isbn10 As String) As String

役割:

ISBN-10をISBN-13へ変換します。

この関数では、①の数字のみ判定や②のISBN10形式判定は呼び出していません。


② ISBN10形式判定 と ③ ISBN10to13変換 は、以下に詳細説明がありますので、参照してください。

Follow me!