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

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

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

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

Q&A

解決済

1回答

840閲覧

VIsualStudio2022でDataTableとDataGridViewのバインドをしたいです。

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

0グッド

0クリップ

投稿2023/03/31 04:11

編集2023/04/02 17:32

実現したいこと

①DataTableのDataGridViewの相互でバインドをする
②ボタンクリックでコンボボックス等の情報をDataTableにいれる。
③この時、DataTable.Row[0][0]が空白であれば、4列入力する。入れようとしている文字列と同じであれば[1][1]から3列いれる。入れようと文字列と違うのであれば、DataTableをクリアして新しくDataTable作りなおす。

前提

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

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

現状では、条件分の入力方法が分からないのと、ボタンクリックしても何も起きません。
エラーメッセージはありません。

イメージ説明

該当のソースコード

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

ソースコード

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(); 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; } // 合計金額を求める private void CalculateButton_Click(object sender, EventArgs e) { //DataTable作成 // 品物が選択されているか判定する 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); } // グラフ用の文字列を作成する string graphLine = new string('■', count); // グラフを表示する GraphTextBox.Text += graphLine + Environment.NewLine; // 合計金額を表示する _ = int.TryParse(TotalTextBox.Text, out int total); TotalTextBox.Text = $"{total + price}"; } /// <summary> /// 買い物リストをcsvファイルとして保存する /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void SaveButton_Click(object sender, EventArgs e) { SaveFileDialog dlg = new SaveFileDialog { Title = "ファイルを保存する", FileName = @"ItemList.csv", Filter = "CSV(カンマ区切り)|*.csv" }; if (dlg.ShowDialog() == DialogResult.Cancel) { MessageBox.Show("キャンセルされました"); return; } using (StreamWriter writer = new StreamWriter(dlg.FileName, false, Encoding.GetEncoding("shift_jis"))) foreach (DataRow row in dt.Rows) { writer.WriteLine(string.Join(",", row.ItemArray)); } }

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2023/03/31 05:16

訂正してください。DataGritView ⇒ DataGridView .NET Framework なのか .NET Core/.NET のどっちなのかとそのバージョンを書いてください。 質問のコードの表示が乱れています。直してください。
退会済みユーザー

退会済みユーザー

2023/03/31 11:29

質問のコードの表示が乱れています。直してください。
退会済みユーザー

退会済みユーザー

2023/03/31 14:15

なんど直してもこうなります。 直さないと回答できませんか?
退会済みユーザー

退会済みユーザー

2023/03/31 14:34 編集

コードを ``` と ``` で囲ってください。
TN8001

2023/04/02 08:32

新しい質問を編集しようとして間違えたんだと思いますが、解決後の質問を大幅に変更するのはご遠慮ください。 回答との整合性が取れず閲覧者が混乱します。
guest

回答1

0

ベストアンサー

③この時、DataTable.Row[0][0]が空白であれば、4列入力する。入れようとしている文字列と同じであれば[1][1]から3列いれる。入れようと文字列と違うのであれば、DataTableをクリアして新しくDataTable作りなおす。

このDataTableDataGridView)は、1日分しか保持しないのですか?
よく「同じ値はグループ化?して重複表示しない」ようなものがありますが、それの1日だけ版??

複数日入るようなら、ソートと↓のようなものを組み合わせたほうが幸せな気がします。
DataGridViewの行をグループ化する - .NET Tips (VB.NET,C#...)


とりあえずそうだ(1日だけ版)として、提示通りの条件で書きました。

cs

1using System.Data; 2using System.Text; 3 4namespace Q1fyr16mcto59tg 5{ 6 public partial class Form1 : Form 7 { 8 // ItemListDataGridViewとバインドしたDataTable 9 // 最初にDataSourceにセットしたら、以降はAddやClearするだけで作り直したり入れ替えたりはしない!! 10 private readonly DataTable dt; 11 12 public Form1() 13 { 14 InitializeComponent(); 15 16 // DataTable作成 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 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); // Shift_JIS有効化 26 } 27 28 private void CalculateButton_Click(object sender, EventArgs e) 29 { 30 // 品物が選択されているか確認 31 if (string.IsNullOrWhiteSpace(ItemNameComboBox.Text)) 32 { 33 MessageBox.Show("品物を選択してください"); 34 return; 35 } 36 37 // 個数に1以上の数値が入力されているか確認 38 int count = (int)CountNumericUpDown.Value; 39 if (count <= 0) 40 { 41 MessageBox.Show("1つ以上の数字を入力してください"); 42 return; 43 } 44 45 // 単価が入力されているか確認 46 int ListPrice = (int)ListPriceNumericUpDown.Value; 47 if (ListPrice <= 0) 48 { 49 MessageBox.Show("単価を入力してください"); 50 return; 51 } 52 53 54 // 今回の金額 55 int price = ListPrice * count; 56 57 // 買い物リスト用の文字列を作成 58 string date = dateTimePicker.Value.ToLongDateString(); 59 string item = ItemNameComboBox.Text; 60 61 62 // 「DataTable.Row[0][0]が空白であれば、4列入力」 63 // 1行も追加されていないと dt.Rows[0][0] はエラーになるので行数が0かどうかで判断 64 if (0 == dt.Rows.Count) 65 { 66 // ここでやってもいいけど同じことを何度も書くのは無駄なのでif後にやる 67 //DataRow row = dt.NewRow(); 68 //row["日付"] = date; 69 //row["商品"] = item; 70 //row["個数"] = count; 71 //row["値段"] = price; 72 //dt.Rows.Add(row); 73 } 74 75 // 「入れようとしている文字列と同じであれば[1][1]から3列いれる」 76 // else if (dt.Rows[0][0].ToString() == date) と書いてもいいが 77 else if (dt.Rows[0].Field<string>("日付") == date) 78 { 79 date = " "; 80 // ここでやってもいいけど...略 81 //DataRow row = dt.NewRow(); 82 //row["日付"] = " "; 83 //row["商品"] = item; 84 //row["個数"] = count; 85 //row["値段"] = price; 86 //dt.Rows.Add(row); 87 } 88 89 // 「入れようと文字列と違うのであれば、DataTableをクリア」 90 else 91 { 92 dt.Clear(); 93 // ここでやってもいいけど...略 94 //DataRow row = dt.NewRow(); 95 //row["日付"] = date; 96 //row["商品"] = item; 97 //row["個数"] = count; 98 //row["値段"] = price; 99 //dt.Rows.Add(row); 100 101 GraphTextBox.Text = ""; 102 TotalTextBox.Text = ""; 103 } 104 105 // 買い物リストに追加 106 DataRow row = dt.NewRow(); 107 row["日付"] = date; 108 row["商品"] = item; 109 row["個数"] = count; 110 row["値段"] = price; 111 dt.Rows.Add(row); 112 113 114 // グラフ用の文字列を作成 115 //string graphLine = ""; 116 //for (int i = 0; i < count; i++) graphLine += "■"; 117 string graphLine = new string('■', count); 118 119 120 // グラフを表示 121 //if (string.IsNullOrWhiteSpace(GraphTextBox.Text)) 122 // GraphTextBox.Text = graphLine; 123 //else 124 // GraphTextBox.Text += Environment.NewLine + graphLine; 125 // 厳密には同じではないが改行を後ろにすれば分岐が不要 126 GraphTextBox.Text += graphLine + Environment.NewLine; 127 128 129 // 合計金額を表示 130 //if (int.TryParse(TotalTextBox.Text, out int total)) 131 //{ 132 // int sum = total + price; 133 // TotalTextBox.Text = sum.ToString(); 134 //} 135 //else 136 // TotalTextBox.Text = price.ToString(); 137 // totalは初期値0なので分岐は不要 138 // _ = はなくてもいいが🛈️(CA1806)がでるので破棄(使わないこと)を明示 139 _ = int.TryParse(TotalTextBox.Text, out int total); 140 TotalTextBox.Text = $"{total + price}"; 141 } 142 143 144 private void SaveButton_Click(object sender, EventArgs e) 145 { 146 SaveFileDialog dlg = new SaveFileDialog 147 { 148 Title = "ファイルを保存する", 149 //InitialDirectory = @"C:\", 150 FileName = "ItemList.csv", 151 Filter = "CSV(カンマ区切り)|*.csv", 152 }; 153 154 if (dlg.ShowDialog() == DialogResult.Cancel) 155 { 156 MessageBox.Show("キャンセルされました"); 157 return; 158 } 159 160 using StreamWriter writer = new StreamWriter(dlg.FileName, false, Encoding.GetEncoding("shift_jis")); 161 foreach (DataRow row in dt.Rows) 162 { 163 writer.WriteLine(string.Join(",", row.ItemArray)); 164 } 165 } 166 } 167}

アプリ画像

投稿2023/03/31 15:20

編集2023/04/01 20:38
TN8001

総合スコア9246

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

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

退会済みユーザー

退会済みユーザー

2023/04/01 01:58

ありがとうございます。 「リストは日付ごとに作る」ということで、作ったらcsv保存するようになっています。
退会済みユーザー

退会済みユーザー

2023/04/01 02:11

やっぱり、ボタンを押しても反応しないのですが…なんででしょうか? 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"; /// <summary> /// コンストラクタ /// </summary> public LunchBoxMemoForm() { InitializeComponent(); } /// <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; //DataTable作成 DataTable dt = new DataTable(); dt.TableName = "ItemList"; dt.Columns.Add("日付", typeof(string)); dt.Columns.Add("商品", typeof(string)); dt.Columns.Add("個数", typeof(int)); dt.Columns.Add("値段", typeof(int)); // 買い物リストに追加する if (0 == dt.Rows.Count) { DataRow row = dt.NewRow(); row["日付"] = date; row["商品"] = item; row["個数"] = count; row["値段"] = price; dt.Rows.Add(row); ItemListDataGridView.DataSource = dt; } else if (dt.Rows[0].Field<string>("日付") == date) { DataRow row = dt.NewRow(); row["日付"] = " "; row["商品"] = item; row["個数"] = count; row["値段"] = price; dt.Rows.Add(row); ItemListDataGridView.DataSource = dt; } else { dt.Clear(); DataRow row = dt.NewRow(); row["日付"] = date; row["商品"] = item; row["個数"] = count; row["値段"] = price; dt.Rows.Add(row); ItemListDataGridView.DataSource = dt; } // グラフ用の文字列を作成する string graphLine = ""; for (int i = 0; i < count; i++) { graphLine = graphLine + "■"; } // グラフを表示する if (string.IsNullOrWhiteSpace(GraphTextBox.Text)) { GraphTextBox.Text = graphLine; } else { GraphTextBox.Text = GraphTextBox.Text + NewLine + graphLine; } // 合計金額を表示する if (int.TryParse(TotalTextBox.Text, out int total)) { int sum = total + price; TotalTextBox.Text = sum.ToString(); } else { TotalTextBox.Text = price.ToString(); } } /// <summary> /// 買い物リストをcsvファイルとして保存する /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void SaveButton_Click(object sender, EventArgs e) { SaveFileDialog dlg = new SaveFileDialog { Title = "ファイルを保存する", InitialDirectory = @"C:\", FileName = @"ItemList.csv", Filter = "CSV(カンマ区切り)|*.csv" }; if (dlg.ShowDialog() == DialogResult.Cancel) { MessageBox.Show("キャンセルされました"); return; } else { string filename = dlg.FileName; using (StreamWriter writer = new StreamWriter(@"C:", false, Encoding.GetEncoding("shift_jis"))) { int rowCount = ItemListDataGridView.Rows.Count; if (ItemListDataGridView.AllowUserToAddRows == true) { rowCount = rowCount - 1; } for (int i = 0; i < rowCount; i++) { List<String> strList = new List<String>(); for (int j = 0; j < ItemListDataGridView.Columns.Count; j++) { strList.Add(ItemListDataGridView[j, i].Value.ToString()); } String[] strArray = strList.ToArray(); String strCsvData = String.Join(",", strArray); writer.WriteLine(strCsvData); } } } }
TN8001

2023/04/01 02:51 編集

> やっぱり、ボタンを押しても反応しないのですが…なんででしょうか? 何も反応がないということですか?(少なくとも1行は追加されると思うのですが) ボタンにCalculateButton_Clickイベントが付いているかを確認してください。 それとも2行目が追加されないという意味ですか? そうであれば、Piiさんのコードでは //DataTable作成 DataTable dt = new DataTable(); が、CalculateButton_Clickの中にあります。 私の回答ではコンストラクタの中にあります(かつフィールドです) ボタンを押すたびnewしてしまっては、2行以上になりません。
退会済みユーザー

退会済みユーザー

2023/04/01 23:41

1行目も追加されませんし、グラフも追加されません。 コメントに書いたように private void CalculateButton_Click(object sender, EventArgs e) を付けております。
TN8001

2023/04/02 00:24

> 1行目も追加されませんし、グラフも追加されません。 CalculateButton_Clickが呼ばれているのは確実ですか?(品物等が未選択だとMessageBoxが出る) 呼ばれているのに何も起きないというのは考えにくいです(Piiさんのコードであっても回答のコードであっても) ボタンのイベントのつけ方(確認の仕方)はだいじょぶですよね? [イベント ハンドラーを追加または削除する方法 - Windows Forms .NET | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/desktop/winforms/controls/how-to-add-an-event-handler)
退会済みユーザー

退会済みユーザー

2023/04/02 02:07

イベントの付け方を確認しましたところ、追加されるようになりました。ありがとうございます。 そうしたら、Gridに日付、商品、個数、値段、日付、 商品、個数、値段と2個づつ列ができ、2個目の方にしか追加されなくなってしまいました。 日付、商品、個数、値段、日付、  商品、      個数、値段             4月2日 コロッケバーガー 2個 100円 みたいな。 また、2行目以降が作られなくなりました。
TN8001

2023/04/02 02:50

> そうしたら、Gridに日付、商品、個数、値段、日付、 商品、個数、値段と2個づつ列ができ、2個目の方にしか追加されなくなってしまいました。 Piiさんの2023/04/01 11:11のコメントのコードでも、回答コードでもそのようにはなりません。 試行錯誤されてコードがごっちゃになっているのだと思います。 回答コードはPiiさんのコントロール名に合わせていますので、フィールド・コンストラクタ・イベントハンドラを「回答コードそのまま」コピペして使ってください。 // フィールド private readonly DataTable dt; // コンストラクタ public Form1(){ /*省略*/ } // イベントハンドラ private void CalculateButton_Click(object sender, EventArgs e){ /*省略*/ } (希望通りの動作になって)回答コードについてのわからない点は、お気軽にコメントください。
退会済みユーザー

退会済みユーザー

2023/04/02 03:50

ありがとうございます。 直りました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問