Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 索引/匹配VBA在表及其列中搜索的替代方法_Excel_Vba - Fatal编程技术网

Excel 索引/匹配VBA在表及其列中搜索的替代方法

Excel 索引/匹配VBA在表及其列中搜索的替代方法,excel,vba,Excel,Vba,我需要在表及其列中搜索(在a列中搜索一个值并从B列返回一个值),我不喜欢使用索引/匹配组合,因为我正在为新手用户准备工作簿,他无法掌握索引/匹配逻辑。我没有找到任何简单/优雅的公式来做到这一点(除了索引/匹配组合之外),然后我编写了以下VBA代码 另外,如果有多个对应行匹配,该函数会自动对列中的值求和以读取 ' return a value taken from a column searching for a value in another column; ' the function wo

我需要在表及其列中搜索(在a列中搜索一个值并从B列返回一个值),我不喜欢使用索引/匹配组合,因为我正在为新手用户准备工作簿,他无法掌握索引/匹配逻辑。

我没有找到任何简单/优雅的公式来做到这一点(除了索引/匹配组合之外),然后我编写了以下VBA代码

另外,如果有多个对应行匹配,该函数会自动对列中的值求和以读取

' return a value taken from a column searching for a value in another column;
' the function works in the same way as Index(Match());
' if the column ColNameToRead contains number values, and if ValueToSearch is found more then one time in the column ColNameToSearch, then the returned value
' is the sum of all occurrence found.
Public Function SearchValInCol(TabName As String, ColNameToSearch As String, ValueToSearch As Variant, ColNameToRead As String)

    Application.Volatile (True)   ' see "Excel Recalculation"  https://msdn.microsoft.com/en-us/library/office/bb687891.aspx

    SearchValInCol = "Error, value not found!"

    ' search table in all Worksheets; exit if not found
    Dim foundTable
    Dim objSheet
    Dim objTable
    foundTable = 0
    For Each objSheet In ActiveWorkbook.Sheets
        For Each objTable In objSheet.ListObjects
            If objTable.Name = Trim(TabName) Then
                Set foundTable = objTable
                Exit For
            End If
        Next
    Next
    If IsNumeric(foundTable) Then Exit Function  ' exit function if the table is not found


    ' search column named ColNameToSearch in table; exit if not found
    Dim foundColumnToSearch
    Dim counter
    foundColumnToSearch = 0
    For counter = 1 To foundTable.ListColumns.Count
        If foundTable.HeaderRowRange(counter) = Trim(ColNameToSearch) Then
            Set foundColumnToSearch = foundTable.ListColumns(counter).DataBodyRange
            Exit For
        End If
    Next counter
    If IsNumeric(foundColumnToSearch) Then Exit Function ' exit function if the column is not found


    ' search column named ColNameToRead in table; exit if not found
    Dim foundColumnToRead
    foundColumnToRead = 0
    For counter = 1 To foundTable.ListColumns.Count
        If foundTable.HeaderRowRange(counter) = Trim(ColNameToRead) Then
            Set foundColumnToRead = foundTable.ListColumns(counter).DataBodyRange
            Exit For
        End If
    Next counter
    If IsNumeric(foundColumnToRead) Then Exit Function ' exit function if the column is not found


    ' search value ValueToSearch in column foundColumnToSearch; exit if not found
    Dim cellVal
    Dim retVal
    retVal = 0
    For counter = 1 To foundColumnToSearch.Rows.Count
        If foundColumnToSearch.Cells(counter, 1) = ValueToSearch Then
            ' if the value to search is a number, sum it with the previous value; otherwise return the first occurrence
            If IsNumeric(foundColumnToRead.Cells(counter, 1)) Then
                retVal = retVal + foundColumnToRead.Cells(counter, 1)
            Else
                retVal = foundColumnToRead.Cells(counter, 1)
                Exit For
            End If
        End If
    Next counter

    SearchValInCol = retVal

End Function
在下表(表1)中搜索从“数量”列返回值的“商品”“葡萄酒”

可以使用以下公式:

=SearchVal("Table1"; Table1[[#Headers];[article]]; "vino"; Table1[[#Headers];[quantity]])

另一个更简单的解决方案(始终使用VBA)是

' return a value taken from a column searching for a value in another column;
' the function works in the same way as Index(Match());
' if the column ColToRead contains number values, and if ValueToSearch is found more then one time in the column ColToSearch, then the returned value
' is the sum of all occurrence found.
Public Function SearchValInCol2(ColToSearch, ValueToSearch As Variant, ColToRead)

    Application.Volatile (True)   ' see "Excel Recalculation"  https://msdn.microsoft.com/en-us/library/office/bb687891.aspx

    SearchValInCol2 = "Error, value not found!"

    ' search value ValueToSearch in column ColToSearch; exit if not found
    Dim counter
    Dim cellVal
    Dim retVal
    retVal = 0
    For counter = 1 To ColToSearch.Rows.Count
        If ColToSearch.Cells(counter, 1) = ValueToSearch Then
            ' if the value to search is a number, sum it with the previous value; otherwise return the first occurrence
            If IsNumeric(ColToRead.Cells(counter, 1)) Then
                retVal = retVal + ColToRead.Cells(counter, 1)
            Else
                retVal = ColToRead.Cells(counter, 1)
                Exit For
            End If
        End If
    Next counter

    SearchValInCol2 = retVal

End Function
在下表“表1”中搜索

调用函数的公式可以是:

=SearchValInCol2(Table1[article];"vino";Table1[quantity])

这比以前的解决方案更简洁易读,并且避免在公式中使用文本字符串“Table1”,如果表名发生变化,该字符串将不会更新。

为什么不使用VLOOKUP?如果用户无法学习
索引/匹配
(或
VLOOKUP()
),这比索引/匹配更简单,我不确定UDF/宏是否是一个好主意。当然,它可能“更简单”,但他们必须始终启用宏,这对于这样的新手来说可能不是一个好习惯。此外,学习
索引/匹配
/
VLOOKUP()出于多种原因,所以也许考虑使用它,只是教育用户。给用户一个UDF,而不是教他们索引/匹配。嗯……听起来像给不亮火柴的人提供手枪。好的,我会尝试解释索引/匹配或VLoopUp,但是如果有更多的话,怎么写一个简单的公式来返回一个求和值。搜索列中有多个对应的值?尽管索引/匹配是标准的,UDF是…UDF,但“SearchValInCol2”无疑更简洁易读。为此,您可以使用sumifs()
article     quantity
vino               7
acqua              8
patate             5
vino               7
=SearchValInCol2(Table1[article];"vino";Table1[quantity])