DataGridProducts表をバインドして編集機能追加 (ch62DataGrid1.aspx)

 

DataGridOracleデータベースのProducts表をバインドして表示します。Products表から行(レコード)を抽出するには、パッケージ(ProductPackage)に登録されているストアドプロシージャ(GetProducts)を使用します。DataGridで編集した行をOracleデータベースのProducts表に反映するには、ストアドプロシージャ(UpdateProductsRc)を使用します。

 

iSQL*PlusまたはSQL*Plusを起動して、事前にパッケージ仕様部(C:\vbora\sql\ProductPackage.sql)とパッケージ本体部(C:\vbora\sql\ProductPackageBody.sql)を作成してください。

 

パッケージ仕様部(ProductPackage.sql)

CREATE OR REPLACE PACKAGE ProductPackage AS

  TYPE rcurProducts IS REF CURSOR;

  PROCEDURE GetProducts(

    orcurProducts OUT rcurProducts);

  PROCEDURE UpdateProductsRc(

    iProductName IN VARCHAR2,

    iCategoryID IN NUMBER,

    iProductID IN NUMBER,

    oRowCount OUT NUMBER);

END ProductPackage;

 

パッケージ本体部(ProductPackageBody.sql)

CREATE OR REPLACE PACKAGE BODY ProductPackage AS

  PROCEDURE GetProducts(

    orcurProducts OUT rcurProducts) IS

  BEGIN

    OPEN orcurProducts FOR

      SELECT *

      FROM Products

      ORDER BY ProductID;

  END GetProducts;

  PROCEDURE UpdateProductsRc(

    iProductName IN VARCHAR2,

    iCategoryID IN NUMBER,

    iProductID IN NUMBER,

    oRowCount OUT NUMBER) IS

  BEGIN

    UPDATE Products

    SET ProductName = iProductName,

CategoryID = iCategoryID

    WHERE ProductID = iProductID;

    oRowCount := SQL%ROWCOUNT;

  END UpdateProductsRc;

END ProductPackage;

 

このサンプルでは、以下のノウハウを習得することができます。

 

DataGridに編集機能を追加する方法

▼プロパティビルダから連結列を作成する方法

▼連結列を読み取り専用にする方法

DataGridEditCommandUpdateCommandDeleteCommandイベントの使い方

▼ストアドプロシージャを使用して表の行(レコード)を更新する方法

▼ストアドプロシージャから更新したレコード件数を返す方法

 

1. Webフォーム追加

 

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

 

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

 

ツールボックスの[Webフォーム]からDataGridをドラッグ&ドロップします。デザイナにDataGrid1のオブジェクトが作成されます。DataGrid1の右クリックから[自動フォーマット]を選択します。「自動フォーマット」が表示されたら、「スキームの選択」から[プロフェッショナル1]を選択して[OK]をクリックして閉じます。

 

DataGrid1の右クリックから[プロパティビルダ]を選択します。「DataGrid1プロパティ」が表示されたら、左側から[]を選択します。[実行時に自動的に列を作成する]をクリックしてチェックを外します。「使用可能な列」から[連結列]を選択してiconRightArrowをクリックします。右側の「選択された列」に連結列が表示されます。連結列(BoundColumn)プロパティの「ヘッダーテキスト」に「ID」、「データフィールド」に「ProductID」を入力します。[読み取り専用]をクリックしてチェックマークを付けます。同様の手順で、「商品」、「商品区分」の連結列を作成します。

 

連結列(BoundColumn)のプロパティ

ヘッダーテキスト

データフィールド

読み取り専用

ID

ProductID

チェック

商品

ProductName

 

商品区分

CategoryID

 

 

「使用可能な列」のリストボックスから[ボタン列]をクリックして展開します。[編集、更新、キャンセル]を選択したら、iconRightArrowをクリックします。「選択された列」に編集ボタン列が表示されます。編集ボタン列(EditCommandColumn)プロパティの「テキストのキャンセル」を「中止」に書き換えます。「ボタンの種類」から[PushButton]を選択します。

 

「プロパティビルダ」の左側から[書式]を選択します。画面中央の「オブジェクト」から[ヘッダー]を選択して「水平方向の配置」から[中央]を選択します。「オブジェクト」から[]をクリックして展開したら、[Columns[0] – ID][項目]を「右」揃えにします。[Columns[3]]の編集ボタン列をクリックして展開したら、[項目][中央]揃えにします。

 

最後に、[OK]をクリックして「プロパティビルダ」を閉じます。

 

3. コードビューに切り替え

 

メニューバーから[表示][コード]を選択してコードビューに切り替えます。クラスモジュールの先頭に、以下のImportsステートメントを追加します。

 

Imports System.Data

Imports Oracle.DataAccess.Client

Imports Oracle.DataAccess.Types

 

Page_Loadイベントに以下のコードを追加します。

 

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)

cccHandles MyBase.Load

  If Not IsPostBack Then

    BindGrid()

  End If

End Sub

 

クラスモジュールの最後に、Sub BindGridFunction CreateDataSetを追加します。

 

Private Sub BindGrid()

  With DataGrid1

    .DataSource = CreateDataSet("ProductPackage.GetProducts")

    .DataKeyField = "ProductID"

    .DataBind()

  End With

End Sub

 

Private Function CreateDataSet(ByVal strPackage As String) As DataSet

  Dim con As New OracleConnection(ConfigurationSettings.AppSettings("conStringOraNw"))

  Dim cmd As New OracleCommand(strPackage, con)

  Dim da As New OracleDataAdapter

  Dim ds As New DataSet

 

  cmd.CommandType = CommandType.StoredProcedure

  cmd.Parameters.Add("1", OracleDbType.RefCursor, ParameterDirection.Output)

  da.SelectCommand = cmd

  da.Fill(ds)

  Return ds

End Function

 

コードビュー左上の「クラス名」のドロップダウンリストから[DataGrid1]、右上の「メソッド名」のドロップダウンリストから[EditCommand]を選択します。DataGrid1_EditCommandイベントが生成されたら、以下のコードを追加します。

 

Private Sub DataGrid1_EditCommand(ByVal source As Object,

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

cccHandles DataGrid1.EditCommand

  DataGrid1.EditItemIndex = e.Item.ItemIndex

  BindGrid()

End Sub

 

同様の手順で、「クラス名」のドロップダウンリストから[DataGrid1]を選択したら、「メソッド名」のドロップダウンリストから[CancelCommand][UpdateCommand]を選択します。DataGrid1_CancelCommandDataGrid1_UpdateCommandイベントが生成されたら、以下のコードを追加します。

 

Private Sub DataGrid1_CancelCommand(ByVal source As Object,

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

cccHandles DataGrid1.CancelCommand

  DataGrid1.EditItemIndex = -1

  BindGrid()

End Sub

 

Private Sub DataGrid1_UpdateCommand(ByVal source As Object,

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

cccHandles DataGrid1.UpdateCommand

  Dim strProductName As String = CType(e.Item.Cells(1).Controls(0), TextBox).Text

  Dim intCategoryID As Integer = Int32.Parse(CType(e.Item.Cells(2).Controls(0), TextBox).Text)

  Dim intProductID As Integer = DataGrid1.DataKeys(e.Item.ItemIndex)

 

  UpdateRecord(strProductName, intCategoryID, intProductID)

  DataGrid1.EditItemIndex = -1

  BindGrid()

End Sub

 

クラスモジュールの最後に、Function UpdateRecordを追加します。

 

Private Function UpdateRecord(ByVal strProductName As String, _

  ByVal intCategoryID As Integer, _

  ByVal intProductID As Integer) As Integer

 

  Dim con As New OracleConnection(ConfigurationSettings.AppSettings("conStringOraNw"))

  Dim cmd As New OracleCommand("ProductPackage.UpdateProductsRc", con)

  With cmd

    .CommandType = CommandType.StoredProcedure

    .BindByName = True

    .Parameters.Add("iProductName", OracleDbType.Varchar2, 40).Value = strProductName

    .Parameters.Add("iCategoryID", OracleDbType.Int32).Value = intCategoryID

    .Parameters.Add("iProductID", OracleDbType.Int32).Value = intProductID

    .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

 

 

4. ブラウザに表示

 

ソリューションエクスプローラから[ch62DataGrid1.aspx]を右クリックしてブラウザに表示します。DataGridProducts表が表示されます。[編集]をクリックすると、商品と商品区分がテキストボックスに表示されます。[更新]をクリックするとProducts表を更新します。[中止]をクリックすると編集したデータを編集前の状態に復元します。

 

fig6-2-2

[編集]をクリックすると商品、商品区分がテキストボックスに表示される

 

 

■解説

 

DataGridに編集機能を追加するには、DataGrid1の右クリックから[プロパティビルダ]を選択して「DataGrid1プロパティ」を表示します。左側の[]から[実行時に自動的に列を作成する]をクリックしてチェックを外します。「使用可能な列」から[連結列]を選択して「ID」、「商品」、「商品区分」の連結列を作成します。「使用可能な列」から[編集、更新、キャンセル]を選択して「編集」ボタン列を作成します。

 

DataGridから[編集]をクリックすると、Page_LoadDataGrid1_EditCommandの順にイベントが発生します。Page_Loadイベントでは、IsPostBackプロパティを調べて初期ロードならBindGridメソッドを実行します。

 

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)

cccHandles MyBase.Load

  If Not IsPostBack Then

    BindGrid()

  End If

End Sub

 

DataGrid1_EditCommandイベントでは、DataGridオブジェクトのEditItemIndexプロパティにカレントのアイテム番号を設定します。BindGridメソッドを実行すると、カレントアイテムの商品と商品区分がテキストボックスに表示されて編集モードになります。このとき[編集]ボタンが[更新][中止]ボタンに切り替わります。

 

DataGridから[更新]をクリックすると、Webページがポストバックされて、Page_LoadDataGrid1_UpdateCommandの順にイベントが発生します。[中止]をクリックすると、Webページがポストバックされて、Page_LoadDataGrid1_CancelCommandの順にイベントが発生します。

 

Private Sub DataGrid1_EditCommand(ByVal source As Object,

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

cccHandles DataGrid1.EditCommand

  DataGrid1.EditItemIndex = e.Item.ItemIndex

  BindGrid()

End Sub

 

DataGrid1_UpdateCommandイベントでは、DataGridTextBoxから編集データを取得してUpdateRecordメソッドを実行します。UpdateRecordの引数には、商品、商品区分ID、商品IDを指定します。DataGridオブジェクトのEditItemIndexプロパティに「-1」を設定して、BindGridメソッドを実行すると、編集行が通常行として表示されます。

 

Private Sub DataGrid1_UpdateCommand(ByVal source As Object,

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

cccHandles DataGrid1.UpdateCommand

  Dim strProductName As String = CType(e.Item.Cells(1).Controls(0), TextBox).Text

  Dim intCategoryID As Integer = Int32.Parse(CType(e.Item.Cells(2).Controls(0), TextBox).Text)

  Dim intProductID As Integer = DataGrid1.DataKeys(e.Item.ItemIndex)

 

  UpdateRecord(strProductName, intCategoryID, intProductID)

  DataGrid1.EditItemIndex = -1

  BindGrid()

End Sub

 

UpdateRecordメソッドは、OracleCommandオブジェクトのExecuteNonQueryメソッドを実行してストアドプロシージャ(UpdateProductsRc)を実行します。Oracleデータベースに対して、ExecuteNonQueryメソッドを実行したときは、戻り値として常に「-1」が返ります。このサンプルはExecuteNonQuery[1]メソッドの戻り値を参照する代わりに、出力パラメータ(oRowCount)に設定されている更新レコード件数(SQL%ROWCOUNT)を取得して返します。

 

PROCEDURE UpdateProductsRc(

  iProductName IN VARCHAR2,

  iCategoryID IN NUMBER,

  iProductID IN NUMBER,

  oRowCount OUT NUMBER) IS

BEGIN

  UPDATE Products

  SET ProductName = iProductName,

CtegoryID = iCategoryID

  WHERE ProductID = iProductID;

  oRowCount := SQL%ROWCOUNT;

END UpdateProductsRc;

 

Private Function UpdateRecord(ByVal strProductName As String, _

  ByVal intCategoryID As Integer, _

  ByVal intProductID As Integer) As Integer

 

  Dim con As New OracleConnection(ConfigurationSettings.AppSettings("conStringOraNw"))

  Dim cmd As New OracleCommand("ProductPackage.UpdateProductsRc", con)

  With cmd

    .CommandType = CommandType.StoredProcedure

    .BindByName = True

    .Parameters.Add("iProductName", OracleDbType.Varchar2, 40).Value = strProductName

    .Parameters.Add("iCategoryID", OracleDbType.Int32).Value = intCategoryID

    .Parameters.Add("iProductID", OracleDbType.Int32).Value = intProductID

    .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



[1] AccessSQL Serverに対してExecuteNonQueryメソッドを実行したときは、更新したレコード件数が戻り値として返ります。