DOBON.NET DOBON.NETプログラミング掲示板過去ログ

datagridviewの内容を保存

環境/言語:[Windows XP / VS C# 2010 Express]
分類:[.NET]

よろしくお願いします。開発環境はWindows XP VS C# 2010 Expressです。
以下にソースコードを書きますが、現在datagridviewの内容をcsvファイルに保存するプログラムを組んでいるのですが、思い通りになりません。現状ではdatagridviewの内容をそのまま保存となっているのですが、自分の思う完成形は列ヘッダのテキストを1行目に、datagridviewの内容は2行目以降になるcsvファイルにすることです。分かりにくいかも知れませんが、以下のソースコードに足りない部分やおかしい部分がありましたらご教授していただきたく思います。

private void write_button_Click(object sender, EventArgs e)
        {
            saveFileDialog1.InitialDirectory = @"..\..\";
            saveFileDialog1.Filter = "csv files (*.csv)|*.csv| C# files (*.cs) | *.cs | Rescource files ( *.resx) | *resx | Solution File (*.sln) |*.sln| All files(*.*)|*.*";
            saveFileDialog1.FilterIndex = 1;
            saveFileDialog1.RestoreDirectory = true;
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                this.SaveFile(saveFileDialog1.FileName);
            }

        }

        private void SaveFile(string filename)
        {
            System.IO.StreamWriter sw = new System.IO.StreamWriter(filename, false, System.Text.Encoding.GetEncoding(932));
            for (int r = 0; r <= dataGridView1.Rows.Count - 1; r++)
            {
                for (int c = 0; c <= dataGridView1.ColumnCount - 1; c++)
                {
                    string dt = "";
                    if (dataGridView1.Rows[r].Cells[c].Value != null)
                    {
                        dt = dataGridView1.Rows[r].Cells[c].Value.ToString();
                    }
                    if (c < dataGridView1.ColumnCount - 1)
                    {
                        dt = dt + ",";
                    }
                    sw.Write(dt);
                }
                sw.Write("\n");
            }
            sw.Close();
        }
■No27792に返信(としおさんの記事)

dataGridView1.Columns[<index>].HeaderText

でヘッダタイトルが取得出来るので、各行のループ前に
タイトル行を出力する。

データ行数がどのくらいか分かりませんが、細かくファイルへの
書込みはしないで出来るだけ一括で書き込んだ方がいいと思います。
書込みバッファを大きくとってもいいかもしれない。
■No27793に返信(shuさんの記事)
> ■No27792に返信(としおさんの記事)
>
> dataGridView1.Columns[<index>].HeaderText
>
> でヘッダタイトルが取得出来るので、各行のループ前に
> タイトル行を出力する。
>
> データ行数がどのくらいか分かりませんが、細かくファイルへの
> 書込みはしないで出来るだけ一括で書き込んだ方がいいと思います。
> 書込みバッファを大きくとってもいいかもしれない。

早速のお返事ありがとうございます。
shuさんのおっしゃっていることは二つ目のfor文の最初に
> dataGridView1.Columns[<index>].HeaderText
でヘッダテキストを取得し、変数dtに出力ということでしょうか?
また、書き込みバッファを大きくとるというのはどういうことでしょうか?

まだまだ駆け出しなので初歩的なことも分からずすいません。
■No27797に返信(としおさんの記事)
> shuさんのおっしゃっていることは二つ目のfor文の最初に
>>dataGridView1.Columns[<index>].HeaderText
> でヘッダテキストを取得し、変数dtに出力ということでしょうか?

違います。
外側の for は行単位、内側の for は列単位のループなのですから、
既存のループ内に入れてしまっては、ヘッダテキストが
データ件数分出力されてしまいますよね。

データの出力は既にできているのですから、それらのループに入る前に、
ヘッダテキストのみを出力する処理を記載してみてください。
■No27798に返信(魔界の仮面弁士さんの記事)
> ■No27797に返信(としおさんの記事)
>>shuさんのおっしゃっていることは二つ目のfor文の最初に
> >>dataGridView1.Columns[<index>].HeaderText
>>でヘッダテキストを取得し、変数dtに出力ということでしょうか?
>
> 違います。
> 外側の for は行単位、内側の for は列単位のループなのですから、
> 既存のループ内に入れてしまっては、ヘッダテキストが
> データ件数分出力されてしまいますよね。
>
> データの出力は既にできているのですから、それらのループに入る前に、
> ヘッダテキストのみを出力する処理を記載してみてください。

お返事ありがとうございます。
外側のfor文の外に
dt = dataGridView1.Coulmns[0].HeaderText;
.
.
.
dt = dataGridView1.Columns[<index>].Headertext;
のようにするということですか?
■No27797に返信(としおさんの記事)

> また、書き込みバッファを大きくとるというのはどういうことでしょうか?
>
System.IO.StreamWriter sw = new System.IO.StreamWriter(filename, false, System.Text.Encoding.GetEncoding(932));
のEncodingの引数の後にbyte単位のバッファサイズをint値で指定します。

sw = new System.IO.StreamWriter(filename, false, System.Text.Encoding.GetEncoding(932), 512);
なら512byteのバッファが使用されます。
■No27799に返信(としおさんの記事)

> 外側のfor文の外に
> dt = dataGridView1.Coulmns[0].HeaderText;
> .
> .
> .
> dt = dataGridView1.Columns[<index>].Headertext;
> のようにするということですか?
そのような記述になると思いますがここもforループにした
方が良いです。『,』の連結も忘れずに。

後、追加情報ですがDisplayIndexというのがあって表示順だとこれで
並び替えるのが正解ですが、これにこだわるとさらに処理が必要に
なります(データ行の部分も含めて)
■No27801に返信(shuさんの記事)
> ■No27799に返信(としおさんの記事)
> 
>>外側のfor文の外に
>>dt = dataGridView1.Coulmns[0].HeaderText;
>>.
>>.
>>.
>>dt = dataGridView1.Columns[<index>].Headertext;
>>のようにするということですか?
> そのような記述になると思いますがここもforループにした
> 方が良いです。『,』の連結も忘れずに。
> 
> 後、追加情報ですがDisplayIndexというのがあって表示順だとこれで
> 並び替えるのが正解ですが、これにこだわるとさらに処理が必要に
> なります(データ行の部分も含めて)

ありがとうございます。
外側のfor文の前に
for( int n = 0; n< dataGridView1.ColumnCount - 1;n++)
{
      dt = dataGridView1.Columns[n].Header.Text;
      dt = dt + ",";
      sw.Write(dt);
}
sw.Write("\n");

としたらうまくいきました。ありがとうございます。
まだまだ分からないことがたくさんあるので、また質問させていただきます。
ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板