C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: DataGridViewの2回目が遅いのはなぜ? 【初心者】


(過去ログ 113 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■66759 / inTopicNo.1)  DataGridViewの2回目が遅いのはなぜ? 【初心者】
  
□投稿者/ とんちき (1回)-(2013/05/22(Wed) 20:04:35)

分類:[VB.NET/VB2005 以降] 

環境:VB.NET 2010 OS:WinXP SP3 (32bit)

初めまして、初心者の「とんちき」と申します。
よろしくお願いします。

DataGridViewを使用して1000行の表を作成しているのですが、2回目に実行するとなぜかすごく遅いです。
ちなみに1回目は、一瞬に処理が終了します。
2回目実行時間は55秒もかかってしまいます。

DataGridViewの性質(仕様)なのか,コードの記述が悪いのかわかりません。
ListViewで同じような表をしても1回目と2回目の実行時間には大差はありません。

ソースコードを貼りますので、ご指導、ご指摘またはアイディアを頂ければ幸いです。
よろしくお願いします。

-- 【ソース】 --
Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows フォーム デザイナで生成されたコード "
    ' 〜 省略 〜
#End Region

    Private Sub メインフォーム_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load

        初期表示()

    End Sub
    Private Sub 初期表示()
        With DataGridView1
            .AutoGenerateColumns = False                                  '手動列追加をゆるす
            .AllowUserToOrderColumns = True                               '列の位置をユーザーが変更できるようにする
            .AlternatingRowsDefaultCellStyle.BackColor = Color.PaleGreen  '行の背景色を交合に色分けする
            .AllowUserToAddRows = False                                   'ユーザーが新しい行を追加できないようにする
            .AllowUserToDeleteRows = False                                'ユーザーが行削除をしないようにする
            .MultiSelect = False                                          'セル、行、列が複数選択されないようにする
            .SelectionMode = DataGridViewSelectionMode.FullRowSelect      '行全体が選択されるようにする
            .ReadOnly = True                                              '読込み専用
            .Columns.Add("TENCD", "店舗コード")                           '1列名の追加
            .Columns.Add("HINCD", "")                                   '2列名の追加
            .Columns.Add("HINNM", "商品名")                               '3列名の追加
        End With

        ProgressBar1.Hide()
    End Sub
    Private Sub データ取得ボタン_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim データ件数 As Integer

        label2.Text = ""
        '商品表のデータ部を削除
        If DataGridView1.Rows.Count > 0 Then
            DataGridView1.Columns.RemoveAt(2)
            DataGridView1.Columns.RemoveAt(1)
            DataGridView1.Columns.RemoveAt(0)

            初期表示()
            DataGridView1.Update()
        End If
        データ件数 = 1000
        If データ件数 = 0 Then
            MsgBox("該当するデータがありませんでした", "エラー")
            label2.Text = "【該当データ無】"
        Else
            label1.Text = "データを取得中です" & データ件数.ToString & "件"
            label1.Show()
            label1.Update()
            label2.Update()

            ' MsgBox("データを抽出します")
            With ProgressBar1
                .Show()
                .Minimum = 0
                .Value = 0
                .Maximum = データ件数
                .Update()
            End With

            Dim 行 As Integer

            For 行 = 0 To データ件数 Step 1

                DataGridView1.Rows.Add()
                '商品表.Rows(行).Cells(0).Value = SQLデータ("TENCD")
                DataGridView1.Rows(行).Cells(1).Value = String.Format("{0,7} ", 行)
                '商品表.Rows(行).Cells(2).Value = RTrim(SQLデータ("HINNM"))
                If 行 Mod 100 = 0 Then
                    ProgressBar1.Value = 行
                    label2.Text = String.Format("【現在 {0,7} 件】", 行)
                    label2.Update()
                End If

            Next

            ProgressBar1.Value = データ件数
            '列の自動調整
            label1.Text = "後処理中です しばらくお待ちください"
            label1.Update()
            DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells

            ProgressBar1.Hide()
            label1.Hide()

            label2.Text = String.Format("【該当 {0,7} 件】", 行)
        End If
    End Sub
End Class

引用返信 編集キー/
■66761 / inTopicNo.2)  Re[1]: DataGridViewの2回目が遅いのはなぜ? 【初心者】
□投稿者/ 魔界の仮面弁士 (225回)-(2013/05/22(Wed) 21:06:42)
No66759 (とんちき さん) に返信
> DataGridViewを使用して1000行の表を作成しているのですが、
データバインドを利用しましょう。


> For 行 = 0 To データ件数 Step 1
速度は別として、複数回実行時に、本当に期待する結果になっていますか?

RowCount を修正しているわけでも、.Rows.Clear() しているわけでもないので、
2回目は 1001〜2000行、3回目は2001〜3000行目を追加することになりますが、
現状のコードだと、データは常に先頭 1000行にしか書き込まれていません。


> 2回目に実行するとなぜかすごく遅いです。
今回は、「.AutoSizeColumnsMode = AllCells」が原因でしょう。
もしもデザイン時に AllCells 指定してから実行すれば、1 回目から遅くなるはずです。

同様に、RowHeadersWidthSizeMode も遅くなる要因となります。


> DataGridViewの性質(仕様)なのか,コードの記述が悪いのかわかりません。

(案1)AutoSizeColumnsMode プロパティを AllCells に設定する代わりに、
 AutoResizeColumns(AllCells) メソッドの呼び出しで代用する。

(案2)データを追加している最中は None にしておき、
 データを書き込み終わってから、改めて AllCells に戻す。
引用返信 編集キー/
■66764 / inTopicNo.3)  Re[2]: DataGridViewの2回目が遅いのはなぜ? 【初心者】
□投稿者/ とんちき (2回)-(2013/05/22(Wed) 22:21:40)
No66761 (魔界の仮面弁士 さん) に返信

魔界の仮面弁士さん早速のサポートありがとうございます。

> (案2)データを追加している最中は None にしておき、
>  データを書き込み終わってから、改めて AllCells に戻す。
これで、初回と同じレスポンスの速さで実現出来ました。
ありがとうございます。素敵です!!

> RowCount を修正しているわけでも、.Rows.Clear() しているわけでもないので、
> 2回目は 1001〜2000行、3回目は2001〜3000行目を追加することになりますが、
> 現状のコードだと、データは常に先頭 1000行にしか書き込まれていません。
データ部をクリアしたかったので、先頭から追加したかったのでこれでいいです。


> データバインドを利用しましょう。
オラクルのODP.NETでも使用できるのでしょうか?

引用返信 編集キー/
■66766 / inTopicNo.4)  Re[3]: DataGridViewの2回目が遅いのはなぜ? 【初心者】
□投稿者/ 魔界の仮面弁士 (226回)-(2013/05/22(Wed) 23:02:33)
No66764 (とんちき さん) に返信
>>現状のコードだと、データは常に先頭 1000行にしか書き込まれていません。
> データ部をクリアしたかったので、
クリアするコードはどの部分でしょうか?

> 先頭から追加したかったのでこれでいいです。
Rows.Add は、末尾に行を追加するための命令ですよ。

以前の行を上書きするだけなら、そもそも .Rows.Add する必要は無いはずですし、
先頭に行を追加したいという意味なら、.Rows.Insert です。

DataGridView 操作ということで、このあたりも読んでおくと良いでしょう。
http://mitsu.three-atmarks.com/archives/60


> > データバインドを利用しましょう。
> オラクルのODP.NETでも使用できるのでしょうか?
使用できます。そもそも、DataGridView が Oracle と通信するわけではありませんよね?
(極端な話、「DataGridView1.DataSource = Me.Controls」のようなバインドだってできるわけで)

基本的には、DataSet/DataTable あたりとバインドすることになるとは思いますが、
DataTable 自体は、その元データがどこから取得されたものなのかを管理していません。

tbl.Rows.Add で書き込まれた DataTable であろうと、
DataAdapter 等で書き込まれた DataTable であろうと、
DataSet.ReadXml 等で読み込まれたものであろうと、
それを表示する DataGridView 側にとっては違いは無いということです。
引用返信 編集キー/
■66775 / inTopicNo.5)  Re[4]: DataGridViewの2回目が遅いのはなぜ? 【初心者】
□投稿者/ とんちき (3回)-(2013/05/23(Thu) 13:08:12)
No66766 (魔界の仮面弁士 さん) に返信

魔界の仮面弁士さんありがとうございます。

> >>現状のコードだと、データは常に先頭 1000行にしか書き込まれていません。
>>データ部をクリアしたかったので、
> クリアするコードはどの部分でしょうか?
DataGridView1.Columns.RemoveAt(2)
DataGridView1.Columns.RemoveAt(1)
DataGridView1.Columns.RemoveAt(0)
↑クリアのつもりで書きましたが
正しくは.Rows.Clear() ですね。


>
>>先頭から追加したかったのでこれでいいです。
> Rows.Add は、末尾に行を追加するための命令ですよ。
>
> 以前の行を上書きするだけなら、そもそも .Rows.Add する必要は無いはずですし、
> 先頭に行を追加したいという意味なら、.Rows.Insert です。
>
> DataGridView 操作ということで、このあたりも読んでおくと良いでしょう。
> http://mitsu.three-atmarks.com/archives/60
読んでみました。やってみます。

>>> データバインドを利用しましょう。
>>オラクルのODP.NETでも使用できるのでしょうか?
> 使用できます。そもそも、DataGridView が Oracle と通信するわけではありませんよね?
> (極端な話、「DataGridView1.DataSource = Me.Controls」のようなバインドだってできるわけで)
ハイ、やってみました。
簡単で高速に処理できました。
これは、画期的ですね! 最高です!!

とても助かりました。ありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -