🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

Q&A

2回答

644閲覧

List<独自クラス>内での特定プロパティの合算方法

hiro24

総合スコア12

C#

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

0グッド

0クリップ

投稿2018/07/29 10:32

いつもお世話になっております。

C#の初学者です。

以下の動作を目的をするWindows Formアプリを作成している中で、書籍やネットで検索してもどうしても解決できなかったため投稿させていただきました。

【開発環境】
・OS:Windows 10
・Visual Studio 2017 ver.15.7.3
・.NET ver.4.7.02556

【目的】
[1]CSVファイルを読み込む(※取り込み内容:【目的の動作(例)】の入力ファイル参照)
[2]読み込んだCSVファイルをList化し、ListViewに表示する
[3]List内で同一店舗名、同一コード、同一レートのもがすでに存在している場合、販売数量をそのすでに存在しているListに加算する。※1種類しか存在しないものはそのまま表示する。

文章ではわかりにくいと思いますので詳細は、【目的の動作(例)】の画像を参照の程お願いいたします。

【目的の動作(例)】
イメージ説明
例1)青塗りのデータ
店舗名:A、商品コード:111、割引率:1が共通している。そのためこれらを一つにまとめた販売数:100+200=300の結果を出力する

例2)オレンジ塗りのデータ(例1と同内容)
店舗名:B、商品コード:222、割引率:2が共通している。そのためこれらを一つにまとめた販売数:300+500=800の結果を出力する

※色塗りなしは、1種類しかないためそのまま表示。

上記の画像をご覧いただくとわかるように、同じ店舗もしくは商品コードでも割引率が違うものなどが存在します。
これらも区別して上記のような結果を得られる動作が欲しいと考えています。

【困っていること】
・CSVを順次読み込んでいく中でList内で同一店舗名、同一コード、同一レートでがすでに存在している場合、数量をそのすでに存在しているListに加算するやり方がわからないこと。(目的の[3])

【現在までで出来ていること】
以下のようにCSVをListViewに表示するところまではできています。(目的の[1],[2])
イメージ説明

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Reflection; using System.Globalization; using System.IO; namespace Excel_convert { public partial class Form1 : Form { public myconvertor myapp = new myconvertor(); public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void button1_Click(object sender, EventArgs e) { openFileDialog1.ShowDialog(); if (System.IO.File.Exists(openFileDialog1.FileName)) { myapp.Caliculate(openFileDialog1.FileName); myapp.mydata.filuplv(myapp.SaleDatas_output, "", listView1); } } } public class filedumprecov { public List<ListViewItem> LV<t>(List<t> mylist) { List<ListViewItem> myitems; ListViewItem myitem; myitems = new List<ListViewItem>(); PropertyInfo[] properties = typeof(t).GetProperties(); int k = 0; foreach (t exp in mylist) { string[] tempstring = new string[properties.Count()]; bool isred = false; int i = 0; foreach (PropertyInfo prop in properties) { tempstring[i] = Convert.ToString(prop.GetValue(exp)); if (prop.PropertyType == typeof(Int32)) { int mynumber = Convert.ToInt32(prop.GetValue(exp)); if (mynumber < 0) { isred = true; } } i++; } myitem = new ListViewItem(tempstring); if (isred) { myitem.ForeColor = Color.Red; } k++; myitems.Add(myitem); } return myitems; } public void filuplv<t>(List<t> mylist, string myheader, ListView myLV) { string[] columns = myheader.Split(','); PropertyInfo[] properties = typeof(t).GetProperties(); if (columns.Count() < 2) { columns = new string[properties.Count()]; for (int i = 0; i < properties.Length; i++) { columns[i] = properties[i].Name; } } myLV.Clear(); myLV.View = View.Details; myLV.GridLines = true; myLV.FullRowSelect = true; for (int i = 0; i < properties.Length; i++) myLV.Columns.Add(columns[i]); int k = 0; foreach (ListViewItem myitem in LV(mylist)) { myLV.Items.Add(myitem); k++; } SetListViewColumnSizes(myLV, -2); } public void SetListViewColumnSizes(ListView lvw, int width) { foreach (ColumnHeader col in lvw.Columns) col.Width = width; } public List<t> LoadList<t>(t listItemin, string filename) where t : new() { PropertyInfo[] properties = listItemin.GetType().GetProperties(); List<t> mylist = new List<t>(); Type mytype = listItemin.GetType(); t listitem; listitem = new t(); string whole_file = System.IO.File.ReadAllText(filename, System.Text.Encoding.GetEncoding("shift_jis")); whole_file = whole_file.Replace('\n', '\r'); string[] lines = whole_file.Split(new char[] { '\r' }, StringSplitOptions.RemoveEmptyEntries); int num_rows = lines.Length; int num_cols = properties.Count(); string[,] values = new string[num_rows, num_cols]; for (int r = 1; r < num_rows; r++) { string[] line_r = lines[r].Split(','); for (int c = 0; c < num_cols; c++) { properties[c].SetValue(listitem, Convert.ChangeType(line_r[c], properties[c].PropertyType, null)); } mylist.Add(listitem); listitem = new t(); } return mylist; } } public class SaleData { public string tenpo { get; set; } public int code { get; set; } public int rate { get; set; } public int quantity { get; set; } } public class myconvertor { public filedumprecov mydata = new filedumprecov(); public List<SaleData> SaleDatas_input; public SaleData SaleData_input = new SaleData(); public List<SaleData> SaleDatas_output; public SaleData SaleData_output = new SaleData(); public SaleData SaleDataView(SaleData input_SD) { SaleData my_output = new SaleData(); my_output.tenpo = input_SD.tenpo; my_output.code = input_SD.code; my_output.rate = input_SD.rate; my_output.quantity = input_SD.quantity; return my_output; } public void Caliculate(string my_file) { SaleDatas_input = mydata.LoadList(SaleData_output, my_file); SaleDatas_output = new List<SaleData>(); foreach(SaleData inpt in SaleDatas_input) { /*******************************************問題だと思われる個所 (はじめ)******************************************************/ if(SaleDatas_output.Exists(inpt.tenpo == SaleData_output.tenpo && inpt.code == SaleData_output.code && inpt.rate == SaleData_output.rate)) { //inpt.quantity += SaleData_output.quantity; //SaleDatas_output.Add(SaleDataView(inpt)); } else { SaleDatas_output.Add(SaleDataView(inpt)); } /*****************************************問題だと思われる個所 (終わり)********************************************************/ } } } }

お手数をおかけしてしまい申し訳ございませんが、どなたかお力添えの程頂けないでしょうか。

大変恐縮ですが、よろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

GroupByとSelectでできます
順番までやる場合はOrderByとThenByも必要になります
一応確認済みのソースも張っておきますが、できればご自身でググって色々試しながら身に着けてください

C#

1 // 元データ 2 var saleDatas = new List<SaleData>(); 3 4 //データ追加は省略 5 6 // 出力用データ 7 var SaleDatas = 8 // グループ化:quantity以外がキー 9 saleDatas.GroupBy(x => new { tenpo = x.tenpo, code = x.code, rate = x.rate }) 10 // quantityのみ合計でそれ以外はキー項目 11 .Select(x => new SaleData { tenpo = x.Key.tenpo, code = x.Key.code, rate = x.Key.rate, quantity = x.Sum(y => y.quantity) }) 12 // 商品コード、店舗名、割引率の順番にソート 13 .OrderBy(x=>x.code) 14 .ThenBy(x => x.tenpo) 15 .ThenBy(x => x.rate);

投稿2018/07/29 14:49

編集2018/07/29 14:53
len_souko

総合スコア1363

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

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

0

ざっとかいてみました。

C#

1 2public void Caliculate(List<SaleData> list) 3{ 4 for(int i=0;i<list.Count;i++){ 5 for(int k=list.Count-1;k>i;k--){ 6 if( list[i].tenpo == list[k].tenpo && 7 list[i].code == list[k].code && 8 list[i].rate == list[k].rate 9 ){ 10 // 合算処理 11 list[i].quantity += list[k].quantity; 12 list.RemoveAt(k); // 処理済みを削除 13 } 14 } 15 } 16} 17

動かしてませんが、考え方はわかるでしょうか。

投稿2018/07/29 12:53

編集2018/07/29 14:17
y_waiwai

総合スコア88040

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問