スポンサーリンク
技術情報

郵便バーコード取得クラス【VB.NET】ソース公開!

この記事は郵便バーコードを作る為の.NETでのサンプルってないかな?にソースを公開して答えます!

バーコードを作るための文字列生成コードを公開します!

郵便バーコードって?

郵便バーコードは郵便物の宛先区分を機械化するために使われます。

郵便番号とそれ以外の住所情報から基本となる文字を作り、バーコード化したものです。一定条件で郵送料の割引が適用されます。

C#版はこちら

郵便バーコード取得クラス【C#.NET】ソース公開! この記事は郵便バーコードを作る為の.NETでのサンプルってないかな?にソースを公開して答えます! バーコードを作るための文...

バーコード用文字生成の手順

住所からの文字の生成の手順は図の通り。

特殊な処理

手順でなんとなくイメージは湧きますが、意外と特殊処理が存在します。

特殊処理の内容
  • 特定文字前の数字は採用(丁目/丁 /番地/番/号/地割/線/の/ノ)
  • 漢数字→アラビア数字化 (例)百一番地 → 101
  • 抜き出し文字のハイフン1文字置換
    「漢字・かな文字・カタカナ・漢数字・ブランク・2文字以上連続したアルファベット文字」

フローの確認方法

郵便局のHPで、下記で一致すればロジック上問題ないとされています。

住所 文字情報
千葉市稲毛区緑町3丁目30-8 郵便ビル403号 3-30-8-403
秋田県大仙市堀見内 南田茂木 添60-1 60-1
東京都台東区台東5-6-3 ABCビル10F 5-6-3-10
北海道札幌市東区北六条東4丁目 郵便センター6号館 4-6
北海道札幌市東区北六条東8丁目 郵便センター10号館 8-10
山梨県韮崎市龍岡町下條南割 韮崎400 400
千葉県鎌ケ谷市右京塚 東3丁目-20-5 郵便・A&bコーポB604号 3-20-5B604
東京都青梅市河辺町十一丁目六番地一号 郵便タワー601 11-6-1-601
岩手県宮古市大字津軽石第二十一地割大淵川480 21-480
大阪府堺市堺区中田出井町四丁六番十九号 4-6-19
北海道帯広市稲田町南七線 西28 7-28
茨城県日立市宮田町6丁目7-14 ABCビル2F 6-7-14-2
神戸市中央区港島中町9丁目7-6 郵便シティA棟1F1号 9-7-6A1-1
京都府綾部市青野町綾部6-7 LプラザB106 6-7LB106
札幌市中央区南四条西29丁目1524-23 第2郵便ハウス501 29-1524-23-2-
福井県福井市新田塚3丁目80-25 J1ビル2-B 3-80-25J1-2B

公開クラスについて

今回公開するクラスのイメージ・使用方法・ソースについて解説します!

クラスの設計イメージ

今回のクラスは手順の図の部分をコーディングしています。
郵便番号は住所から判断できないので、メソッド引数として渡します。
住所の文字情報を出力するイメージです。

SQL CLRーVS/SQL Server 2017で使ってみた!-イメージ図

使用方法

txtYubin.Text = cYubin.GetYubin(txtZipCode.Text, txtAddress.Text)

文字列取得クラスソース

Imports System.Text.RegularExpressions

Public Class cYubin
    Implements IDisposable

    Private Class _cArabicReplace
        Implements IDisposable
        Private _sRegexKanji As String = ""
        Private _sRegexPlace As String = ""
        Private _sRegexSpecific As String = ""

        Private _sCheckAddress As String = ""
        Private _sCheckPlace4 As String = ""
        Private _sCheckPlace As String = ""

        Private _sPatternKanji As String = "〇一二三四五六七八九"
        Private _sPatternPlace As String = "十百千"
        Private _sPatternPlace4 As String = "万億兆"

        Sub New()
            Dim sPatternSpecific As String = "(丁目|丁|番地|番|号|地割|線|の|ノ| )"

            _sCheckAddress = String.Format("[{0}]+{1}", _sPatternKanji + _sPatternPlace + _sPatternPlace4, sPatternSpecific)
            _sCheckPlace4 = String.Format("[{0}]+[{1}]*", _sPatternKanji + _sPatternPlace, _sPatternPlace4)
            _sCheckPlace = String.Format("[{0}]*[{1}]*", _sPatternKanji, _sPatternPlace)

            _sRegexSpecific = String.Format("[{0}]", sPatternSpecific)
            _sRegexPlace = String.Format("[{0}]", _sPatternPlace)
            _sRegexKanji = String.Format("[{0}]", _sPatternKanji)
        End Sub

        Public Sub Dispose() Implements IDisposable.Dispose
        End Sub

        Public Function GetArabic(ByVal sKanji As String) As String
            Dim sReturn As String = ""
            sReturn = Regex.Replace(sKanji, _sCheckAddress, AddressOf _GetArabic)
            Return sReturn
        End Function

        Private Function _GetArabic(ByVal m As System.Text.RegularExpressions.Match) As String
            Dim sValue As String = Regex.Replace(m.Value, _sRegexSpecific, "-")
            Dim sReturn As String = ""

            ''(1)4桁文字単位抽出
            Dim mlPlace4 As MatchCollection = Regex.Matches(sValue, _sCheckPlace4)
            If mlPlace4.Count > 0 Then
                Dim lValue As Long = 0
                Dim mPlace4 As Match
                For Each mPlace4 In mlPlace4

                    ''(1-1)4桁倍率算出
                    Dim iPlace4 As Integer = InStr(_sPatternPlace4, mPlace4.Value.Substring(mPlace4.Value.Length - 1))

                    ''(2)1桁文字単位算出
                    Dim mlPlace As MatchCollection = Regex.Matches(mPlace4.Value, _sCheckPlace)
                    Dim mPlace As Match
                    For Each mPlace In mlPlace
                        If Not mPlace.Value = "" Then

                            ''(2-1)1桁倍率算出
                            Dim sPlace As String = Regex.Replace(mPlace.Value, _sRegexKanji, "")
                            Dim iPlace As Integer = sPlace.Length
                            If iPlace > 0 Then iPlace = InStr(_sPatternPlace, sPlace)

                            ''(3)アラビア数字取得内部関数
                            Dim sKanji As String = Regex.Replace(Regex.Replace(mPlace.Value, _sRegexPlace, ""), _sRegexKanji, AddressOf _GetReplaceNumeric)
                            Dim iKanji As Integer = 1
                            If IsNumeric(sKanji) Then iKanji = CInt(sKanji)

                            ''(4)4桁/1桁倍率/アラビア数値の加算処理
                            lValue += CLng(iKanji * 10 ^ (4 * iPlace4 + iPlace))
                        End If
                    Next
                Next
                sReturn = CStr(lValue).Trim
            Else
                sReturn = Regex.Replace(sValue, _sRegexKanji, AddressOf _GetReplaceNumeric)
            End If

            Return sReturn + "-"
        End Function

        Private Function _GetReplaceNumeric(ByVal m As System.Text.RegularExpressions.Match) As String
            Dim sReturn As String = ""
            Dim iLoop As Integer
            For iLoop = 0 To m.Length - 1
                Dim iPosition As Integer = InStr(_sPatternKanji, m.Value.Substring(iLoop)) - 1
                If iPosition < 0 Then iPosition = 0
                sReturn += CStr(iPosition)
            Next
            Return sReturn
        End Function
    End Class

    Private _sRegexEmpty As String = "[・&/\.]"
    Private _sRegexPatternOver As String = "[^「\dA-Za-z」]"

    Private _sRegixDouble As String = "[A-Za-z][A-Za-z]+"
    Private _sRegixSingle As String = "-*[A-Za-z]-*"
    Private _sRegixFloor As String = "[\d]F"

    Private _sYubinSymbol As String = "-"
    Private _iYubinLength As Integer = 20

    Private _cArabic As _cArabicReplace = New _cArabicReplace

    Public Sub Dispose() Implements IDisposable.Dispose
        If Not _cArabic Is Nothing Then _cArabic.Dispose() : _cArabic = Nothing
    End Sub

    Private Function _GetReplaceFloor(ByVal m As System.Text.RegularExpressions.Match) As String
        Return m.Value.Substring(0, m.Length - 1) + _sYubinSymbol
    End Function

    Private Function _GetReplaceAlphabet(ByVal m As System.Text.RegularExpressions.Match) As String
        Return Replace(m.Value, _sYubinSymbol, "")
    End Function

    Public Shared Function GetYubin(ByVal sZipCode As String, ByVal sAddress As String) As String
        Return (New cYubin).GetYubinCode(sZipCode, sAddress)
    End Function

    Public Function GetYubinCode(ByVal sZipCode As String, ByVal sAddress As String) As String

        ''(1)住所バーコード生成
        ''(1-1)半角英数字/特定処理の空白処理
        Dim sReturn As String = Regex.Replace(Trim(StrConv(sAddress, VbStrConv.Narrow)), _sRegexEmpty, "")

        ''(1-2)漢数字のアラビア数字置換
        sReturn = _cArabic.GetArabic(sReturn)

        ''(1-3)階層記号直前数値空白処理
        sReturn = Regex.Replace(sReturn, _sRegixFloor, AddressOf _GetReplaceFloor)

        ''(1-4)連続英文字空白処理
        sReturn = Regex.Replace(sReturn, _sRegixDouble, "")

        ''(1-5)英数字以外の空白処理
        sReturn = Regex.Replace(sReturn, _sRegexPatternOver, _sYubinSymbol)

        ''(1-6)英字前後の”-”除去処理
        sReturn = Regex.Replace(sReturn, _sRegixSingle, AddressOf _GetReplaceAlphabet)

        ''(1-7)連続ハイフンの記号除去処理
        sReturn = Regex.Replace(sReturn, _sYubinSymbol + "+", _sYubinSymbol).Trim(CChar(_sYubinSymbol))

        ''(2)郵便番号のハイフン除去処理
        Dim sBase As String = Regex.Replace(Trim(sZipCode), _sYubinSymbol, "")

        ''(3)1及び2の文字列生成/戻り値設定
        Dim iLength As Integer = (sBase + sReturn).Length
        If _iYubinLength < iLength Then iLength = _iYubinLength
        Return (sBase + sReturn).Substring(0, iLength)
    End Function
End Class

注意点

バーコードを生成するには、手順にもある通り特殊文字の挿入・置換、チェックデジットの計算がありますが、本クラスでは実装していません。

バーコードを生成コンポーネントに渡す前提として作っています。

郵便局の判断住所との照合で一致する事を確認しておりますが、条件で適合しないものがあればお知らせ頂ければありがたいです。

まとめ

郵便バーコードはその性質上から、入力住所の重複チェックやまるめ処理などにも利用ができ、バーコード生成以外にも使いまわしができます。

すでにコンポーネントを購入・解決されているケースが多いと思いますが、ぜひご活用下さい!

(11/12):【修正済】フローの確認方法の表が間違ってました(1行目)
(11/12):【修正済】未使用の内部変数削除しました