tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルVBAでデータ貼り付け速度がちょう非常に遅い
記事No5793
投稿日: 2007/07/06(Fri) 18:21
投稿者通販の鬼
(環境)
CUP(2.4G)
メモリ(512M)
VB.net2005
OS:WinXP

お世話になります。通販の鬼と申します。
今回VBよりexcelObjを作成し、エクセルにデータを書き込むという処理を行っておりますが、データの貼り付けで時間がかかりすぎて困っております。
速度を高速にするやり方など御座いましたらご回答いただければと思います。
よろしくお願いします。
下記に、サンプルコードを添付します。
サンプルでは4分以上かかります。

’====================================
'エクセルオブジェクト作成
(省略)・・・

’データ作成
Dim aryExcelTransfer(40000, 30) As Object

for i=0 to 40000
    aryExcelTransfer(i,0)="aaa"
    aryExcelTransfer(i,1)="aaa"
    aryExcelTransfer(i,2)="aaa"
    aryExcelTransfer(i,3)="aaa"
next

xlsWorkSheet.Range("A1").Resize(40000,30)=aryExcelTransfer

[ツリー表示へ]
タイトルRe: VBAでデータ貼り付け速度がちょう非常に遅い
記事No5795
投稿日: 2007/07/06(Fri) 19:17
投稿者魔界の仮面弁士
>> VBAでデータ貼り付け速度がちょう非常に遅い
あれま。
VB.NET からの操作より、VBA からの操作の方が、(極端に)遅かった、ということですか。
普通は、VBA の方が高速のはずなんですけれどね…。

> CUP(2.4G)
おっと。(^^;

> Dim aryExcelTransfer(40000, 30) As Object
40001個×31個ですか? これはちょっと大きすぎるかも。
一度に貼り付ける件数を減らすために、データを分割して、
それを繰り返し貼るようにしてみてください。

> xlsWorkSheet.Range("A1").Resize(40000,30)=aryExcelTransfer
VSTO での操作なら、.Range("A1").Offset(…) でも良いですが、
そうでないなら、変数にうけて、逐次 COM の解放処理が必要です。
http://hanatyan.sakura.ne.jp/dotnet/Excel08.htm

それと、配列の代入先は、Value プロパティに対して行った方が良いかも。

[ツリー表示へ]
タイトルRe^2: VBAでデータ貼り付け速度がちょう非常に遅い
記事No5797
投稿日: 2007/07/06(Fri) 19:24
投稿者通販の鬼
本末転倒していました。
CPU2.4Gです。

それとVBAと書きましたがVB.net2005上でエクセルを操作しています。
よろしくお願いします。

[ツリー表示へ]
タイトルRe: VBAでデータ貼り付け速度がちょう非常に遅い
記事No5796
投稿日: 2007/07/06(Fri) 19:20
投稿者通販の鬼
ちなみに、新規BookにCopy()したあと、この処理を行っております。

Copy()前だと
xlsWorkSheet.Range("A1").Resize(40000,30)=aryExcelTransfer
は早くて

Copy()後だと
xlsWorkSheet.Range("A1").Resize(40000,30)=aryExcelTransfer
は遅くなります。

不可思議な現象です。無知な私です。

[ツリー表示へ]
タイトルRe^2: VBAでデータ貼り付け速度がちょう非常に遅い
記事No5799
投稿日: 2007/07/06(Fri) 20:20
投稿者花ちゃん
キチンと動作する(プロセスが残らない)実際に使っている遅いコードを投稿して見て下さい。
指定されたサンプル? では、数秒しかかかりません。

[ツリー表示へ]
タイトルRe^3: VBAでデータ貼り付け速度がちょう非常に遅い
記事No5800
投稿日: 2007/07/06(Fri) 20:42
投稿者通販の鬼
> キチンと動作する(プロセスが残らない)実際に使っている遅いコードを投稿して見て下さい。
> 指定されたサンプル? では、数秒しかかかりません。

○花ちゃん さんへ

返信ありがとうございます!!
確かにそうなのですが、使用するデータによっても速度はかわるようです。
シンプルなデータですと即処理が終わりますが複雑なデータを貼り付けると遅いようです。

+αで、罫線やフォントが指定された1行を
範囲選択でPasteSpecial(1:40000)
等で、範囲貼り付けしても恐ろしいほどのお時間がかかります。
これは必ず再現すると思いますので再現していただけますか?
動作としてはこれと同じような内容でメモリの使用量がある一定量を超えると
何らかの箇所がボトルネックとなり遅くなっている。という動作だと思われます。

○魔界の仮面弁士 さんへ

ご返信ありがとうございます。
ガベージコレクション等は確実にロードされるよう考慮した設計になっているので
それについては問題ありません。ご返信ありがとう御座います。

[ツリー表示へ]
タイトルRe^4: VBAでデータ貼り付け速度がちょう非常に遅い
記事No5801
投稿日: 2007/07/06(Fri) 20:53
投稿者通販の鬼
○花ちゃん さんへ

ソースサンプルを添付します。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    'Excel出力ボタン:クリック時
    '----------------------------------

    ''プロジェクト→参照の追加→COM→「Microsoft Excel 10.0 ObjectLibrary」(Ver10はOfficeXPです)を参照して下さい。

    '==================  起動時の処理  ===================  
    Dim l_xlsApp As New Excel.Application
    Dim l_xlsBooks As Excel.Workbooks = l_xlsApp.Workbooks
    '既存のファイルを開く場合
    Dim l_xlsFilePath As String = "\原データリスト雛形.xls"
    Dim l_xlsBook As Excel.Workbook = l_xlsBooks.Open(My.Computer.FileSystem.CurrentDirectory & l_xlsFilePath)    'ファイルオープン
    Dim l_xlsSheets As Excel.Sheets = l_xlsBook.Worksheets
    Dim l_xlsSheet As Excel.Worksheet = l_xlsSheets.Item(1) 'シート1指定

    l_xlsApp.DisplayAlerts = False  'アラート情報の非表示

    'シート名変更
    l_xlsSheet.Name = "テストシート"

    '==================  データの入力処理  ==================  

    '書式設定サンプル
    l_xlsSheet.Range("a1").Font.Color = RGB(255, 0, 0)  'フォントカラー
    l_xlsSheet.Range("a1").Interior.Color = RGB(255, 255, 0)  '背景カラー

    ''''Excel出力速度低下はオブジェクトへのアクセス数に比例します。なるべく配列等でいっぺんに送るべし

    'Excel転送用配列へデータ代入
    'Dim l_aryExcelTransfer(39, 2) As Object
    Dim l_aryExcelTransfer(40000, 25) As Object

    'For r As Integer = 0 To 39 'テストデータ作成
    For r As Integer = 0 To 40000 'テストデータ作成
        l_aryExcelTransfer(r, 0) = "ORD" & Format(r + 1, "0000")
        l_aryExcelTransfer(r, 1) = Rnd() * 1000
        l_aryExcelTransfer(r, 2) = l_aryExcelTransfer(r, 1) * 0.07

        l_aryExcelTransfer(r, 3) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 4) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 5) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 6) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 7) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 8) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 9) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 10) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 11) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 12) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 13) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 14) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 15) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 16) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 17) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 18) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 19) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 20) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 21) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 22) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 23) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 24) = l_aryExcelTransfer(r, 1) * 0.07
        l_aryExcelTransfer(r, 25) = l_aryExcelTransfer(r, 1) * 0.07

    Next
    '配列をExcelへ転送
    'l_xlsSheet.Cells(7, 5).Resize(40, 3).Value = l_aryExcelTransfer     '起点を指定し範囲内に配列を挿入
    l_xlsSheet.Range("A1").Resize(40000, 26).Value = l_aryExcelTransfer
    
    'l_xlsApp.Visible = True
    'For l_cnt As Integer = 0 To 34000 Step 1000
    'Next

    'l_xlsSheet.Cells(7, 5).Resize(10000, 26).Value = l_aryExcelTransfer     '起点を指定し範囲内に配列を挿入
    'l_xlsSheet.Cells(10007, 5).Resize(1000, 26).Value = l_aryExcelTransfer     '起点を指定し範囲内に配列を挿入
    'l_xlsSheet.Cells(20007, 5).Resize(1000, 26).Value = l_aryExcelTransfer     '起点を指定し範囲内に配列を挿入
    'l_xlsSheet.Cells(30007, 5).Resize(1000, 26).Value = l_aryExcelTransfer     '起点を指定し範囲内に配列を挿入
    'l_xlsSheet.Cells(30007, 5).Resize(3000, 26).Value = l_aryExcelTransfer     '起点を指定し範囲内に配列を挿入
    'l_xlsSheet.Cells(7, 5).Resize(34001, 26).Value = l_aryExcelTransfer     '起点を指定し範囲内に配列を挿入
    'l_objSheet.Range("E7").Resize(40, 3).Value = DataArray     '起点を指定し範囲内に配列を挿入

    'l_objSheet.Cells(1, 1).Value = "Excel出力テスト"    'A1セルにデータを挿入する場合

    '==================  データの表示処理  ==================  
    '雛形を新規ブックへコピー
    l_xlsSheet.Copy()

    '雛形閉じる  
    l_xlsBook.Close()

    '表示
    l_xlsApp.Visible = True

    '==================  終了処理  =====================  
    MRComObject(l_xlsSheet)            'xlSheet の解放
    MRComObject(l_xlsSheets)           'xlSheets の解放
    'l_xlsBook.Close(False)             'xlBook を閉じる
    MRComObject(l_xlsBook)             'xlBook の解放
    MRComObject(l_xlsBooks)            'xlBooks の解放
    'l_xlsApp.Quit()                    'Excelを閉じる
    MRComObject(l_xlsApp)              'xlApp を解放

End Sub

[ツリー表示へ]
タイトルRe^5: VBAでデータ貼り付け速度がちょう非常に遅い
記事No5802
投稿日: 2007/07/06(Fri) 20:54
投稿者通販の鬼
お世話になります。
追記事項として、下記の箇所が重いです。


    '==================  データの表示処理  ==================  
    '雛形を新規ブックへコピー
    l_xlsSheet.Copy()

よろしくお願いします。

[ツリー表示へ]
タイトルRe^6: VBAでデータ貼り付け速度がちょう非常に遅い
記事No5803
投稿日: 2007/07/06(Fri) 21:22
投稿者花ちゃん
> 追記事項として、下記の箇所が重いです。
それ以前の問題かと。
No.5795 で回答されていたはずですが?
このコードではプロセスが終了しないままになっているので。

>下記に、サンプルコードを添付します。
>サンプルでは4分以上かかります。

だったのでは、内容がコロコロ変わると....。

[ツリー表示へ]