2012-01-14 82 views
3

我在使用列表對象(AKA Excel表格)的Excel應用程序中遇到問題。我懷疑這可能是一個錯誤,但儘管我谷歌搜索,我找不到任何它的參考。我已經爲我的應用程序開發了一種解決方法,但是我感興趣的是如果任何人都可以提供有關發生這種情況的信息。Excel列表 - 對象VBA性能錯誤?

注意:我在Windows Vista上使用Excel 2007。設置如下:我有一個電子表格,它將數據保存在List對象中,VBA代碼可以通過命令按鈕啓動;此代碼可能會對工作表上的任意數量的單元格進行編輯,因此Excel的計算模式在進行任何編輯之前都設置爲手動。

我遇到的問題是,如果當前活動的單元格在列表對象內,那麼將計算模式設置爲手動似乎沒有任何效果。因此,如果用戶碰巧在同一個實例中打開繁重的計算工作簿,那麼VBA代碼運行速度非常緩慢。我實際上不得不拉開我的應用程序以發現這是由活動單元格引起的;我用這個場景的簡單版本創建了一個新的工作手冊,以確認我的應用程序沒有出現某種腐敗。

我已經做了一些測試案例這個問題,以下是從我所發現的結果:

  1. 雖然看上去一般與計算,仍然有時間差時,計算模式手動和自動之間切換...

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

    手動模式比自動模式快不到20%。但我的期望是他們會差不多,因爲即使在手動模式下,這個問題似乎也是開始計算的。

  2. 與此相比,當活動單元格是不是在一個列表對象,結果有很大的不同......

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

    現在,手動運行速度提高了50倍,自動運行表明計算時間不應超過3.2秒!因此,現在第一個測試看起來像是在手動模式下可能會運行兩次計算,而在自動模式下則會運行近三次。

  3. 再次重複這一試驗,這一次是在與任何單元格不計算公式的情況下,突然它似乎並不那麼糟糕,

    • 活動單元格列出對象& Calc是手動= 0.17秒
    • 活動單元格列出對象& Calc是自動= 0.20秒
    • 活動單元格是空& Calc是手動= 0.14秒
    • 活動單元格是空& Calc是Automatic = 0。18秒

    它仍然較慢,但現在只有10-20%,使它不明顯。但是這確實表明問題必須以某種方式與計算相關,否則它應該與第一次測試一樣長。

如果有人想創建這些測試,看看自己的設置如下:

  • 新工作簿添加了一個列表對象(沒有鏈接到任何數據)
  • 添加一些公式,將需要一段時間來計算(我剛做'= 1 * 1'重複30,000次)
  • 寫一個快速的VBA代碼,通過細胞的簡單編輯(I)環數百倍,(ii)和記錄需要的時間
  • 然後只需運行該代碼同時改變列表對象和空單元格之間的活動單元格

我會非常感興趣的是,如果有人能夠解釋爲什麼Excel會以這種方式運行,並且如果有錯誤或者是否有一些與List對象有關的功能,這些功能實際上有一些真正的用途?

感謝, 斯圖爾特

+0

我無法複製您的結果。在手動計算模式下編輯列表對象中的數據時,不會重新計算易失公式。如果Screenupdating處於打開狀態,那麼反覆編輯列表對象中的列表對象並且列表對象中的活動單元格速度與預期的一樣緩慢,但屏幕更新關閉時,我沒有得到明顯區別。你能發佈一個鏈接到你的示例文件嗎? – 2012-01-15 18:31:59

+0

@CharlesWilliams感謝您的回覆。也許我沒有完全解釋我的設置,[鏈接到這裏下載](http://dl.dropbox.com/u/3010466/Excel%20List-Object%20VBA%20Preformance%20Bug.xlsm) 我已經screenupdating轉向在我的所有測試中關閉。我並沒有完全知道什麼時候excel會運行計算,但是我今天在worksheet_calculation事件上添加了一個計數器,看看它是如何表現的 - 當計算模式爲手動計數時爲0,並且形式爲真。所以我可能是我在咆哮錯誤的樹? – Skytunnel 2012-01-15 19:28:27

+2

感謝您的鏈接。爲了獲得放緩,你似乎需要3個條件:1.活動單元格必須在Listobject(Table)中。 2.正在更新的單元必須與Listobject在同一工作表上。 3.所用時間是公式數的函數(但公式不會被重新計算)。目前我無法想象爲什麼會發生這種情況。 – 2012-01-16 16:06:14

回答

1

這不是相對於「蟲」你發現了,這是相當有趣和耐人尋味。

我想和大家分享,有避免延誤計算一個偉大的方式。我在這方面有着出色的成績,現在我一直都在使用它。

簡而言之,Excel中需要較長的時間複製數據來回「VBA世界」和「電子表格世界」之間。

如果你做所有的「讀」一次,過程,然後做一次所有的「寫」,你就會得到驚人的表現。

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

在部分標註:這是使用變長數組作爲記錄在這裏完成讀寫大型數據塊在單次操作

我能夠重構一些代碼,我有花費5分鐘運行並將其降至1.5分鐘。重構花費了我10分鐘,這是驚人的,因爲它是相當複雜的代碼。

0

關於表的性能(和性能,在一般情況):

我知道這是一個老問題,但我想獲得該記錄。舊版本的Excel和2007年後的版本之間改變

的一件事是Excel中現在激活任何PasteSpecial的操作的靶紙。您無法通過關閉ScreenUpdating並手動進行計算來覆蓋它。這種激活會使工作表可見,並導致無法控制的閃爍。

我原來的VBA代碼跑得很快上運行Excel 2000中的一個現代化的機器上的變化到Excel 2013在代碼執行的可怕的緩慢令人驚歎的一個古老的,單處理器XP框。殺死性能的三個方面是PasteSpecial從一個表單到另一個表單,以及需要激活表單的其他任何代碼(縮放級別,高級過濾器,表單級範圍名稱等)以及自動執行表單保護/取消保護。

這太糟糕了,因爲PasteSpecial幫助「清理」了您複製的數據(將.Copy直接用於目標會導致偶然的錯誤)。

因此,您需要檢查您的代碼,並確保您正在使用直接分配給您需要的數據類型(例如Value,Value2,Text和Formula中的數據類型)的正確屬性,而不是PasteSpecial。

例如.Range(「MYRANGE」)。Value = .Cells(5,7).Value2

您還需要謹慎地抵制在整個代碼中使用Select和Activate。

如上所述,您在Excel論壇中發現的關於最後一點的許多評論將會使您「從不」需要使用Activation的聲明,這顯然是不真實的,因爲Excel中的一些內容僅適用於或需要激活牀單。瞭解激活由特定方法或使用對象自動強制的情況也有助於編碼。不幸的是,你不會看到這方面的文檔。

更新:

關於條件格式,你會遇到大量的有條件格式的單元時,發現有關的Excel緩慢各種論壇的抱怨。我懷疑這會影響Excel表格,因爲他們有很多表格格式選項。爲了測試這一點,我拿了一個我們使用的大型工作簿,目前這些工作簿被格式化爲幾個工作表,並且他們的Excel表格樣式相同。

將表格轉換爲常規範圍之後,我注意到代碼執行速度沒有差別。這似乎表明,Excel表格格式的使用遠遠優於條件格式化自己的單元格陣列。