- 住所の統廃合や新設に伴うコードマスタ更新方法の確立
- 郵便番号の公式データが正規化されていないために生じるデータ変換
この2つの問題を一気に解決するのが、今回ご紹介する「JPAddress for .NET 1.0J」です。JPAddressは単純な郵便番号-住所検索コンポーネントではありません。なぜなら郵便番号を使ったときに生じる問題の解決まで視野に入れた総合ソリューション型コンポーネントだからです。
また、JPAddressは郵便番号データと検索エンジンの組み合わせなので、Windowsフォームアプリ、WPFアプリ、ASP.NETアプリというマルチ環境で利用できます。どのような環境でも同じ開発方法がとれるというのは、開発効率性、同じ郵便番号データを使える点、など優位な点が多々あります。
準備
「JPAddress for .NET 1.0J」インストール
「SPREAD for WPF 1.0J」もそうでしたが、新しいインストーラのデザインはかなりお気に入りです。

今回もデフォルト指定のインストール先ではなく「C:\Program Files (x86)\GrapeCity」フォルダに変更しましたが、自動的にサブフォルダとしての製品フォルダが指定できるので非常に便利です。
Windowsフォームアプリで使用する
ツールボックスへの追加
JPAddressに限ったことではありませんが、コンポーネントをVisual Studioで使うためにはツールボックスへ登録しておくのが便利です。そのためには、1度だけツールボックスへの登録操作を行わなければなりません。1度登録してしまえば次回以降にこの操作は必要ありません。
ツールボックスへの登録を行うには、まず、Visual Studioを起動してWindowsフォームアプリケーションの新規作成を行います。
はじめにツールボックスを右クリックして[タブの追加]を選択し、「GrapeCity Win」タブを追加します。次に、「GrapeCity Win」タブの下を右クリックして[アイテムの選択]をクリックしてダイアログを表示します。
一覧で「GrapeCity.Win.JPAddress」をチェックして[OK]ボタンをクリックすれば、ツールボックスに追加できます。ここでVisual Studioを再起動しておくとよいでしょう。
ウィンドウデザイナでの作業
Windowsフォームアプリケーションの新規作成では、Form1というWindowsフォームが1つだけあるプロジェクトが生成されます。「Form1」では味気ないので、「MainForm」と名前を変更してから作業を進めたいと思います。名前の変更は、ソリューションエクスプローラーで「Form1」を右クリックして[名前の変更]メニューから行いましょう。
次にツールボックスにある「GcJPAddress」アイコンを、デザイナ上のウィンドウにドラッグ&ドロップします。

JPAddressはUIのあるコンポーネントではないので、フォームデザイナでは非表示コントロールが配置される領域に配置されます。同時に、JPAddressを開発環境で動作させるのに必要なライセンスファイルがプロジェクトに追加されます。

ロジックコードの記述
せっかくフォームデザイナに配置したJPAddressですが、今回のサンプルではデザインとロジックを分離したいので、さくっとフォームデザイナ上からアイコンを削除して、ロジック記述用のJPAddressModel.vbを作成して、そこでコードを使ってJPAddressを使ってみたいと思います。
Visual StudioのソリューションエクスプローラーでModelsフォルダを作成し、Modelsフォルダを右クリックして[追加]‐[クラス]メニューでクラスファイルを追加します。
クラスファイルには次のようなコードを記述します。
Imports GrapeCity.Win.JPAddress Imports System.ComponentModel Public Class JPAddressModel Implements INotifyPropertyChanged Private _Address As List(Of AddressInfo) Public Property Address As List(Of AddressInfo) Get Return Me._Address End Get Set(value As List(Of AddressInfo)) Me._Address = value Call NotifyPropertyChanged("Address") End Set End Property Public Sub GetAddress(postCode As String) Me.Address = (New GcJPAddress).GetAddress(postCode, True).ToList End Sub Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) _ Implements INotifyPropertyChanged.PropertyChanged Private Sub NotifyPropertyChanged(ByVal propertyName As String) RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName)) End Sub End Class
JPAddressの使い方は非常に簡単で、実際に郵便番号から住所を検索しているのは、GetAddressメソッドの中の次の1行です。
Me.Address = (New GcJPAddress).GetAddress(postCode, True).ToList
これでAddressプロパティに住所が設定されることになります。郵便番号から住所を検索したとき、複数の結果が返ってくる場合があります。そのためJPAddressでの検索結果もIEnumerable型になっています。ここでは画面との連結を考えてToListを使ってListに変換しています。
それでは次に、Addressプロパティを画面に連結するためのクラスをつくりましょう。
画面連結用クラスの作成
ソリューションエクスプローラーでViewModelsフォルダを作成し、フォルダ上で右クリックをして[追加]‐[クラス]メニューを選択して、MainViewModelクラスファイルを作成します。JPAddressModelのPublicなプロパティ、メソッド、イベントをそのままPublicで公開すればいいのでコードは次のようになります。
Imports System.ComponentModel Imports GrapeCity.Win.JPAddress Public Class MainViewModel Implements INotifyPropertyChanged Private WithEvents VmModel As New JPAddressModel Public ReadOnly Property Address As List(Of AddressInfo) Get Return Me.VmModel.Address End Get End Property Public Sub GetAddress(postCode) Call Me.VmModel.GetAddress(postCode) End Sub Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) _ Implements INotifyPropertyChanged.PropertyChanged Private Sub VmModel_PropertyChanged(sender As Object, e As PropertyChangedEventArgs) _ Handles VmModel.PropertyChanged RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(e.PropertyName)) End Sub End Class
画面の作成
今回のサンプルでは、郵便番号欄、検索ボタン、検索結果一覧という画面構成にします。

一覧部分はDataGridViewを採用し、Columnsに表示したい要素を事前に設定しておきます。
画面コードの作成
最後に画面に連結するためのコードをMainForm.vbに記述しましょう。
Public Class MainForm Private ViewModel As New MainViewModel Private Me_BindingSource As New BindingSource Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles Me.Load Me.Result_DataGridView.AutoGenerateColumns = False Me.Me_BindingSource.DataSource = ViewModel Me.Result_DataGridView.DataSource = Me.Me_BindingSource Me.Result_DataGridView.DataMember = "Address" End Sub Private Sub Search_Button_Click(sender As Object, e As EventArgs) _ Handles Search_Button.Click Call Me.ViewModel.GetAddress(Me.PostCode_TextBox.Text) End Sub End Class
DataGridViewのAutoGenerateColumnsプロパティは、なぜかプロパティウィンドウで設定できませんが、このプロパティをFalseにしておかないと、事前に設定したColumnsが無視されてデータが表示されてしまうので注意してください。なお、AutoGenerateColumnsプロパティは逆転の発想で最初はTrueにしておいて、どのようなフィールド名でデータが格納しているかを一気に調べることに使うという手もあります。
実行
それでは完成したプロジェクトのプロジェクト構成を確認してみましょう。

クラスを用途別のフォルダに分けることで、かなりすっきりした構成になっていると思います。ビルドでエラーがでないようであればさっそく実行してみましょう。
デフォルトで郵便番号を設定していますので、画面が表示されたら[住所検索]ボタンをクリックしてみてください。

グレープシティ本社の住所が表示できれば正常に動作しています。
WPFアプリで使用する
ツールボックスへの追加
Visual Studioのツールボックスは、タブや登録済コントロールの表示をWindowsフォームアプリとWPFアプリで別になるように制御しています。
そのため、例えばWindowsフォームアプリのプロジェクトでツールボックスに「GrapeCity Win」というタブを作っても、WPFアプリのプロジェクトではそのタブは表示されません。しかしWPF側で「GrapeCity Win」という名前でタブを登録しようとしても、既存チェックにひっかかりタブを作ることができません。
そこで、ツールボックスを右クリックして[タブの追加]を選択し、「GrapeCity WPF」タブを追加します。そして、「GrapeCity WPF」タブの下を右クリックして[アイテムの選択]を選択してダイアログを表示します。
一覧で「GrapeCity.Windows.JPAddress」をチェックして[OK]ボタンをクリックすれば、ツールボックスに追加できます。ここで、Visual Studioを再起動しておくとよいでしょう。
ウィンドウデザイナでの作業
WPFアプリでもWindowsフォームアプリと同じように、ツールボックスにある「GcJPAddress」アイコンをデザイナ上のウィンドウにドラッグ&ドロップします。

しかしこのまま実行すると、ライセンスファイルがないというエラーになってしまいます。

理由はWindowsフォームアプリのときとは異なり、自動的にライセンスファイルが追加されません。

WPFアプリの場合、手動で追加しなければならないので、先ほどWindowsフォームアプリで自動作成されたものをMy Projectフォルダにコピーしてからソリューションエクスプローラーで[プロジェクトに含む]メニューで取り込みましょう。

この作業を行っているときにちょっとひらめいたのですが、Windowsフォームアプリで追加されたライセンスファイルには「GrapeCity.Win.JPAddress.GcJPAddress」のライセンスが記述されているので、本来はこれをWPF用にする必要があります。しかし、WPFアプリの場合も、UIとロジックを分離してWPF上ではなく裏側でJPAddressを使うので、ライセンスファイルをそのままに参照するライブラリを「GrapeCity.Win.JPAddress.GcJPAddress」にしてみたらどうなるでしょうか。
興味が湧いてきたのでこの方法で実装してみたいと思います。もちろんこれはメーカー非推奨なので、うまくいったとしても利用は自己責任の世界になります。
ロジックコードの記述
Visual StudioのソリューションエクスプローラーでModelsフォルダを作成します。ここで新たにクラスファイルを作成してもいいのですが、Windowsフォームアプリで作ったJPAddressModel.vbを取り込んで使ってみましょう。Modelsフォルダを右クリックして[追加]‐[既存の項目]メニューでクラスファイルを追加します。
画面連結用クラスの作成
画面連結用クラスについても同様にWindowsフォームアプリで作成したものを取り込みます。取り込んだものにWPF特有のCommandバインディング用のコードを追加します。
Imports System.ComponentModel Imports GrapeCity.Win.JPAddress Public Class MainViewModel Implements INotifyPropertyChanged : (略) : 'Public Sub GetAddress(postCode) ' Call Me.VmModel.GetAddress(postCode) 'End Sub Private _getAddressCommand As ICommand Public ReadOnly Property GetAddress As ICommand Get If Me._getAddressCommand Is Nothing Then Me._getAddressCommand = New GetAddressCommand(Me) End If Return Me._getAddressCommand End Get End Property Private Class GetAddressCommand Implements ICommand Private _viewModel As MainViewModel Public Sub New(viewModel As MainViewModel) _viewModel = viewModel AddHandler _viewModel.PropertyChanged, AddressOf ViewModel_Changed End Sub Public Function CanExecute(parameter As Object) As Boolean _ Implements ICommand.CanExecute Return (String.IsNullOrEmpty(Nothing)) End Function Public Event CanExecuteChanged(sender As Object, e As EventArgs) _ Implements ICommand.CanExecuteChanged Private Sub ViewModel_Changed(sender As Object, e As EventArgs) RaiseEvent CanExecuteChanged(sender, e) End Sub Public Sub Execute(parameter As Object) Implements ICommand.Execute Dim postcode As String = parameter.ToString.Replace("-", "") Me._viewModel.VmModel.GetAddress(postcode) End Sub End Class End Class
画面の作成
今回のサンプルでは、郵便番号欄、検索ボタン、検索結果一覧という画面構成にします。
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="MainWindow" Title="JPAddress Sample" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <TextBox Grid.Column="0" Grid.Row="0" x:Name="PostCode_TextBox" Text="981-3205" Margin="10" /> <Button Grid.Column="1" Grid.Row="0" Content="住所検索" Margin="10" Command="{Binding GetAddress}" CommandParameter="{Binding Text, ElementName=PostCode_TextBox}"/> <DataGrid Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="3" AutoGenerateColumns="False" IsReadOnly="True" ItemsSource="{Binding Address}"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Prefecture}" Header="都道府県" /> <DataGridTextColumn Binding="{Binding City}" Header="市区町村" /> <DataGridTextColumn Binding="{Binding Town}" Header="町" /> <DataGridTextColumn Binding="{Binding Area}" Header="町域" /> </DataGrid.Columns> </DataGrid> </Grid> </Window>
画面コードの作成
最後に画面に連結するためのコードをMainForm.vbに記述しましょう。
Class MainWindow Private ViewModel As New MainViewModel Public Sub New() ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 Me.DataContext = Me.ViewModel End Sub End Class
DataGridViewのAutoGenerateColumnsプロパティは、なぜかプロパティウィンドウで設定できませんが、このプロパティをFalseにしておかないと事前に設定したColumnsが無視されてデータが表示されてしまうので注意してください。なお、AutoGenerateColumnsプロパティは逆転の発想で最初はTrueにしておいてどのようなフィールド名でデータが格納しているかを一気に調べることに使うという手もあります。
実行
デフォルトで郵便番号を設定していますので、画面が表示されたら[住所検索]ボタンをクリックしてみてください。

グレープシティ本社の住所が表示できます。
もちろん本来であればWPF用の方を使うのが正しい組み合わせなので、
- 参照設定
- Importsステートメント
- ライセンスファイル
の「GrapeCity.Win.JPAddress.dll」を「GrapeCity.Windows.JPAddress.dll」に変更してWPF用に切り替えておきましょう。
住所の更新
ここまで紹介した機能だけでみると、JPAddressは単なる住所検索コンポーネントでしかありません。もちろん郵便番号だけでなく、地区コードからの検索などまだ紹介していない検索機能もありますが、それ以上にJPAddressがその他の住所検索コンポーネントと違うのは辞書更新サービスの存在です。
JPAddressのUpdateメソッドを使えば、httpを利用してグレープシティ辞書更新サービスサーバーから最新の辞書を取得して辞書データを更新することができるのです。もちろん、Proxyサーバーにも対応しており、IEでインターネットに接続できるように設定してあれば、グレープシティ辞書更新サービスサーバーへの接続もその情報を使って接続可能です。
それでは、Updateメソッドの使い方をみてみましょう。
Imports GrapeCity.Win.JPAddress Imports System.ComponentModel Public Class JPAddressModel Implements INotifyPropertyChanged Private Jpa As New GcJPAddress Public Sub New() Call Update() End Sub Private Sub Update() Jpa.Proxy = System.Net.WebRequest.GetSystemWebProxy() Jpa.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials ' 「vwvyz」には認証IDを設定します。 Jpa.Update("vwvyz ") End Sub : (略) : End Class
このように非常に簡単なコードで実装が可能です。Updateメソッドはダウンロードと辞書更新が完了するまで処理待ち状態になるため、更新中のアプリの挙動についても考慮する必要はありません。
このサービスは年間契約の有償サービスのため利用するには別途申し込みが必要です。ただし、トライアル版では利用できませんが、製品購入後であれば認証IDにプロダクトキーを指定することで90日間のテスト利用ができます。
まとめ
今回のサンプルでは自動的に更新を行っていましたが、承認プロセスをアプリに取り入れ、確認用端末を更新してテスト結果がOKであれば、例えばDBなどに承認OKのフラグを立てて各端末やWebサーバーでUpdateメソッドをアプリの内部で自動的に呼び出すという流れも作ることができます。
住所検索部分であれば、郵便局の郵便番号データダウンロードからデータをダウンロードして使いやすいように加工をしてアプリに組み込めば自作できます。しかし、定期的に更新される郵便番号データダウンロードを毎回使いやすいように加工して配布するという手間を自社要員で実施する必要はないと思います。リソースの最適化という視点やデータ生成結果の品質ということを考えても、複数の取引先にデータ配信しているところにアウトソーシングするのがよいのではないでしょうか。