C#で自動車の登録番号をスプリットしてみた


 

//自動車登録ナンバーのスプリット 要素の分割 陸運局、分類番号、平仮名、一連指定番号
public static string[] SplitNumber(string Z)
{
string[] sNum = new string[4];

Regex regex = new Regex(@"[\x01-\x7E\d]");//数字を全部抜き取る

string X = regex.Replace(Z, "");

sNum[2] = Class_Z.Right(X,1);//最後の一文字、平仮名を取得

sNum[0] = X.Replace(sNum[2], "");//平仮名を消して陸運局を取得

Char[] delimiter = sNum[2].ToCharArray();

string[] Y = Z.Split(delimiter);//元のナンバーのデリミタに平仮名を使って分割

sNum[1] = Y[0].Replace(sNum[0], "");//先のデータから陸運局を消し分類番号を取得

sNum[3] = Y[1];//最後は一連指定番号をそのまま取得出来ている。

return sNum;//分割した要素を配列で返す。0:陸運局 1:分類番号 2:平仮名 3:指定番号
}

 

民間車検工場で俺のオリジナル整備管理システムと仕入伝票管理システムを運用しているのだが、そもそもオフコン時代のダウンサイジングで、まずはVB4でバイナリファイル管理システム化していている所から引き継いだので、ソースはぐちゃぐちゃだった。

ファイル管理なので、スタンドアロンで1台のパソコンでしか処理出来ない状態だった。

それを、なんとか解析してDB化してネットワークで共有する仕組みに変える必要があって、俺の前に4社ほど挑戦した様だが、どこも出来なかくて、それぞれのシステム屋は、既存のシステムを破棄して、自社が持っているシステムを使う様にと言う案内しか出来ず、ユーザとトラブった訳だ。

そんな状況で俺にオファーがあって、既存の仕組みをそのまま利用して改造して欲しいと言う要件なので、その通りにしただけだが、前のシステム屋がやりたくない理由はソースを見て直にわかった。

しかし、ここで投げてはシステム屋冥利に尽きると思ったので、まずは、バイナリファイルをDBに放り込むコンバーターから作って、MDBでカジュアルにDB化して、まずは、保存するデータをファイルからDBにして他の処理はそのまま利用する方法で組み入れてみたのだ。

元々ソースコードがファイル管理で組み上がっているので、DB化するメリットは半減以下になっているが、それでもなんとかネットワーク利用で複数台で処理が出来る状態にまでこぎ着けた。

その際、伝票番号を連番で発行している部分などスタンドアロンで1台しか想定してない組み方なので、この辺は実に困ったもので、他のPCと伝票番号が重複しないようにするのに結構手間取った。

そんなこんなで、辛うじてDB化、ネットワーク対応、ファイル管理ロジックの修正で徐々にDBライクなロジックを組み入れ、なんとか使える状態にするまで1年は掛かったかな。

その後、MDBをSQLServerに入れ替え、今は普通のネットワーク利用でのごく普通の、整備履歴管理システムとして運用出来るまでに至ったのだが、当時はWindowsXPで、次にVistaとなり、まぁこの辺まではVB6でも問題無く利用出来ていたわけだが、Windows7の登場で若干VB6を動かすのに手間がかかるようになってきた。

結局、Windows10でも普通に開発、動作には問題はないわけだが、exeをそのまま動かすだけでは無理で、VB6のランタイムライブラリを導入する手間があったり、他のライブラリも導入していたので、それぞれの対応状況など不安要素があって、早急にFrameWork化しとかないと、結構、後々しんどくなるなぁと思っている。

そこで、ようやくC#で開発してみようかと言うモチベーションが沸き起こり、着手し始めたわけだが、C#自体はとても組みやすい言語なので、オブジェクト指向でソースも上手く書けばかなり短く書けるし、最初から意識して書いているので結構効率よく開発出来ているのだが、VB6をそのままコンバート出来ないので、完全に0ベースからの作り直しを余儀なくされている。

そんな中、C#は正規表現やLINQなどがとても便利で扱いやすいので、自動車登録番号のスプリッターを作ってみたら旨く言った。

元々、自動車の番号を検索する際、同じ番号は結構あるが、DB化したとはいえ、LIKEで検索すると、意図した結果を得られない。

例えば「3」を検索キーにして一連指定番号を検索したくても、LIKEだと分類番号もひっかかってくるし、余計なヒットで「3」と言う番号のナンバーを並べたいだけなのに、山程ヒットしてしまう。

なので、一連指定番号だけの検索が必要なのだが、それでも一桁のナンバーを検索するのに、結構苦労する事になるわけだ。

3で検索したくても3を含む番号がヒットするし、2桁、3桁と色々と冗長な検索をして行かなければならなくなる。

そこで、この車両番号をそれぞれ分割して比較する必要があるのだが、これが、分類番号も1桁から3桁など固定値では区切ることが出来ないし、ナンバーも1桁から4桁とこれも固定で抽出する事が出来ない。

決め手は平仮名の1文字をデリミタとして分割出来ればあとはなんとかなりそうだなぁと思ったので、正規表現で数字に挟まれた文字を抽出して平仮名さえ取得出来れば後はなんとかと思ったが、正規表現って結構ややこしくて、ここは手っ取り早く、車両番号から数字を全部消して見たところ、陸運局と平仮名が取得出来たので、唯一の固定ルールとして平仮名は1文字と決まっているので、これで、まずはスプリットして陸運局と分類番号の塊と車両番号に分け、後は陸運局の文字を消して数字だけを残せばそれが分類番号と4種類を個別に取り出すと言う面倒な事をやらなければならない事になる。

なんか正規表現一発で上手く取得する方法があれば良いのだが、なんか頭が回らんので、ここは手堅くこの方法で自動車登録番号のスプリット関数を作ってみたわけだ。

この数字を取る正規表現で住所から郵便番号をGREPする事も出来る。

「Regex regex = new Regex(@”[\x01-\x7E\d{^丁目-番地-}]”);」これで、日本郵政からダウンロード出来る郵便番号ファイルをそのまま使って、住所から郵便番号を検索する仕組みが作れるので結構便利だ。

住所から郵便番号をGREPでヒットされる場合、町までであとは必要ないので元々入力している住所から番地情報を消して検索すれば良いのだが、この住所も上手く分割出来ないので、当てずっぽうで、数字を取って、番地とか丁目とかの決まり単位を取り除いて町までに丸めたキーワードを作って、検索すればLINQで一発で検索出来るのでこれも便利なのだ。

C#で開発するのに、LINQは便利なので使わない手はないわけで、LINQと正規表現を制覇すればかなりスッキリしたソースが書けるので良い感じに仕上がっている。

後は、汎用的にパッケージングして全国の自動車整備関連業者に俺の整備履歴管理システムを宣伝してちょっと小遣い稼ぎが出来れば良いなぁと思っている。

この業界、色々と専門で開発しているシステム屋は多いのだが、利用する所が整備士なので、パソコンを苦手としている所もかなり多いし、比較的、従業員の年齢層も高めで、押しつけのシステムだと毛嫌いする所も多い。

なので、かなり我が儘な対応を実装してきたので、他のシステム屋の作るシステムよりも使い勝手には自信がある。

何より、TABキーでコントロールを移動するのはもってのほかで、ほとんどTABキーもしくはマウスのクリックで入力場所を移動させるシステムばっかりで、ENTERで次の項目に移動出来るシステムは意外に無く、簡単に処理できるのに、結構ユーザ目線で開発されていないのだ。

システム屋的にはTABキーで移動っていうのは空気みたいなものだが、この操作方法を説明すると、「TABキーって何」となるわけだ。

そこに目を向けないといつまで経ってもユーザビリティーの高いシステムは提供出来ないわけで、俺はWEBシステムでさへENTER移動出来る様に気を遣って開発している。

ユーザが近いところで開発しれいれば、ユーザ目線で喜んでもらえるシステムはいくらでも提供出来るが、システム屋目線で開発したシステムはやがて使われなくなるし、満足度が低い製品はトラブルの元になる事をたくさん見てきたのだが、未だにそういうシステムがはびこってしまって、悲しい現実に向き合わなければならないわけだ。

それすなわち、システム屋の妥協によって、居心地の悪いシステムが乱発されている訳で、もっと人に優しいシステムを目指さなければならないとつくづく思ってやまない。