前回の記事。
sheephuman.hatenablog.com
あれから苦労してVB→C#への翻訳に成功しました。
VBと書き方が異なるために苦労しました。
コード
やってる事は前回と変わらないです。
同一項目で集計してくれるように手を加えました。
private void toolStripButton1_Click(object sender, EventArgs e) { var ds = GetData(); ds.Tables[0].Rows[dataGridView1.Rows.Count-1].Delete(); //最終行は削除 var result = (from p in ds.Tables[0].AsEnumerable() group p by p["Column1"] into r select new { Column1 = r.Key, Column2 = r.Sum((s) => decimal.Parse(s["Column2"].ToString())), Column3 = r.Sum((s) => decimal.Parse(s["Column3"].ToString())) }).ToList(); var ds2 = new DataSet(); ds2.Tables.Add(ToDataTable(result)); chart1.DataSource = ds2; chart1.Series.Clear(); // 'Chartコントロールにタイトルを設定 chart1.Titles.Clear(); for (int i = 0; i < ds.Tables[0].Columns.Count-1; i++) { //'列名の取得 string columnName = ds.Tables[0].Columns[i+1].ColumnName; //'系列の設定 chart1.Series.Add(columnName); //'グラフの種類 chart1.Series[columnName].ChartType = SeriesChartType.Column; //'X軸 chart1.Series[columnName].XValueMember = ds.Tables[0].Columns[0].ColumnName.ToString(); chart1.ChartAreas[0].AxisX.MajorGrid.Enabled = false; chart1.ChartAreas[0].AxisX.MinorGrid.Enabled = false; //Y軸 chart1.Series[columnName].YValueMembers = columnName; chart1.Series[columnName].Label = "#VAL{C}"; } //'X軸タイトル chart1.ChartAreas[0].AxisX.Title = "月"; } private DataSet GetData() { var ds = new DataSet(); var dt = new DataTable(); DataRow dtRow; //'列の作成 dt.Columns.Add(dataGridView1.Columns[0].HeaderText); dt.Columns.Add(dataGridView1.Columns[1].HeaderText); dt.Columns.Add(dataGridView1.Columns[2].HeaderText); ds.Tables.Add(dt); dtRow = ds.Tables[0].NewRow(); dt.Rows.Add(dtRow); //'★★★データの追加★★★ for (int i = 0; i < dataGridView1.Rows.Count - 1; i++) { // dt.Rows.Add(dtRow[0]); //dt.Rows[0].Table.NewRow(); dt.Rows[i].SetField(0, dataGridView1[0, i].Value); dt.Rows[i].SetField(1 ,dataGridView1[1, i].Value); dt.Rows[i].SetField(2, dataGridView1[2, i].Value); // dtRow[1] = (DataRow)dataGridView1[1, i].Value; //dtRow[2] = (DataRow)dataGridView1[2, i].Value; ds.Tables[0].Rows.Add(dt.Rows); } return ds; } DataTable ToDataTable<T>(List<T> data) { var properties = TypeDescriptor.GetProperties(typeof(T)); var table = new DataTable(); foreach (PropertyDescriptor prop in properties) table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType); foreach (T item in data) { var row = table.NewRow(); foreach (PropertyDescriptor prop in properties) row[prop.Name] = prop.GetValue(item) ?? DBNull.Value; table.Rows.Add(row); } return table; } private void toolStripButton2_Click(object sender, EventArgs e) { //'Dictionaryオブジェクトの宣言 var myDic = new Dictionary<string, int>(); myDic.Add("orange", 1); myDic.Add("apple", 2); myDic.Add("melon", 3); myDic.Add("sheep", 4); myDic.Add("safoak", 5); dataGridView1.Rows.Add(); Random rnd = new Random(); for (int i = 0; i < dataGridView1.Rows.Count - 1; i++) { dataGridView1[0, i].Value = myDic.ElementAt(rnd.Next(5)).Key; dataGridView1[1, i].Value = rnd.Next(0, 1000); //一列目 dataGridView1[2, i].Value = rnd.Next(0, 1000); //2列目 } toolStripButton1_Click(sender,e); }
これでどれだけ入力しても、集計して表示できます。
実際に実行した画面は、前の記事を参考にしてください。
家計簿アプリに組み込む予定。
参考にしたページ
このコードは、DataSetに新規行および空白行があると動作しないようです。
Linqって慣れないとややこしい。
適当につっこんだら動いたんでよく分かりませんが、TypeDescriptorクラスでプロパティをGetして、そのなかにTableのColumnとRowをAddしてるみたいです。よくできてると思います。