DataGridの編集時、入力データを検証する
●入力したデータを検証する (ch61DataGrid1.aspx)
DataGridにOracleデータベースのCustomers表をバインドして表示します。Customers表から行(レコード)を抽出するには、パッケージ(CustomerPackage)に登録されているストアドプロシージャ(GetCustomersGT40)を使用します。DataGridで編集した行をOracleデータベースのCustomers表に反映するには、ストアドプロシージャ(UpdateCustomersRc)を使用します。
iSQL*PlusまたはSQL*Plusを起動して、事前にパッケージ仕様部(C:\vbora\sql\CustomerPackage.sql)とパッケージ本体部(C:\vbora\sql\CustomerPackageBody.sql)を作成してください。
パッケージ仕様部(CustomerPackage.sql)
CREATE OR REPLACE PACKAGE
TYPE rcurCustomers IS REF CURSOR;
PROCEDURE GetCustomersGT40(
orcurCustomers OUT rcurCustomers);
PROCEDURE UpdateCustomersRc(
iCompanyName IN VARCHAR2,
iContactName IN VARCHAR2,
iPhone IN VARCHAR2,
iCustomerID IN NUMBER,
oRowCount OUT NUMBER);
END CustomerPackage;
パッケージ本体部(CustomerPackageBody.sql)
CREATE OR REPLACE PACKAGE BODY
PROCEDURE GetCustomersGT40(
orcurCustomers OUT rcurCustomers) IS
BEGIN
OPEN orcurCustomers FOR
SELECT *
FROM Customers
WHERE CustomerID > 40
ORDER BY CustomerID;
END GetCustomersGT40;
PROCEDURE UpdateCustomersRc(
iCompanyName IN VARCHAR2,
iContactName IN VARCHAR2,
iPhone IN VARCHAR2,
iCustomerID IN NUMBER,
oRowCount OUT NUMBER) IS
BEGIN
UPDATE Customers
SET CompanyName = iCompanyName,
ContactName = iContactName,
Phone = iPhone
WHERE CustomerID = iCustomerID;
oRowCount := SQL%ROWCOUNT;
END UpdateCustomersRc;
END CustomerPackage;
このサンプルでは、以下のノウハウを習得することができます。
▼DataGridから編集したデータを検証する方法
▼DataGridのテンプレート列に入力した値を取得する方法
▼連結列をテンプレート列に変換する方法
▼テンプレート列のItemTemplate、EditItemTemplateを編集する方法
▼TextBoxのTextプロパティにデータ連結式を記述する方法
▼TextBoxに検証コントロールを適用する方法
1. 新規フォルダ作成
VS.NETを起動してプロジェクトvboraを開きます。ソリューションエクスプローラから[vbora]を右クリックして、新規フォルダ「ch6」を作成します。
2. Webフォーム追加
ソリューションエクスプローラからフォルダ[ch6]を右クリックして、新規Webフォーム「ch61DataGrid1」を追加します。
3.
DataGridを作成して編集機能追加
DataGridに編集機能を追加します。

図 DataGridに編集機能追加
4. テンプレート列に変換
DataGrid1の右クリックから[プロパティビルダ]を選択します。「DataGrid1プロパティ」が表示されたら、左側から[列]を選択します。「選択された列」のリストボックスから[得意先]を選択します。画面最下位の[この列をテンプレート列に変換する]をクリックして、連結列をテンプレート列に変換します。「選択された列」のリストボックスに表示されている[得意先]が、テンプレート列に変わります。
同様の手順で、[担当]、[電話]の連結列をテンプレート列に変換します。最後に、[OK]をクリックして「プロパティビルダ」を閉じます。

図 プロパティビルダから[列]を選択して連結列をテンプレート列に変換
5. テンプレートの編集
DataGrid1の右クリックから[テンプレートの編集]→[Columns[1] – 得意先]を選択します。「DataGrid1 –
Columns[1] – 得意先」のテンプレート編集が表示されたら、EditItemTemplateからTextBoxをクリックして選択します。

図 EditItemTemplateのTextBoxの「ID」プロパティを書き換え
ツールボックスの[Webフォーム]からRequiredFieldValidatorをドラッグして、EditItemTemplateのTextBoxの右側にドロップします。

図 ツールボックスからRequiredFieldValidatorをドラッグ&ドロップ
プロパティウィンドウから[RequiedFieldValidator1]を選択したら、「ControlToValidate」プロパティから[txtCompanyName]を選択します。「Display」プロパティからは、[Dynamic]を選択します。「ErrorMessage」プロパティに「*」を入力します。

図 RequiredFieldValidatorのプロパティ設定
「テンプレート編集」の右クリックから[テンプレートの編集]→[Columns[2] – 担当]を選択します。「DataGrid1 –
Columns[2] – 担当」のテンプレート編集が表示されたら、EditItemTemplateからTextBoxをクリックして選択します。
ツールボックスの[Webフォーム]からRequiredFieldValidatorをドラッグしてEditItemTemplateのTextBoxの右側にドロップします。プロパティウィンドウから[RequiedFieldValidator2]を選択したら、「ControlToValidate」プロパティから[txtContactName]を選択します。「Display」プロパティからは、[Dynamic]を選択します。「ErrorMessage」プロパティに「*」を入力します。

図 担当のEditItemTemplateにRequiredFieldValidatorを追加
「テンプレート編集」の右クリックから[テンプレートの編集]→[Columns[3] – 電話]を選択します。「DataGrid1 –
Columns[3] – 電話」のテンプレート編集が表示されたら、EditItemTemplateからTextBoxをクリックして選択します。
ツールボックスの[Webフォーム]からRequiredFieldValidatorをドラッグしてEditItemTemplateのTextBoxの右側にドロップします。プロパティウィンドウから[RequiedFieldValidator3]を選択したら、「ControlToValidate」プロパティから[txtPhone]を選択します。「Display」プロパティからは、[Dynamic]を選択します。「ErrorMessage」プロパティに「*」を入力します。

図 電話のEditItemTemplateにRequiredFieldValidatorを追加
「テンプレートの編集」の右クリックから[テンプレート編集の終了]を選択して閉じます。
6.
UpdateCommandイベントの書き換え
メニューバーから[表示]→[コード]を選択してコードビューに切り替えます。DataGrid1_UpdateCommandイベントを以下のように書き換えます。
Private Sub DataGrid1_UpdateCommand(ByVal source As Object,
ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
Handles DataGrid1.UpdateCommand
Dim strCompanyName As String = CType(e.Item.FindControl("txtCompanyName"), TextBox).Text
Dim strContactName As String = CType(e.Item.FindControl("txtContactName"), TextBox).Text
Dim strPhone As String = CType(e.Item.FindControl("txtPhone"), TextBox).Text
Dim intCustomerID As Integer = DataGrid1.DataKeys(e.Item.ItemIndex)
UpdateRecord(strCompanyName, strContactName, strPhone, intCustomerID)
DataGrid1.EditItemIndex = -1
BindGrid()
End Sub
7.
Function UpdateRecordの書き換え
Function UpdateRecordを以下のように書き換えます。
Private Function UpdateRecord(ByVal strCompanyName As String, _
ByVal strContactName As String, _
ByVal strPhone As String, _
ByVal intCustomerID As Integer) As Integer
Dim con As New OracleConnection(ConfigurationSettings.AppSettings("conStringOraNw"))
Dim cmd As New OracleCommand("CustomerPackage.UpdateCustomersRc", con)
With cmd
.CommandType = CommandType.StoredProcedure
.BindByName = True
.Parameters.Add("iCompanyName", OracleDbType.Varchar2, 40).Value = strCompanyName
.Parameters.Add("iContactName", OracleDbType.Varchar2, 30).Value = strContactName
.Parameters.Add("iPhone", OracleDbType.Varchar2, 24).Value = strPhone
.Parameters.Add("iCustomerID", OracleDbType.Int32).Value = intCustomerID
.Parameters.Add("oRowCount", OracleDbType.Int32).Direction = ParameterDirection.Output
End With
con.Open()
cmd.ExecuteNonQuery()
Dim intRetValue As Integer = Int32.Parse(cmd.Parameters("oRowCount").Value)
con.Close()
Return intRetValue
End Function
8. ブラウザに表示
ソリューションエクスプローラから[ch61DataGrid1.aspx]を右クリックしてブラウザに表示します。DataGridにCustomers表が表示されたら[編集]をクリックします。「得意先」、「担当」、「電話」のテキストボックスを空白にすると、エラーメッセージとして「*」が赤色で表示されます。エラーメッセージが表示されている状態で、[更新]をクリックしても無効になります。テキストボックスにデータを入力すると、エラーメッセージが消えて[更新]が有効になります。

図 DataGridの編集時、エラーが表示される
■解説
DataGridの編集時に入力したデータを検証するには、連結列をテンプレート列に変換します。連結列をテンプレート列に変換するには、DataGridの「プロパティビルダ」から[列]を選択します。「選択された列」から連結列を選択して、[この列をテンプレート列に変換する]をクリックします。「プロパティビルダ」から[OK]をクリックすると、以下のようなテンプレート列が生成されます。
<ItemTemplate>...</ItemTemplate>は通常行、<EditItemTemplate>...</EditItemTemplate>は編集行を表示するときに使用します。
<asp:DataGrid id="DataGrid1" runat="server"
AutoGenerateColumns="False">
<Columns>
<asp:BoundColumn DataField="CustomerID"
ReadOnly="True" HeaderText="ID">
</asp:BoundColumn>
<asp:TemplateColumn
HeaderText="得意先">
<ItemTemplate>
<asp:Label id=Label1 runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.CompanyName") %>'>
</asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox id=txtCompanyName runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.CompanyName") %>'>
</asp:TextBox>
</EditItemTemplate>
</asp:TemplateColumn>
・・・
</Columns>
</asp:DataGrid>
DataGridに検証コントロールを追加するには、DataGridの右クリックから[テンプレートの編集]→[Columns[1] – 得意先]を選択して、テンプレートの編集を表示します。ツールボックスからRequiredFieldValidatorをドラッグして、EditItemTemplateのTextBoxの右側にドロップします。RequiredFieldValidarのプロパティウィンドウから「ControlToValidate」プロパティにTextBoxのIDを設定します。「ErrorMessage」プロパティには、エラーメッセージを入力します。ここでは、「*」を入力しています。「Dynamic」プロパティからは、[None|Static|Dynamic]のいずれかを選択します。ここでは、[Dynamic]を選択してエラーメッセージの領域をダイナミックに確保します。テンプレート編集の右クリックから、[テンプレート編集の終了]を選択すると、以下のような検証コントロールが生成されます。
<Columns>
・・・
<asp:TemplateColumn HeaderText="得意先">
<ItemTemplate>
<asp:Label id=Label1 runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.CompanyName") %>'>
</asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox id=txtCompanyName runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.CompanyName") %>'>
</asp:TextBox>
<asp:RequiredFieldValidator id="RequiredFieldValidator1" runat="server"
ErrorMessage="*" ControlToValidate="txtCompanyName"
Display="Dynamic">
</asp:RequiredFieldValidator>
</EditItemTemplate>
</asp:TemplateColumn>
・・・
</Columns>
これで、DataGridから[編集]をクリックしたときに得意先、担当、電話のテキストボックスに検証コントロールが適用されます。
DataGridから[更新]をクリックすると、WebページがポストバックされてPage_Load→DataGrid1_UpdateCommandの順にイベントが発生します。DataGrid1_UpdateCommandイベントでは、得意先、担当、電話のデータを取得するのに、DataGridItemオブジェクトのFindControlメソッドを使用しています。
連結列から編集データを取得するには、以下のように記述しますが、テンプレート列から編集データを取得するには、FindControlメソッドを使用します。
Dim strCompanyName As String = CType(e.Item.Cells(1).Controls(0), TextBox).Text
Dim strContactName As String = CType(e.Item.Cells(2).Controls(0), TextBox).Text
Dim strPhone As String = CType(e.Item.Cells(3).Controls(0), TextBox).Text
FindControlメソッドの引数には、EditItemTemplateに配置されているTextBoxのコントロールIDを指定します。
Dim strCompanyName As String = CType(e.Item.FindControl("txtCompanyName"), TextBox).Text
Dim strContactName As String = CType(e.Item.FindControl("txtContactName"), TextBox).Text
Dim strPhone As String = CType(e.Item.FindControl("txtPhone"), TextBox).Text
編集データを取得したら、UpdateRecordメソッドを実行してOracleデータベースを更新します。
Private Sub DataGrid1_UpdateCommand(ByVal source As Object,
ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
Handles DataGrid1.UpdateCommand
Dim strCompanyName As String = CType(e.Item.FindControl("txtCompanyName"), TextBox).Text
Dim strContactName As String = CType(e.Item.FindControl("txtContactName"), TextBox).Text
Dim strPhone As String = CType(e.Item.FindControl("txtPhone"), TextBox).Text
Dim intCustomerID As Integer = DataGrid1.DataKeys(e.Item.ItemIndex)
UpdateRecord(strCompanyName, strContactName, strPhone, intCustomerID)
DataGrid1.EditItemIndex = -1
BindGrid()
End Sub
UpdateRecordメソッドは、パッケージ(CustomerPackage)に登録されているストアドプロシージャ(UpdateCustomersRc)を使用してOracleデータベースのCustomers表を更新します。このストアドプロシージャは、出力パラメータ(oRowCount)に更新された行数(レコード件数)を返します。
PROCEDURE UpdateCustomersRc(
iCompanyName IN VARCHAR2,
iContactName IN VARCHAR2,
iPhone IN VARCHAR2,
iCustomerID IN NUMBER,
oRowCount OUT NUMBER) IS
BEGIN
UPDATE Customers
SET CompanyName = iCompanyName,
ContactName = iContactName,
Phone = iPhone
WHERE CustomerID = iCustomerID;
oRowCount := SQL%ROWCOUNT;
END UpdateCustomersRc;
OracleConnectionとOracleCommandのインスタンスを生成したら、OracleCommandオブジェクトのCommandTypeプロパティにCommandType.StoredProcedure、BindByNameプロパティにTrueを設定します。
OracleConnectionオブジェクトのOpenメソッドでOracleデータベースを開いたら、OracleCommandオブジェクトのExecuteNonQueryメソッドを実行してストアドプロシージャ(UpdateCustomersRc)を実行します。Oracleデータベースの場合、ExecuteNonQueryメソッドの戻り値として常に「-1」が返ります。ここでは、ExecuteNonQueryメソッドの戻り値を利用する代わりに、ストアドプロシージャの出力パラメータ(oRowCount)から更新されたレコード件数を取得します。ストアドプロシージャで更新されたレコード件数を取得するには、暗黙カーソル「SQL%ROWCOUNT」を使用します。
OracleConnectionのCloseメソッドで、Oracleデータベースを閉じたら戻り値として更新されたレコード件数を返します。
Private Function UpdateRecord(ByVal strCompanyName As String, _
ByVal strContactName As String, _
ByVal strPhone As String, _
ByVal intCustomerID As Integer) As Integer
Dim con As New OracleConnection(ConfigurationSettings.AppSettings("conStringOraNw"))
Dim cmd As New OracleCommand("CustomerPackage.UpdateCustomersRc", con)
With cmd
.CommandType = CommandType.StoredProcedure
.BindByName = True
.Parameters.Add("iCompanyName", OracleDbType.Varchar2, 40).Value = strCompanyName
.Parameters.Add("iContactName", OracleDbType.Varchar2, 30).Value = strContactName
.Parameters.Add("iPhone", OracleDbType.Varchar2, 24).Value = strPhone
.Parameters.Add("iCustomerID", OracleDbType.Int32).Value = intCustomerID
.Parameters.Add("oRowCount",
OracleDbType.Int32).Direction = ParameterDirection.Output
End With
con.Open()
cmd.ExecuteNonQuery()
Dim intRetValue As Integer =
Int32.Parse(cmd.Parameters("oRowCount").Value)
con.Close()
Return intRetValue
End Function