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

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

ただいまの
回答率

90.12%

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

解決済

回答 1

投稿 編集

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

taketake221

score 15

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

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/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.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる