更好的Excel复杂查找公式

时间:2012-06-21 15:22:21

标签: excel-2007 excel-formula

我正在尝试改进我继承的复杂查找过程。查找是通过几个UDF与一些标准工作表函数结合生成的。但问题是,当用户更新源表中的某些数据时,重新计算时间是不可接受的。

所以,我看了一眼,并认为我可能能够编写一个更好的Excel公式解决方案。好吧,我确实找到了一个解决方案,但是对于Excel来说处理大型数据集太多了,当我的VBA针对数据集运行公式时它会崩溃(这是可以理解的!)。

现在,我可以在VBA中完全实现这一点,但是用户必须在每次更改后按一个按钮或其他内容进行更新。我想要的是一种更简单的方法,如果有的话,使用一些高级的Excel 2007公式。由于我不熟悉那些公式,我正在寻求帮助!

好的,这是我必须要做的事情。

SourceSheet

Tid's,结算日期和月末价格(由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

我需要做的是通过查看源表上的价格,根据数据集中的某些逻辑在这些列中填写适当的价格变化。

在psuedo-formula中,这是我需要为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

是否有任何其他公式或公式组合可以让我以比我创造的怪物更有效的方式获得我所寻求的东西?

1 个答案:

答案 0 :(得分:1)

我同意Kharoof的评论。您应该将此公式分成几列。根据我的统计,你还需要4列。好处是双重的:1)你的公式变得更短,因为你不会反复重复相同的功能2)你节省了内存,因为Excel会计算一次而不是几次。

例如,您可以四次调用完全相同的ADDRESS函数。 Excel不记得&#34;在评估公式时它是什么,所以每次都重新计算它。如果将其放入其自己的单元格中,则Excel将在依赖于它的任何单元格之前评估单元格,并将其存储为值而不是公式。当其他单元格引用它时,Excel将提供预先评估的结果。

首先,这里是你的最终公式应该是什么:(括号中的名称表示辅助列适合那里。它会像CI$3那样是一些单元格引用但我不是确定您要放置它的位置。您必须根据添加这些列的位置更新这些引用。)

=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%。