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

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

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

郵便バーコードって?

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

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

VB版はこちら
郵便バーコード取得クラス【VB.NET】ソース公開!
郵便バーコードの文字列取得クラス【VB.NET】のソースを公開!バーコード作る前の住所から文字情報を生成するロジックを無料公開します! 住所の重複チェックやまるめ処理にも利用がで
READ MORE..

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

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

郵便バーコード取得クラス【C#.NET】ソース公開!-フロー図

特殊な処理

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

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

フローの確認方法

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

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

公開クラスについて

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

クラスの設計イメージ

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

郵便バーコード取得クラス【C#.NET】ソース公開!-イメージ図

使用方法

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

文字列取得クラスソース

using System.Text.RegularExpressions;
using Microsoft.VisualBasic;

public class cYubin
{
    private string _sRegexEmpty = "[・&/\\.]";
    private string _sRegexPatternOver = "[^「\\dA-Za-z」]";

    private string _sRegixDouble = "[A-Za-z][A-Za-z]+";
    private string _sRegixSingle = "-*[A-Za-z]-*";
    private string _sRegixFloor = "[\\d]F";

    private string _sYubinSymbol = "-";
    private int _iYubinLength = 20;

    private class cArabicReplace
    {
        private string _sRegexKanji = "";
        private string _sRegexPlace = "";
        private string _sRegexSpecific = "";

        private string _sCheckAddress = "";
        private string _sCheckPlace4 = "";
        private string _sCheckPlace = "";

        private string _sPatternKanji = "〇一二三四五六七八九";
        private string _sPatternPlace = "十百千";
        private string _sPatternPlace4 = "万億兆";

        public cArabicReplace()
        {
            string sPatternSpecific = "(丁目|丁|番地|番|号|地割|線|の|ノ| )";

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

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

        public string GetArabic(string sKanji)
        {
            string sReturn = "";
            sReturn = Regex.Replace(sKanji, _sCheckAddress, _GetArabic);
            return sReturn;
        }

        private string _GetArabic(System.Text.RegularExpressions.Match m)
        {
            var sValue = Regex.Replace(m.Value, _sRegexSpecific, "-");
            var sReturn = "";

            //(1)4桁文字単位抽出
            MatchCollection mlPlace4 = Regex.Matches(sValue, _sCheckPlace4);
            if(mlPlace4.Count > 0){
                long lValue = 0;

                foreach(Match mPlace4 in mlPlace4) { 

                    //(1 - 1)4桁倍率算出
                    int iPlace4 = _sPatternPlace4.IndexOf( mPlace4.Value.Substring(mPlace4.Value.Length - 1))+1;

                    //(2)1桁文字単位算出
                    MatchCollection mlPlace = Regex.Matches(mPlace4.Value, _sCheckPlace);
                    foreach (Match mPlace in mlPlace) {
                        if (mPlace.Value != "") {

                            //(2 - 1)1桁倍率算出
                            string sPlace = Regex.Replace(mPlace.Value, _sRegexKanji, "");
                            int iPlace = sPlace.Length;
                            if (iPlace > 0) { iPlace = _sPatternPlace.IndexOf(sPlace)+1; }


                                //(3)アラビア数字取得内部関数
                                string sKanji = Regex.Replace(Regex.Replace(mPlace.Value, _sRegexPlace, ""), _sRegexKanji, _GetReplaceNumeric);
                                int iKanji = 1;
                                if (!int.TryParse(sKanji, out iKanji)) { iKanji = 1; }

                                //(4)4桁 / 1桁倍率 / アラビア数値の加算処理
                                lValue += Convert.ToInt32(iKanji * Math.Pow(10 , (4 * iPlace4 + iPlace)));
                            }
                        }
                    }
                sReturn = Convert.ToString(lValue).Trim();
            }                 
            else 
            {
                 sReturn = Regex.Replace(sValue, _sRegexKanji, _GetReplaceNumeric);
            }

            return sReturn + "-";
         }

        private string _GetReplaceNumeric(System.Text.RegularExpressions.Match m )
        {
            string sReturn = "";
            for( int iLoop = 0; iLoop< m.Length; iLoop++)
            {
                int iPosition = _sPatternKanji.IndexOf(m.Value.Substring(iLoop)) ;
                if (iPosition < 0) { iPosition = 0; }
                sReturn += Convert.ToString(iPosition);
            }
            return sReturn;
        }
    }
       
    private cArabicReplace _cArabic = new cArabicReplace();
    
    private  string  _GetReplaceFloor(  System.Text.RegularExpressions.Match m)
    {
        return m.Value.Substring(0, m.Length - 1) + _sYubinSymbol;
    }

    private string _GetReplaceAlphabet(System.Text.RegularExpressions.Match m)
    {
        return m.Value.Replace( _sYubinSymbol, "");
    }

    public static string GetYubin(string sZipCode ,string sAddress  ) {
        return (new cYubin()).GetYubinCode(sZipCode, sAddress);
    }

    public string GetYubinCode(string sZipCode, string sAddress) {

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

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

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

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

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

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

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

        //(2)郵便番号のハイフン除去処理
        string sBase  = Regex.Replace(sZipCode.Trim(), _sYubinSymbol, "");

        //(3)1及び2の文字列生成 / 戻り値設定
        int iLength = (sBase + sReturn).Length;
        if (_iYubinLength < iLength){ iLength = _iYubinLength; }
        return (sBase + sReturn).Substring(0, iLength);
    }
}

注意点

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

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

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

全角→半角の置換にStrConvというVBライブラリを使用しています。他ライブラリはひと手間かかりそうなので採用を見送りました。

まとめ

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

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

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です