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

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

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

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

Q&A

解決済

2回答

1969閲覧

VisualStudio2022でDataTableとDataGridViewのバインドをしたものをDataGridViewのほうから選択的に削除・編集、CSVの読み込みがしたいです。

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

0グッド

0クリップ

投稿2023/04/02 04:20

編集2023/04/02 23:17

実現したいこと

①DataTableとDataGridViewのバインドをしたものをDataGridViewのほうから1行選んで削除・編集したいです。

違うボタンを押すことで「選択されたデータグリッドが削除→データテーブルも削除」
また違うボタンを押すことで「選択されたデータグリッドが削除→データテーブルも削除→コンボボックスとNumericUpDownに入れた数字をデータテーブルに入れる→データグリッドに表示」

②CSVファイルを読み込んでDataTableにいれ、DataGridViewで表示

前提

「コンボボックスとNumericUpDownに入れた数字をデータテーブルに入れる→データグリッドに表示させる」がボタンで実行されるという状態です。

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

Data Tableから読み込んでいるData Grid Viewの1行を選択的に削除するにはどうしたらいいのでしょうか?
今現状、データグリッドを削除・編集するというコードのみで、選択的に消されないという状況です。しかもデータグリッドからも消されない。

また、ファイル選択後、読み込みをしようとするとエラーが出ます。(//*1)
→ハンドルされていない例外
System.Data.OleDb.OleDbException: '1 つ以上の必要なパラメーターの値が設定されていません。'
という表示が出ます。

該当のソースコード

using System; using System.IO; using System.Windows.Forms; using System.Data; using System.Text; using System.Collections.Generic; using System.Security.Cryptography; using System.Data.OleDb; using System.Runtime.InteropServices.ComTypes; using System.Windows.Forms.VisualStyles; namespace recruitPGwork { public partial class LunchBoxMemoForm : Form { private const string NewLine = "\r\n"; private readonly DataTable dt; /// <summary> /// コンストラクタ /// </summary> public LunchBoxMemoForm() { InitializeComponent(); //DataTable作成 dt = new DataTable("ItemList"); dt.TableName = "ItemList"; dt.Columns.Add("日付", typeof(string)); dt.Columns.Add("商品", typeof(string)); dt.Columns.Add("個数", typeof(int)); dt.Columns.Add("値段", typeof(int)); ItemListDataGridView.DataSource = dt; } /// <summary> /// 合計金額を求める /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void CalculateButton_Click(object sender, EventArgs e) { // 品物が選択されているか判定する if (string.IsNullOrWhiteSpace(ItemNameComboBox.Text)) { MessageBox.Show("品物を選択してください"); return; } // 個数に1以上の数値が入力されているかチェックする int count = (int)CountNumericUpDown.Value; if (count == 0) { MessageBox.Show("1つ以上の数字を入力してください"); return; } // 単価が入力されているかの確認 int ListPrice = (int)ListPriceNumericUpDown.Value; if (ListPrice == 0) { MessageBox.Show("単価を入力してください"); return; } // 今回の金額 var price = ListPrice * count; // 買い物リスト用の文字列を作成する var date = dateTimePicker.Value.ToLongDateString(); var item = ItemNameComboBox.Text; // 買い物リストに追加する if (0 == dt.Rows.Count) { DataRow row = dt.NewRow(); row["日付"] = date; row["商品"] = item; row["個数"] = count; row["値段"] = price; dt.Rows.Add(row); } else if (dt.Rows[0].Field<string>("日付") == date) { date = " "; DataRow row = dt.NewRow(); row["日付"] = date; row["商品"] = item; row["個数"] = count; row["値段"] = price; dt.Rows.Add(row); } else { dt.Clear(); DataRow row = dt.NewRow(); row["日付"] = date; row["商品"] = item; row["個数"] = count; row["値段"] = price; dt.Rows.Add(row); GraphTextBox.Text = ""; TotalTextBox.Text = ""; }   } /// <summary> /// 買い物リストを削除する /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void DeletionButton_Click(object sender, EventArgs e) { foreach (DataGridViewRow r in ItemListDataGridView.SelectedRows) { if (!r.IsNewRow) { ItemListDataGridView.Rows.Remove(r); } } } /// <summary> /// 買い物リストをcsvファイルから読み込む /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void LoadingButton_Click(object sender, EventArgs e) { var dlg = new OpenFileDialog() { Title = "ファイルの選択", CheckFileExists = true, RestoreDirectory = true, InitialDirectory = @"C:\", FileName = @"ItemList.csv", Filter = "CSVファイル|*.csv|すべてのファイル|*.*" }; if (dlg.ShowDialog() == DialogResult.OK) { OleDbConnection connection; OleDbCommand command; OleDbDataAdapter adapter; DataSet dataset = new DataSet(); DataGrid datagrid = new DataGrid(); connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + Path.GetDirectoryName(dlg.FileName) + "\\; Extended Properties=\"Text;HDR=YES;FMT=Delimited\""); command = new OleDbCommand("SELECT [日付], [商品], [個数], [値段] FROM [" + Path.GetFileName(dlg.FileName) + "]", connection); dataset.Clear(); adapter = new OleDbDataAdapter(command); adapter.Fill(dataset); //*1 dt.Columns.Add("日付"); dt.Columns.Add("商品"); dt.Columns.Add("個数"); dt.Columns.Add("値段"); for (int line = 0; line < dataset.Tables[0].Rows.Count; line++) { DataRow data = dataset.Tables[0].Rows[line]; Object[] new_row = new Object[] { String.Format(@"{0} ({1})", data["日付"], data["商品"]), data["個数"], data["値段"] }; dt.Rows.Add(new_row); } datagrid.DataSource = dt; } else { MessageBox.Show("ファイルが見つかりません"); return; } } }

補足情報(FW/ツールのバージョンなど)

VIsualStudio2022 C# .NET Framework フォームデザイナーを用いています。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2023/04/02 04:50

まったく違う内容なのですが…。
退会済みユーザー

退会済みユーザー

2023/04/02 07:51

回答したのでそれに対するフィードバックを返してください。役に立った/立たなかったぐらいはすぐに返せるのでは? 役に立たなかったならどこがダメかを書くとより期待に近い回答が出てくるかも。 それから、回答が付いたら、後出しで最初の質問と違うことを言ったり追加質問するなどは止めましょう。質問と回答のつじつまが合わなくなって、後からこのスレッドを見た人には意味が分からなくなるので。
guest

回答2

0

ベストアンサー

「選択されたデータグリッドが削除→データテーブルも削除→コンボボックスとNumericUpDownに入れた数字をデータテーブルに入れる→データグリッドに表示」

これが編集ということだと思いますが、わざわざ削除しないでも直接変更可能です。

編集ありとなるとグラフ・合計表示が今の方式では無理なので、DataTableを全件舐めて再計算しますかね(そこまで大量でないでしょうし)

Data Tableから読み込んでいるData Grid Viewの1行を選択的に削除するにはどうしたらいいのでしょうか?

セルの選択ではダメです。行を選択してください。
DataGridViewのプロパティがどうなっているかわかりませんが、デフォルトでは左端に行ヘッダーがあります(小さい▶が出るところ)
行ヘッダーのクリックで行の選択になります(ドラッグやCtrl+クリック等で複数行も可)

ただし一番上の行を削除すると日付が消えてしまいます。
削除前に覚えておいて戻せばいいんですが、何かモヤモヤします(そもそも同一日付しか入らないのに、DataGridViewに出す必要があるんですかね?)

また、ファイル選択後、読み込みをしようとするとエラーが出ます。(//*1)

保存があれ(ただカンマで繋げるだけ)なら、読み込みもSplitするだけでいいんじゃないですかね?

cs

1using System; 2using System.Data; 3using System.IO; 4using System.Text; 5using System.Windows.Forms; 6 7namespace Q1fyr16mcto59tg 8{ 9 public partial class Form1 : Form 10 { 11 private readonly DataTable dt; 12 13 public Form1() 14 { 15 InitializeComponent(); 16 17 dt = new DataTable("ItemList"); 18 dt.Columns.Add("日付", typeof(string)); 19 dt.Columns.Add("商品", typeof(string)); 20 dt.Columns.Add("個数", typeof(int)); 21 dt.Columns.Add("値段", typeof(int)); 22 23 ItemListDataGridView.DataSource = dt; 24 } 25 26 private void CalculateButton_Click(object sender, EventArgs e) 27 { 28 if (string.IsNullOrWhiteSpace(ItemNameComboBox.Text)) 29 { 30 MessageBox.Show("品物を選択してください"); 31 return; 32 } 33 int count = (int)CountNumericUpDown.Value; 34 if (count <= 0) 35 { 36 MessageBox.Show("1つ以上の数字を入力してください"); 37 return; 38 } 39 int ListPrice = (int)ListPriceNumericUpDown.Value; 40 if (ListPrice <= 0) 41 { 42 MessageBox.Show("単価を入力してください"); 43 return; 44 } 45 46 int price = ListPrice * count; 47 string date = dateTimePicker.Value.ToLongDateString(); 48 string item = ItemNameComboBox.Text; 49 50 if (0 == dt.Rows.Count) 51 { 52 } 53 else if (dt.Rows[0].Field<string>("日付") == date) 54 { 55 date = " "; 56 } 57 else 58 { 59 dt.Clear(); 60 } 61 62 DataRow row = dt.NewRow(); 63 row["日付"] = date; 64 row["商品"] = item; 65 row["個数"] = count; 66 row["値段"] = price; 67 dt.Rows.Add(row); 68 69 // グラフ・合計表示 70 UpdateText(); 71 } 72 73 private void EditingButton_Click(object sender, EventArgs e) 74 { 75 if (string.IsNullOrWhiteSpace(ItemNameComboBox.Text)) 76 { 77 MessageBox.Show("品物を選択してください"); 78 return; 79 } 80 int count = (int)CountNumericUpDown.Value; 81 if (count <= 0) 82 { 83 MessageBox.Show("1つ以上の数字を入力してください"); 84 return; 85 } 86 int ListPrice = (int)ListPriceNumericUpDown.Value; 87 if (ListPrice <= 0) 88 { 89 MessageBox.Show("単価を入力してください"); 90 return; 91 } 92 93 int price = ListPrice * count; 94 string item = ItemNameComboBox.Text; 95 foreach (DataGridViewRow r in ItemListDataGridView.SelectedRows) 96 { 97 if (!r.IsNewRow) 98 { 99 // DataGridViewRowからDataRow取得 100 DataRow row = ((DataRowView)r.DataBoundItem).Row; 101 102 // 各データ変更 103 row["商品"] = item; 104 row["個数"] = count; 105 row["値段"] = price; 106 } 107 } 108 109 UpdateText(); 110 } 111 112 private void DeletionButton_Click(object sender, EventArgs e) 113 { 114 if (0 == dt.Rows.Count) return; 115 116 // 日付を保存 117 string date = dt.Rows[0].Field<string>("日付"); 118 119 // 選択行の削除 120 foreach (DataGridViewRow r in ItemListDataGridView.SelectedRows) 121 { 122 if (!r.IsNewRow) 123 ItemListDataGridView.Rows.Remove(r); 124 } 125 126 // 日付を復元 127 if (0 < dt.Rows.Count) dt.Rows[0]["日付"] = date; 128 129 UpdateText(); 130 } 131 132 private void LoadingButton_Click(object sender, EventArgs e) 133 { 134 var dlg = new OpenFileDialog() 135 { 136 Title = "ファイルの選択", 137 CheckFileExists = true, 138 RestoreDirectory = true, 139 //InitialDirectory = @"C:\", 140 FileName = "ItemList.csv", 141 Filter = "CSV(カンマ区切り)|*.csv", 142 }; 143 144 if (dlg.ShowDialog() == DialogResult.Cancel) 145 { 146 MessageBox.Show("キャンセルされました"); 147 return; 148 } 149 150 dt.Clear(); 151 152 foreach (string line in File.ReadLines(dlg.FileName, Encoding.GetEncoding("shift_jis"))) 153 { 154 string[] array = line.Split(','); 155 DataRow row = dt.NewRow(); 156 row["日付"] = array[0]; 157 row["商品"] = array[1]; 158 row["個数"] = array[2]; 159 row["値段"] = array[3]; 160 dt.Rows.Add(row); 161 } 162 163 UpdateText(); 164 } 165 166 private void SaveButton_Click(object sender, EventArgs e) 167 { 168 SaveFileDialog dlg = new SaveFileDialog 169 { 170 Title = "ファイルを保存する", 171 //InitialDirectory = @"C:\", 172 FileName = "ItemList.csv", 173 Filter = "CSV(カンマ区切り)|*.csv", 174 }; 175 176 if (dlg.ShowDialog() == DialogResult.Cancel) 177 { 178 MessageBox.Show("キャンセルされました"); 179 return; 180 } 181 182 using (StreamWriter writer = new StreamWriter(dlg.FileName, false, Encoding.GetEncoding("shift_jis"))) 183 { 184 foreach (DataRow row in dt.Rows) 185 { 186 writer.WriteLine(string.Join(",", row.ItemArray)); 187 } 188 } 189 } 190 191 private void UpdateText() 192 { 193 string graph = ""; 194 int total = 0; 195 foreach (DataRow row in dt.Rows) 196 { 197 int count = row.Field<int>("個数"); 198 int price = row.Field<int>("値段"); 199 200 graph += new string('■', count) + Environment.NewLine; 201 total += price; 202 } 203 204 GraphTextBox.Text = graph; 205 TotalTextBox.Text = $"{total}"; 206 } 207 } 208}

投稿2023/04/02 08:34

編集2023/04/02 12:47
TN8001

総合スコア9317

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

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

退会済みユーザー

退会済みユーザー

2023/04/02 11:11

またご回答いただきましてありがとうございます。 とても分かりやすく大変助かりました。 CSVでの入出力があると、GridViewの方がいいのかと思って、テキストボックスからグリッドにしてしまいました。 また、1番上を消すとリスト作り直しになってしまうのが、なんだか「う~ん」て感じですね。どうにかできるんでしょうか?? そして私の使用しているのがC#7.3らしく、回答でいただいていた 117・195・196行目の“!”と182行目の”using”に対応していないというエラーが出てしましました。 調べたらどう直せるか出てきますかね??
TN8001

2023/04/02 12:48 編集

> CSVでの入出力があると、GridViewの方がいいのかと思って、テキストボックスからグリッドにしてしまいました。 DataGridViewの一番の目的は一覧表示でしょうから、TextBoxで済むという話でもないですが... 編集をどちらでやるかという話でしょうか? > また、1番上を消すとリスト作り直しになってしまうのが、なんだか「う~ん」て感じですね。どうにかできるんでしょうか?? 作り直しているというか「入れ直している」ですがモヤモヤはそこではなくて、csvに日付を入れるのでなく「ファイル名を日付にする」ようなほうが使いやすいんじゃないかということです。 > そして私の使用しているのがC#7.3らしく、回答でいただいていた > 117・195・196行目の“!”と182行目の”using”に対応していないというエラーが出てしましました。 .NET6ではなく.NET Frameworkを使用されているようですね(そんな気はしていましたが^^; 回答を編集しました。
退会済みユーザー

退会済みユーザー

2023/04/02 23:15

元々ある程度できているものを改造していて、最初はテキストボックスに”,”で区切って1行ずつ入力していく感じでした。CSV入出力の仕方を調べていくとGridViewからの~みたいな記事が多かったのでそのほうがいいのかな~って思っていました。 ファイル名を日付にするのはDataTableそのものもでしょうか?CSVにしたときのみでいいのでしょうか?? これは.NET Framework使用なんですね!すみません。失礼いたしました。 丁寧にありがとうございます。
TN8001

2023/04/03 09:59

> 最初はテキストボックスに”,”で区切って1行ずつ入力していく感じでした。 なるほど > CSV入出力の仕方を調べていくとGridViewからの~みたいな記事が多かったのでそのほうがいいのかな~って思っていました。 項目が決まっているならDataGridViewのほうがいいですよね(カンマ入れ忘れとかおきないですし) > ファイル名を日付にするのはDataTableそのものもでしょうか?CSVにしたときのみでいいのでしょうか?? csvがどう利用されるのかわかってないのでなんともいえませんが... 「日付が1行目にしか入らない」というのが、csvとしてイレギュラーなんですよね^^; 通常csvのデータは1行で完結しないといけません。 上の行を見ないと日付がわからないというのは非常に扱いにくくなります。 「csvをほかのアプリで利用するので形式はいじれない」のであれば、議論の余地なくそうせざるを得ませんが... 日付別のcsvでもデータに日付を入れておくのはありだとは思います(例えば「月別のcsvに変えたくなった」ようなときにファイル連結するだけで済む)
guest

0

Data Tableから読み込んでいるData Grid Viewの1行を選択的に削除するにはどうしたらいいのでしょうか?

アプリの構造を、

DataTable ⇔ BindingSource ⇔ DataGridView

というようにし、DataGridView 上で削除したい行をクリック(選択)してから、BindingSource の RemoveCurrent() メソッドを適用してはいかが?

具体例は以下の記事を見てください。サンプルコードの中の button2_Click メソッドがそれです。

CSV ファイルを DataGridView に表示
http://surferonwww.info/BlogEngine/post/2020/09/11/show-date-in-csv-file-on-datagridview.aspx

質問のコードでは DataGridView の行を削除しようとしているようですが、それは悪手です。

DataTable + DataGridView のアプリなら、行の削除は DataTable の方を操作しましょう。BindingSource を使うとサンプルコードにあるようにそれが容易にできます。

投稿2023/04/02 04:58

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2023/04/03 05:36

分からないなら何が分からないのか聞いたらいいのに・・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問