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

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

ただいまの
回答率

90.51%

  • C#

    7116questions

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

  • CSV

    635questions

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

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

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 456

hiro24

score 4

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

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

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

【目的】
・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で列をエクセルのようにソートをかけて本条件を満たすような動作などわかりませんでした。

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2018/07/01 21:54

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

    キャンセル

  • hiro24

    2018/07/02 20:32

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

    キャンセル

回答 2

checkベストアンサー

+1

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

  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. これら↑ができていれば
var preorder = Load_File_temporary_and_final_order.LoadFile<Order>(@"temporary_order.csv");
var final = Load_File_temporary_and_final_order.LoadFile<Order>(@"aiueo_final_order.csv");
var diff = preorder.Except(final).ToList();


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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/28 08:47

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

    キャンセル

  • 2018/07/28 08:52 編集

    こんなざっくり説明から作れるってすごいですね。とても努力されたことと尊敬します。

    なお、MSDN(https://msdn.microsoft.com/ja-jp/library/system.string(v=vs.110).aspx)をご覧いただければ分かるかと思いますが、stringはIEquatable<string>を実装しています。

    キャンセル

0

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    7116questions

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

  • CSV

    635questions

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