トップ画面を作成する
サンプルアプリでは、トップ画面で請求書番号を選んで[更新]をクリックすると更新画面、[印刷]をクリックするとPDFを表示します。
図4のようにサンプルアプリでは、意図的に2つのコンボボックスを配置しています。上が標準のDropDownListコントロール、下がInputManのComboコントロールです。この2つのコントロールにドロップダウンリストの一覧としてデータセットを割り当てます。
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles Me.Load If Not Me.IsPostBack Then '最初のロードのときにのみ実行 Call GetBill() End If End Sub Private Sub GetBill() Dim userID As String = My.User.Name Dim password As String = CType(Session("password"), String) Using _webs As New CZ1001BoundService.BillBound Dim ds As System.Data.DataSet = _webs.GetBillList(userID, password) '標準コントロール Me.BillNo_DropDownList.DataMember = "BillCondition" Me.BillNo_DropDownList.DataSource = ds Me.BillNo_DropDownList.DataBind() 'InputManコントロール Me.BillNo_Combo.ListBox.HeaderPane.Visible = True Me.BillNo_Combo.ListBox.AutoGenerateColumns = True Me.BillNo_Combo.ListBox.AutoWidth = True Me.BillNo_Combo.ListBox.TextSubItemIndex = 0 Me.BillNo_Combo.DataMember = "BillCondition" Me.BillNo_Combo.DataSource = ds Me.BillNo_Combo.DataBind() Me.BillNo_Combo.ListBox.Columns(0).AutoWidth = True End Using End Sub
標準コントロールとInputManコントロールの大きな違いは、InputManコントロールであれば複数列のドロップダウンリストが作成できる点です。例えば、表示値とコード値のように複数の値を持つようなことも可能です。また、コード値列のVisibleプロパティをFalseにすると、コード値をドロップダウンリストでは見せないようにもできます。
更新画面を作成する
トップ画面で[更新]をクリックされたときに動作するイベントプロシージャには次のように記述します。
Protected Sub OK_Button_Click(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles OK_Button.Click If Me.BillNo_Combo.SelectedIndex >= 0 Then Me.Session("BillNo") = Me.BillNo_Combo.SelectedItem.SubItems(0).Value Me.Response.Redirect("~/entry/CZ1001Entry.aspx") Else Me.Message_Label.Text = "請求書番号を選択してください。" End If End Sub
- [BillNo]セッション変数に選択された請求書番号を設定
- RedirectメソッドによりCZ1001Entry.aspxにリダイレクト
更新画面にデータを表示する
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles Me.Load '複数ウィンドウ対策 If Me.ViewState("billNo") Is Nothing Then Me.ViewState("billNo") = Me.Session("billNo") Else Me.Session("billNo") = Me.ViewState("billNo") End If ' If Not (Me.Session("BillNo") Is Nothing) AndAlso _ Me.Session("BillNo").ToString.Length > 0 Then If Not Me.IsPostBack Then '最初のロードのときにのみ実行 Call Me_Load() If Not (Me.Session("billNo") Is Nothing) Then Call GetRecords(Me.Session("billNo").ToString) Else Call GetRecords("") End If End If Else My.Response.Redirect("~/CZ1001Menu.aspx") End If End Sub '''''' 指定した請求書の編集を行う ''' ''' '''Private Sub GetRecords(ByVal billNo As String) Dim userID As String = My.User.Name Dim password As String = CType(Session("password"), String) Using _webs As New CZ1001BoundService.BillBound Dim ds As System.Data.DataSet = _webs.GetRecords(userID, _ password, _ billNo) 'Spread以外の設定 Me.PreInvoice_Number.Format.Digit = "#########0" Me.PreInvoice_Number.DisplayFormat.Digit = "#,###,###,##0" Me.PreInvoice_Number.DisplayFormat.PositiveSuffix = "円" Me.PreIncome_Number.Format.Digit = "#########0" Me.PreIncome_Number.DisplayFormat.Digit = "#,###,###,##0" Me.PreIncome_Number.DisplayFormat.PositiveSuffix = "円" If ds.Tables("BillCondition").Rows.Count > 0 Then With ds.Tables("Customers").Rows(0) Me.Name_Label.Text = .Item("CustomerName").ToString End With With ds.Tables("BillCondition").Rows(0) Me.BillNO_Label.Text = .Item("BillNo").ToString Me.EndDate_Calendar.SelectedDate = CType(.Item("EndDate").ToString, Date) Me.EndDate_Calendar.FocusDate = Me.EndDate_Calendar.SelectedDate Me.PreInvoice_Number.Value = CType(.Item("PreInvoice"), Decimal) Me.PreIncome_Number.Value = CType(.Item("PreIncome"), Decimal) End With End If Me.FpSpread1.ActiveSheetView.DataMember = "Bill" Me.FpSpread1.ActiveSheetView.DataSource = ds Me.FpSpread1.DataBind() Me.FpSpread1.ActiveSheetView.RecalculateAll() End Using End Sub
- Page_Loadでは、セッション変数がウィンドウ間で共通のため、複数ウィンドウで使われたときにも正常に動作するようにViewState変数を併用
- Page_Loadでは、PostBack以外のときはGetRecords関数を呼んで値を設定
- GetRecordsでは、XML WebサービスのGetRecordsメソッドによりデータを取得
- 画面左側の項目は、データテーブルより該当値を取得して設定
- 右側の一覧は、DataSourceプロパティにデータセットを指定してDataBindメソッドにより反映
- RecalculateAllメソッドで「金額」欄を計算
更新画面の内容でデータを更新する
更新画面で[更新]をクリックすると、画面での変更値をbill.mdbファイルに書きだすXML Webサービスを呼び出します。XML Webサービスを呼び出すときに画面の値をDatasetに格納する必要があるので、次のリスト8のようなコードを実行します。
Private Sub SetRecords(ByVal billNo As String) Dim userID As String = My.User.Name Dim password As String = CType(Session("password"), String) Me.FpSpread1.SaveChanges() Using _webs As New CZ1001BoundService.BillBound Dim ds As System.Data.DataSet = CType(Me.FpSpread1.ActiveSheetView.DataSource, _ System.Data.DataSet) With ds.Tables("BillCondition").Rows(0) .BeginEdit() .Item("EndDate") = Me.EndDate_Calendar.SelectedDate.BaseDate .Item("PreInvoice") = Me.PreInvoice_Number.Value .Item("PreIncome") = Me.PreIncome_Number.Value .EndEdit() End With Try Call _webs.SetRecords(ds, userID, password, billNo) Me.Message_Label.Text = "" Catch ex As Exception '例外をログなどに記述 Me.Message_Label.Text = "エラーが発生しました。" End Try End Using End Sub
- SaveChangesメソッドにより画面上の変更をデータセットに反映
- Spreadにバインドしているデータセットをds変数に設定
- 画面の左側の値をds.Tables("BillCondition").Rows(0)に反映
- データを更新するXML Webメソッド(SetRecordメソッド)をコール
私がこのサンプルアプリを作成しているとき、はじめはSaveChangesメソッドの存在に気が付かず、画面上で変更しているのにデータセットが更新されないという事象に悩みましたが、FAQの[全般]-[クライアント側で変更した値をサーバー側で取得したい]の内容を読んで解決しました。非常に重要なメソッドなので、記述忘れのないようにしましょう。