2012-06-21 79 views
4

我正在嘗試改進我繼承的複雜查找過程。查找是通過幾個UDF與一些標準工作表函數結合生成的。但是,問題是當用戶更新源表中的某些數據時,重新計算時間是不可接受的。複雜查找更好的Excel公式

所以,我看了一下,並認爲我可能會寫一個更好的Excel公式唯一的解決方案。那麼,我確實找到了一個解決方案,但Excel對於大型數據集處理太多了,而且當我的VBA針對數據集運行公式時,它崩潰了(可以理解!)。

現在,我可以在VBA中完全實現此功能,但用戶在每次更改後都必須按下某個按鈕或某個按鈕來更新。我想要的是更簡單的方法,如果有的話,使用一些高級的Excel 2007公式。由於我對這些公式不太熟悉,因此我正在尋求幫助!

好的,這是我必須與之合作。

SourceSheet

TID的,結算日期,及月底價格(由1,2,3-識別層段,等)在列象下面

Tid SettleDate 1 2 3 4 5 6 7 8 9 10 ... n 

FormulaSheet

在其他列中,我有以下列

InitLayer LiqdLayer InstrClass Tid SettleDate InitPrice LiqdPrice Position 

我也有在列的層數到整個數據集的權利,就像這樣:

1 2 3 4 5 ... n 

我需要做基於一些邏輯填補這些列中的適當的價格變化在數據集中查找源表單上的價格。

在僞公式,這就是我需要在FormulaSheet

If Layer < InitLayer OR Layer > LiqdLayer Then Return "-" 

ElseIf Layer = InitLayer Then (Layered Price - InitPrice) * Position 

    where Layered Price is obtained by finding the Intersect of the LayerNumber 
    Column and Tid Row in the SourceSheet 

ElseIf Layer = LiqdLayer Then Previous Layered Price * Position 

    where Previous Layered Price is obtained by finding the Intersect of the Previous 
    LayerNumber Column and Tid Row in the SourceSheet 

Else (LayeredPrice - Previous Layered Price) * 6 

    where Layered Price and Previous Layered Price are defined as above 

End If 

我沒有想出這個公式,對小數據集行之有效發生每層列,但其toooooooooo對於大型數據集來說太大而且討厭,或者太大而且討厭的時期!

=IF(OR(CH$3<$AT6,CH$3>$AU6),"-",IF($AT6=CH$3,(HLOOKUP(CH$3,layered_prices,RIGHT(ADDRESS(MATCH(IF($AX6="CUR",$T6 & " " & $G6,$T6),IF($AX6="CUR",layered_curtid,layered_tid),1),1,4),LEN(ADDRESS(MATCH(IF($AX6="CUR",$T6 & " " & $G6,$T6),IF($AX6="CUR",layered_curtid,layered_tid),1),1,4))-1)-1,FALSE)-$AV6)*$C6,IF($AU6=CH$3,($AW6-HLOOKUP(CG$3,layered_prices,RIGHT(ADDRESS(MATCH(IF($AX6="CUR",$T6 & " " & $G6,$T6),IF($AX6="CUR",layered_curtid,layered_tid),1),1,4),LEN(ADDRESS(MATCH(IF($AX6="CUR",$T6 & " " & $G6,$T6),IF($AX6="CUR",layered_curtid,layered_tid),1),1,4))-1)-1,FALSE))*$C6,(HLOOKUP(CH$3,layered_prices,RIGHT(ADDRESS(MATCH(IF($AX6="CUR",$T6 & " " & $G6,$T6),IF($AX6="CUR",layered_curtid,layered_tid),1),1,4),LEN(ADDRESS(MATCH(IF($AX6="CUR",$T6 & " " & $G6,$T6),IF($AX6="CUR",layered_curtid,layered_tid),1),1,4))-1)-1,FALSE)-HLOOKUP(CG$3,layered_prices,RIGHT(ADDRESS(MATCH(IF($AX6="CUR",$T6 & " " & $G6,$T6),IF($AX6="CUR",layered_curtid,layered_tid),1),1,4),LEN(ADDRESS(MATCH(IF($AX6="CUR",$T6 & " " & $G6,$T6),IF($AX6="CUR",layered_curtid,layered_tid),1),1,4))-1)-1,FALSE))*$C6))) 

公式鍵

CH = Layer Number 
CG = Previous Layer Number 
AT = InitLayer 
AU = LiqdLayer 
AX = InstrClass (used to find a separate lookup for Currencies) 
T = Tid 
G = SettleDate (used to find a separate lookup for Currencies) 
AV = InitPrice 
AW = LiqPrice 
C = Position 
layered_prices = named range for the range of prices under the layer columns in SourceSheet 
layered_tid = named range for tid rows in SourceSheet 
layered_curtid = named range for currency tid rows in Source Sheet (just a separte lookup if InstrType = Currency, formula the same 

是否有我所創建的其他公式或公式,讓我得到我在一個更有效的方式比怪物正在尋求的組合?

+0

數據集有多大?如果它超過20萬行,它可能不可能作爲一個公式...... – bendataclear

+0

雖然我們可能在少數情況下達到這個數字,但大多數情況下不會達到這個數字。我一直在探索查找和參考部分,我可能會找到一些東西......如果我找到更好的答案,就會發布。 –

+0

很難想象這個問題,是否可以發佈/鏈接到少量的示例數據/。 – bendataclear

回答

1

我同意Kharoof的評論。你應該把這個公式分成幾列。從我的數量來看,你需要4列。好處有兩方面:1)您的公式縮短得多,因爲您不會一遍又一遍地重複相同的功能; 2)您節省內存,因爲Excel將計算一次而不是多次。

例如,您可以調用四次完全相同的ADDRESS函數。Excel不會「記住」評估公式時的情況,因此每次都會重新計算一次。如果你將它放在它自己的單元格中,那麼Excel將在依賴它的任何單元格之前評估單元格,並將它存儲爲值而不是公式。當其他單元格引用它時,Excel將提供預先評估的結果。


首先,這裏是你最終的公式應該是什麼:(名稱中的括號[]中表明一個輔助列適合在那裏,它就會像CI$3某些單元格引用,但我不知道你在哪裏」 d想把它放在你必須根據你在哪裏添加這些列來更新這些引用)

=IF(OR(CH$3<$AT6,CH$3>$AU6),"-",IF($AT6=CH$3,([LayerNumber]-$AV6)*$C6,IF($AU6=CH$3,($AW6-[PreviousLayerNumber])*$C6,([LayerNumber]-[PreviousLayerNumber])*$C6))) 

這裏是四個幫手列:。

[ADDRESS] = ADDRESS(MATCH(IF($AX6="CUR",$T6 & " " & $G6,$T6),IF($AX6="CUR",layered_curtid,layered_tid),1),1,4) 
[RIGHT] = RIGHT([ADDRESS],LEN([ADDRESS])-1) 
[LayerNumber] = HLOOKUP(CH$3,layered_prices,[RIGHT]-1,FALSE) 
[PreviousLayerNumber] = HLOOKUP(CG$3,layered_prices,[RIGHT]-1,FALSE) 

通過分裂它的公式的每一步都易於跟蹤/調試,並且更快速地處理Excel。如果您想要進行一些定量改進,那麼這五個公式將比您現在使用的單一公式縮短約70%。