VBA中Vlookup的替代方案?

时间:2017-01-19 21:10:01

标签: excel vba excel-vba

也许是一个奇怪的问题,但是有没有另一种方法可以打开工作簿,在列中搜索特定引用,然后使用VBA从该行中的另一列中提取数据,而不使用VLookup?

我试图获取数据的表包含数字,文本,日期的混合,查找值通常> 13位数。

我有点使用VLookup的东西,但它太不一致了 - 每次都会因为数据类型不匹配而中断。很多'类型不匹配'或'ByRef'错误 - 我得到一个正确然后另一个休息。

不幸的是,我不知道该怎么搜索才能让我朝着正确的方向前进。

如果它有助于解释我正在尝试做什么,这里是我的代码使用VLookup一直出错:

Sub getData()

Application.EnableEvents = False
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.Calculation = xlManual

Dim wb As Workbook, src As Workbook
Dim srcRange As Range
Dim InputString
Dim strStatus
Dim strStatusNum
Dim strD1
Dim I As Integer

Set wb = ActiveWorkbook

I = 7

Set src = Workbooks.Open("D:\Files\test2.xlsx", True, True)
    With src.Sheets(1)
        Set srcRange = .Range(.Range("A1"), .Range("H1").End(xlDown))
End With

Do While wb.ActiveSheet.Cells(I, 1) <> ""

    'Makes sure src.Close is called if errors
    'On Error Resume Next

    InputString = wb.Worksheets("Sheet 1").Cells(I, 1)

    strStatus = Application.VLookup(InputString, srcRange, 3, False)

    strD1 = Application.VLookup(InputString, srcRange, 4, False)

    'Convert strStatus to actual number e.g. "03. no d1"
    strStatusNum = Left(strStatus, 2)

    wb.Worksheets("Sheet 1").Cells(I, 4) = strStatusNum

        If (strStatusNum <> 3) Then

            wb.Worksheets("Sheet 1").Cells(I, 2) = "Not at 03. No Work Order"

        ElseIf (strStatusNum = 3) And (strD1 <> "") Then

            wb.Worksheets("Sheet 1").Cells(I, 2) = "D1 Received"
            wb.Worksheets("Sheet 1").Cells(I, 3) = strD1

        Else

            wb.Worksheets("Sheet 1").Cells(I, 2) = "No D1"

        End If

    I = I + 1

Loop


src.Close (False)

Application.EnableEvents = True
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.Calculation = xlAutomatic

End Sub

编辑:更正了一些语法。

3 个答案:

答案 0 :(得分:4)

在列的情况下,您可以使用Find对象的Range方法。返回值是具有匹配值的第一个单元格(表示为另一个Range对象),除非根本没有匹配。然后返回Nothing

在返回的(单个单元格)范围内,您可以使用EntireRow方法获取一个Range,该Range表示找到的单元格行上的所有单元格。在返回的(行)范围内,您可以使用Cells方法选择与要返回的同一行中的列匹配的单元格(再次表示为另一个Range对象)。

顺便说一下,工作簿函数中VLOOKUP的更灵活的替代方法是INDEXMATCH的组合。

答案 1 :(得分:0)

未经测试但已编译:

Sub getData()

    Dim src As Workbook
    Dim srcRange As Range
    Dim strStatus, strStatusNum, strD1
    Dim m, rw As Range

    Set rw = ActiveSheet.Rows(7)

    Set src = Workbooks.Open("D:\Files\test2.xlsx", True, True)
    With src.Sheets(1)
        Set srcRange = .Range(.Range("A1"), .Range("H1").End(xlDown))
    End With

    Do While rw.Cells(1).Value <> ""

        m = Application.Match(rw.Cells(1), srcRange.Columns(1), 0)

        If Not IsError(m) Then 'proceed only if got match

            strStatus = srcRange.Cells(m, 3).Value
            strD1 = srcRange.Cells(m, 4).Value
            strStatusNum = Left(strStatus, 2)

            rw.Cells(4).Value = strStatusNum

            If strStatusNum <> 3 Then
                rw.Cells(2) = "Not at 03. No Work Order"
            ElseIf strStatusNum = 3 And strD1 <> "" Then
                rw.Cells(2) = "D1 Received"
                rw.Cells(3) = strD1
            Else
                rw.Cells(2) = "No D1"
            End If

        End If

        Set rw = rw.Offset(1, 0)

    Loop

    src.Close False

End Sub

答案 2 :(得分:0)

您可能在重构代码之后

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    listView.setNestedScrollingEnabled(true);
    listView.startNestedScroll(View.OVER_SCROLL_ALWAYS);
}