5

リスト オブジェクト (別名 Excel テーブル) を使用する Excel アプリケーションのパフォーマンスに問題があります。バグの可能性があると思いますが、グーグルで検索しても、それに関する参照は見つかりませんでした。私はすでに自分のアプリケーションの回避策を開発しましたが、私が興味を持っているのは、なぜこれが起こるのかについて誰かが洞察できるかどうかです.

注: Windows Vista で Excel 2007 を使用しています。セットアップは次のとおりです。 リスト オブジェクトにデータを保持するスプレッドシートがあり、コマンド ボタンから起動できる VBA コードがあります。このコードは、ワークシートの任意の数のセルに対して複数の編集を行う可能性があるため、編集前に Excel の計算モードを [手動] に設定します。

私が遭遇した問題は、現在アクティブなセルがリスト オブジェクト内にある場合、計算モードを手動に設定してもまったく効果がないように見えることです。そのため、ユーザーがたまたま重い計算ブックを同じインスタンスで開いている場合、VBA コードの実行速度は非常に遅くなります。これがアクティブなセルによって引き起こされていることを発見するために、実際にはアプリケーションを分解する必要がありました。そして、このシナリオの単純なバージョンで新しいワークブックを作成して、アプリケーションに何らかの破損がないことを確認しました。

私はこれを使って多くのテストケースを行ってきました.以下は私が見つけた結果です:

  1. 一般的には計算に関係しているように見えますが、手動と自動で計算モードを切り替えると、まだ時間差があります...

    • 手動 = 7.64 秒
    • 自動 = 9.39 秒

    手動モードは、自動よりも 20% 未満高速です。しかし、問題は手動モードでも計算が開始されるように思われることを考えると、それらは多かれ少なかれ同じになると予想していました。

  2. アクティブ セルがリスト オブジェクト上にない場合と比較すると、結果は大きく異なります...

    • 手動 = 0.14 秒
    • 自動 = 3.23 秒

    現在、手動実行は 50 倍高速であり、自動実行では計算に 3.2 秒以上かかることはありませんでした! したがって、最初のテストでは、手動モードでは計算が 2 回実行され、自動モードではほぼ 3 回計算が実行されたように見えます。

  3. このテストをもう一度繰り返します。今度はどのセルにも計算式がないインスタンスで、突然それほど悪くないように見えます。

    • アクティブ セルが List オブジェクトで、Calc が手動 = 0.17 秒
    • アクティブ セルが List オブジェクトで、Calc が自動 = 0.20 秒
    • アクティブ セルが空で、Calc が手動 = 0.14 秒
    • アクティブなセルは空で、計算は自動 = 0.18 秒

    まだ遅くはありますが、現在は 10 ~ 20% に過ぎず、目立たなくなりました。しかし、これは、問題が何らかの方法で計算に関連している必要があることを示しています。それ以外の場合は、最初のテストと同じくらい時間がかかったはずです。

これらのテストを作成して自分で確認したい場合は、次のようにセットアップします。

  • リスト オブジェクトが追加された新しいワークブック (データにリンクする必要はありません)
  • 計算にしばらく時間がかかる数式を追加します(「= 1 * 1」を30,000回繰り返しました)
  • 簡単な VBA コードを記述します。(i) セルの単純な編集を数百回ループし、(ii) かかった時間を記録します。
  • 次に、リストオブジェクトと空のセルの間でアクティブセルを変更しながらコードを実行します

Excel がこのように動作する理由を誰かが説明できるかどうか、また、それがバグなのか、それとも実際に実際に使用されている List Objects に関する機能なのかを聞いてみたいと思います。

ありがとう、スチュアート

4

2 に答える 2

2

これは、あなたが見つけた「バグ」とは関係ありません。これは非常に興味深く興味深いものです。

計算の遅延を回避する優れた方法があることを共有したいだけです。これで素晴らしい結果が得られ、今では常に使用しています。

簡単に言えば、Excel は「VBA の世界」と「表計算の世界」の間でデータをコピーするのに長い時間がかかります。

すべての「読み取り」を一度に実行し、処理してから、すべての「書き込み」を一度に実行すると、驚くべきパフォーマンスが得られます。これは、ここに記載されているようにバリアント配列を使用して行われます。

http://msdn.microsoft.com/en-us/library/ff726673.aspx#xlFasterVBA

1 回の操作で大きなデータ ブロックを読み書きする

実行に 5 分かかっていた一部のコードをリファクタリングし、1.5 分に短縮することができました。リファクタリングには 10 分かかりました。非常に複雑なコードだったので、これは驚くべきことです。

于 2012-02-04T18:27:09.153 に答える
1

テーブルのパフォーマンス (および一般的なパフォーマンス) について:

これは古い質問であることは知っていますが、これを文書化したいと思います。

古いバージョンの Excel と 2007 以降のバージョンの間で変更された点の 1 つは、Excel が PasteSpecial 操作のターゲット シートをアクティブにするようになったことです。ScreenUpdating をオフにして計算を手動にすることで、これをオーバーライドすることはできません。このようなアクティブ化により、シートが表示され、制御不能なちらつきが発生します。

私の元の VBA コードは、Excel 2000 を実行している古いシングル プロセッサの XP ボックスで非常に高速に実行されました。最新のマシンで Excel 2013 に変更すると、コードの実行速度が非常に遅くなりました。パフォーマンスを低下させる 3 つの領域は、あるシートから別のシートへの PasteSpecial、シートをアクティブにする必要があるその他のコード (ズーム レベル、高度なフィルター、シート レベルの範囲名など)、およびシートの保護/保護解除の自動化です。

PasteSpecial はコピーしたデータを「クレンジング」するのに役立ったので、これは残念です (.Copy をターゲットに直接使用すると、時折エラーがスローされます)。

そのため、コードを見直して、PasteSpecial ではなく、必要なデータ型 (たとえば、Value、Value2、Text、および Formula の中から) の適切なプロパティへの直接代入を使用していることを確認する必要があります。

例 .Range("MYRANGE").Value = .Cells(5, 7).Value2

また、コード全体で Select と Activate を使用しないように細心の注意を払う必要があります。

上で参照したように、最後の点に関する Excel フォーラムで見つかる多くのコメントは、アクティブ化を使用する必要は「決して」ないという声明を出していますが、これは明らかに真実ではありません。特定のメソッドまたはオブジェクトの使用によってアクティブ化が自動的に強制されるケースを理解すると、コーディングにも役立ちます。残念ながら、これに関するドキュメントの方法はあまり見られません。

アップデート:

条件付き書式に関しては、多数の条件付き書式付きセルに遭遇したときの Excel の遅さについて、さまざまなフォーラムで多くの苦情が寄せられています。多くのテーブル形式オプションがあるため、これは Excel テーブルに影響を与えるのではないかと思いました。これをテストするために、現在使用している大きなワークブックを使用しました。これは現在、同じスタイルの Excel テーブルを持つ複数のワークシートとしてフォーマットされています。

テーブルを従来の範囲に変換した後、コードの実行速度に違いは見られませんでした。これは、独自のセル配列を条件付きで書式設定するよりも、Excel テーブル形式を使用する方がはるかに優れていることを示しているように思われます。

于 2014-10-07T00:12:48.983 に答える