none
動的にSQLを設定しているGridViewにcheckBoxを付け、複数選択させたい RRS feed

  • 質問

  • VS2005&ASP.NET2.0&ODP.NET&Oracle9.2.0.4で開発しています。ブラウザはIE6です。

    あるテーブルに対して、条件をユーザににゅうりょくしてもらい、GridViewにデータを表示し、

    その中で選択されたレコードに対してUPDATEをかけたいのです。

    この場合、WEBで調べてみると、各行にCHECKBOXを付加してTEMPLATEを利用して、チェックされた行のキー値を取得して・・・とあったのですが、

    動的にSQL文を設定しているので、以上のことをコード上(C#)で実現したいのですが、できるでしょうか?

     

    2006年12月6日 6:32

すべての返信

  • できるかできないか、ということであればできると思います。
    ただいまいちやりたいことがどういうことなのかわかりません。

    ユーザが1行ずつ選択するのでよければGridViewの基本的な機能を利用したほうがよいと思います。

    動的にSQL文を設定しているとのことですが、それはデータを選択してくるところですよね。
    ユーザが更新する部分も必要なSQL文をうまく設定してあげて、更新用のデータをきちんと渡してあげればいいだけの話だと思います。

     

    2006年12月6日 6:38
  • ご返事ありがとうございます。

    ユーザがGridViewに表示されたレコードを複数選択することを想定しています。

    このためにGridViewの機能ではなく、CheckBoxを付けて、・・・という事を実装したいと考えました。

    実はこの処理は、まずユーザがデータを検索する照会画面があって、そこでは、条件句(WHER句)をさまざまに

    指定できます。ですのでSQLが動的になってしまいます。その画面で作成したSQL文を当該の画面で受けて、

    GridViewで表示します。そして表示したレコードのうち、選択したレコード(複数可)、即ちチェックされたレコードを

    UPDATEしたいのです。

     

    2006年12月6日 7:05
  • 独自の実装をいろいろと入れないといけないので面倒そうですね。
    ただ、できないことじゃないと思います。
    前にも書いてますけど、動的なSQLはデータの選択の部分だけでしょうから、データを更新する部分は自分でSQLを設定してそれを使って更新すればいいだけですよね。

    まぁ、どのようにやるかはいろんな方法があると思いますのでがんばってみてください。

    2006年12月6日 7:37
  • 動的に SQL を生成する部分は Oracle の場合 NVL や DECODE を使えば、ほとんどの SQL が 1 つで済みます。
    また、UPDATE を実行するのをストアドプロシージャにしたほうがいいと思います。
    パラメータに配列も渡せますし。
    っていうか、動的 SQL にしなければならない SQL なんてほとんど存在しませんよ。
    極めれば、どんなに複雑でも高速な SQL を書くことができます。
    まずは Oracle PL/SQL を勉強してください。
    2006年12月6日 7:37
  • 一度に複数の行をEditModeにしてしまうという手もあると思います。

    Show all GridView Rows in EditMode
    http://aspadvice.com/blogs/azamsharp/archive/2006/11/08/Show-all-GridView-Rows-in-EditMode.aspx

    データベースへの更新は以下が参考になると思います。DataGridの例で古いのですが、基本的にはGridViewでも考え方は同じです。

    Editing Multiple Rows At Once
    http://msdn.microsoft.com/library/en-us/dv_vstechart/html/vbtchTopQuestionsAboutASPNETDataGridServerControl.asp?frame=true#vbtchtopquestionsaboutaspnetdatagridservercontroleditingmultiplerows

    2006年12月6日 7:56
    モデレータ
  • 「どっとねっとふぁん」さん他、みなさんレスありがとうございます。

    SQLの部分は今までのレスを参考に自分で何とかしようと思います。

    ただ、もう1点、私が知りたい事があります。

    データはGridViewには、SQLで取得したレコードが返ってきますが、その他に、CheckBoxを追加して、

    その値を基にどのレコードが選択されたのかを知りたい、ということがります。

    まず、データは今ODP.NETを使っていますが、データを表示するまではこうしています。

    protected void Page_Load(object sender, System.EventArgs e)
    {
     // 入力された店舗コードを検索する。予約テーブル
     string cnStr = "User Id=xxx; Password=yyy; Data Source=ds";
     OracleConnection cnBk = new OracleConnection(cnStr);
     cnBk.Open();
     OracleCommand cmd = cnBk.CreateCommand();

     // レコード検索:SQL文設定
     string cmdStr = "SELECT A,B,C FROM TBL_A;
     cmd.CommandText = cmdStr;
     OracleDataReader rdr = cmd.ExecuteReader();

    // dbgBkSgCdはGridView。

     dbgBkSgCd.DataSource = rdr;
     dbgBkSgCd.DataBind();

     // 後始末
     cmd.Dispose();
     rdr.Close();
     rdr.Dispose();
     cnBk.Close();
     cnBk.Dispose();
    }

    この後、SELECTリストとは別にCHECKを入れる列をGridViewに加え、そしてその列を参照して

    チェックが入ったレコードを取得する、という処理を実装しいのですが、この辺をプログラムで

    どう書けばよいのか教えていただけないでしょうか。

     

    2006年12月6日 8:15
  • GridView.Rows から一行ずつ取り出して、チェックボックスの値をチェックし、現在のデータを取り出す、といった形になると思います。

     

    2006年12月6日 8:28
  • そう考えまして、

    HTMLソースの<columns>に

                <asp:TemplateField SortExpression="chkCancelSort" HeaderText="キャンセル">
                  <ItemTemplate>
                    <asp:CheckBox  runat="server" ID="chkCancel" />
                  </ItemTemplate>
                </asp:TemplateField>
    を加え、ボタンのクリック時に

            for (int i = 0; i < grid.Rows.Count; i++)
            {
                txtTest2.Text = txtTest2.Text +  grid.RowsIdea.Cells[0].Text + Environment.NewLine;
            }


     としましたが(Cells[0]がチェックボックスの列)、値が取れないのですが、どこがおかしいのでしょう?

    他の列の値は取れるのですが・・・。

    2006年12月6日 8:40
  • FindControlでCheckBoxの参照を取得しなきゃダメです。たぶん、

    ((CheckBox)grid.RowsIdea.FindControl("chkCancel")).Checked

    みたいな感じになります。

    Foreach(GridViewRow gvr in grid.Rows)
    {
      ((CheckBox)gvr.FindControl("chkCancel")).Checked;
    }

    みたいな書き方もできます。コードは空で書いているので、微妙に間違いがあるかもしれません。

    2006年12月6日 8:53
    モデレータ
  • このプログラムだとCellに直接書き込まれているテキストデータが取れるだけです。
    Cellの中にチェックボックスがあるのですから、そのチェックボックスを指定して値を取り出さないといけないですよね。
    今取れている値も表示しているデータだけだと思います。
    テキストボックス等を埋め込んでみたら同じように取り出せないでしょうね。

    #こういった質問よく見かけるんだけど、参考にしているところが一緒なんだろうか。。。

    2006年12月6日 8:55
  •  どっとねっとふぁん さんからの引用

    #こういった質問よく見かけるんだけど、参考にしているところが一緒なんだろうか。。。

    コントロールへの参照はわかりにくいとしても、CheckBoxであれば、Checkedプロパティというところへ発想が行くようにならないといけないんですが・・・。ここのところをちょっと心配しています。
    2006年12月6日 9:03
    モデレータ
  • > CheckBoxであれば、Checkedプロパティというところへ発想が行くようにならないといけないんですが

    ああ、そこも気にはなりました。

    > コントロールへの参照はわかりにくいとしても

    コントロールツリーという意識がないとわかりにくいかもしれませんね。
    この点は書籍だと
    Microsoft Visual Studio 2005によるWebアプリケーション構築技法
    に記述があったはず。
    ページのトレース情報を表示するとどんなコントロールが生成されているかわかるようになってるんですけどね。

    ちなみに Cell[0].Controls[0] をCheckBoxにキャストしてもデータは取り出せると思います。
    FindControlを使うよりは直接的なので若干早いかな、と思いますが、プログラムの意味は伝わりにくくなるなぁ。

    2006年12月6日 9:14
  • 皆様、回答ありがとうございました。

    何とか実装できそうなので、後はがんばってみます。

    ちなみに、Template関連など、手がかりになりそうなトピックを書いているサイトを探している中で、

    CheckBoxへのキャストしているサイトもWEBで探している中にありましたが、

    CheckBox ckb = (CheckBox)wkRow.FindControl("chkCancel");

    と書いたりしみたのですが、うまくいかず・・・「()」が足りないことに気が付かなかったりしていたようです。

    (ちなみに、上記のコードはなぜか今はビルドが通ります。・・・なぜだろう。悩んでいた時は通らなかったのに。)

    2006年12月6日 9:25
  • どっとねっとふぁんさんか、trapemiya さんのどちらかが本を書けば済むこと。
    #おいらは本は書きませんけどね。

    2006年12月6日 10:00
  •  おがわみつぎ さんからの引用

    どっとねっとふぁんさんか、trapemiya さんのどちらかが本を書けば済むこと。

    前にもちらっと書いたことがあると思うんですが、自分の勉強のために、自分用の本、というかそこまでおおげさではなくて説明文を書くことはよくあります。何かの技術を勉強した後に、忘れないために、それをまとめて文章にしている程度ですけどね。自分のあやふやなところもわかるんで、それはそれで役に立っていると思います。どっかで、なんか、まとめたいなぁとは思います。
    2006年12月6日 15:31
    モデレータ