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

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

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

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

ASP.NET

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

Q&A

解決済

2回答

643閲覧

ASP.NET GridViewのデータ判別方法

mimi77

総合スコア27

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

ASP.NET

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

0グッド

0クリップ

投稿2022/08/26 08:52

編集2022/08/27 01:42

OS windows10
Visual Studio2019
.NET Framework 4.8

ASP.NETでWeb Formsを作成しています。
ASP.NETでグリッドビューを作成し、そこへデータを入力しています。
「確定」というボタンを押すと、入力したデータをテーブルへインサートし、
その後そのデータを帳票へ出力するというシステムを作成しています。
GridViewには、asp:TextBoxやasp:DropDownListを設定しております。

実現したいこと

実現したいこととしては、インサートをすればテーブルにデータがどんどんたまっていきますが、
帳票へ出力したいのはあくまでGridViewに入力したデータのみを出力したいです。

流れとしては
GridViewにデータ入力 → 確定 → テーブルへインサート → 帳票出力(GridViewのデータのみ)

となります。

GridViewには複数行データが入力可能です。

発生している問題・エラーメッセージ

テーブルからの印刷はできるのですが、今GridViewに入力したデータかどうかをどのように判定してよいかががわかりません。
インサートする際に、アイデンティティを振ろうかと思ったのですが、番号のみではどのタイミングでインサートがされたかが不明なため困っております。

イメージとしては、1回目にインサートを行ったデータ(複数)に対しては 1 2回目にインサートをを行ったデータに対しては 2 といったようなインサートごとにグループ分けするための値を入れれば良いでしょうか。

<asp:GridView ID="gvData" runat="server" AutoGenerateColumns="false" CssClass="gridview_table_style" OnRowDataBound="gvData_RowDataBound" OnDataBound="gvData_DataBound" OnRowCreated="ContactList_RowCreated" style="margin: 10px 0 0 50px" ShowHeaderWhenEmpty="True"> <HeaderStyle Wrap="false" /> <Columns> <asp:TemplateField> <HeaderTemplate>名前</HeaderTemplate> <ItemTemplate> <asp:TextBox ID="txtName" Text='<%# Bind("NM_KANJI") %>' runat="server" style="text-align:left" /> </ItemTemplate> </asp:TemplateField> <asp:TemplateField> <HeaderTemplate>郵便番号</HeaderTemplate> <ItemTemplate> <asp:TextBox ID="txtPostCode" Text='<%# Bind("ZIP_CODE_RQU") %>' CssClass="input_10 width_td_150_0 display_inlineblockt cv_hyphen cv_tolower ci_postal" runat="server" MaxLength="8" /> </ItemTemplate> </asp:TemplateField> <asp:TemplateField> <HeaderTemplate>住所-</HeaderTemplate> <ItemTemplate> <asp:TextBox ID="txtAddress" Width="300px" Text='<%# Bind("ADDRESS") %>' runat="server" style="text-align:left" /> </ItemTemplate> </asp:TemplateField> <asp:TemplateField> <HeaderTemplate>電話番号</HeaderTemplate> <ItemTemplate> <asp:TextBox ID="txtPhoneNum" Text='<%# Bind("PHONE") %>' runat="server" CssClass="width_td_150_0 ci_tel cv_tolower ci_maxlength20" MaxLength="13" /> </ItemTemplate> </asp:TemplateField> <asp:TemplateField> <HeaderTemplate>商品名</HeaderTemplate> <ItemTemplate> <asp:DropDownList ID="Listbox_shohin" Text='<%# Bind("SHOHIN_NM") %>' runat="server" style="text-align:left" /> <asp:HiddenField ID="hdnHenreiCode" runat="server" Value='<%# Bind("HENREI_CODE") %>' /> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> aspx側 確定ボタンの記述 <asp:Button CssClass="gray inline" ID="Button2" Text="確定"  runat="server" OnClick="btn_Confirm_Click" /> C# 側 確定ボタンを押した際の処理 protected void btn_Confirm_Click(object sender, EventArgs e) { if (CheckInput()) { SqlConnection oConn = DBConnectionClass.DBConnect(); using (SqlCommand command = oConn.CreateCommand()) { SqlTransaction tran = oConn.BeginTransaction(IsolationLevel.ReadCommitted); foreach (GridViewRow gvData_Row in gvData.Rows) { InsertData(tran, gvData_Row); } } }   } この時点でインサートは行われています。(DBを更新するとGridviewのデータが入っています。) この直後に帳票へデータ出力を行います。 C# 側 InsertDataの処理 protected void InsertData(SqlTransaction tran, GridViewRow rowData) { SqlConnection oConn = DBConnectionClass.DBConnect(); using (SqlCommand command = oConn.CreateCommand()) { TextBox txtName = (TextBox)rowData.FindControl("txtName"); TextBox txtPostCode = (TextBox)rowData.FindControl("txtPostCode"); TextBox txtAddress = (TextBox)rowData.FindControl("txtAddress"); TextBox txtPhoneNum = (TextBox)rowData.FindControl("txtPhoneNum"); DropDownList Listbox_shohin = (DropDownList)rowData.FindControl("Listbox_shohin"); string RQUESTDES = ListboxSelect.Text; string Estimate_Nm = lblEstimatedisp.Text; string InformantCode = hidInformantCode.Value; string Remarks = txtremarks.Text; string Estimatenm = txtEstimatenm.Text; if (txtName.Text == "" && txtPostCode.Text == "" && txtAddress.Text == "" && txtPhoneNum.Text == "") { } else{ command.CommandText = string.Format(@" INSERT INTO M_HENREI (ESTIMATE_NO ,RQUESTDES ,NM_KANJI ,ZIP_CODE_RQU ,ADDRESS ,PHONE ,SHOHIN_NM ,INFORMANT_CODE ,REMARKS ,KENMEI) VALUES ( '{0}' ,'{1}' ,'{2}' ,'{3}' ,'{4}' ,'{5}' ,'{6}' ,'{7}' ,'{8}' ,'{9}')" , Estimate_Nm , RQUESTDES , string.IsNullOrEmpty(((TextBox)rowData.FindControl("txtName")).Text) ? "" : ((TextBox)rowData.FindControl("txtName")).Text , string.IsNullOrEmpty(((TextBox)rowData.FindControl("txtPostCode")).Text) ? "" : ((TextBox)rowData.FindControl("txtPostCode")).Text , string.IsNullOrEmpty(((TextBox)rowData.FindControl("txtAddress")).Text) ? "" : ((TextBox)rowData.FindControl("txtAddress")).Text , string.IsNullOrEmpty(((TextBox)rowData.FindControl("txtPhoneNum")).Text) ? "" : ((TextBox)rowData.FindControl("txtPhoneNum")).Text , string.IsNullOrEmpty(((DropDownList)rowData.FindControl("Listbox_shohin")).Text) ? "" : ((DropDownList)rowData.FindControl("Listbox_shohin")).Text ,InformantCode ,Remarks ,Estimatenm ); command.ExecuteScalar(); oConn.Dispose(); } } }

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2022/08/26 09:24 編集

> ASP.NETでグリッドビューを作成し、そこへデータを入力しています。 カタカナでグリッドビューと書くのはやめましょう。System.Web.UI.WebControls 名前空間の GridView コントロールのことなら GridView と書いてください。 でも、違うみたいですね。System.Web.UI.WebControls 名前空間の GridView コントロールには「データを入力して・・・」とかいう機能はありません。少なくともデフォルトでは。 何なのですか?
mimi77

2022/08/26 09:35

ご回答ありがとうございます。 質問内容に追記、訂正を行いました。
退会済みユーザー

退会済みユーザー

2022/08/26 09:53

上にも書きましたが、デフォルトでは コントロールには「データを入力して・・・」とかいう機能はありません。何か特別なことをしてるならそれを詳しく書いてください。
mimi77

2022/08/26 10:20

GridViewのコードを追記しました。
退会済みユーザー

退会済みユーザー

2022/08/26 11:23

そのコードで "「確定」というボタンを押すと、入力したデータをテーブルへインサートし" というところまででさえも動いているとは思えないのですが? そこが動いているというところまでコードを開示できませんか?
mimi77

2022/08/26 22:18

かしこまりました。現在コードを見られる状態では無いため、本日の午前中にコードをアップ致します。
退会済みユーザー

退会済みユーザー

2022/08/27 02:29

主キーは何ですか? foreach (GridViewRow gvData_Row in gvData.Rows) のループでレコードを INSERT する際、INSERT した主キーの値が取得できますか? できるのであれば、それを Session に保持しておいて、帳票出力の際は Session から主キーを取得して、その主キーのレコードを SELECT すればよさそうですが。
退会済みユーザー

退会済みユーザー

2022/08/27 22:00

ASP.NET は web アプリだから複数・多数の異なるユーザーがアクセスしてきて INSERT すると思いますが、ユーザー別に、そのユーザーが INSERT したレコードのみを帳票に出力する場合、質問者さんの回答にあるフラグ案では対応できませんけど? それに対応する必要があるなら、上のコメントに書いた主キーを Sessionに保持する方法で考えてはいかが? DB に手を加えて、余計なフィールドを追加しなくてすみますし。
guest

回答2

0

質問者さんは自己解決して去ってしまったようですが、質問のコメント欄の 2022/08/28 07:00 の私のコメントで書いた案を以下に書いておきます。

ASP.NET は web アプリだから複数・多数の異なるユーザーがアクセスしてきて INSERT すると思いますが、ユーザー別に、そのユーザーが INSERT したレコードのみを帳票に出力する場合、質問者さんの回答にあるフラグ案では対応できません。

ユーザー別に、そのユーザーが INSERT したレコードのみを帳票に出力する必要があるなら、C# のコードの INSERT 操作を行うところでそのレコードの主キーを Session に保持しておき、帳票用のレコードを取得する際は Session に保持した主キーで抽出する SELECT クエリを使うのが良さそうです。その方法ならフラグ用の余計なフィールドを追加する必要もありませんし。

問題は主キーが IDENTITY になっていて、INSERT した後でないと主キー値が分からない場合ですが、それは Transact-SQL の SCOPE_IDENTITY() と SqlCommand.ExecuteScalar メソッドを使って可能です。

SCOPE_IDENTITY (Transact-SQL)
https://docs.microsoft.com/ja-jp/sql/t-sql/functions/scope-identity-transact-sql?view=sql-server-ver16

SqlCommand.ExecuteScalar メソッド
https://docs.microsoft.com/ja-jp/dotnet/api/system.data.sqlclient.sqlcommand.executescalar?view=netframework-4.8

サンプルコードは上の SqlCommand.ExecuteScalar メソッドの方のドキュメントにありますので見てください。

簡単に概要を書いておくと、SQL 文に以下のように単一バッチとなるように SCOPE_IDENTITY() を SELECT する SQL 文を追加し、

INSERT INTO Production.ProductCategory (Name) VALUES (@Name); SELECT CAST(scope_identity() AS int)

以下のように ExecuteScalar メソッドを実行して INSERT 操作と、DB が設定した主キー値の取得の両方を行います。

newProdID = (Int32)cmd.ExecuteScalar();

このスレッドの本題とは関係ないことですが、質問に書いてあるコードはユーザー入力で SQL 文を組み立てており、SQL インジェクションの問題がありますので、そこは直すことをお勧めします。SQL 文をパラメータ化してください。

パラメータ化クエリ
http://surferonwww.info/BlogEngine/post/2012/02/02/Parameterized-query.aspx

投稿2022/08/28 01:34

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

自己解決

ご回答ありがとうございました。
自己解決しました。

方法としてはテーブルに印刷したかどうかのフラグを持たせ 
データをインサート(フラグは0) → 印刷(フラグが0のデータのみを印刷) → フラグを全て1にする

という処理を実装しました。

投稿2022/08/27 04:26

mimi77

総合スコア27

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

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

退会済みユーザー

退会済みユーザー

2022/08/27 05:30 編集

ASP.NET は web アプリだから複数・多数の異なるユーザーがアクセスしてきて INSERT すると思いますが、ユーザー別に、そのユーザーが INSERT したレコードのみを帳票に出力する場合、フラグではダメですけど、そういうことは考えなくていい?
mimi77

2022/08/30 08:14

ご回答ありがとうございます。 ログインしていなかったため、回答に気が付かず申し訳ございません。 今回の場合、あくまでGridViewに入力したデータを帳票へ出力したいので、 異なるユーザーでの操作は考えなくて大丈夫です。 SQL インジェクションの問題についても解説ありがとうございます。 参考にさせていただきます。
退会済みユーザー

退会済みユーザー

2022/08/30 22:22

> 異なるユーザーでの操作は考えなくて大丈夫です。 そういう条件は重要なので最初に質問に書くようにしてください。書いてないと普通に Web アプリの常識 (複数ユーザーが同時アクセス) で考える人が多いはずです。 それから、DB が作成中で変更可ならそれも最初の質問に書くようにお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問