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

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

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

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

C#

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

Q&A

解決済

2回答

10482閲覧

2つのCSVファイルから差異を抽出する方法

hiro24

総合スコア12

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

C#

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

0グッド

0クリップ

投稿2018/07/01 11:41

編集2018/07/02 11:31

お忙しいところ失礼いたします。

プログラミング初学者です。

諸事情によりプログラミングを行う必要があり、学習を進めておりました。
そこで、書籍やネットで検索してもどうしても解決できなかったため投稿させていただきました。

【目的】
・2つのCSVファイルから差異を抽出する

【何をつくっているか】
『仮注文票の帳簿』という全顧客からの仮注文データと、各顧客から送られてくる『最終注文票』というデータがあります。
そして、各顧客から送られてくる『最終注文票』に対して『仮注文票の帳簿』を照合し差異があるものを抽出しその結果を各顧客別にcsv出力するWindows Formアプリを作成したいと考えています。

具体例は、【詳細】を参照の程お願いいたします。

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

【詳細】
[1]『仮注文票の帳簿』、『最終注文票』(csv形式)の二つのデータを用意する。
<仮注文票の帳簿>(temporary_order.csv)
取引先 商品名 商品コード 受注数量 割引率
あいうえお A 1111 10000 8
あいうえお B 2222 20000 3
あいうえお A 1111 10000 5
あいうえお C 3333 30000 2
あいうえお A 1111 5000 8
かきくけこ A 1111 6000 3
かきくけこ B 2222 4000 2
かきくけこ C 3333 7000 1
かきくけこ A 1111 2000 2
さしすせそ B 2222 3000 2



<取引先からの最終注文票>(aiueo_final_order.csv)
例)あいうえおの場合
取引先 商品名 商品コード 受注数量 割引率
あいうえお A 1111 15000 8
あいうえお B 2222 20000 3
あいうえお A 1111 10000 5
あいうえお C 3333 60000 2
あいうえお D 4444 10000 6

[2]二つの票を突き合わせてせて帳簿に対して最終注文票で差異があるものだけ抽出する。

※抽出補足条件※
『仮注文票の帳簿』の
取引先 商品名 商品コード 受注数量 割引率
あいうえお A 1111 10000 8
あいうえお A 1111 5000 8

『取引先からの最終注文票』
取引先 商品名 商品コード 受注数量 割引率
あいうえお A 1111 15000 8

これらは、『受注数量』の合計と『割引率』が一致しているため差異無としたいです。

[3][2]で抽出したものの項目に総額を追加してcsv出力をする。

したがって、上記から帳簿に対して最終注文票の差異のみを出力するため理想的な結果は以下のようにしたいと考えています。
※その際には、下記のように別のcsvファイルの『商品価格一覧表』を参照し総額も追加できるようにしたいと考えています。
※総額=『商品価格一覧表』の価格×受注数量

<最終的な出力>(aiueo_final_order_difference.csv)
取引先 商品名 商品コード 受注数量 割引率 総額
あいうえお C 3333 60000 2 18000000
あいうえお D 4444 10000 6 4000000

※商品価格一覧表※(price_list.csv)
商品名 商品コード 価格
A 1111 100
B 2222 200
C 3333 300
D 4444 400
E 5555 500


このように当初予定にないものや予定から変更されるものをListViewでリストアップし、その結果をCSVに出力することが目的となっています。
※ListViewを行いたい理由は、inputとoutputが正常にできているか目視でも確認できるようにしたいためです。

イメージ説明

以下に自分が考えられるだけのコードを記載させていただきます。

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; namespace Call_in_test { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void button1_Click(object sender, EventArgs e) //仮注文帳簿 Load Dataボタン { listView1.View = View.Details; listView1.Items.Clear(); listView1.Columns.Clear(); /*****仮注文帳簿をロードするためのメソッドが必要******/ } private void button3_Click(object sender, EventArgs e) //最終注文 Load Dataボタン { listView2.View = View.Details; listView2.Items.Clear(); listView2.Columns.Clear(); /*****最終注文をロードするためのメソッドが必要******/ } private void button2_Click(object sender, EventArgs e) //差異抽出ボタン { listView3.View = View.Details; listView3.Items.Clear(); listView3.Columns.Clear(); /*****差異を抽出するためのメソッドが必要******/ } } public class load_temporary_order { public string client_name { get; set; } public string product_name { get; set; } public int code { get; set; } public int quantity { get; set; } public decimal Discount_rate { get; set; } } public class load_final_order { public string client_name { get; set; } public string product_name { get; set; } public int code { get; set; } public int quantity { get; set; } public decimal Discount_rate { get; set; } } public class final_order_difference { public string client_name { get; set; } public string product_name { get; set; } public int code { get; set; } public int quantity { get; set; } public decimal Discount_rate { get; set; } public decimal total_amount { get; set; } } public class Price_List { public string product_name { get; set; } public int code { get; set; } public decimal price { get; set; } } public class Filepath { public string path1 = @"temporary_order.csv"; public string path2 = @"aiueo_final_order.csv"; public string path3 = @"aiueo_final_order_difference.csv"; } public class Load_File_temporary_and_final_order { static List<T> LoadFile(string filepath) { List<T> loads = new List<T>(); string[] lines = File.ReadAllLines(filepath); foreach (string line in lines) { string[] items = line.Split(','); T lists = new T { client_name = items[0], product_name = items[1], code = items[2], quantity = items[3], Discount_rate = items[4] }; loads.Add(lists) } return loads; } } public class Difference_Extraction { /***********************差異抽出などのメソッドを記入する??*****************************/ } }

最初はListを使うと考えたのですが、自分の現在の知識ではListで列をエクセルのようにソートをかけて本条件を満たすような動作などわかりませんでした。

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

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

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2018/07/01 12:54

何を作っているかと開発環境ぐらいは書きましょう。コードから Windows Forms アプリではなかろうかと想像していますが、質問の一行目に書いておいてもらえれば余計な想像をしないですむので助かります。OS, .NET, Visual Studio のバージョンによっては、話が違ってくることもあるので、ちゃんと書いてください。
hiro24

2018/07/02 11:32

ご指摘いただいた項目を追加させて頂きました。 本文の方も修正いたしましたが、以下に修正前との差分を記載させて頂きます。 ※差分※ 【何をつくっているか】 ・『仮注文票の帳簿』という全顧客からの仮注文データと、各顧客から送られてくる『最終注文票』というデータがあります。  そして、各顧客から送られてくる『最終注文票』に対して『仮注文票の帳簿』を照合し差異があるものを抽出しその結果を各顧客別にcsv出力するWindows Formアプリを作成したいと考えています。 具体例は、【詳細】を参照の程お願いいたします。 【開発環境】 ・OS:Windows 10 ・Visual Studio 2017 ver.15.7.3 ・.NET ver.4.7.02556 重要項目の記載が漏れてしまい申し訳ございませんでした。 今後気をつけていきます。 お手数をお掛けしてしまい申し訳ございませんでした。
guest

回答2

0

ベストアンサー

差分を求めることについての回答をしますが、その答えをここで得てもまだ辿りつけないのではないかと想定します。

  1. class load_temporary_orderclass load_final_orderclass final_order_differenceを一つにしましょう。これをclass Orderとかえたとします。
  2. OrderクラスにIEquatable<T>を実装しましょう(class Order : IEquatable<Order>ということですね)。具体的には、object.Equals(object)object.GetHashCode()をオーバーライドすることになります。参考になる質問をご提案します。
  3. これら↑ができていれば

csharp

1var preorder = Load_File_temporary_and_final_order.LoadFile<Order>(@"temporary_order.csv"); 2var final = Load_File_temporary_and_final_order.LoadFile<Order>(@"aiueo_final_order.csv"); 3var diff = preorder.Except(final).ToList();

とするだけで差分が取れます。
なお、データの整合性というか包含関係とやりたいこと次第ですが、Exceptはカッコの中にないものを出すので、final.Except(preorder)としたほうがいいかもしれません。具体的には、仮にあったものが最終で消えたり(0になったときにレコードが消えるのか?)、仮にないものが最終でいきなりでてくるのかなど、一口に違いをとるといってもその要件次第でプログラムの作りはおおきく変わってきます。

投稿2018/07/01 13:44

papinianus

総合スコア12705

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

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

hiro24

2018/07/27 23:47

返答が遅くなってしまい申し訳ございませんでした。 ご回答ありがとうございました。 papinianusさんのおっしゃる方法を試してみましたら、無事に差集合(差分抽出)を行うことができました。 特に、string型はint型と違いIEquatable<T>を実装しなければならないことが理解できました。 ありがとうございました。
guest

0

まず、参考情報として、、MSDNより、

ListView.Sort メソッド
ListView.Sorting プロパティ
List<T> クラス

この辺が参考になるでしょうか。
まだ、提示ソース詳細は見ていませんが。

投稿2018/07/01 11:58

pepperleaf

総合スコア6383

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問