我有一个复杂的场景,我试图用Excel公式编写而不进入宏。
情况是我被提供了一个日期范围,称为范围A.即10/1/2011 - 2011年5月4日
我有一个包含3列的查找表;从日期,到日期,费率。该表包含大约50行,每行代表一个独特的3个月期间(年度季度)和相应的费率。
我需要能够获取范围A,找出每个季度中的天数,并将这些天数乘以四分之一的价格。
在示例10/1/2011 - 5/4/2011中,我应该以81 * 2011_Q1_rate + 5 * 2011_Q2_rate结束。
这对于几个for循环和VLOOKUP来说很简单,但我需要避免使用宏。有没有人有任何其他建议?
谢谢,
斯科特。
答案 0 :(得分:1)
我打算把这个分成几部分因为最后的等式变得很长。
我们必须做两件事,首先拉开你的日期范围。我的范围在单元格F16
中进行测试。这是使用=MATCH(DATEVALUE(LEFT(F16,FIND(" - ",F16))),A1:A12,1)
和=MATCH(DATEVALUE(RIGHT(F16,LEN(F16)-2-FIND(" - ",F16))),A1:A12,1)
完成的,其中A1
到C12
是您的From Date
到Rate
数组。这两个匹配语句将为我们提供您的范围所属的第一季度和最后一个季度的行。使用这些行号,我们使用address()
创建引用,例如=ADDRESS(MATCH(DATEVALUE(LEFT(F16,FIND(" - ",F16))),A1:A12,1),2)&":"&ADDRESS(MATCH(DATEVALUE(RIGHT(F16,LEN(F16)-2-FIND(" - ",F16))),A1:A12,1),2)
。上一个公式将在我的测试用例中吐出$B$1:$B$9
。
第二部分是找到总数。我们将使用sumproduct()
。这是简单的sumproduct()
公式:=SUMPRODUCT((B1:B7-A1:A7+1),C1:C7)
。该范围现在只是静态测试。这将需要季度末减去以数组格式开头的季度,并为每个季度添加1。这是因为1/31/13 - 1/1/13 = 30 days
当我们希望它为31天时。然后将该数组乘以每个月的费率。
现在,当我们将它们拼凑在一起时,我们将使用第一个范围,使用indirect()
,并将动态范围替换为简单的sumproduct()
公式,然后使用=SUMPRODUCT((INDIRECT(ADDRESS(MATCH(DATEVALUE(LEFT(F16,FIND(" - ",F16))),A1:A12,1),2)&":"&ADDRESS(MATCH(DATEVALUE(RIGHT(F16,LEN(F16)-2-FIND(" - ",F16))),A1:A12,1),2))-INDIRECT(ADDRESS(MATCH(DATEVALUE(LEFT(F16,FIND(" - ",F16))),A1:A12,1),1)&":"&ADDRESS(MATCH(DATEVALUE(RIGHT(F16,LEN(F16)-2-FIND(" - ",F16))),A1:A12,1),1))+1),INDIRECT(ADDRESS(MATCH(DATEVALUE(LEFT(F16,FIND(" - ",F16))),A1:A12,1),3)&":"&ADDRESS(MATCH(DATEVALUE(RIGHT(F16,LEN(F16)-2-FIND(" - ",F16))),A1:A12,1),3)))
完成。
现在该公式没有考虑到部分月份。我们用=((DATEVALUE(LEFT(F16,FIND(" - ",F16)))-INDIRECT(ADDRESS(MATCH(DATEVALUE(LEFT(F16,FIND(" - ",F16))),A1:A12,1),1)))*INDIRECT(ADDRESS(MATCH(DATEVALUE(LEFT(F16,FIND(" - ",F16))),A1:A12,1),3)))
和=((INDIRECT(ADDRESS(MATCH(DATEVALUE(RIGHT(F16,LEN(F16)-2-FIND(" - ",F16))),A1:A12,1),2))-DATEVALUE(RIGHT(F16,LEN(F16)-2-FIND(" - ",F16))))*INDIRECT(ADDRESS(MATCH(DATEVALUE(RIGHT(F16,LEN(F16)-2-FIND(" - ",F16))),A1:A12,1),3)))
来减去部分月份(从我们之前的等式中窃取),我们就完成了。
最后的等式:
=SUMPRODUCT((INDIRECT(ADDRESS(MATCH(DATEVALUE(LEFT(F16,FIND(" - ",F16))),A1:A12,1),2)&":"&ADDRESS(MATCH(DATEVALUE(RIGHT(F16,LEN(F16)-2-FIND(" - ",F16))),A1:A12,1),2))-INDIRECT(ADDRESS(MATCH(DATEVALUE(LEFT(F16,FIND(" - ",F16))),A1:A12,1),1)&":"&ADDRESS(MATCH(DATEVALUE(RIGHT(F16,LEN(F16)-2-FIND(" - ",F16))),A1:A12,1),1))+1),INDIRECT(ADDRESS(MATCH(DATEVALUE(LEFT(F16,FIND(" - ",F16))),A1:A12,1),3)&":"&ADDRESS(MATCH(DATEVALUE(RIGHT(F16,LEN(F16)-2-FIND(" - ",F16))),A1:A12,1),3)))-((DATEVALUE(LEFT(F16,FIND(" - ",F16)))-INDIRECT(ADDRESS(MATCH(DATEVALUE(LEFT(F16,FIND(" - ",F16))),A1:A12,1),1)))*INDIRECT(ADDRESS(MATCH(DATEVALUE(LEFT(F16,FIND(" - ",F16))),A1:A12,1),3)))-((INDIRECT(ADDRESS(MATCH(DATEVALUE(RIGHT(F16,LEN(F16)-2-FIND(" - ",F16))),A1:A12,1),2))-DATEVALUE(RIGHT(F16,LEN(F16)-2-FIND(" - ",F16))))*INDIRECT(ADDRESS(MATCH(DATEVALUE(RIGHT(F16,LEN(F16)-2-FIND(" - ",F16))),A1:A12,1),3)))
如果将数据范围拆分为两个单独的单元格,则会使方程更小,并且由于错误的可能性更小,因此更有可能正常工作。