実現したいこと
Column6でグルーピングを行い、Column4の値が正の場合のみ集計したい(=負の値は集計しない)
発生している問題・分からないこと
以下のソースコードで集計はできているのですが、負の値を除外する方法が分かりません。
該当のソースコード
dt = dt.AsEnumerable.GroupBy(Function(r) r("Column6").ToString).Select(Function(g) dt.Clone.LoadDataRow({g.First().Item("Column0").ToString,g.First().Item("Column1").ToString,g.First().Item("Column2").ToString,g.First().Item("Column3").ToString,g.Sum(Function(r) CDec(r("Column4"))),g.First().Item("Column5").ToString,g.First().Item("Column6").ToString},False)).CopyToDataTable()
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
IF文を追加してみたりしましたが、「>」が使用できない等のエラーが出てきました。
補足
特になし
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
Column6でグルーピングを行い、Column4の値が正の場合のみ集計したい(=負の値は集計しない)
表機能等で元データと希望の結果を提示いただくと、他人にも伝わりやすいです。
Column0 | Column4 | Column6 |
---|---|---|
Row0 | 10 | Group1 |
Row1 | -20 | Group1 |
Row2 | 30 | Group1 |
Row3 | -100 | Group2 |
Row4 | 200 | Group2 |
IF文を追加してみたりしましたが、「>」が使用できない等のエラーが出てきました。
Return
やEnd
がなかった等じゃないですかね?
ラムダ式 - Visual Basic | Microsoft Learn
そのコードや正しいエラー文も提示いただくと、他人にも伝わりやすいです。
ヘルプ|質問するときのヒント
この場合、負の値がデータテーブルに残らなくなってしまいますのでやりたいこととは異なるようです。
正の場合は合算を行い、負の場合は合算を行わずそのまま出力を行いたいという希望になります。
nururiさんの回答でWhere
で除外して集計されていますが、その後にマイナス値の行を追加すれば希望通りということでしょうか?
dt.Clone.LoadDataRow
だいぶ無駄っぽい気がします。
VBはよくわからないのでC#で(msms_msさんが「これじゃ全然わからない」ということであれば、頑張ってVBにしてみますけど^^;
cs
1using System.Data; 2 3namespace Qmiaghvxqhdj00i; 4 5public partial class Form1 : Form 6{ 7 public Form1() 8 { 9 InitializeComponent(); 10 11 var dt = new DataTable(); 12 13 dt.Columns.Add("Column0"); 14 dt.Columns.Add("Column4", typeof(decimal)); 15 dt.Columns.Add("Column6"); 16 17 dt.Rows.Add("Row0", 10m, "Group1"); 18 dt.Rows.Add("Row1", -20m, "Group1"); 19 dt.Rows.Add("Row2", 30m, "Group1"); 20 dt.Rows.Add("Row3", -100m, "Group2"); 21 dt.Rows.Add("Row4", 200m, "Group2"); 22 23 24 // 現状 25 var msms_ms = dt.AsEnumerable() 26 .GroupBy(r => r["Column6"].ToString()) 27 .Select(g => 28 { 29 var row = dt.NewRow(); 30 row["Column0"] = g.First()["Column0"].ToString(); 31 row["Column4"] = g.Sum(r => (decimal)r["Column4"]); 32 row["Column6"] = g.First()["Column6"].ToString(); 33 return row; 34 }) 35 .CopyToDataTable(); 36 37 38 // 負の値を除外して集計 39 var nururi = dt.AsEnumerable() 40 .Where(r => (decimal)r["Column4"] >= 0) 41 .GroupBy(r => r["Column6"].ToString()) 42 .Select(g => 43 { 44 var row = dt.NewRow(); 45 row["Column0"] = g.First()["Column0"].ToString(); 46 row["Column4"] = g.Sum(r => (decimal)r["Column4"]); 47 row["Column6"] = g.First()["Column6"].ToString(); 48 return row; 49 }) 50 .CopyToDataTable(); 51 // 後、負の値の行をマージ 52 var minus = dt.AsEnumerable() 53 .Where(r => (decimal)r["Column4"] < 0) 54 .CopyToDataTable(); 55 nururi.Merge(minus); 56 57 58 var tn8001 = dt.AsEnumerable() 59 .GroupBy(r => 60 { 61 // グループ化するキーを負の値でなければそのまま 62 if (0 < (decimal)r["Column4"]) 63 return r["Column6"].ToString(); 64 65 // 負の値だったら何かユニークな値にすれば、別のグループとして扱われる 66 else 67 // ちょっと危ないか?全カラムを連結するとか?? 68 return r.GetHashCode().ToString(); 69 }) 70 .Select(g => 71 { 72 var row = dt.NewRow(); 73 row["Column0"] = g.First()["Column0"].ToString(); 74 row["Column4"] = g.Sum(r => (decimal)r["Column4"]); 75 row["Column6"] = g.First()["Column6"].ToString(); 76 return row; 77 }) 78 .CopyToDataTable(); 79 80 81 dataGridView1.DataSource = dt; 82 dataGridView2.DataSource = msms_ms; 83 dataGridView3.DataSource = nururi; 84 dataGridView4.DataSource = tn8001; 85 } 86}
下ふたつで順番が違いますが、DataTable
の追加順はあまり意味はないので問題ないでしょう(実際はIdや作成日等のカラムがあるでしょうから好きにソートすればいい)
追記
vb.net
1Public Class Form1 2 Public Sub New() 3 InitializeComponent() 4 5 Dim dt = New DataTable 6 dt.Columns.Add("Column0") 7 dt.Columns.Add("Column4", GetType(Decimal)) 8 dt.Columns.Add("Column6") 9 dt.Rows.Add("Row0", 10D, "Group1") 10 dt.Rows.Add("Row1", -20D, "Group1") 11 dt.Rows.Add("Row2", 30D, "Group1") 12 dt.Rows.Add("Row3", -100D, "Group2") 13 dt.Rows.Add("Row4", 200D, "Group2") 14 15 16 '現状 17 Dim msms_ms = dt.AsEnumerable _ 18 .GroupBy(Function(r) r("Column6").ToString) _ 19 .Select(Function(g) 20 Dim row = dt.NewRow 21 row("Column0") = g.First()("Column0").ToString 22 row("Column4") = g.Sum(Function(r) CDec(r("Column4"))) 23 row("Column6") = g.First()("Column6").ToString 24 Return row 25 26 'カラムが多いならこれが手っ取り早いかな(何が入っているかにもよるが... 27 'Dim row = dt.NewRow 28 'row.ItemArray = g.First().ItemArray 29 'row("Column4") = g.Sum(Function(r) CDec(r("Column4"))) 30 'Return row 31 End Function) _ 32 .CopyToDataTable 33 34 35 '負の値を除外して集計後、負の値の行をマージ 36 Dim nururi = dt.AsEnumerable _ 37 .Where(Function(r) CDec(r("Column4")) >= 0) _ 38 .GroupBy(Function(r) r("Column6").ToString) _ 39 .Select(Function(g) 40 Dim row = dt.NewRow 41 row("Column0") = g.First()("Column0").ToString 42 row("Column4") = g.Sum(Function(r) CDec(r("Column4"))) 43 row("Column6") = g.First()("Column6").ToString 44 Return row 45 End Function) _ 46 .CopyToDataTable 47 Dim minus = dt.AsEnumerable _ 48 .Where(Function(r) CDec(r("Column4")) < 0) _ 49 .CopyToDataTable 50 nururi.Merge(minus) 51 52 53 'キー細工 54 Dim tn8001 = dt.AsEnumerable _ 55 .GroupBy(Function(r) 56 'グループ化するキーを負の値でなければそのまま 57 If 0 < CDec(r("Column4")) Then 58 Return r("Column6").ToString 59 60 Else '負の値だったら何かユニークな値にすれば、別のグループとして扱われる 61 'ちょっと危ないか? ハッシュが衝突するというより、 62 '(わたしは)Column6に何が入ってるか知らないという意味で。 63 '(数字が入っていたらぶつかる可能性もあるかも?と) 64 Return r.GetHashCode.ToString 65 66 'あるいは全カラムを連結するとか? 67 68 'Guidがいいか? 69 'Return Guid.NewGuid.ToString 70 End If 71 End Function) _ 72 .Select(Function(g) 73 Dim row = dt.NewRow 74 row("Column0") = g.First()("Column0").ToString 75 row("Column4") = g.Sum(Function(r) CDec(r("Column4"))) 76 row("Column6") = g.First()("Column6").ToString 77 Return row 78 End Function) _ 79 .CopyToDataTable 80 81 82 DataGridView1.DataSource = dt 83 DataGridView2.DataSource = msms_ms 84 DataGridView3.DataSource = nururi 85 DataGridView4.DataSource = tn8001 86 End Sub 87End Class
投稿2024/03/28 15:53
編集2024/03/29 21:56総合スコア9862
0
GroupByの前に、Whereで条件指定すればいいと思います。
vb.net
1Where(Function(row) Convert.ToInt32(row("Column4")) >= 0)
適当にConvert.ToInt32とかしちゃってますが、元が違う型なら別のものを指定してください。
投稿2024/03/28 04:47
編集2024/03/28 04:51総合スコア160
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。