- PR -

クリップボードオブジェクトについて

投稿者投稿内容
mio
ぬし
会議室デビュー日: 2005/08/25
投稿数: 734
お住まい・勤務地: 神奈川県
投稿日時: 2006-05-25 18:01
VBAでやってたことですが。
二次元配列に値を格納して、Rangeへ貼り付けではできませんかね。
kaki@
会議室デビュー日: 2006/05/25
投稿数: 15
投稿日時: 2006-05-25 18:33
皆様、ご返答ありがとうございます。

確かにRange指定を行い、一気に貼り付けを行っていたのですが、
行単位でセル塗りつぶしを行わなければならない為、
行単位で貼り付ける経由となっています。
ちなみに、出力するデータはソート順が決まっており、
塗りつぶす対象行は連続しているとは限らない出力構成となっています。

また、想定されるデータ数が多いシートで2000〜3000レコードあり、
実測としては10分を超えるレスポンス結果でした。

その為、クリップボードオブジェクトを利用し、
レスポンス向上を図ったという経由です(実際、約2,3分で処理が行われました)。

じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-05-25 18:47
引用:

kaki@さんの書き込み (2006-05-25 18:33) より:

確かにRange指定を行い、一気に貼り付けを行っていたのですが、
行単位でセル塗りつぶしを行わなければならない為、
行単位で貼り付ける経由となっています。


塗りつぶしは、貼り付けるだけではできないですよね...
結局、貼り付けた後に塗りつぶすんですよね。
これなら、クリップボードでなくても、Range で埋め込むのと同じ手間ですよね。
(行単位に貼り付けるより、Range で一括で埋め込んだ方が絶対早いでしょうし)

引用:

また、想定されるデータ数が多いシートで2000〜3000レコードあり、
実測としては10分を超えるレスポンス結果でした。
その為、クリップボードオブジェクトを利用し、
レスポンス向上を図ったという経由です(実際、約2,3分で処理が行われました)。


その為、クリップボード経由を選択されたんですか?
最初の方のレスで私が、

引用:

Range に対して配列でデータを設定できるかと思いますが...


と書きましたが、この方法で試したところほぼ一瞬でセルの埋め込み自体は終了します。
(3000 行 + 14 列 で試しました)

ただし、'塗りつぶし' は別途時間がかかることになります。
でも、塗りつぶしの手間に関しては、クリップボード経由でも同じですね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2006-05-25 19:09
引用:
しかし、実際の処理実行中に、Ctrl+Cなどの
コピー処理を実行すると、格納された値が上書きされてしまい
結果が正しく出力出来ない状態です。

逆にコピーしていたはずのデータをプログラムが上書きしてしまうことにもなります。
皆さんおっしゃっているようにクリップボードは使用すべきではないでしょう。

引用:
実測としては10分を超えるレスポンス結果でした。

どういうコードを書いているのか提示がないので定かではないですが、
プログラムの書き直しで改善できるように思います。
「VB.net独自のExcel操作オブジェクト」が何なのかもわかりませんし。

Excelファイルさえ作ってしまえば。
ADO経由で行う方法もあります。
MSのHow-Toには似たような例が結構あります。
塗りつぶすのは別途になりますが。。。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-05-25 19:17
引用:

べるさんの書き込み (2006-05-25 19:09) より:

Excelファイルさえ作ってしまえば。
ADO経由で行う方法もあります。


あ、その方法がありましたね。
思いっきり失念しておりました。(;_ _)

でも、一応貼っておきますw (範囲指定がハードコーディングなので置き換えてください)

コード:

    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim oDataTable   As System.Data.DataTable
        Dim stStrings    As String(,)

        Try
            oDataTable = GetDataTable()
            stStrings = GetDataArray(oDataTable)
        Finally
            If Not oDataTable Is Nothing Then
                oDataTable.Dispose()
            End If
        End Try

        Dim xlApplication As Excel.Application

        Try
            xlApplication = New Excel.Application()
            'xlApplication.Visible = True
            Dim xlWorkbooks As Excel.Workbooks

            Try
                xlWorkbooks = xlApplication.Workbooks
                Dim xlWorkbook As Excel.Workbook

                Try
                    xlWorkbook = xlWorkbooks.Add()
                    Dim xlWorksheets As Excel.Sheets

                    Try
                        xlWorksheets = xlWorkbook.Worksheets
                        Dim xlWorksheet As Excel.Worksheet

                        Try
                            xlWorksheet = DirectCast(xlWorksheets(1), Excel.Worksheet)
                            Dim xlCells As Excel.Range

                            Try
                                xlCells = xlWorksheet.Cells
                                Dim xlRange As Excel.Range

                                Try
                                    xlRange = xlCells.Range("A1:Z3000")
                                    xlRange.Value2 = stStrings
                                Finally
                                    If Not xlRange Is Nothing Then
                                        System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange)
                                    End If
                                End Try
                            Finally
                                If Not xlCells Is Nothing Then
                                    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlCells)
                                End If
                            End Try
                        Finally
                            If Not xlWorksheet Is Nothing Then
                                System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorksheet)
                            End If
                        End Try
                    Finally
                        If Not xlWorksheets Is Nothing Then
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorksheets)
                        End If
                    End Try

                    xlApplication.DisplayAlerts = False
                    xlWorkbook.SaveAs("C:\MosaMosaAA.xls")
                Finally
                    If Not xlWorkbook Is Nothing Then
                        Try
                            xlWorkbook.Close()
                        Finally
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkbook)
                        End Try
                    End If
                End Try
            Finally
                If Not xlWorkbooks Is Nothing Then
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkbooks)
                End If
            End Try
        Finally
            If Not xlApplication Is Nothing Then
                Try
                    xlApplication.Quit()
                Finally
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApplication)
                End Try
            End If
        End Try
    End Sub

    Private Shared Function GetDataArray(ByVal oDataTable As System.Data.DataTable) As String(,)
        Dim iRowCount     As Integer   = oDataTable.Rows.Count
        Dim iColumnsCount As Integer   = oDataTable.Columns.Count
        Dim stReturns     As String(,) = New String(iRowCount - 1, iColumnsCount - 1) {}

        For iRow As Integer = 0 To oDataTable.Rows.Count - 1
            Dim oDataRow As System.Data.DataRow = oDataTable.Rows(iRow)

            For iColumn As Integer = 0 To iColumnsCount - 1
                stReturns(iRow, iColumn) = oDataRow(iColumn).ToString()
            Next
        Next

        Return stReturns
    End Function

    Private Shared Function GetDataTable() As System.Data.DataTable
        Dim oConnection As System.Data.SqlClient.SqlConnection

        Try
            oConnection = New System.Data.SqlClient.SqlConnection(...)
            Dim oDataAdapter As System.Data.SqlClient.SqlDataAdapter

            Try                
                oDataAdapter = New System.Data.SqlClient.SqlDataAdapter("SELECT * FROM Orders", oConnection)
                Dim oDataTable As New System.Data.DataTable("Orders")
                oDataAdapter.Fill(oDataTable)

                Return oDataTable
            Finally
                If Not oDataAdapter Is Nothing Then
                    oDataAdapter.Dispose()
                End If
            End Try
        Finally
            If Not oConnection Is Nothing Then
                oConnection.Dispose()
            End If
        End Try 
    End Function


_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
きくちゃん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 854
お住まい・勤務地: 都内某所
投稿日時: 2006-05-25 19:55
梶さんに 5,000 点。

引用:

サードパーティの製品を使用するという選択もあるかと。。。


「Excel Creator .NET」とか。安いし。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-05-25 20:06
テンポラリに CSV 吐いて、読み込んだ後に消してもいいのでは?
# って、戻すか

エクセルのバージョンが XP 以降なら、DataSet を XML に吐き出して、エクセルに読み込ませるというのもありかも。
# って、外部ファイルにこだわるか
ちゃっぴ
ぬし
会議室デビュー日: 2004/12/10
投稿数: 873
投稿日時: 2006-05-26 00:12
Excel というものは、1つづつ処理するととてつもなく時間がかかってしまうものです。
なんで、できるだけまとめてやることに越したこと無い。

Cell への出力は、2次元配列使ってまとめて行う。

引用:
ユーザー要望として、一定期間内にレコードの変更があれば、
そのレコード行に対し、行単位でセル塗りつぶしを行って欲しいという仕様となっております。



その後、どっか作業列に連番を書き込む。
んで、更新日時で sort すれば、塗りつぶす cell がきれいにまとまるので
まとめて塗りつぶし。

最後に作業列で sort して、はい出来上がり。
ものによりますけど、こちらのほうが早い場合が多いです。

スキルアップ/キャリアアップ(JOB@IT)