我在 Excel 中使用这个数组公式时遇到了一些问题。
我有两个范围(数据列),对应于整个数组的行号和列号,该数组包含要应用于不相关函数的乘数。我想找到从列/行引用中找到的最小乘数。
假设列号范围为
A1:A10
,行号范围为 A15:A24
,乘数数组为 K4:M23
。执行此操作的一种低效方法是:
=MIN(INDEX(K4:M23,A15,A1),INDEX(K4:M23,A16,A2),etc...)
...但这会变得很麻烦,特别是在检查错误等时。更不用说如果这个函数被调用几千次(它恰好是这样),那么内存的使用量。
所以我想到了数组函数:
{=MIN(INDEX(K4:M23,A15:A24,A1:A10))}
...但这仅返回数组中的第一个元素。如果此函数作为多单元格数组公式输入,它会正确处理它,但似乎按原样,
MIN
应用于每个奇异元素,并且该函数返回原始数组大小,而不是最小值的单个值.
有什么办法解决这个问题吗?
如果我正确理解你的问题,下面的VBA函数应该产生你想要的结果。
该函数接受三个参数:对数组范围的引用;对行号范围的引用;以及对列号范围的引用。 它返回与行号和列号对应的单元格中的最小值。
Function ArrayMin(MatrixRange As Range, RowRange As Range, ColRange As Range) As Double
Application.Volatile
Dim colNum As Long
Dim rowNum As Long
Dim cellVal As Double
Dim MinVal As Double
Dim i As Long
MinVal = 1000000 'a number >= than max array range value
For i = 0 To ColRange.Rows.Count - 1
rowNum = RowRange(1, 1).Offset(i, 0).Value
colNum = ColRange(1, 1).Offset(i, 0).Value
cellVal = MatrixRange(rowNum, colNum).Value
If cellVal < MinVal Then
MinVal = cellVal
End If
Next
ArrayMin = MinVal
End Function
可以通过在工作簿中插入新的标准 VBA 模块并粘贴代码来以标准方式安装。
我从来无法像数组一样操作索引的输出。 可以做的就是过滤原始乘数表。 为了避免辅助单元,这可以在定义的名称内完成
rowFilter: = SIGN( MATCH(rowIndex, selectedRows, 0))
columnFilter: = SIGN( MATCH(columnIndex, selectedColumns, 0 ) )
filteredMultipliers:= multipliers * rowFilter * columnFilter
工作表公式
= AGGREGATE( 15, 6, filteredMultipliers, 1 )
将识别最小值,忽略有意的#N/A错误。
感谢 pbart 的一点启发,这就是我最终正确执行的方法......(在我提出问题一年半后。)
我基本上创建了一个与
K4:M23
具有相同尺寸的参考数组,该数组在列和行数组的交叉点处有一个,并将它们相乘。
=AGGREGATE(15,6,(IF(MMULT(TRANSPOSE(IFERROR(IF(A15:A24=COLUMN(1:20),1,0),0)),IFERROR(IF(A1:A10={1,2,3},1,0),0))=0,#N/A,1)*K4:M23),1)
不确定这是最有效的,但在不使用
Match
或 Index
的情况下进行数组查找还不错。
老问题,但是下面的数组公式(CSE)怎么样: =MIN(INDEX(K4:M23,INDEX(A15:A24,N(IF(1,ROW(N1:N10)))),INDEX(A1:A10,N(IF(1,ROW(N1:N10))) ))))