2012-06-21 57 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%。