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

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

ただいまの
回答率

90.84%

  • C#

    6290questions

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

  • Visual Studio

    1621questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

CSVデータへの書き込み結果とデータグリッドビューへの読み込み結果が合わない(空になる)

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 356

P5_USER

score 30

質問

お世話になります。

読み込みボタンクリックイベントで,CSVファイルを開いて内容を読み込んでデータグリッドビューに表示
書き込みボタンクリックで,CSVファイルを開いてデータグリッドビューに内容を書き込む
というだけの行為なのですが,
2回目の読み込みボタンクリックで表示されるデータグリッドビューが空になってます(CSVファイルも空になっていました)。

同じファイルパスを指定しているにもかかわらず,データがなくなってしまうのはどこが悪いのでしょうか。

実現したいこと

実行時,2回目の読み込みボタンクリック(読み込みボタン1回目→書き込みボタン→読み込みボタン2回目)
でCSVの中身が空になってしまう事態を避けたい。

ここが怪しいのかなと思うのですが,対処方法がわからないです。
イメージ説明

該当のデザイナー

[編集]ボタン(Name:button_Collection)をクリックすると
Read_And_ViewFileメソッドを呼び出し,
コレクションルーム(Name:tabPage2)に遷移(表示)します。
イメージ説明
[決定]ボタン(Name:button_Return)をクリックすると
SaveFileメソッドを呼び出し,
選択ルーム(Name:tabPage1)に遷移(表示)します。
イメージ説明

該当のソースコード

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.IO;
using Microsoft.VisualBasic.FileIO;
using CsvHelper;

namespace KMAP
{
    public partial class Form1 : Form
    {
        TabPageManager _tabPageManager = null;


        //ファイルパス作成用変数
        public string userName;
        public string cDrive_To_UserName;
        public string cDrive_To_Desktop;
        public string cDrive_To_Conversion_Folder;
        public string cDrive_To_AirPortList_Folder;
        public string ListName;

        public Form1()
        {
            InitializeComponent();
        }

        public void Form1_Load(object sender, EventArgs e)
        {
            MakePathAndFile();

            //タブページマネージャーを作成する。
            _tabPageManager = new TabPageManager(tabControl1);

            _tabPageManager.ChangeTabPageVisible(0, true);
            _tabPageManager.ChangeTabPageVisible(1, false);
            _tabPageManager.ChangeTabPageVisible(2, false);
        }

        /// <summary>
        /// ファイルパスを作成したり,フォルダを作成したりする。
        /// </summary>
        public void MakePathAndFile()
        {
            //ユーザ名を取得する。
            userName = Environment.UserName;

            //Cドライブからデスクトップまでのディレクトリパスを生成する。
            cDrive_To_UserName = Path.Combine(@"C:\Users", userName);
            cDrive_To_Desktop = Path.Combine(cDrive_To_UserName, @"Desktop\");

            //デスクトップに出現位置変換済フォルダを作成する。
            cDrive_To_Conversion_Folder = Path.Combine(cDrive_To_Desktop + @"出現位置変換済フォルダ");
            DirectoryInfo directoryInfo1;
            directoryInfo1 = Directory.CreateDirectory(cDrive_To_Conversion_Folder);

            //出現位置変換済フォルダに空港情報フォルダ(隠しフォルダ)を作成する。
            cDrive_To_AirPortList_Folder = Path.Combine(cDrive_To_Conversion_Folder + @"\空港情報フォルダ");
            DirectoryInfo directoryInfo2;
            directoryInfo2 = Directory.CreateDirectory(cDrive_To_AirPortList_Folder);
            directoryInfo2.Attributes |= FileAttributes.Hidden;

            //機体モデル出現位置リスト.csvのフルパスを作成する。
            ListName = Path.Combine(cDrive_To_AirPortList_Folder, "機体モデル出現位置リスト" + ".csv");

        }

        /// <summary>
        /// CSVのファイルパスを指定して読み込む
        /// </summary>
        /// <param name="filePath"></param>
        private void Read_And_ViewFile(string filePath)
        {
            // CSVファイルオープン
            using (OpenFileDialog ofd = new OpenFileDialog() { Filter = "csv|*.csv", ValidateNames = true })
            {
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    var sr = new StreamReader(new FileStream(ofd.FileName, FileMode.Open));
                    var csv = new CsvReader(sr);
                    airPortDataClassBindingSource.DataSource = csv.GetRecords<AirPortDataClass>().ToList();
                    sr.Close();
                }
            }
        }

        /// <summary>
        /// CSVのファイルパスを指定して保存する
        /// </summary>
        /// <param name="filePath">CSVのファイルパスを指定します</param>
        private void SaveFile(string filePath)
        {
            using (var sw = new StreamWriter(filePath, false, Encoding.GetEncoding("UTF-8")))
            {
                var writer = new CsvWriter(sw);

                foreach (AirPortDataClass AirPortData in airPortDataClassBindingSource.DataSource as IEnumerable<AirPortDataClass>)
                {
                    writer.WriteHeader(typeof(AirPortDataClass));

                    writer.WriteRecord(AirPortData);
                }
            }
        }

        /// <summary>
        /// KMAPのDATファイルをstringで読み込みます。
        /// </summary>
        /// <param name="text"></param>
        /// <param name="path"></param>
        public void Load_Dat_File(TextBox text, String path)
        {
            StreamReader reader = new StreamReader(path);
            textBox_DAT_File.Text = path;
        }

        //DATファイルを選択する
        private void button_DAT_Choice_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog ret = new OpenFileDialog() { Filter = "dat形式(*.dat)|*.dat|全てのファイル(*.*)|*.*" })
            {
                if (ret.ShowDialog() == DialogResult.Cancel)
                {
                    return;
                }
                Load_Dat_File(textBox_DAT_File, ret.FileName);
            }
        }

        //次のタブページに移動する
        private void button_Next1_Click(object sender, EventArgs e)
        {
            if (this.textBox_DAT_File.Text == "未登録")
            {
                MessageBox.Show("DATファイルを選択してください。", "注意");
                return;
            }
            _tabPageManager.ChangeTabPageVisible(0, false);
            _tabPageManager.ChangeTabPageVisible(1, false);
            _tabPageManager.ChangeTabPageVisible(2, true);
        }

        //コレクションルームに入る
        private void button_Collection_Click(object sender, EventArgs e)
        {

            //CSVファイルを読み込んでデータグリッドビューに表示
            Read_And_ViewFile(ListName);

            _tabPageManager.ChangeTabPageVisible(0, false);
            _tabPageManager.ChangeTabPageVisible(1, true);
            _tabPageManager.ChangeTabPageVisible(2, false);
        }

        //コレクションルームから出る
        private void button_Return_Click(object sender, EventArgs e)
        {
            //CSVファイルを開いてデータグリッドビューのデータを格納
            SaveFile(ListName);

            //メッセージボックス表示
            MessageBox.Show("機体モデル出現位置リスト.csvを更新しました。", "情報");

            //タブ表示を変える
            _tabPageManager.ChangeTabPageVisible(0, true);
            _tabPageManager.ChangeTabPageVisible(1, false);
            _tabPageManager.ChangeTabPageVisible(2, false);
        }

        //最初のタブページに戻る
        private void button_Back_TabPage_Click(object sender, EventArgs e)
        {
            _tabPageManager.ChangeTabPageVisible(0, true);
            _tabPageManager.ChangeTabPageVisible(1, false);
            _tabPageManager.ChangeTabPageVisible(2, false);
        }

        //アプリケーションを終了する
        private void button_End_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}


以下は別クラスで作成

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KMAP
{
    public class AirPortDataClass
    {
        public string ICAO_Code { get; set; }
        public string Name { get; set; }
        public string Latitude { get; set; }
        public string Longitude { get; set; }
        public string Azimuth { get; set; }
    }
}

補足情報(言語/FW/ツール等のバージョンなど)

言語はC#
開発環境はVisualStudio2017
.NET Framework Version 4.7.02556
です

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • Zuishin

    2018/01/13 22:43

    デザイナーとコードがどうつながっているのかわからないのでわかりません。「読み込みボタン」とやらを押すとどうなるのかもわかりません。結局どのメソッドがどの順序で呼ばれるのかの説明を質問に追記してください。

    キャンセル

  • P5_USER

    2018/01/13 23:31

    Zuishinさん 更新しました。該当のデザイナーが追加項目になります。

    キャンセル

回答 2

checkベストアンサー

+1

CsvHelper

When you are done writing the row, don't forget to call NextRecord to flush the data and write the line ending.

WriteHeaderやWriteRecordの後には必ずNextRecordを呼べと書いてあります。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/01/16 15:05

    sh_akiraさん
    ありがとうございます。

    無事,読み込みをすることが出来ました。

    キャンセル

+1

foreach (AirPortDataClass AirPortData in airPortDataClassBindingSource.DataSource as IEnumerable<AirPortDataClass>)
{
  writer.WriteHeader(typeof(AirPortDataClass));

  writer.WriteRecord(AirPortData);
}


ここおかしくないですか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/01/14 10:15

    dojikkoさん
    ありがとうございます。

    指摘の行はwriter.WriteRecord(AirPortData);のことでしょうか。

    キャンセル

  • 2018/01/14 19:23

    WriteHeaderの方です
    これだとループが回るたびにヘッダーを書くことになりませんか?

    キャンセル

  • 2018/01/14 19:51

    writer.WriteHeader(typeof(AirPortDataClass));をforeachの一つ上の行に変更しましたが,
    CSVの書き込みは為されていませんでした。

    しかし,確かに,ご指摘の通りの行動をすると予想されるので,書き込み結果が明らかになってからもう一度確かめようと思っています。

    キャンセル

  • 2018/01/15 00:42

    もうされていると思いますが、private void SaveFile(string filePath)の行にブレイクポイントを設定して、デバック実行してみて正しく値が渡されて実行されているか確認してみてはどうでしょう

    キャンセル

  • 2018/01/15 10:20

    一つ気になるところがありました。
    SaveFileメソッド内のforeachの.DataSourceの中を見てみると,
    4つ枠を構えている配列の1番目だけにデータがありました。

    その時の画像を質問文に追加しました。

    キャンセル

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

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

関連した質問

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

  • C#

    6290questions

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

  • Visual Studio

    1621questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • トップ
  • C#に関する質問
  • CSVデータへの書き込み結果とデータグリッドビューへの読み込み結果が合わない(空になる)