minato128 blog

minato128の公開メモ帳です。

SPREAD for .NET 3.0J Windows FormsのCells(row, col).Textが遅すぎる (追記)んなわけなかった

1次元配列をスプレッドにひたすらセットするコードを書いてみたら、20個もない配列でも体感でわかるほど遅かった。
SetClipに書きなおしてみたら、一瞬で反映された。
Web版ではこんなの使ったことない気がするけど、WindowsFormsではこっちを使うのが常識なんだろうか。


実行環境

windowsXP sp3
VS2008/FW3.5
PowerTools SPREAD for .NET 3.0J Windows Forms Ed
FarPoint.Win.SpreadJ
    アセンブリ バージョン: 3.0.2010.2005
    Win32 バージョン: 3.0.2010.2005


Cells(row, col).Textを使ったソース。適当に書いたから雑だけど一応動く。

        spread.SuspendLayout()
        spread.ActiveSheet.RowCount = 0 'クリア
        Dim testData As String() = New String() {"aaa", "vvvvv", "bbbbbb", "ddddd", "ああああ", "いいいい", "うううう", "f", "えええええ", "33333", "eeeeee", DateTime.Now.ToString}

        Dim rowIdx As Integer = -1
        Dim colIdx As Integer = 0
        For Each value In test
            '列番号が0のとき行追加
            If colIdx = 0 Then
                spread.ActiveSheet.RowCount += 1
                rowIdx += 1
            End If
            '値をセット
            spread.ActiveSheet.Cells(rowIdx, colIdx).Text = value & rowIdx.ToString & colIdx.ToString
            'spread.ActiveSheet.SetText()
            '列番号インクリメント
            colIdx += 1
            '列番号が5になったら初期値に戻す
            If colIdx = 5 Then
                colIdx = 0
            End If
        Next
        spread.ResumeLayout()


こっちがSetClipで書きなおしたやつ

        spread.SuspendLayout()
        spread.ActiveSheet.RowCount = 0 'クリア
        Dim testData As String() = New String() {"aaa", "vvvvv", "bbbbbb", "ddddd", "ああああ", "いいいい", "うううう", "f", "えええええ", "33333", "eeeeee", DateTime.Now.ToString}

        Dim data As New System.Text.StringBuilder
        Dim cnt As Integer = 0
        For Each value In testData
            If (cnt + 1) Mod COL_COUNT = 0 Then
                data.Append(value & vbCrLf)
            Else
                data.Append(value & vbTab)
            End If
            cnt += 1
        Next
        Dim rowCnt As Integer = testData.Length / COL_COUNT
        If testData.Length Mod COL_COUNT <> 0 Then
            rowCnt += 1
        End If
        spread.ActiveSheet.RowCount = rowCnt
        spread.ActiveSheet.SetClip(0, 0, spread.ActiveSheet.RowCount, COL_COUNT, data.ToString)
        spread.ResumeLayout()


・2010/12/07追記
データが増えたらSetClipでも異様な重さになった。
Cells(row, col).Textのせいじゃないとわかって調べたら、セルタイプを設定してなかったからだった。
セルタイプを設定したらCells(row, col).TextでもSetClipでも同じくらいのレスポンス。
セルタイプの自動設定処理が重かったっぽい。
今までは全列がテキスト型ってことがなかったら、最初に設定してたんだけど、
今回はそれを端折ったせいでこんなことになってしまった。

結論 セルタイプはちゃんと設定しよう!

Dim celltype As New FarPoint.Win.Spread.CellType.TextCellType
For Each value In test
	spread.ActiveSheet.Cells(rowIdx, colIdx).CellType = celltype
Next