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

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

新規登録して質問してみよう
ただいま回答率
85.48%
SQL Server

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

Visual Studio 2010

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

ASP.NET

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

Q&A

解決済

1回答

6238閲覧

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

taketake221

総合スコア17

SQL Server

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

Visual Studio 2010

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

ASP.NET

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

0グッド

0クリップ

投稿2016/10/02 06:30

編集2016/10/02 09:18

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

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をここでどう記述すればよいのかがわかりませんので、教えていただきたいです。

VB

1Protected Sub FormView1_ItemUpdating(sender As Object, e As System.Web.UI.WebControls.FormViewUpdateEventArgs) Handles FormView1.ItemUpdating 2 3 Dim point As Integer 4 5 Dim dtToday As DateTime = Date.Today 6 7 /・・・質問5つ分(繰り返し文は不問とします)・・・/ 8 Select Case DropDownList1.DirectCast(FormView1.FindControl("DropDownList1"), DropDownList).SelectedValue 9 Case "はい" 10 point = point + 1 11 Case "いいえ" 12 point = point - 1 13 End Select 14 15 Dim strSQL As String 16 strSQL = "UPDATE tbl_testRg" & 17 " SET point = " & point & "," & 18 " date = " & "'" & dtToday & "'" & 19 " WHERE 更新先フィールドのID(記述方法がわかりません)" 20 21 Dim cnStr As String = System.Configuration.ConfigurationManager. 22 ConnectionStrings("○○○○○○ConnectionString").ConnectionString 23 24 Using connection As New SqlConnection(cnStr) 25 26 Dim command As New SqlCommand(strSQL, connection) 27 28 connection.Open() 29 30 Try 31 command.ExecuteNonQuery() 32 33 Catch ex As Exception 34 35 lblMsg.Text = "エラー発生のため、処理を中止します! </ br>" & ex.Message 36 37 End Try 38 connection.Close() 39 End Using 40 End Sub

FormView部分

1<asp:SqlDataSource ID="SqlDataSource1" runat="server" 2 ConnectionString="<%$ ConnectionStrings:testdb_tinoueConnectionString %>" 3 DeleteCommand="DELETE FROM [tbl_testRg] WHERE [ID] = @ID" 4 InsertCommand="INSERT INTO [tbl_testRg] ([ID], [result1], [result2], [result3], [result4], [result5]) VALUES (@ID, @result1, @result2, @result3, @result4, @result5)" 5 SelectCommand="SELECT * FROM [tbl_testRg]" 6 UpdateCommand="UPDATE [tbl_testRg] SET [result1] = @result1, [result2] = @result2, [result3] = @result3, [result4] = @result4, [result5] = @result5 WHERE [ID] = @ID"> 7 <DeleteParameters> 8 <asp:Parameter Name="ID" Type="Int32" /> 9 </DeleteParameters> 10 <InsertParameters> 11 <asp:Parameter Name="ID" Type="Int32" /> 12 <asp:Parameter Name="result1" Type="String" /> 13 /・・・質問5つ分・・・/ 14 </InsertParameters> 15 <UpdateParameters> 16 <asp:Parameter Name="result1" Type="String" /> 17 /・・・質問5つ分・・・/ 18 <asp:Parameter Name="ID" Type="Int32" /> 19 </UpdateParameters> 20 </asp:SqlDataSource> 21 <asp:FormView ID="FormView1" runat="server" AllowPaging="True" 22 DataKeyNames="ID" DataSourceID="SqlDataSource1"> 23 <EditItemTemplate> 24 <table cellpadding="0" cellspacing="0" class="style3"> 25 <tr> 26 <td> 27 ID</td> 28 <td> 29 <asp:Label ID="IDLabel1" runat="server" Text='<%# Eval("ID") %>' /> 30 </td> 31 </tr> 32 <tr> 33 <td> 34 質問1</td> 35 <td> 36 <asp:DropDownList ID="DropDownList1" runat="server" 37 SelectedValue='<%# Bind("result1") %>'> 38 <asp:ListItem Value="はい">はい</asp:ListItem> 39 <asp:ListItem Value="いいえ">いいえ</asp:ListItem> 40 <asp:ListItem Value="未回答">未回答</asp:ListItem> 41 </asp:DropDownList> 42 </td> 43 </tr> 44 /・・・質問5つ分・・・/ 45 </table> 46 <br /> 47 <asp:Button ID="Button1" runat="server" CommandName="Update" Text="登録" /> 48 <asp:Button ID="Button2" runat="server" Text="キャンセル" CommandName="Cancel" /> 49 &nbsp; 50 </EditItemTemplate>

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

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 07:16

編集2016/10/03 02:15
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

taketake221

2016/10/02 07:58

SurferOnWww様、迅速な回答をありがとうございます。 知識不足で申し訳ありません。 「理由は動的に生成される(静的には存在しない)からです」というご説明に納得いたしました。 Control.FindControl メソッド 、キャストの部分については、 「Select Case DirectCast(FormView1.FindControl("DropDownList○"), DropDownList).SelectedValue」と記述して実行した結果、エラーは発生しませんでしたが、 "point"と"date"が更新されないままでした。 strSQLのUPDATE文の箇所を含めてまだ記述不足点があるので、改善箇所をご教示いただければと思います。
退会済みユーザー

退会済みユーザー

2016/10/02 08:09

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

2016/10/02 08:15

SurferOnWww様、ありがとうございます。 おっしゃるようにpoint と date 以外は期待通り更新されています。 私個人がpoint と dateの更新がうまくいかない原因に、strSQLのUPDATE文の記述不足があるのではと思ったので回りくどくなってしまいました。申し訳ありません。
taketake221

2016/10/02 08:45

SurferOnWww様、たびたび申し訳ありません。 こちらで何度か確認した結果、 " date = " & "'" & dtToday & "'" & の部分にミスがあり、WHERE ID = 1とテスト用にこちらで更新フィールドのIDの値を指定した場合のみ正しい動作が確認できました。 質問編集にも追記しましたが、更新先のフィールドのIDを識別?して正しい動作が得られるようにするには、「WHERE ID =」の先をどのように記述すればよいのでしょうか。
退会済みユーザー

退会済みユーザー

2016/10/02 09: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 の値が期待通り取得できているか確認してください。
taketake221

2016/10/02 10:07

SurferOnWww様、重ね重ねありがとうございます。 いただいたコメントの上9行については納得・理解しています。 ただ、おっしゃっているパラメータを渡すしくみについてはコード案が思い浮かばないので、申し訳ありませんがまたお世話になります。 最後の2行ですが、FormView1_ItemUpdating メソッドの中で のcount の値というのは何のことでしょうか?算出するpointや取得するdate等の値とは別なんでしょうか。
退会済みユーザー

退会済みユーザー

2016/10/02 10:21

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

2016/10/02 10:24

算出するpointや取得するdate等の値については、 テスト用に、 Dim strSQL As String strSQL = "UPDATE tbl_testRg" & " SET point = " & point & "," & " date = " & "'" & dtToday & "'" & " WHERE ID = 1" として正しい結果が算出・データベースに格納されているのをブレークポイントの設置で確認済みではあります。
退会済みユーザー

退会済みユーザー

2016/10/02 10:41

何か話が通じてないような気がします。最初の話ではエラーでコンパイルさえできず確認などできなかったはずですが? 自分が気にしているのは FindControl で DropDownList が取得できて、SelectedValue が取得できて、合計が期待通り取得できているかということです。それができてないと始らないので。 すみませんが今日はもう閉店ということで、明日また回答させてください。
taketake221

2016/10/02 10:58

SurferOnWww様、何度もありがとうございます。 こちらの説明不足ですね、申し訳ないです。 ・「Select Case DropDownList○.SelectedValue」の部分で「DropDownList○は宣言されていません。」のエラーを、 「Select Case DirectCast(FormView1.FindControl("DropDownList○"), DropDownList).SelectedValue とすることで改善。 DropDownList、SelectedValueいずれも取得し、期待通りのpoint(合計値)が取得できていることを確認できています。 こちらの不手際・説明不足でお手数をたくさんおかけしますが、明日またどうぞよろしくお願いいたします。
退会済みユーザー

退会済みユーザー

2016/10/03 01:39

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

2016/10/03 01:45

SurferOnWww様、ありがとうございます。 たびたびお世話になります。どうぞよろしくお願いします。
退会済みユーザー

退会済みユーザー

2016/10/03 02:11

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

2016/10/03 02:12

SurferOnWww様、丁寧に回答していただきありがとうございます。 ご提示いただいた説明にそって試してみると、 e.Command.Parameters["@point"].Value = point e.Command.Parameters["@date"].Value = dtToday の部分で「プロパティアクセスはプロパティに割り当てるか、またはその値を使わなければいけません」と表示されました。
taketake221

2016/10/03 02:14

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

2016/10/03 03:00

SurferOnWww様。 訂正後の、 e.Command.Parameters("@point").Value = point e.Command.Parameters("@date").Value = dtToday で実行したところ、正しいpointの値と日付が回答とともにデータベースに格納され、更新が正常に機能していることが確認できました! ありがとうございます。ベストアンサーをつけさせていただきます! ※追加情報として記載いただいたフィールドのNULL許可については、今後ぜひそういたします。教えていただきありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問