質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.45%

  • SQL Server

    745questions

    SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

  • ASP.NET

    634questions

    ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

  • Visual Studio 2010

    137questions

    Microsoft Visual Studio 2010はMicrosoftが提供している統合開発環境(IDE)です。

ASP.NET FormView-EditItemTemplateでの編集に応じてデータベースを同時更新したい。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,575

taketake221

score 11

質問タイトルがわかりにくいかもしれません。ご勘弁ください。

ASP.NET Webフォームアプリに関する質問です。
演習で、データベースを更新できるしくみを実装中です。
(実装機能については以前させていただいたこちらの質問で記載していたものと類似していますが、構成や機能が一部異なりましたので、新たに質問させていただきました。)

※OSはWindows7、.NET Framework4、Visual Stdio 2010、SQLserver2012、IE11を利用しています。

イメージ説明

更新先のテーブル構成は以上のような感じで、
result1~result5 には"はい"、"いいえ"、"未回答"の回答いずれかが、
pointには格納された回答に応じた点数(各回答が「はい」ならpoint+1、「いいえ」ならpoint-1、「未回答」なら加減なしで判定し、最終値を格納)が、dateには格納日が格納されます。

「編集」ボタンをおすと、フォームビューで表示した過去の回答(ラベルコントロールの内容)をもとに、
ドロップダウンリストで回答が可能になります。

イメージ説明     イメージ説明

「登録」ボタンを押すと、ドロップダウンリストで選択された回答によってポイントを計算し、日付とともに同時にデータベースに格納したいのですが、どのように記述すればよいのでしょうか。

10/02 17:00編集(タイトル変更)

Select Case DropDownList1.DirectCast(FormView1.FindControl("DropDownList1"), DropDownList).SelectedValue


の記述で、目に見えるエラーは改善されたようですが、
データベース上ではresult1~result5までの回答データが更新されるだけで、点数(point)と日付(date)は更新がなされない状況です。

10/2 17:30編集

strSQL = "UPDATE tbl_testRg" &
                " SET point = " & point & "," &
                " date = " & "'" & dtToday & "'" &
                " WHERE 更新先フィールドのID(記述方法がわかりません)"


の部分で「& "'" & dtToday & "'" &」の記述にミスがあり、改善したところ、
テスト用にWHERE ID = 1としてID:1のデータ編集の場合のみ正常に動作することが確認できました。

元にするフィールドのIDをここでどう記述すればよいのかがわかりませんので、教えていただきたいです。

Protected Sub FormView1_ItemUpdating(sender As Object, e As System.Web.UI.WebControls.FormViewUpdateEventArgs) Handles FormView1.ItemUpdating

        Dim point As Integer

        Dim dtToday As DateTime = Date.Today

    /・・・質問5つ分(繰り返し文は不問とします)・・・/
        Select Case DropDownList1.DirectCast(FormView1.FindControl("DropDownList1"), DropDownList).SelectedValue
            Case "はい"
                point = point + 1
            Case "いいえ"
                point = point - 1
        End Select

        Dim strSQL As String
        strSQL = "UPDATE tbl_testRg" &
                " SET point = " & point & "," &
                " date = " & "'" & dtToday & "'" &
                " WHERE 更新先フィールドのID(記述方法がわかりません)"

        Dim cnStr As String = System.Configuration.ConfigurationManager.
            ConnectionStrings("○○○○○○ConnectionString").ConnectionString

        Using connection As New SqlConnection(cnStr)

            Dim command As New SqlCommand(strSQL, connection)

            connection.Open()

            Try
                command.ExecuteNonQuery()

            Catch ex As Exception

                lblMsg.Text = "エラー発生のため、処理を中止します! </ br>" & ex.Message

            End Try
            connection.Close()
        End Using
    End Sub
<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
        ConnectionString="<%$ ConnectionStrings:testdb_tinoueConnectionString %>" 
        DeleteCommand="DELETE FROM [tbl_testRg] WHERE [ID] = @ID" 
        InsertCommand="INSERT INTO [tbl_testRg] ([ID], [result1], [result2], [result3], [result4], [result5]) VALUES (@ID, @result1, @result2, @result3, @result4, @result5)" 
        SelectCommand="SELECT * FROM [tbl_testRg]" 
        UpdateCommand="UPDATE [tbl_testRg] SET [result1] = @result1, [result2] = @result2, [result3] = @result3, [result4] = @result4, [result5] = @result5 WHERE [ID] = @ID">
        <DeleteParameters>
            <asp:Parameter Name="ID" Type="Int32" />
        </DeleteParameters>
        <InsertParameters>
            <asp:Parameter Name="ID" Type="Int32" />
            <asp:Parameter Name="result1" Type="String" />
       /・・・質問5つ分・・・/
        </InsertParameters>
        <UpdateParameters>
            <asp:Parameter Name="result1" Type="String" />
       /・・・質問5つ分・・・/
            <asp:Parameter Name="ID" Type="Int32" />
        </UpdateParameters>
    </asp:SqlDataSource>
    <asp:FormView ID="FormView1" runat="server" AllowPaging="True" 
        DataKeyNames="ID" DataSourceID="SqlDataSource1">
        <EditItemTemplate>
            <table cellpadding="0" cellspacing="0" class="style3">
                <tr>
                    <td>
                        ID</td>
                    <td>
                        <asp:Label ID="IDLabel1" runat="server" Text='<%# Eval("ID") %>' />
                    </td>
                </tr>
                <tr>
                    <td>
                        質問1</td>
                    <td>
                        <asp:DropDownList ID="DropDownList1" runat="server" 
                            SelectedValue='<%# Bind("result1") %>'>
                            <asp:ListItem Value="はい">はい</asp:ListItem>
                            <asp:ListItem Value="いいえ">いいえ</asp:ListItem>
                            <asp:ListItem Value="未回答">未回答</asp:ListItem>
                        </asp:DropDownList>
                    </td>
                </tr>
         /・・・質問5つ分・・・/
            </table>
            <br />
            <asp:Button ID="Button1" runat="server" CommandName="Update" Text="登録" />
            <asp:Button ID="Button2" runat="server" Text="キャンセル" CommandName="Cancel" />
            &nbsp;
        </EditItemTemplate>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

コード上の「DropDownList○.SelectedValue」の部分で「DropDownList○は宣言されていません。

基本的に FormView とか DetailsView とか GridView とかに配置されたコントロール(今回の場合 DropDownList ですが、それは TextBox も同じこと)は DropDownList○ という形では取得できません。

理由は動的に生成される(静的には存在しない)からです。

取得するには FindControl メソッドを使用します。

Control.FindControl メソッド (String)
https://msdn.microsoft.com/ja-jp/library/486wc64h(v=vs.90).aspx

FormView1_ItemUpdating メソッドの中で FormView1.FindControl("DropDownList○") として取得できると思います。

Control 型を返すので DropDownList にキャストするのを忘れないようにしましょう。

上記にしたがって、「Private Property DropDownList1 As Object」の一文を付け足して実行すると、

そういうことをするのは全くの見当違いです。

【2016/10/3 10:50 追記】

先の私の 2016/10/02 18:42 のコメントで書いた件の具体的な方法を追記します。

コメントで、

FormView.ItemUpdating イベントでも渡せないか考えてみます

と書きましたが、直感的でなく混乱しそうなので、SqlDataSource.Updating イベントのハンドラで point と date のパラメータを渡すやり方を説明します。(FormView1_ItemUpdating メソッドは一切使いません)

(1) SqlDataSource の UpdateCommand に設定した UPADTE クエリに [point]=@point, [date]=@date を追加。以下のような感じです。

UpdateCommand="UPDATE [tbl_testRg] SET [result1] = @result1, [result2] = @result2, 
        [result3] = @result3, [result4] = @result4, [result5] = @result5,
                [point]=@point, [date]=@date WHERE [ID] = @ID">

(場所は分かりますよね? FormView1_ItemUpdating メソッドの中の strSQL ではありませんよ)

(2) SqlDataSource の UpdateParameters に以下 Parameter を追加。上記 (1) のようなクエリにしたとすると以下のようになるはずです。

<asp:Parameter Name="point" Type="Int32" />
<asp:Parameter Name="date" Type="DateTime" />

(3) SqlDataSource.Updating イベントのハンドラ(メソッド)を作成。その中で FormView1_ItemUpdating メソッドの修正版で行ったように、FindControl で DropDownList を取得し、SelectedValue を取得し、point を計算する。

(4) 上記 (3) に続いて、ハンドラの引数 SqlDataSourceCommandEventArgs オブジェクトからパラメータを取得し、その Value プロパティに point と dtToday を代入する。以下のような感じです。(訂正:C# と VB.NET のコードを併記しました)

C#

e.Command.Parameters["@point"].Value = point;
e.Command.Parameters["@date"].Value = dtToday;

VB.NET

e.Command.Parameters("@point").Value = point
e.Command.Parameters("@date").Value = dtToday

(5) FormView1_ItemUpdating メソッドは不要なので削除(とりあえずコメントアウトしてください)。

上記は頭の中で考えただけで、当方では検証してません(できません)。質問者さんの方でやってみて結果を連絡ください。

<追加情報>
今回の問題とは直接関係ないことですが・・・
最初の質問の画像を見ると ID フィールド以外は NULL 可になっているようです。実際にデータに NULL があると今のやり方では破綻するので注意してください。NULL にする必要がない限り NULL 不可にすることをお勧めします。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/02 16:58

    SurferOnWww様、迅速な回答をありがとうございます。

    知識不足で申し訳ありません。
    「理由は動的に生成される(静的には存在しない)からです」というご説明に納得いたしました。

    Control.FindControl メソッド 、キャストの部分については、
    「Select Case DirectCast(FormView1.FindControl("DropDownList○"), DropDownList).SelectedValue」と記述して実行した結果、エラーは発生しませんでしたが、
    "point"と"date"が更新されないままでした。

    strSQLのUPDATE文の箇所を含めてまだ記述不足点があるので、改善箇所をご教示いただければと思います。

    キャンセル

  • 2016/10/02 17:09

    質問を小出しにしないで、うまくいかないこと、聞きたい事を全部書いてください。point と date 以外は期待通り更新されているのですか?

    キャンセル

  • 2016/10/02 17:15


    SurferOnWww様、ありがとうございます。

    おっしゃるようにpoint と date 以外は期待通り更新されています。

    私個人がpoint と dateの更新がうまくいかない原因に、strSQLのUPDATE文の記述不足があるのではと思ったので回りくどくなってしまいました。申し訳ありません。

    キャンセル

  • 2016/10/02 17:45

    SurferOnWww様、たびたび申し訳ありません。

    こちらで何度か確認した結果、
    " date = " & "'" & dtToday & "'" &
    の部分にミスがあり、WHERE ID = 1とテスト用にこちらで更新フィールドのIDの値を指定した場合のみ正しい動作が確認できました。

    質問編集にも追記しましたが、更新先のフィールドのIDを識別?して正しい動作が得られるようにするには、「WHERE ID =」の先をどのように記述すればよいのでしょうか。

    キャンセル

  • 2016/10/02 18:42

    DropDownList の SelectedValue プロパティに、質問者さんが行ったように '<%# Bind("result1") %>' とデータバインドメソッドを設定すると、最初に更新画面を表示するときはオリジナルのデータで DropDownList のアイテムが選択されて表示され、異なるアイテムを選択して更新をかけるとそのアイテムの Value でデータベースを更新できる。しかもそれは自動的に ASP.NET がやってくれる・・・というところは理解されているでしょうか?

    何故なら、[登録]ボタンクリックで、SqlDataSource の UpdateCommand の UPDATE クエリが SQL Server に対して自動的に発行され、その際パラメータ @result1 ~ @result5 に DropDownList1 ~ 5 の SelectedValue が自動的に渡されるから・・・と言うことは理解されているでしょうか?

    ということは、現状の UPADTE クエリに [point]=@point, [date]=@date を追加し、SQL Server に UPDATE クエリが発行される前のどこかのタイミングで、パラメータ @point, @date に値を渡してやれば良さそうです。

    FormView1_ItemUpdating メソッドの中に質問者さんが自力で ADO.NET のコードを書いて UPDATE クエリを追加で発行する必要はないはずです。

    パラメータを渡すタイミングですが、SqlDataSource.Updating イベントが使えると思います。FormView.ItemUpdating イベントでも渡せないか考えてみます。

    その前に、質問者者参の方でデバッガなどを使って、FormView1_ItemUpdating メソッドの中で count の値が期待通り取得できているか確認してください。

    キャンセル

  • 2016/10/02 19:07


    SurferOnWww様、重ね重ねありがとうございます。

    いただいたコメントの上9行については納得・理解しています。
    ただ、おっしゃっているパラメータを渡すしくみについてはコード案が思い浮かばないので、申し訳ありませんがまたお世話になります。

    最後の2行ですが、FormView1_ItemUpdating メソッドの中で のcount の値というのは何のことでしょうか?算出するpointや取得するdate等の値とは別なんでしょうか。

    キャンセル

  • 2016/10/02 19:21

    間違えました、すみません。count ではなく point です。

    キャンセル

  • 2016/10/02 19:24

    算出するpointや取得するdate等の値については、
    テスト用に、

    Dim strSQL As String
    strSQL = "UPDATE tbl_testRg" &
    " SET point = " & point & "," &
    " date = " & "'" & dtToday & "'" &
    " WHERE ID = 1"

    として正しい結果が算出・データベースに格納されているのをブレークポイントの設置で確認済みではあります。

    キャンセル

  • 2016/10/02 19:41

    何か話が通じてないような気がします。最初の話ではエラーでコンパイルさえできず確認などできなかったはずですが?

    自分が気にしているのは FindControl で DropDownList が取得できて、SelectedValue が取得できて、合計が期待通り取得できているかということです。それができてないと始らないので。

    すみませんが今日はもう閉店ということで、明日また回答させてください。

    キャンセル

  • 2016/10/02 19:58

    SurferOnWww様、何度もありがとうございます。
    こちらの説明不足ですね、申し訳ないです。

    ・「Select Case DropDownList○.SelectedValue」の部分で「DropDownList○は宣言されていません。」のエラーを、
    「Select Case DirectCast(FormView1.FindControl("DropDownList○"), DropDownList).SelectedValue とすることで改善。

    DropDownList、SelectedValueいずれも取得し、期待通りのpoint(合計値)が取得できていることを確認できています。

    こちらの不手際・説明不足でお手数をたくさんおかけしますが、明日またどうぞよろしくお願いいたします。

    キャンセル

  • 2016/10/03 10:39

    上の 2016/10/02 18:42 のコメントに書いた件の具体的なやり方ですが、コメント欄ではうまく書けないので回答欄に追記します。

    キャンセル

  • 2016/10/03 10:45

    SurferOnWww様、ありがとうございます。

    たびたびお世話になります。どうぞよろしくお願いします。

    キャンセル

  • 2016/10/03 11:11

    解答欄の追記の (4) ですが C# 頭になってました。VB.NET では角カッコ [ ] は使えませんね。訂正しておきます。

    キャンセル

  • 2016/10/03 11:12

    SurferOnWww様、丁寧に回答していただきありがとうございます。

    ご提示いただいた説明にそって試してみると、

    e.Command.Parameters["@point"].Value = point
    e.Command.Parameters["@date"].Value = dtToday

    の部分で「プロパティアクセスはプロパティに割り当てるか、またはその値を使わなければいけません」と表示されました。

    キャンセル

  • 2016/10/03 11:14

    SurferOnWww様、ありがとうございます。

    こちらの返信が入れ違いのタイミングになってしまいました。
    訂正後の構文で試してみて結果をご連絡いたします。

    キャンセル

  • 2016/10/03 12:00

    SurferOnWww様。

    訂正後の、
    e.Command.Parameters("@point").Value = point
    e.Command.Parameters("@date").Value = dtToday

    で実行したところ、正しいpointの値と日付が回答とともにデータベースに格納され、更新が正常に機能していることが確認できました!
    ありがとうございます。ベストアンサーをつけさせていただきます!

    ※追加情報として記載いただいたフィールドのNULL許可については、今後ぜひそういたします。教えていただきありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.45%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • SQL Server

    745questions

    SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

  • ASP.NET

    634questions

    ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

  • Visual Studio 2010

    137questions

    Microsoft Visual Studio 2010はMicrosoftが提供している統合開発環境(IDE)です。