VBA – 获取数组中第n个最大值的索引

我想查找数组中第n个最大值的索引。 我可以做以下事情,但是当两个值相等时会遇到麻烦。

fltArr(0)=31 fltArr(1)=15 fltArr(2)=31 fltArr(3)=52 For i = 0 To UBound(fltArr) If fltArr(i) = Application.WorksheetFunction.Large(fltArr, n) Then result = i End If Next 

n = 1 —> 3
n = 2 —> 2(但我希望这是0)
n = 3 —> 2
n = 4 —> 1

使用第二个数组来快速获得所需的数据,而不必为每个n值循环访问每个元素

 Sub test() Dim fltArr(0 To 3) Dim X Dim n As Long Dim lngPos As Long fltArr(0) = 31 fltArr(1) = 15 fltArr(2) = 31 fltArr(3) = 52 X = fltArr For n = 1 To 4 lngPos = Application.WorksheetFunction.Match(Application.Large(X, n), X, 0) - 1 Debug.Print lngPos X(lngPos) = Application.Max(X) Next End Sub 

编辑:

 Public Sub RunLarge() Dim n%, i%, result%, count% Dim fltArr(3) As Integer Dim iLarge As Integer fltArr(0) = 31: fltArr(1) = 15: fltArr(2) = 31: fltArr(3) = 52 n = 1 Debug.Print " n", "iLarge", "result" While n <= 4 count% = n - 1 iLarge = Application.WorksheetFunction.Large(fltArr, n) For i = 0 To UBound(fltArr) If fltArr(i) = iLarge Then result = i count% = count% - 1 If count% <= 0 Then Exit For End If Next Debug.Print n, iLarge, result n = n + 1 Wend End Sub 

结果:

  n iLarge result 1 52 3 2 31 0 3 31 2 4 15 1 

这有点“脏”,但看到你在Excel中…

 ' Create a sheet with codename wsTemp... For i = 0 To UBound(fltArr) wsTemp.cells(i,1) = i wsTemp.cells(i,2) = fltArr(i) Next with wsTemp .range(.cells(1,1),.cells(i,2)).sort(wsTemp.cells(1,2),xlDescending) end with Result = wsTemp.cells(n,1) 

如果你想控制“我应该select两个相等的两个哪一个”这个东西,那么你也可以把这个sorting扩展为“按值sorting然后按索引sorting”。

也许这个:

 Public Sub RunLarge() Dim fltArr() As Variant, X As Long fltArr = Array(31, 15, 31, 52) 'Create the array For X = 1 To 4 'Loop the number of large values you want to index For i = LBound(fltArr) To UBound(fltArr) 'Loop the array If fltArr(i) = Application.WorksheetFunction.Large(fltArr, 1) Then 'Find first instance of largest value result = i fltArr(i) = -9999 'Change the value in the array to -9999 Exit For End If Next Debug.Print result Next End Sub 

当它发现大数的第一个实例时,它用-9999代替它,所以在下一次扫描时它将select它的下一个实例。

这里是查找集合中第n个最大项目的代码。 所有你需要做的就是写一个函数,它会返回索引。

 Sub testColl() Dim tempColl As Collection Set tempColl = New Collection tempColl.Add 57 tempColl.Add 10 tempColl.Add 15 tempColl.Add 100 tempColl.Add 8 Debug.Print largestNumber(tempColl, 2) 'prints 57 End Sub 

而function本身,最简单的我可以拿出来。

 Function largestNumber(inputColl As Collection, indexMax As Long) Dim element As Variant Dim result As Double result = 0 Dim i As Long Dim previousMax As Double For i = 1 To indexMax For Each element In inputColl If i > 1 And element > result And element < previousMax Then result = element ElseIf i = 1 And element > result Then result = element End If Next previousMax = result result = 0 Next largestNumber = previousMax End Function