DataGridにレコードを追加する機能を付加したサンプル

図 DataGridにレコードを追加する機能を付加したサンプル
このサンプルは、親ウィンドウから子ウィンドウを開いて、新規レコードを追加します。子ウィンドウから追加したレコードは、親ウィンドウのDataGridに表示されます。
新規レコードを追加するには、親ウィンドウに表示されているレコードの追加ボタン
をクリックします。子ウィンドウが開いたら、テキストボックスに得意先名、担当者名、部署役職、電話番号を入力します。最後に、子ウィンドウから[追加]ボタンをクリックすると、得意先テーブルにレコードが追加されます。追加ボタンをクリックしても、子ウィンドウは開いた状態になっていますので、連続してレコードを追加することができます。[閉じる]のボタンをクリックすると、子ウィンドウを閉じます。子ウィンドウから追加したレコードは、親ウィンドウのDataGridに反映されます。親ウィンドウのDataGridには、得意先テーブルのレコードが得意先IDの降順に10件表示されます。
◆ プログラムPopupInsert.aspxのポイント
¶ポイント1 新規登録でDataGridに表示されていないカラムを入力するには
Web Matrixのテンプレートを使用すれば、DataGridにレコードを追加する機能を簡単に付加することができます。ところが、DataGridにレコードを追加する機能を組み込んだ場合、入力できるレコードのフィールドがDataGridに表示されているカラムに限定されるため、あまり実用的ではありません。このサンプルでは、レコードの追加処理を、子ウィンドウに分離することによりこの問題を解決しています。子ウィンドウからは、DataGridに表示されていないカラムを入力することができます。また、子ウィンドウと親ウィンドウを連動させていますので、子ウィンドウから追加したレコードが親ウィンドウのDataGridに反映されます。
子ウィンドウと親ウィンドウを連動させるには、Page.GetPostBackEventReference()メソッドを使用します。このメソッドを使用すると、子ウィンドウから親ウィンドウをポストバックさせてデータを渡すことができます。サンプルでは、この機能を応用して子ウィンドウから追加したレコードを親ウィンドウのDataGridに反映しています。
¶ポイント2 ページ間でDataTableオブジェクトを共有するには
このサンプルでは、親ウィンドウと子ウィンドウ間でDataTableを共有するために、Session変数にDataTableを保存しています。DataTableを共有することにより、子ウィンドウからレコードを追加する処理を高速化することができます。
¶ポイント3 子ウィンドウから親ウィンドウにデータを渡すには
このサンプルでは、子ウィンドウから親ウィンドウのTextBoxに処理の結果を示すメッセージを渡しています。子ウィンドウから親ウィンドウにデータを渡すには、JavaScriptを登録して実行させます。Webサーバ側からJavaScriptを登録するには、Page.RegisterClientScriptBlock()メソッドを使用します。子ウィンドウから親ウィンドウを参照するには、JavaScriptのwindow.openerを使用します。
Dim sbScript As New StringBuilder()
With sbScript
.Append("<script language='javascript'> ")
.Append("window.opener.frmMain.txtMessage.value = 'message';")
.Append("</" & "script>")
End With
RegisterClientScriptBlock("insert", sbScript.ToString)
¶ポイント4 Webサーバ側からポップアップウィンドウにメッセージを表示するには
このサンプルでは、Webサーバ側でエラーを検出したときエラーメッセージをポップアップウィンドウに表示させています。クライアント側にポップウィンドウを表示するには、JavaScripを登録して実行させます。Webサーバ側からJavaScriptを登録するには、Page.RegisterClientScriptBlock()メソッドを使用します。ポップアップウィンドウにメッセージを表示するには、JavaScriptのwindow.alert()メソッドを使用します。
Dim sbScript As New StringBuilder()
With sbScript
.Append("<script language='javascript'> ")
.Append("alert('error message'); ")
.Append("</" & "script>")
End With
RegisterClientScriptBlock("alertScript", sbScript.ToString)
¶ポイント5 アプリケーション独自のカーソルを表示するには
このサンプルでは、TextBoxにクライアント側で動作するonFocus、onBlurイベントを登録して背景色を切り替えています。onFocusイベントでフォーカスを取得したときは、TextBoxの背景色をLightGreenに変えます。onBlurイベントでフォーカスを喪失したときは、背景色をAliceBlueに戻します。これで、アプリケーション独自のカーソルが表示されます。
TextBoxにクライアント側で動作するイベントを登録するには、AttributesコレクションのAdd()メソッドを使用します。
txtCompanyName.Attributes.Add("onFocus", "this.style.backgroundColor='LightGreen'")
txtCompanyName.Attributes.Add("onBlur", "this.style.backgroundColor='AliceBlue'")
◆ メインプログラムDataGridInsert.aspxの解説(HTML編)
親ウィンドウのWebフォームには、ImageButtonとDataGridを作成しています。ImageButtonでは、レコードの追加ボタンを表示します。このボタンをクリックすると、子ウィンドウが開きます。DataGridには、得意先テーブルのレコードを得意先IDの降順に10件表示します。つまり、新規登録された順番に表示します。
行151-157では、ImageButtonを定義しています。行153では、OnCommandイベントを登録しています。このイベントでは、子ウィンドウを開きます。行154では、ImageUrlプロパティにイメージのurlを設定しています。
151: <asp:ImageButton
id="ibtnInsert" runat="server"
152: CommandName="insert"
153:
OnCommand="ibtnInsert_Command"
154:
ImageUrl="../img/insert.gif"
155:
Title="Add new record"
156:
CssClass="imageButton"
157:
ImageAlign="Middle" />
行158-164では、LabelとTextBoxを定義してDataGridの件数を表示しています。TextBoxのReadOnlyプロパティには、Trueを設定して読み込み専用にしています。TextBoxには、ランタイム時にレコード件数を設定します。
158: <asp:Label
id="lblRo
159:
Text="件数" Font-Name="Tahoma"
Font-Size="9pt"
160:
CssClass="rowNumber" />
161: <asp:TextBox id="txtRo
162:
CssClass="rowNumber"
163:
Columns="3"
164:
ReadOnly="True" />
行177-229では、DataGridを定義しています。このDataGridでは、AutoGenerateColumnsプロパティにFalseを設定してカラムの自動生成機能を抑止しています。行191-228の<Columns>…</Columns>では、TemplateColumnとBoundColumnを定義しています。TemplateColumnのItemTemplateでは、LinkButtonを定義しています。LinkButtonは、レコードセレクターとして使用します。BoundColumnでは、得意先テーブルの得意先ID、得意先名、担当者名、役職、電話番号、都道府県をバインドしています。
191: <Columns>
192: <asp:TemplateColumn
193:
HeaderText="<div
class='dgrdHeaderBox'>1</div>">
194: <ItemTemplate>
195:
<asp:LinkButton id="lbtnSelect" runat="server"
196:
CommandName="Select"
197:
Text="<div class='dgrdItemArrow'>4</div>"
Width="10"
198:
Visible="True" />
199:
</ItemTemplate>
202:
</asp:TemplateColumn>
203: <asp:BoundColumn
ItemStyle-Width="20"
204:
HeaderText="<div class='dgrdHeader'>ID</div>"
205:
DataField="CustomerID">
207:
</asp:BoundColumn>
・・・
228: </Columns>
行238-243では、TextBoxを定義しています。TextBoxのReadOnlyプロパティがTrueになっていることに注意してください。このTextBoxは、メッセージを表示するのとは別に、Webページをポストバックさせるために重要な役割をします。TextBoxの役割については、コード編にて解説します。
238: <asp:TextBox id="txtMessage"
runat="server"
239: Text=""
240:
Style="background-color:SkyBlue"
241: Columns="107"
242: Visible="True"
243: ReadOnly="True" />
行248-251では、Buttonを定義しています。このButtonもWebページをポストバックさせるのに重要な役割をします。ButtonのVisibleプロパティには、Falseを設定しています。Buttonが非可視状態なのに、OnClickイベントを登録していますので不思議に思うかもしれません。実は、このイベントは、ランタイム時にプログラムから起動させます。
248: <asp:Button id="btnRefresh"
runat="server"
249: Text="Hidden"
250: Visible="False"
251:
OnClick="btnRefresh_Click" />
リスト DataGridInsert.aspxのソースコード(HTML編)
|
132:
<html> 191: <Columns> 228: </Columns> |
◆ メインプログラムDataGridInsert.aspxの解説(コード編)
DataGridInsert.aspxは、DataGrid上に得意先テーブルを表示します。レコードの追加ボタンをクリックすると、子ウィンドウを開きます。また、子ウィンドウと連携して、子ウィンドウから追加したレコードをDataGridに表示する処理も行っています。
Sub
Page_Load()イベントの処理
このイベントは、DataGridInsert.aspxがロードされたときに実行されます。このイベントでは、クライアント側で動作するイベントの登録と、DataGridに得意先テーブルをバインドします。
行9-10では、メッセージを表示するTextBoxにクライアント側で動作する、onPropertyChangeイベントを登録しています。Webコントロールに、クライアント側で動作するイベントを登録するには、AttributesコレクションのAdd()メソッドを使用します。Add()メソッドの引数には、イベント名とイベントの処理を記述します。Page.GetPostBackEventReference()メソッドは、WebページをポストバックさせるためのJavaScriptを生成します。このメソッドの引数には、Webページがポストバックされたときに実行されるWebコントロールのIDを指定します。ここでは、リフレッシュボタンのID(btnRefresh)を指定しています。
9:
txtMessage.Attributes.Add("OnPropertyChange", _
10:
GetPostBackEventReference(btnRefresh))
Attributes.Add()メソッドが実行されると、以下のようなHTMLタグが生成されます。
<input name="txtMessage" type="text" size="107"
readonly="readonly" id="txtMessage"
OnPropertyChange="__doPostBack('btnRefresh','')"
style="background-color:SkyBlue" />
GetPostBackEventReference()メソッドを使用すると、本来ポストバックしないWebコントロールをポストバックさせることができます。このサンプルでは、クライアント側からTextBoxのTextプロパティを書き換えることによりWebページをポストバックさせてbtnRefreshのイベントを起動させています。
行11-18のIf…Else…End Ifでは、DataGridに得意先テーブルをバインドしています。ページが最初にロードされたときは、BindDataGrid()を呼び出してDataGridに得意先テーブルをバインドします。ページがポストバックされたときは、Session変数に格納されている得意先テーブルのDataTableオブジェクトを取得して変数に保存します。Session変数にDataTableが保存されていないときは、BindDataGrid()を呼び出します。
|
8: Sub Page_Load() |
Sub dgrdCustomers_ItemDataBound()イベントの処理
このイベントは、DataGridのDataBind()メソッドが実行されたときに発生します。このイベントでは、DataGridのアイテム(DataGridItem)にクライアント側で動作するOnClickイベントを登録しています。これにより、任意のセルをクリックして行を選択できるようになります。
|
35: Sub
dgrdCustomers_ItemDataBound(s As Object, _ |
Sub
ibtnInsert_Command()イベントの処理
このイベントは、Webページからレコードの追加ボタンをクリックしたときに発生します。このイベントでは、InsertScriptBlock()を呼び出して、新規ウィンドウを表示します。
|
57: Sub
ibtnInsert_Command(s As Object, e As CommandEventArgs) |
Sub
btnRefresh_Click()イベントの処理
このイベントは、クライアント側からメッセージを表示するTextBoxを書き換えたときに発生します。このサンプルでは、子ウィンドウから親ウィンドウのTextBoxにメッセージを設定して書き換えます。つまり、子ウィンドウから親ウィンドウをポストバックさせています。btnRefresh_Clickイベントでは、DataGridに得意先テーブルをバインドしてリフレッシュします。
行22-27のWith…End Withでは、DataGridに得意先テーブルが格納されているDataTableをバインドしています。行28では、件数を表示するTextBoxにレコード件数を設定しています。レコード件数は、DataTableのRo
|
21: Sub
btnRefresh_Click(s As Object, e As EventArgs) |
Sub
BindDataGrid()の処理
このサブプロシージャは、DataGridに得意先テーブルをバインドして表示します。BindDataGridは、Page_Loadイベントから呼ばれます。
行62-63では、得意先テーブルからレコードを抽出するSQLを生成しています。このSQLでは、Order By句で「CustomerID Desc」を指定していますので、得意先IDの降順にレコードが並べ替えられます。また、Top 10のオプションを指定していますので、上位10件のレコードが抽出されます。
行64では、CreateDataSet()関数を呼び出して得意先テーブルのDataSetを作成しています。CreateDataSet()の引数には、SQLを指定します。この関数からは、DataSetが返されます。
62: Dim strSQL As String =
"Select Top 10 * From Customers " & _
63: "Order by
CustomerID Desc"
64: Dim ds AS DataSet =
CreateDataSet(strSQL)
行68では、DataSetのTablesコレクションから得意先テーブルのDataTableを作成しています。
行70-75のWith…End Withでは、DataGridに得意先テーブルのDataTableをバインドしています。行71では、DataGridのDataSourceプロパティにDataTableを設定しています。行72では、DataKeyFieldプロパティに得意先テーブルの主キー(得意先ID)を設定しています。ここで設定した主キーは、DataGridから行を選択したときに参照します。行73では、DataBind()メソッドでDataTableをバインドしています。行74では、SelectedIndexプロパティに-1を設定して以前選択されていた行を解除しています。
行76では、件数を表示するTextBoxのTextプロパティに、レコード件数を設定しています。レコード件数は、DataTableのRo
|
61: Sub BindDataGrid() |
Sub
InsertScriptBlock()の処理
このサブプロシージャでは、新規ウィンドウを開くJavaScriptを生成して登録します。InsertScriptBlockは、レコードの追加ボタンをクリックしたときに、追加ボタンのOnCommandイベントから呼ばれます。
行81-83では、JavaScriptのwindow.open()メソッドの引数に指定するオプションを生成しています。行85-90のWith…End Withでは、StringBuilder()のAppend()メソッドで以下のJavaScriptを生成しています。
<script language='javascript'>
window.open('PopupInsert.aspx','_blank','height=200,width=330,left=10,top=10,
location=no,menubar=no,resizable=yes,scrollbars=no,status=no,titlebar=yes,toolbar=no');
</script>
JavaScriptのwindow.open()メソッドは、新規ウィンドウを開きます。Open()メソッドの引数には、url、target、featuresを指定します。Urlには、新規ウィンドウに表示するファイルPopupInsert.aspxを指定します。Targetには、_blankを指定して新規ウィンドウを開くようにします。Featuresには、ウィンドウのサイズなど各種オプションを指定します。
行91では、Page.RegisterClientScriptBlock()メソッドでJavaScriptを登録します。ここで登録したJavaScriptは、Webページがロードされたときにクライアント側のブラウザで実行されます。
|
80: Sub
InsertScriptBlock() |
Sub
InsertAlertScript()の処理
このサブプロシージャでは、エラーメッセージをポップアップウィンドウに表示するJavaScriptを生成して登録します。InsertAlertScriptは、CreateDataSet()関数からエラーが発生したときに呼ばれます。
行95では、引用符(')をJavaScriptのエスケープシーケンス\'に置換しています。メッセージに引用符が含まれると、alert()メソッドでエラーとなるのを回避します。行97-102では、StringBuilderのAppend()メソッドで以下のJavaScriptを生成しています。
<script language='javascript'>
alert('Error Message');
</script>
JavaScriptのalert()メソッドは、エラーメッセージをポップアップウィンドウに表示します。
行103では、Page.RegisterClientScriptBlick()メソッドでJavaScriptを登録しています。ここで登録したJavaScriptは、Webページがロードされたときにクライアント側のブラウザで実行されます。
|
94: Sub
InsertAlertScript(strMessage As String) |
Function
CreateDataSet()関数の処理
この関数は、DataSetを作成して返します。CreateDataSetは、BindDataGrid()から呼ばれます。
行117-118では、Connectionのインスタンスを生成しています。Connectionの引数には、Web.Configに登録されているデータベース接続文字列を指定しています。Web.Configに登録されている内容を取得するには、ConfigurationSettingsのAppSettings()メソッドを使用します。AppSettings()メソッドの引数には、<add>タグのkeyを指定します。
117: Dim con As New OleDbConnection( _
118:
ConfigurationSettings.AppSettings("conStringAccNw"))
<appSettings>
<add key="conStringAccNw"
value="PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA Source=C:\WebMatrix\webdb\Nwind.mdb" />
</appSettings>
行119では、DataAdapterのインスタンスを生成しています。DataAdapterの引数には、SQLとConnectionオブジェクトを指定しています。
行121-126のTry…Catch…End Tryブロックでは、DataAdapterのFill()メソッドでSQLを実行して得意先テーブルをDataSetに取り込んでいます。行121-122のTryブロックでエラーが発生したときは、行123-125のCatchブロックが実行されます。Catchブロックでは、InsertAlertScript()を呼び出してポップアップウィンドウにエラーメッセージを表示します。
121: Try
122: da.Fill(ds)
123: Catch e As Exception
124:
InsertAlertScript(e.Message)
125: Return Nothing
126: End Try
行127では、関数の戻り値としてDataSetを返します。
|
115:
Function CreateDataSet(strSQL As String, _ |
リスト DataGridInser.aspxのソースコード(コード編)
|
1: <%@ Page
language="vb" SmartNavigation="false" %> 7: 94: Sub InsertAlertScript(strMessage As String) 104:
End Sub |
◆ サブプログラムPopupInsert.aspxの解説(HTML編)
子ウィンドウのWebフォームには、TextBoxとButtonを作成しています。TextBoxには、新規レコードを入力します。
行85-162の<fieldset>…</fieldset>では、角の丸みがかったボックスを表示しています。行86-90の<legend>…</legend>では、ボックスの凡例を表示しています。

図 丸みがかったボックスと凡例を表示した例
行92-104の<tr>…</tr>では、得意先IDのLabelとTextBoxを定義しています。得意先IDは、自動採番されるのでTextBoxのReadOnlyプロパティにTrueを設定して読み込み専用にしています。
行106-120の<tr>…</tr>では、得意先名のLabelとTextBoxを定義しています。行116-118では、RequiredFieldValidatorで得意先名が入力されているかチェックしています。得意先名を入力しないで追加ボタンをクリックすると、TextBoxの右側に「*」が表示されます。
![]()
図 エラーメッセージの「*」が表示された例
後続する<tr>…</tr>では、担当者名、部署役職、電話番号のLabelとTextBoxを定義しています。
行165-205の<table>…</table>には、ImageButton、Label、DropDownList、Buttonを定義しています。ImageButtonとDropDownListのEnabledプロパティには、Falseを設定して使用不可にしています。このサンプルでは、これらの機能はサポートしていません。行195-202では、「追加」と「閉じる」のボタンを定義しています。「閉じる」のボタンには、CausesValidationプロパティにFalseを設定してRequiredFieldValidatorを適用させないようにしています。
![]()
図 ImageButton、Label、DropDownListを使用不可の状態で表示した例
リスト PopupInsert.aspxのソースコード(HTML編)
|
76: <html> 193: </td> |
◆ サブプログラムPopupInsert.aspxの解説(コード編)
PopupInsert.aspxは、Webフォームから入力した得意先データをDataTableに追加します。さらに、DataTableに追加したレコードをデータベースに反映します。追加したレコードをデータベースに反映したら、親ウィンドウをポストバックさせてDataGrid上に追加したレコードを表示します。
Sub Page_Load()イベントの処理
このイベントは、ページがロードされたときに発生します。Page_Loadでは、ページの初期化処理を行います。
行9では、Session変数に保存されている得意先テーブルのDataTableを取得して変数に退避します。行10-13のIf…EndIfでは、ページが最初にロードされたか調べています。最初にロードされたときは、AddCursor()を呼び出してアプリケーション独自のカーソルを表示しています。さらに、「閉じる」ボタンにクライアント側で動作するonClickイベントを登録しています。このイベントでは、JavaScriptのwindow.close()メソッドを実行して子ウィンドウを閉じます。
|
8: Sub Page_Load() |
Sub btnAdd_Click()イベントの処理
このイベントは、追加ボタンをクリックしたときに発生します。このイベントでは、得意先テーブルに新規レコードを追加します。また、ここで追加したレコードを親ウィンドウのDataGridに反映させます。
行17では、InsertRecord()関数を呼び出して得意先テーブルにレコードを追加します。この関数からは、処理の結果がメッセージで返されます。行19-24のWith…End Withでは、StringBuilderのAppend()メソッドで以下のJavaScriptを生成しています。
<script
language='javascript'>
window.opener.frmMain.txtMessage.value =
'XXX';
</script>
JavaScriptのwindow.opener.frmMain.txtMessage.value=は、親ウィンドウのtxtMessage.valueにメッセージを設定します。txtMessageには、クライアント側で動作するonProperyChangeイベントが登録されていますので、このイベントが実行されます。onPropertyChangeイベントには、WebページをポストバックさせるJavaScriptが記述されていますので、WebページがポストバックされてDataGridがリフレッシュされます。これで親ウィンドウのDataGridには、子ウィンドウから追加したレコードが表示されます。
行25では、Page.RegisterClientScriptBlock()メソッドでJavaScriptを登録しています。ここで登録した、JavaScriptは、Webページがロードされたときクライアント側のブラウザから実行されます。
|
16: Sub btnAdd_Click(s As
Object, e As EventArgs) 19: With sbScript |
Sub AddCursor()の処理
このサブプロシージャでは、アプリケーション独自のカーソルを追加します。AddCursorは、Page_Loadイベントからページが最初にロードされたときに呼ばれます。
カーソルを追加するには、TextBoxにクライアント側で動作するonFocusとonBlurイベントを登録します。onFocusイベントは、TextBoxがフォーカスを取得したときに発生します。onBlurは、フォーカスを喪失したときに発生します。これらのイベントで、TextBoxの背景色を書き換えることによりアプリケーション独自のカーソルを表示することができます。
TextBoxにクライアント側で動作するイベントを登録するには、AttributesコレクションのAdd()メソッドを使用します。Add()メソッドの引数には、イベント名とイベント処理を記述します。
onFocusイベントでは、TextBoxの背景色をLightGreenに書き換えます。onBlueイベントでは、TextBoxの背景色をAliceBlueに戻します。
|
28: Sub AddCursor() |
Function InsertRecord()関数の処理
この関数では、Webフォームに入力したデータを得意先テーブルのDataTableに追加します。InsertRecordは、追加ボタンのOnClickイベントから呼ばれます。
行43-46では、TextBoxから入力した得意先名、担当者名、部署各職、電話番号を取得します。行49-54では、DataTableに新規レコードを追加しています。行49では、DataTableのNewRow()メソッドでDataRowを作成します。行50-53では、DataRowのカラムに得意先名、担当者名、部署各職、電話番号を設定しています。行54では、DataTableのRo
行56では、UpdateDataTable()関数を呼び出して、DataTableをデータベースに反映します。UpdateDataTable()からは、処理の結果を示すメッセージとして「正常終了!」、「エラー発生!」が返されます。
|
42: Function
InsertRecord() As String
48: |
Function UpdateDataTable()関数の処理
この関数では、DataTableに追加されたレコードをデータベースに反映します。UpdateDataTableは、InsertRecord()から呼ばれます。UpdateDataTable()の引数には、strSQLとstrConnectionStringを指定します。strSQLには、得意先テーブルからレコードを抽出するSQLを指定します。strConnectionStringには、データベースの接続文字列を指定します。DataTableをデータベースに反映するには、DataAdapterのUpdate()メソッドを使用します。Update()メソッドで使用するINSERT、UPDATE、DELETEのSQLは、CommandBuilderで自動生成します。
行61-62では、Connectionのインスタンスを生成しています。Connectionの引数には、データベースの接続文字列を指定します。行63では、DataAdapterのインスタンスを生成しています。DataAdapterの引数には、SQLとConnectionのオブジェクトを指定します。引数のSQLには、SELECTステートメントを指定します。行64では、CommandBuilderでDataTableをデータベースに反映するためのSQLを自動生成します。CommandBuilderは、SELECTステートメントを元にINSERT、UPDATE、DELETEのSQLを生成します。
行66-70のTry…Catch…End Tryブロックでは、DataAdapterのUpdate()メソッドでDataTableの変更された内容をデータベースに反映します。DataTableに新規レコードが追加されたときは、SQLのINSERTステートメントを実行してDataTableのレコードをデータベースに追加します。DataTableのレコードが更新されたときは、UPDATEステートメントで、データベースのレコードを更新します。DataTableのレコードが削除されたときは、DELETEステートメントで、データベースからレコードを削除します。得意先テーブルのレコードを更新、削除するときは、他のユーザから変更されていないことを確認してから実行します。他のユーザから変更されているときは、同時実行違反のエラーになります。このサンプルでは、レコードの追加しか行っていませんので同時実行違反のエラーになることはありません。
Update()メソッドでエラーが発生したときは、行68-69のCatchブロックが実行されます。
行71では、Session変数に格納されているDataTableを解放します。Session変数に保存されているDataTableを解放すると、メインプログラムがポストバックされたときに、得意先テーブルをデータベースから読み込んでリフレッシュします。行72では、戻り値として処理の結果を示すメッセージを返します。
|
59: Function
UpdateDataTable(strSQL As String, _ |
リスト PopupInsert.aspxのソースコード(コード編)
|
1: <%@ Page language="vb" %> |
Note
|
CommandBuilder()を使用する場合の留意事項 CommandBuilderは、DataAdapterのSelectCommandに格納されているSELECTステートメントを元にINSERT、UPDATE、DELETEステートメントを自動生成します。CommandBuilderで使用するSELECTステートメントには、以下の制約があります。これらの制約に違反するときは、CommandBuilderを使用しないでINSERT、UPDATE、DELETEステートメントを手動にて用意する必要があります。 ・ DataAdapterのSelectCommandに格納されているSELECTステートメントでは、テーブルの主キーを選択する必要があります。 ・ SelectCommandに格納されているSELECTステートメントでは、JOINなどで複数のテーブルを結合することはできまません。 ・ SELECTステートメントに、計算式などを記述することはできません。テーブルのフィールド名のみ記述する必要があります。 |
Note
|
DataAdapterのUpdate()メソッドで使用するINSERTステートメントを手動で用意するには Update()メソッドで使用するINSERTステートメントを手動で用意するには、INSERTのCommandオブジェクトを作成してDataAdapterのInsertCommandに設定します。 .Add("@CompanyName", OleDbType.VarWChar, 40, "CompanyName") .Add("@ContactName", OleDbType.VarWChar, 30, "ContactName") .Add("@ContactTitle", OleDbType.VarWChar, 30, "ContactTitle") .Add("@Phone", OleDbType.VarWChar, 24, "Phone") INSERTステートメントのパラメータ@CompanyName、@ContactName、@ContactTitle、@Phoneには、DataTableのDataColumnが関連付けられていますので、自動的に値が代入されます。 Dim con = New OleDbConnection( _ ConfigurationSettings.AppSettings("conStringAccNw")) Dim da As New OleDbDataAdapter(strSQL, con) da.InsertCommand = CreateInsertCommand() Function CreateInsertCommand() As OleDbCommand Dim sbSQL As New StringBuilder() With sbSQL .Append("Insert Into Customers " & vbCrLf) .Append(" (CompanyName, ContactName, ContactTitle, Phone) " & vbCrLf) .Append(" Values(?, ?, ?, ?)") End With Dim cmd As New OleDbCommand(sbSQL.ToString, con) Dim pc As OleDbParameterCollection = cmd.Parameters With pc .Add("@CompanyName", OleDbType.VarWChar, 40, "CompanyName") .Add("@ContactName", OleDbType.VarWChar, 30, "ContactName") .Add("@ContactTitle", OleDbType.VarWChar, 30, "ContactTitle") .Add("@Phone", OleDbType.VarWChar, 24, "Phone") End With Return cmd End Function |
Tip
|
CommandBuilder()で生成されたINSERT、UPDATE、DELETEステートメントを表示するには CommandBuilderで生成されたINSERT、UPDATE、DELETEステートメントを取得するには、CommandBuilderのGetInsertCommand、GetUpdateCommand、GetDeleteCommandのCommandTextを参照します。 Dim strSQL As String = "Select CustomerID, CompanyName, ContactName,
Dim con As New OleDbConnection( _ ConfigurationSettings.AppSettings(strConnectionString)) Dim da As New OleDbDataAdapter(strSQL, con) Dim cb As New OleDbCommandBuilder(da)
Response.Write(cb.GetInsertCommand.CommandText & "<br>") Response.Write(cb.GetUpdateCommand.CommandText & "<br>") Response.Write(cb.GetDeleteCommand.CommandText & "<br>") SELECTステートメント: SELECT CustomerID, CompanyName, ContactName, ContactTitle, Phone From Customers INSERTステートメント: INSERT INTO Customers( CompanyName , ContactName , ContactTitle , Phone ) VALUES ( ? , ? , ? , ? ) UPDATEステートメント: UPDATE Customers SET CompanyName = ? , ContactName = ? , ContactTitle = ? , Phone = ? WHERE ( (CustomerID = ?) AND ((? IS NULL AND CompanyName IS NULL) OR (CompanyName = ?)) AND ((? IS NULL AND ContactName IS NULL) OR (ContactName = ?)) AND ((? IS NULL AND ContactTitle IS NULL) OR (ContactTitle = ?)) AND ((? IS NULL AND Phone IS NULL) OR (Phone = ?)) ) DELETEステートメント: DELETE FROM Customers WHERE ( (CustomerID = ?) AND ((? IS NULL AND CompanyName IS NULL) OR (CompanyName = ?)) AND ((? IS NULL AND ContactName IS NULL) OR (ContactName = ?)) AND ((? IS NULL AND ContactTitle IS NULL) OR (ContactTitle = ?)) AND ((? IS NULL AND Phone IS NULL) OR (Phone = ?)) ) UPDATE、DELETEステートメントのWHERE句では、レコードが他のユーザから変更されていないことを確認してから更新、削除していることが解ります。 |
Tip
|
追加ボタンの処理が完了するまで再度ボタンをクリックできないようにするには 子ウィンドウから追加ボタンをクリックしてレコードの追加処理中に、再度追加ボタンをクリックすると同じレコードが重複して追加されます。得意先テーブルのように主キー(得意先ID)がオートナンバー型の場合、システムが得意先IDを自動採番するため、重複エラーにならないで登録されてしまいます。この不都合を回避するには、追加ボタンをクリックしたときに、追加処理が完了するまで追加ボタンを使用不可の状態にします。 追加ボタンをクリックしたときに使用不可の状態にするには、Page_LoadイベントでDisableAddButton()を呼びます。DisableAddButton()では、以下のようなJavaScriptを生成してWebページに登録します。 <script language='javascript'> function verifyStatus() { if (typeof(Page_ClientValidate) != 'function' || Page_ClientValidate()) { if (document.frmPopupInsert.btnAdd.disabled==false) { document.frmPopupInsert.btnAdd.disabled=true; __doPostBack('btnAdd',''); return true; } else { return false; } } else { return false; } } </script> DisableAddButton()で登録したJavaScriptのverifyStatus()関数は、<span>…</span>タグのonClickイベントから呼びます。 <span onClick="return verifyStatus();"> <asp:Button id="btnAdd" runat="server" Text="追加" OnClick="btnAdd_Click" /> </span> Webページから追加ボタンをクリックすると、spanのonClickイベントが発生してverifyStatus()関数を呼びます。verifyStatus()では、追加ボタンを使用不可の状態にしてからWebページをポストバックします。Webページがポストバックされると、追加ボタンのOnClickイベントが実行されます。 Sub Page_Load() DisableAddButton() End Sub Sub DisableAddButton() Dim sbScript As New StringBuilder() With sbScript .Append("<script language='javascript'>" & vbCrLf) .Append("function verifyStatus() {" & vbCrLf) .Append(" if (typeof(Page_ClientValidate) != 'function' || Page_ClientValidate()) {" & vbCrLf) .Append(" if (document.frmPopupInsert.btnAdd.disabled==false) {" & vbCrLf) .Append(" document.frmPopupInsert.btnAdd.disabled=true;" & vbCrLf) .Append(" " & GetPostBackEventReference(btnAdd) & ";" & vbCrLf) .Append(" return true;" & vbCrLf) .Append(" } else {" & vbCrLf) .Append(" return false;" & vbCrLf) .Append(" }" & vbCrLf) .Append(" } else {" & vbCrLf) .Append(" return false;" & vbCrLf) .Append(" }" & vbCrLf) .Append("}" & vbCrLf) .Append("</" & "script>") End With RegisterClientScriptBlock("clientScript", sbScript.ToString) End Sub |