Excel VBA中的匹配函数

Excel VBA中的匹配函数,excel,vba,Excel,Vba,我有一个返回第三个最低值的函数。它跳过空格,但包含0,这正是我想要的。当我在工作表上定期使用公式(或作为数组)时,它会起作用。但同样的函数在VBA中不起作用 Example: =MATCH(SMALL(E3:O3,3),E3:O3,FALSE) in the worksheet does the following {1,2,3,blank,5} returns the value 3 {1,2,3,0,5} returns the value 2 wf.Match(wf.Small(aDiv

我有一个返回第三个最低值的函数。它跳过空格,但包含0,这正是我想要的。当我在工作表上定期使用公式(或作为数组)时,它会起作用。但同样的函数在VBA中不起作用

Example:
=MATCH(SMALL(E3:O3,3),E3:O3,FALSE) in the worksheet does the following
{1,2,3,blank,5} returns the value 3
{1,2,3,0,5} returns the value 2

wf.Match(wf.Small(aDivs, i), aDivs, False) in VBA does the following
{1,2,3,blank,5} returns the value 2
{1,2,3,0,5} returns the value 2
(aDivs is a calculation stored in an array)
它以前工作得很好,但因为现在可以不按顺序填充单元格,所以我需要这部分跳过空格。如何使VBA函数像工作表函数一样工作?任何帮助都将不胜感激。谢谢

代码如下:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim i As Long
Dim vaNums As Variant, vaDenoms As Variant, aDivs() As Double
Dim wf As WorksheetFunction
Dim lSmall As Long
Dim rRow As Range
Dim rStart As Range
Dim iCount As Integer
Const lCols As Long = 10
Const lMarkcnt As Long = 3
Set wf = Application.WorksheetFunction
Set rRow = Target.Cells(1).Offset(0, 1).Resize(1, lCols)
Set rStart = Me.Cells(1, 5)
iCount = wf.CountA(rRow, ">0")
If Not Intersect(Target.Cells(1), Me.Range("D3", Me.Range("D3").End(xlDown))) Is Nothing Then
If iCount > 4 Then
    Set rRow = Target.Cells(1).Offset(0, 1).Resize(1, iCount - 1)
    rStart.Resize(1, lCols).Interior.ColorIndex = xlNone
    rStart.Resize(1, lCols).Font.ColorIndex = xlAutomatic
    vaNums = rRow.Value
    vaDenoms = rStart.Offset(1, 0).Resize(1, lCols).Value
    ReDim aDivs(LBound(vaNums, 2) To UBound(vaNums, 2))
    For i = LBound(vaNums, 2) To UBound(vaNums, 2)
        aDivs(i) = vaNums(1, i) / vaDenoms(1, i) + (i / 10000)
    Next i
    For i = 1 To 3
        lSmall = wf.Match(wf.Small(aDivs, i), aDivs, False)
        rStart.Offset(0, lSmall - 1).Interior.Color = 6299648
        rStart.Offset(0, lSmall - 1).Font.ThemeColor = xlThemeColorDark1
    Next i
Else
    rStart.Resize(1, lCols).Interior.ColorIndex = xlNone
    rStart.Resize(1, lCols).Font.ColorIndex = xlAutomatic
End If
Else
rStart.Resize(1, lCols).Interior.ColorIndex = xlNone
rStart.Resize(1, lCols).Font.ColorIndex = xlAutomatic
End If

End Sub

我尝试了这个方法,如果值来自Excel范围,那么它可以工作:

Function GetSmall3(ByRef MyRange As Range)
Dim v, x, y
v = MyRange
x = Application.Small(v, 3)
y = Application.Match(x, v, 0)
GetSmall3 = y
End Function
如果您使用的是excel数组,我认为这将取决于如何引用空值。 我使用了一个空字符串,但仍然有效,您需要一个变量数组

Dim v, x, y
v = Array(1, 2, 3, "", 5)
x = Application.Small(v, 3)
y = Application.Match(x, v, 0)
msgbox y
这与您上次的代码和工作原理类似

Sub Try()
Dim i As Integer, vanums, aDivs, rRow, wf
Dim lSmall
Set wf = Application.WorksheetFunction
Set rRow = Range("A1:J1")
vanums = rRow
ReDim aDivs(LBound(vanums, 2) To UBound(vanums, 2))
For i = LBound(vanums, 2) To UBound(vanums, 2)
        If IsEmpty(vanums(1, i)) Then
            aDivs(i) = Empty
        Else
            aDivs(i) = vanums(1, i)
        End If
Next i
For i = 1 To 3
    lSmall = wf.Match(wf.Small(aDivs, i), aDivs, False)
    MsgBox lSmall
Next
End Sub
A1中的值:J1{1,2,3,empty,5,empty,empty,empty,empty}

最终解决了

Dim i As Long
Dim vaNums As Variant, vaDenoms As Variant, aDivs() As Variant
Dim wf As WorksheetFunction
Dim lSmall As Long
Dim rRow As Range
Dim rStart As Range
Dim iCount As Integer
Dim lRows As Integer
Dim lCols As Long
Set wf = Application.WorksheetFunction
lCols = Range(Cells(1, 5), Cells(1, 5).Offset(0, ActiveSheet.ListObjects(1).ListColumns.Count - 11)).Count
Set rRow = target.Cells(1).Offset(0, 1).Resize(1, lCols)
Set rStart = Me.Cells(1, 5)
iCount = wf.CountA(rRow, ">0")
If Not Intersect(target.Cells(1), Me.Range("D3", Me.Range("D3").End(xlDown))) Is Nothing Then
If iCount > 4 Then
    Set rRow = target.Cells(1).Offset(0, 1).Resize(1, lCols)
    rStart.Resize(1, lCols).Interior.ColorIndex = xlNone
    rStart.Resize(1, lCols).Font.ColorIndex = xlAutomatic
    vaNums = rRow.Value
    vaDenoms = rStart.Offset(1, 0).Resize(1, lCols).Value
    ReDim aDivs(LBound(vaNums, 2) To UBound(vaNums, 2))
    For i = LBound(vaNums, 2) To UBound(vaNums, 2)
            If IsEmpty(vaNums(1, i)) Then
                aDivs(i) = Empty
            Else
                aDivs(i) = vaNums(1, i) / vaDenoms(1, i) + (i / 10000)
            End If
    Next i
    For i = 1 To 3
        lSmall = wf.Match(wf.Small(aDivs, i), aDivs, False)
        rStart.Offset(0, lSmall - 1).Interior.Color = 6299648
        rStart.Offset(0, lSmall - 1).Font.ThemeColor = xlThemeColorDark1
    Next i
Else
    rStart.Resize(1, lCols).Interior.ColorIndex = xlNone
    rStart.Resize(1, lCols).Font.ColorIndex = xlAutomatic
End If
Else
    rStart.Resize(1, lCols).Interior.ColorIndex = xlNone
    rStart.Resize(1, lCols).Font.ColorIndex = xlAutomatic
End If

End Sub

我还是不能让它工作。如果我把我想用的代码放进去可能会有帮助:我实际上需要最低的三个。我明白了,你怎么能在ADIV中得到一个空值,似乎所有的元素都是一个数学运算的结果…我明白你的意思了。这是正确的。是否可以不计算rRow中的单元格是否为空?嗯,这似乎不起作用。我得到一个“类型不匹配”:ADivs(I)=“”