2016-07-29 36 views
0

我有一个电子元件列表,它们的名字在列A,它们的值在列B。我想在每个组件(每行)中搜索所有其他行的最佳匹配(我不想使用2个For循环)。我还需要它在VBA中,因为我在VBA中处理其他函数。组合使用函数Match&Min&Abs

说明:最佳匹配将是行,其中,所述成分值,与所搜索的部件一起排,将是最接近于36

实施例(见我见下表的部分),第2行,电容1的值为17.97822949,我想找到最好的行,与这个电容一起,它们的组合值为36(这意味着它的值最接近18.02177051)。

挑战/问题:找到Match,Min和Abs的组合,它们将返回行号和电容值(列C和列D)。

enter image description here

当前的代码,我有:

Option Explicit 

Sub Match_Min_Abs() 

Dim C_Sht        As Worksheet 
Dim C_Col        As Integer 
Dim C_Row        As Long 
Dim Last_Row       As Long 
Dim Capacitor_Val      As Double 
Dim Current_Rng       As Range 
Dim Row_Found       As Long 
Dim Minimum_Gap       As Double 


Set C_Sht = ThisWorkbook.Worksheets("C_Data") 

' find last row in sheet 
Last_Row = Cells(Rows.Count, "B").End(xlUp).row 

' Capacitors column B 
C_Col = 2 

For C_Row = 2 To Last_Row - 1 

    ' set current search range (from next row till last row) 
    Set Current_Rng = C_Sht.Range(Cells(C_Row + 1, C_Col), Cells(Last_Row, C_Col)) 


    ' ****** this is the part I can't get the right set of functions to work ***** 
    Row_Found = Application.Match(WorksheetFunction.min(Abs(36 - (Current_Rng + Cells(C_Row, C_Col))))) 

    ' Capacitor_Val = Application.Index(Current_Rng, Application.Match(WorksheetFunction.min(Abs(Current_Rng - 36)), Abs(Current_Rng - 36), 0)) 

    C_Sht.Cells(C_Row, C_Col + 1).Value = Row_Found 
    C_Sht.Cells(C_Row, C_Col + 2).Value = Capacitor_Val 

Next C_Row 

End Sub 
+1

工作表数组公式是'= MATCH(MIN(ABS(36 - ($ B $ 2:$ B $ 48 + B2))),ABS(36 - ($ B $ 2:$ B $ 48 + B2) ),0)'所以你总是可以使用WorkSheet.Evaluate改变''B2'引用到你的单元格的值 –

+1

'Row_Found = C_Sht.Evaluate(“MATCH(MIN(ABS(36-(”&Current_Rng&“+”&C_Sht。单元格(C_Row,C_Col).Address&“))),ABS(36-(”&Current_Rng&“+”&C_Sht.Cells(C_Row,C_Col).Address&“)),0)”) –

+0

@ScottCraner第一个公式给了我一个'#NA'结果。第二个,当在VBA中实现时会抛出“运行时错误13类型不匹配”。它在你的测试中起作用了吗? –

回答

1

由于@Scott克拉纳的帮助下,一些小修改(需要添加Current_Rng.Address,并删除一些额外的spaces)我有这工作。 这很重要,因为使用2个For循环来覆盖超过5000个组件的Excel工作表,有时需要超过2分钟才能运行。

Option Explicit 

Sub Match_Min_ABS() 

Dim C_Sht        As Worksheet 
Dim C_Col        As Integer 
Dim C_Row        As Long 
Dim Last_Row       As Long 
Dim Capacitor_Val      As Double 
Dim Current_Rng       As Range 
Dim Row_Found       As Long 
Dim Minimum_Gap       As Double 
Dim Function_Str      As String 


Set C_Sht = ThisWorkbook.Worksheets("C_Data") 

' find last row in sheet 
Last_Row = Cells(Rows.Count, "B").End(xlUp).row 

' Capacitors column B 
C_Col = 2 

For C_Row = 2 To Last_Row - 2 

    ' set current search range (from next row till last row) 
    Set Current_Rng = C_Sht.Range(Cells(C_Row + 1, C_Col), Cells(Last_Row, C_Col)) 

    ' use a string first (easier to debug later) 
    Function_Str = "MATCH(MIN(ABS(36-(" & Current_Rng.Address & "+" & C_Sht.Cells(C_Row, C_Col).Address & ")))," & _ 
      "ABS(36-(" & Current_Rng.Address & "+" & C_Sht.Cells(C_Row, C_Col).Address & ")),0)"      
    Row_Found = C_Sht.Evaluate(Function_Str) + C_Row  

    Capacitor_Val = C_Sht.Cells(Row_Found, C_Col) 
    C_Sht.Cells(C_Row, C_Col + 1).Value = Row_Found 
    C_Sht.Cells(C_Row, C_Col + 2).Value = Capacitor_Val 

Next C_Row 

End Sub 
+0

很高兴你得到它的工作。对不起,我错过了'地址'。 –