2013-02-10 78 views
2

假設我有一個UDF將在工作表中使用100,000次以上。在函數中,有沒有一種方法可以讓它知道在批處理中要調用多少次?基本上我想要做的是讓每個功能都創建待辦事項列表。我想要做的事情如下:VBA UDF能夠「知道」將運行哪些其他函數嗎?

IF remaining functions to be executed after this one = 0 then ... 

有沒有辦法做到這一點?

背景:

我想要將與剛剛給出的參數(日期,時間,節點類型)的用戶執行SQL查詢一個UDF。如果你願意在每次運行該函數時真正執行SQL查詢,那麼這很容易實現。我知道這很容易,因爲我這樣做,而且速度很慢。我的新想法是首先讓函數查看它正在查找的數據是否存在於全局緩存變量中,以及是否不將它添加到全局變量「job-list」中。

我想要做的是當最後一個函數被調用,然後通過作業列表並執行最少數量的SQL查詢並填充全局緩存變量。一旦緩存變量已滿,它將執行表刷新以使所有其他函數再次被調用,因爲在隨後的調用中他們將在緩存中找到他們需要的數據。

+0

聽起來這個控件應該不在函數之外。如果功能應該知道這將是一個糟糕的設計。這些信息在批處理中如何提供? – Bulat 2013-02-10 17:18:32

+0

我很確定UDF無法訪問那種信息。 – 2013-02-10 17:42:33

+0

@Bulat,按批處理我的意思是,像用戶在一堆單元格中粘貼相同函數時那樣運行的函數隊列。看起來像查爾斯建議的應用程序事件可能會做的伎倆,只是不知道如何實現它爲我的目的。我會玩弄它,看看我學到了什麼。 – 2013-02-10 22:41:02

回答

2

首先:
VBA UDF性能對UDF的編碼方式極爲敏感: 看到我的系列文章中關於編寫高效的VBA的UDF:

http://fastexcel.wordpress.com/2011/06/13/writing-efficient-vba-udfs-part-3-avoiding-the-vbe-refresh-bug/

http://fastexcel.wordpress.com/2011/05/25/writing-efficient-vba-udfs-part-1/

你應該還可以考慮使用Array UDF來返回多個結果:
http://fastexcel.wordpress.com/2011/06/20/writing-efiicient-vba-udfs-part5-udf-array-formulas-go-faster/

其次:
第12後在這個系列給出了採用AfterCalculate事件和緩存 http://fastexcel.wordpress.com/2012/12/05/writing-efficient-udfs-part-12-getting-used-range-fast-using-application-events-and-a-cache/
基本上你需要的做法,是由UDF到,如果不及時或可檢查緩存&然後添加一個請求隊列。
然後使用計算後事件來處理隊列,如果需要觸發另一個重新計算。

0

從Excel電子表格執行100,000個SQL查詢似乎是一個糟糕的設計。在這些之上創建一個緩存機制似乎會增加問題的複雜性,使其變得比它可能需要的更復雜。在某些情況下這可能是合適的,但我會考慮其他設計方法。

最明顯的是從Excel電子表格中取數據並將其加載到數據庫中的表中。然後使用數據庫在所有行上執行,即一次。最後一步是將結果讀回Excel。

我發現從Excel獲取大量行到數據庫中的最佳方式是將Excel文件保存爲csv並批量插入它們。

此方法可能無法解決您的問題。但是,一般來說,數據庫中運行的基於集合的方法會更好。

至於cach'ing機制,如果你不得不走下去的路線。我可以想象一個具有以下僞代碼的函數:

Check if input values are in cache. 
If so, read values from cache. 
Else do complex processing. 
Load values in cache. 

這個邏輯可以在函數中進行。正如@Bulat所說,儘管在函數中添加一個額外的緩存層可能會更好。

+0

我這樣做的方法需要100,000個SQL查詢才能看出它的表現有多糟,並且如預期那樣緩慢,令人無法接受。你的僞代碼是我的需求最明顯的解決方案,但問題是「複雜處理」部分,它是我的問題的核心。我的函數將執行三件事之一,從緩存中檢索數據(簡單),創建/追加到作業列表(簡單),或從作業列表創建緩存(可執行),但難度部分是使緩存期間創建緩存最後的func電話。 (即,如果用戶在10k單元中粘貼func,它應該只創建一次緩存) – 2013-02-10 23:08:13

+0

執行「硬件部分」的簡單方法不在函數本身中,而是在AfterCalculate事件中 – 2013-02-11 08:25:45

相關問題