今回は仕事で「チェックデジット」をExcelのシート内に大量に生成する必要があり、ネットでサンプルコードを探しましたが、JANなどに合わせて桁数が固定されていたりちょうど良いものが見当たらなかったので自作しました。
どこかで需要はあるかと思うので、作ったサンプルプログラムを紹介させていただきます。
尚、今回作成したプログラムはVBAのFunctionブロシージャなので、ExcelでもAccessでも両方使用できます。
実装したチェックデジットの仕様
チェックデジットと一言でいっても色々な種類が有ります。
今回私が実装したのは「モジュラス10 ウェイト2」という種類です。
「モジュラス10 ウェイト2」の計算方法
「モジュラス10 ウェイト2」の値を算出するための計算方法を紹介しておきます。
文字で見ると複雑に見えますが、そんなに難しくはありません。
- 算出対象の数字の一桁目(一番右)を奇数、二桁目を偶数と順に一文字ずつ数字を抜き出す
- 奇数位置の数字に2を掛けた値の一桁目を抜き出して合算していく
- 偶数位置の数字はそのままの値を合算していく
- 上記の項番2と3の値を合算し、その値を10で割り余りに出す
- 余りがあれば10から余りを引いた値、余りが無ければ0がチェックデジット
サンプルプログラム
サンプルプログラムを紹介します。
今回作成した関数の第一引数としてチェックデジット算出対象の数値、第二引数として、第一引数で渡した数値の想定される最大桁数を指定します。
最大桁数は、例えば第一引数の数値が連番で、その連番の最大桁数をシステム的に9桁に制限しているなら9を第二引数に渡します。
これは内部的に固定長にして処理しているからですが、この部分の設計は無くしてしまっても良いかと思います。
'引数で渡された数値と指定した桁数を元にチェックデジットを返します。
'引数1:チェックデジット算出対象の数字
'引数2:チェックデジット算出対象の数字の最大桁数
'戻り値:チェックデジット
Function Get_Modulus10(TargetNumber As Long, CharDigit As Integer) As Integer
Dim ConvTarget As String 'チェックデジット算出対象を0埋め固定長にして格納
Dim FormatNumber As String 'Format関数で固定長化する際に指定桁数の0埋め用文字列を格納
Dim i As Integer
Dim ChkNum As Integer
Dim ChkCnt As Integer '文字列抜き出し処理の偶数位置か奇数位置かの判別で使用
Dim TempNum As Integer 'ループ処理内で一時的に使用
Dim SumNum As Integer '一文字ごとに抜き出して処理をして合算する値として使用
Dim ModNum As Integer '処理の終わりに余りを取得する処理で使用
'偶数奇数判別用文字位置のカウンターを初期化
ChkCnt = 1
'指定された桁数で0埋めの文字列を生成します。
For i = 1 To CharDigit Step 1
FormatNumber = FormatNumber & "0"
Next
'引数の数値を0埋めの固定長に置き換えます。
ConvTarget = Format(TargetNumber, FormatNumber)
'桁数分ループしてチェックデジットを算出します。
'文字列を右の末尾から順に先頭へチェックするためにカウンターを減らします。
For i = CharDigit To 1 Step -1
'チェック対象の数字を抜き出します。
ChkNum = Mid(ConvTarget, i, 1)
'現在位置が奇数位置か偶数位置かを判別します。
If ChkCnt Mod 2 = 0 Then
'偶数
'抜き出した数字をそのまま使う
SumNum = SumNum + ChkNum
Else
'奇数
'抜き出した数字を2で掛ける
TempNum = ChkNum * 2
'2を掛けた値が二桁か否かで処理を分岐
If TempNum > 9 Then
'二桁の場合は一桁目を抜き出す
SumNum = SumNum + CInt(Right(CStr(TempNum), 1))
Else
'一桁の場合は2で掛けた値をそのまま使う
SumNum = SumNum + TempNum
End If
End If
'偶数位置奇数位置判別用カウンターをカウントアップします。
ChkCnt = ChkCnt + 1
Next
'上記処理で取得して合算した値を10で割り、余りを取得します。
ModNum = SumNum Mod 10
'上記処理で余りが0の場合はチェックデジットも0として処理を終了します。
If ModNum = 0 Then
Get_Modulus10 = 0
Else
'余りが存在する場合は10から余りを引いた値がチェックデジット
Get_Modulus10 = 10 - ModNum
End If
End Function
最後に
この記事を読んでいる人であれば当然知っているかと思いますが、チェックデジットは、入力された値の誤りを検出する仕組みです。
例えばシステムの画面に桁数の多い数字を手入力する場合などは、どんなに慣れたパンチャーでも一定の確率でミスが発生します。
桁の多い数字の末尾にチェックデジットを組み込んでおき、チェックデジットも含んだ数字を入力させることで、入力に誤りがあった場合入力された数字の末尾の値が本来のチェックデジットと合わなくなり、入力に誤りがあることに気付けるようになります。
ITエンジニアとしては必ず必要な知識なので、もしその言葉を聞いたことがなかったり仕組みを知らない人は、これを機に理解しておいていただくと良いかと思います。
それでは今回も読んでいただきましてありがとうございました。
また次回もよろしくお願いします。

