DataGridの編集時、入力データを検証する

 

●入力したデータを検証する (ch61DataGrid1.aspx)

 

DataGridOracleデータベースの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 CustomerPackage AS

  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 CustomerPackage AS

  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のテンプレート列に入力した値を取得する方法

▼連結列をテンプレート列に変換する方法

▼テンプレート列のItemTemplateEditItemTemplateを編集する方法

TextBoxTextプロパティにデータ連結式を記述する方法

TextBoxに検証コントロールを適用する方法

 

1. 新規フォルダ作成

 

VS.NETを起動してプロジェクトvboraを開きます。ソリューションエクスプローラから[vbora]を右クリックして、新規フォルダ「ch6」を作成します。

 

2. Webフォーム追加

 

ソリューションエクスプローラからフォルダ[ch6]を右クリックして、新規Webフォーム「ch61DataGrid1」を追加します。

 

3. DataGridを作成して編集機能追加

 

DataGridに編集機能を追加します。

 

fig6-1-1

DataGridに編集機能追加

 

4. テンプレート列に変換

 

DataGrid1の右クリックから[プロパティビルダ]を選択します。「DataGrid1プロパティ」が表示されたら、左側から[]を選択します。「選択された列」のリストボックスから[得意先]を選択します。画面最下位の[この列をテンプレート列に変換する]をクリックして、連結列をテンプレート列に変換します。「選択された列」のリストボックスに表示されている[得意先]が、テンプレート列に変わります。

 

同様の手順で、[担当][電話]の連結列をテンプレート列に変換します。最後に、[OK]をクリックして「プロパティビルダ」を閉じます。

 

fig6-1-2

プロパティビルダから[]を選択して連結列をテンプレート列に変換

 

5. テンプレートの編集

 

DataGrid1の右クリックから[テンプレートの編集][Columns[1] – 得意先]を選択します。「DataGrid1 – Columns[1] – 得意先」のテンプレート編集が表示されたら、EditItemTemplateからTextBoxをクリックして選択します。TextBoxのプロパティウィンドウから「(ID)」プロパティを「txtCompanyName」に書き換えます。

 

fig6-1-3

EditItemTemplateTextBoxの「ID」プロパティを書き換え

 

 

ツールボックスの[Webフォーム]からRequiredFieldValidatorをドラッグして、EditItemTemplateTextBoxの右側にドロップします。

 

fig6-1-4

ツールボックスからRequiredFieldValidatorをドラッグ&ドロップ

 

 

プロパティウィンドウから[RequiedFieldValidator1]を選択したら、「ControlToValidate」プロパティから[txtCompanyName]を選択します。「Display」プロパティからは、[Dynamic]を選択します。「ErrorMessage」プロパティに「*」を入力します。

 

fig6-1-5

RequiredFieldValidatorのプロパティ設定

 

「テンプレート編集」の右クリックから[テンプレートの編集][Columns[2] – 担当]を選択します。「DataGrid1 – Columns[2] – 担当」のテンプレート編集が表示されたら、EditItemTemplateからTextBoxをクリックして選択します。TextBoxのプロパティウィンドウから「(ID)」プロパティを「txtContactName」に書き換えます。

 

ツールボックスの[Webフォーム]からRequiredFieldValidatorをドラッグしてEditItemTemplateTextBoxの右側にドロップします。プロパティウィンドウから[RequiedFieldValidator2]を選択したら、「ControlToValidate」プロパティから[txtContactName]を選択します。「Display」プロパティからは、[Dynamic]を選択します。「ErrorMessage」プロパティに「*」を入力します。

 

fig6-1-6

担当のEditItemTemplateRequiredFieldValidatorを追加

 

 

「テンプレート編集」の右クリックから[テンプレートの編集][Columns[3] – 電話]を選択します。「DataGrid1 – Columns[3] – 電話」のテンプレート編集が表示されたら、EditItemTemplateからTextBoxをクリックして選択します。TextBoxのプロパティウィンドウから「(ID)」プロパティを「txtPhone」に書き換えます。

 

ツールボックスの[Webフォーム]からRequiredFieldValidatorをドラッグしてEditItemTemplateTextBoxの右側にドロップします。プロパティウィンドウから[RequiedFieldValidator3]を選択したら、「ControlToValidate」プロパティから[txtPhone]を選択します。「Display」プロパティからは、[Dynamic]を選択します。「ErrorMessage」プロパティに「*」を入力します。

 

fig6-1-7

電話のEditItemTemplateRequiredFieldValidatorを追加

 

「テンプレートの編集」の右クリックから[テンプレート編集の終了]を選択して閉じます。

 

 

6. UpdateCommandイベントの書き換え

 

メニューバーから[表示][コード]を選択してコードビューに切り替えます。DataGrid1_UpdateCommandイベントを以下のように書き換えます。

 

Private Sub DataGrid1_UpdateCommand(ByVal source As Object,

cccByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)

cccHandles 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]を右クリックしてブラウザに表示します。DataGridCustomers表が表示されたら[編集]をクリックします。「得意先」、「担当」、「電話」のテキストボックスを空白にすると、エラーメッセージとして「*」が赤色で表示されます。エラーメッセージが表示されている状態で、[更新]をクリックしても無効になります。テキストボックスにデータを入力すると、エラーメッセージが消えて[更新]が有効になります。

 

fig6-1-8

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をドラッグして、EditItemTemplateTextBoxの右側にドロップします。RequiredFieldValidarのプロパティウィンドウから「ControlToValidate」プロパティにTextBoxIDを設定します。「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_LoadDataGrid1_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,

cccByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)

cccHandles 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;

 

OracleConnectionOracleCommandのインスタンスを生成したら、OracleCommandオブジェクトのCommandTypeプロパティにCommandType.StoredProcedureBindByNameプロパティにTrueを設定します。

 

ParametersコレクションのAddメソッドでパラメータiCompanyNameiContactNameiPhoneoRowCountを追加します。oRowCountDirectionプロパティには、ParameterDirection.Outputを設定して出力パラメータとします。

 

OracleConnectionオブジェクトのOpenメソッドでOracleデータベースを開いたら、OracleCommandオブジェクトのExecuteNonQueryメソッドを実行してストアドプロシージャ(UpdateCustomersRc)を実行します。Oracleデータベースの場合、ExecuteNonQueryメソッドの戻り値として常に「-1」が返ります。ここでは、ExecuteNonQueryメソッドの戻り値を利用する代わりに、ストアドプロシージャの出力パラメータ(oRowCount)から更新されたレコード件数を取得します。ストアドプロシージャで更新されたレコード件数を取得するには、暗黙カーソル「SQL%ROWCOUNT」を使用します。

 

OracleConnectionCloseメソッドで、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