为了实现我们的目标,我们需要创建一系列数组,方便地“混合”,将产生我们必须求和的一系列值。此处以图形方式描述了整个过程:
左侧是源数据和用户输入。源数据(起始数组)假定为 2 个范围,每个范围由连续的单元格(区域)组成。这两个范围的一部分,所有其他数据将通过名称表示/计算。这些是需要的名称:
| Names |
ReferenceToR1C1 |
| Target |
=Sheet1!R4C12 <<<this should return the value to be searched (example: "i03")
|
| MLR_Mtrx_Addr |
=Sheet1!R5C12 <<<this should return a string reporting the address of the multipliers array (example: "B5:D9")
|
| MLD_Mtrx_Addr |
=Sheet1!R6C12 <<<this should return a string reporting the address of the multiplied array (example: "G5:I9")
|
| From |
=Sheet1!R7C12 <<<this should return the starting value from which the formula will sum on (example: 2)
|
| To |
=Sheet1!R8C12 <<<this should return the ending value to which the formula will sum on (example: 11)
|
| Array01 |
=(((ROW(INDIRECT("1:"&MLR_Max_Val)))^1)+(COLUMN(INDIRECT("C1:C"&MLR_Col_Cnt,FALSE))^1-1)*MLR_Max_Val) |
| Array02 |
=((ROW(INDIRECT("1:"&MLR_Max_Val)))^1*(COLUMN(INDIRECT("C1:C"&MLR_Col_Cnt,FALSE))^0)) |
| Array03 |
=Array01/((Array02<=INDIRECT(MLR_Tar_Rel_Row_Addr))) |
| Array04 |
=AGGREGATE(15,6,Array03,From) |
| Array05 |
=AGGREGATE(15,6,Array03,To) |
| Array06 |
=IFERROR((Array03>=Array04)*(Array03<=Array05)*INDIRECT(MLD_Tar_Rel_Row_Addr),0) |
| MLD_Tar_Rel_Row |
=MATCH(Target,OFFSET(INDIRECT(MLD_Mtrx_Addr),0,-1,,1),0) |
| MLD_Tar_Rel_Row_Addr |
=SUBSTITUTE(CELL("address",OFFSET(INDIRECT(MLD_Mtrx_Addr),MLD_Tar_Rel_Row-1,0,1,1))&":"&CELL("address",OFFSET(INDIRECT(MLD_Mtrx_Addr),MLD_Tar_Rel_Row-1,COLUMNS(INDIRECT(MLD_Mtrx_Addr))-1,1,1)),"$","") |
| MLR_Col_Cnt |
=COLUMNS(INDIRECT(MLR_Mtrx_Addr)) |
| MLR_Fin_Val_Cnt |
=SUM(INDIRECT(MLR_Tar_Rel_Row_Addr)) |
| MLR_Max_Val |
=MAX(INDIRECT(MLR_Tar_Rel_Row_Addr)) |
| MLR_Tar_Rel_Row |
=MATCH(Target,OFFSET(INDIRECT(MLR_Mtrx_Addr),0,-1,,1),0) |
| MLR_Tar_Rel_Row_Addr |
=SUBSTITUTE(CELL("address",OFFSET(INDIRECT(MLR_Mtrx_Addr),MLR_Tar_Rel_Row-1,0,1,1))&":"&CELL("address",OFFSET(INDIRECT(MLR_Mtrx_Addr),MLR_Tar_Rel_Row-1,COLUMNS(INDIRECT(MLR_Mtrx_Addr))-1,1,1)),"$","") |
| Note |
| The first five names are still ranged-related. These are the user's input data. The user should modify their ReferenceToR1C1 accordingly to his/her needs as specified by the side notes. |
这段代码应该允许我们快速创建所有上述名称:
Sub SubAddNames()
With ActiveWorkbook.Names
.Add name:="Target", RefersToR1C1:="=Sheet1!R4C12"
.Add name:="MLR_Mtrx_Addr", RefersToR1C1:="=Sheet1!R5C12"
.Add name:="MLD_Mtrx_Addr", RefersToR1C1:="=Sheet1!R6C12"
.Add name:="From", RefersToR1C1:="=Sheet1!R7C12"
.Add name:="To", RefersToR1C1:="=Sheet1!R8C12"
.Add name:="Array01", RefersToR1C1:="=(((ROW(INDIRECT(""1:""&MLR_Max_Val)))^1)+(COLUMN(INDIRECT(""C1:C""&MLR_Col_Cnt,FALSE))^1-1)*MLR_Max_Val)"
.Add name:="Array02", RefersToR1C1:="=((ROW(INDIRECT(""1:""&MLR_Max_Val)))^1*(COLUMN(INDIRECT(""C1:C""&MLR_Col_Cnt,FALSE))^0))"
.Add name:="Array03", RefersToR1C1:="=Array01/((Array02<=INDIRECT(MLR_Tar_Rel_Row_Addr)))"
.Add name:="Array04", RefersToR1C1:="=AGGREGATE(15,6,Array03,From)"
.Add name:="Array05", RefersToR1C1:="=AGGREGATE(15,6,Array03,To)"
.Add name:="Array06", RefersToR1C1:="=IFERROR((Array03>=Array04)*(Array03<=Array05)*INDIRECT(MLD_Tar_Rel_Row_Addr),0)"
.Add name:="MLD_Tar_Rel_Row", RefersToR1C1:="=MATCH(Target,OFFSET(INDIRECT(MLD_Mtrx_Addr),0,-1,,1),0)"
.Add name:="MLD_Tar_Rel_Row_Addr", RefersToR1C1:="=SUBSTITUTE(CELL(""address"",OFFSET(INDIRECT(MLD_Mtrx_Addr),MLD_Tar_Rel_Row-1,0,1,1))&"":""&CELL(""address"",OFFSET(INDIRECT(MLD_Mtrx_Addr),MLD_Tar_Rel_Row-1,COLUMNS(INDIRECT(MLD_Mtrx_Addr))-1,1,1)),""$"","""")"
.Add name:="MLR_Col_Cnt", RefersToR1C1:="=COLUMNS(INDIRECT(MLR_Mtrx_Addr))"
.Add name:="MLR_Fin_Val_Cnt", RefersToR1C1:="=SUM(INDIRECT(MLR_Tar_Rel_Row_Addr))"
.Add name:="MLR_Max_Val", RefersToR1C1:="=MAX(INDIRECT(MLR_Tar_Rel_Row_Addr))"
.Add name:="MLR_Tar_Rel_Row", RefersToR1C1:="=MATCH(Target,OFFSET(INDIRECT(MLR_Mtrx_Addr),0,-1,,1),0)"
.Add name:="MLR_Tar_Rel_Row_Addr", RefersToR1C1:="=SUBSTITUTE(CELL(""address"",OFFSET(INDIRECT(MLR_Mtrx_Addr),MLR_Tar_Rel_Row-1,0,1,1))&"":""&CELL(""address"",OFFSET(INDIRECT(MLR_Mtrx_Addr),MLR_Tar_Rel_Row-1,COLUMNS(INDIRECT(MLR_Mtrx_Addr))-1,1,1)),""$"","""")"
End With
End Sub
正确设置名称后,最终公式将是这个:
=IF(OR(INT(From)<>From,INT(To<>To),To>MLR_Fin_Val_Cnt,From>To),#VALUE!,SUM(IFERROR(Array06,0)))
它只能用作数组公式,因此我们需要复制,选择所需的单元格,粘贴公式,然后按 Ctrl+Shift+Enter。