我在我的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转换为字典,如果可能的话,请参考一些视频教程,以便我可以学习这个概念?
答案 0 :(得分:0)
在没有工作簿的情况下演示字典/数组解决方案将有些挑战。我将展示一个简单的示例,希望该示例演示该解决方案如何为您工作。在我完成的所有测试中,它比循环和使用VLOOKUP的速度快得多。
如有疑问,请写回。
我的测试示例中的查找数据模式为(Id,Value1,Value2)
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