当我有超过10万行数据时,Vlookup函数会花费太多时间运行:

时间:2019-08-22 18:05:42

标签: excel vba

我在我的vba代码中使用了vlookup函数,但是当我有30万行以上的数据时,这将花费太多时间:

我已经尝试过几种优化代码的方法,但是,我在excel 2016 64位,corei7 6内核方面并不成功。

我在论坛上已经阅读了有关Vba Dictionaries和ARRAYS的内容,但是我还没有对此进行研究,并且无法理解,我需要一些指南来正确理解概念,以便在代码上实现解决方案

Sub BuscarDataBancosV6OK()
Dim cel As Range


Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False


Range("U:U").NumberFormat = "dd/mm/yyyy"
Range("V:V").NumberFormat = "General"
Range("W:Z").NumberFormat = "0.00"

For Each cel In Selection 'Range(rng) Los datos de bancos a datos generales

'validar si la celda fechaBANCO tiene información, si tiene INFO pasar al siguiente porque ya procesó anteriormente
If cel.Offset(, 16) = "" Then
    GoTo Validarinfo
Else
    GoTo SIGUIENTE
End If

Validarinfo:

Validador = Application.VLookup(cel.Offset(, -4), Workbooks("PRUEBAS DATOS BANCO GRANDES VER2.xlsm").Sheets("Hoja1").Range("A2:M242000"), 1, False)

If IsError(Validador) Then
    cel.Offset(, 34) = "NO CONCILIADO"
    GoTo SIGUIENTE
Else
    'valor bancos
            cel.Offset(, 9).FormulaR1C1 = _
            "=+VLOOKUP(RC[-13],'[PRUEBAS DATOS BANCO GRANDES VER2.xlsm]Hoja1'!R2C1:R241666C13,8,FALSE)"
            cel.Offset(, 9) = cel.Offset(, 9).Value
    'fecha acreditación
            cel.Offset(, 16).FormulaR1C1 = _
            "=+VLOOKUP(RC[-20],'[PRUEBAS DATOS BANCO GRANDES VER2.xlsm]Hoja1'!R2C1:R241666C13,5,FALSE)"
            cel.Offset(, 16) = cel.Offset(, 16).Value
    'Nombre banco
            cel.Offset(, 17).FormulaR1C1 = _
            "=+VLOOKUP(RC[-21],'[PRUEBAS DATOS BANCO GRANDES VER2.xlsm]Hoja1'!R2C1:R241666C13,13,FALSE)"
            cel.Offset(, 17) = cel.Offset(, 17).Value
    'Comisión banco
            cel.Offset(, 18).FormulaR1C1 = _
            "=+VLOOKUP(RC[-22],'[PRUEBAS DATOS BANCO GRANDES VER2.xlsm]Hoja1'!R2C1:R241666C13,9,FALSE)"
            cel.Offset(, 18) = cel.Offset(, 18).Value
    'Retención IVA banco
            cel.Offset(, 19).FormulaR1C1 = _
            "=+VLOOKUP(RC[-23],'[PRUEBAS DATOS BANCO GRANDES VER2.xlsm]Hoja1'!R2C1:R241666C13,10,FALSE)"
            cel.Offset(, 19) = cel.Offset(, 19).Value
    'Retención IVA renta
            cel.Offset(, 20).FormulaR1C1 = _
            "=+VLOOKUP(RC[-24],'[PRUEBAS DATOS BANCO GRANDES VER2.xlsm]Hoja1'!R2C1:R241666C13,11,FALSE)"
            cel.Offset(, 20) = cel.Offset(, 20).Value
    'Valor acreditado banco
            cel.Offset(, 21).FormulaR1C1 = _
            "=+VLOOKUP(RC[-25],'[PRUEBAS DATOS BANCO GRANDES VER2.xlsm]Hoja1'!R2C1:R241666C13,12,FALSE)"
            cel.Offset(, 21) = cel.Offset(, 21).Value
    'Status conciliación
            cel.Offset(, 34) = "CONCILIADO"
End If

SIGUIENTE:
    Next cel

    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True
    ActiveSheet.DisplayPageBreaks = True
    Application.CutCopyMode = False
End Sub

此外,woorkbook中的“ A”列中的PRUEBAS DATOS BANCO GRANDES VER2.xlsm中没有重复的数据

任何人都可以帮助我将vlookup转换为字典,如果可能的话,请参考一些视频教程,以便我可以学习这个概念?

1 个答案:

答案 0 :(得分:0)

在没有工作簿的情况下演示字典/数组解决方案将有些挑战。我将展示一个简单的示例,希望该示例演示该解决方案如何为您工作。在我完成的所有测试中,它比循环和使用VLOOKUP的速度快得多。

如有疑问,请写回。

我的测试示例中的查找数据模式为(Id,Value1,Value2)

Sample data

Option Explicit

Sub PerformALotOfLookups()
    Dim oDict As Object
    Dim lookupRange As Range
    Dim iterator As Range

    'Dimension of the array should be the number of values you
    'want to store to correspond to the key.
    'In my example, 0 to 1 means there are two values,
    'a 0th value and a 1st value
    Dim arrayOfValues(0 To 1) As Variant

    'The range that we normally vlookup against (only
    'using the first column in my range)
    Set lookupRange = Sheet1.Range("A1:A500")

    Set oDict = CreateObject("Scripting.Dictionary")

    'Set optimization settings
    Application.ScreenUpdating = False

    For Each iterator In lookupRange
        'Check if the ID already exists
        If Not oDict.exists(iterator.Value) Then
            'create the array
            '0th element is the first column to right of iterator
            arrayOfValues(0) = iterator.Offset(, 1).Value

            '1st element is the second column to right of iterator
            arrayOfValues(1) = iterator.Offset(, 2).Value

            'Add key and array to the dictionary
            oDict.Add iterator.Value, arrayOfValues
        End If
    Next iterator

    ''' Now the dictioary exists, and you can query it by key value
    ''' and return a 2 element array. Access elements by index

    ''Example: Lookup value 5
    ''Show a message box for the 0th element
    ''then show a messagebox for the 1st element
    If oDict.exists(5) Then
        MsgBox oDict(5)(0)
        MsgBox oDict(5)(1)
    End If

    ''Example: Lookup value 37
    ''Show a message box for the 0th element
    ''then show a messagebox for the 1st element
    If oDict.exists(37) Then
        MsgBox oDict(37)(0)
        MsgBox oDict(37)(1)
    End If

    Application.ScreenUpdating = True
End Sub