Excel 在范围中查找单元格值,如果未找到,则删除行。取120+;还有几分钟
我有以下代码,但由于我正在处理的工作表有190000行数据,因此需要120多分钟来处理所有数据: 从Excel 在范围中查找单元格值,如果未找到,则删除行。取120+;还有几分钟,excel,vba,Excel,Vba,我有以下代码,但由于我正在处理的工作表有190000行数据,因此需要120多分钟来处理所有数据: 从 Sub Import_Data() Start_Import "WIR-Deploy" End Sub 这就是我设置一切的地方: Option Explicit Public WB1 As Workbook Public WS1 As Worksheet Public WS2 As Worksheet Public updateSuccess As Boolea
Sub Import_Data()
Start_Import "WIR-Deploy"
End Sub
这就是我设置一切的地方:
Option Explicit
Public WB1 As Workbook
Public WS1 As Worksheet
Public WS2 As Worksheet
Public updateSuccess As Boolean
Sub Start_Import(strApp As String)
Dim WS3 As Worksheet
Dim importFile As String
Set WB1 = ThisWorkbook
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Set WS1 = WB1.Sheets("Master Sheet")
If strApp = "WIR-Deploy" Then
Set WS2 = WB1.Sheets("RawWhoIsReady-Deploy@8Jul")
importFile = "H:\99 - Temp\WhoIsReady-Deploy.csv"
Application.StatusBar = "'Who is ready - Deploy' data Import now runnning..."
Else
MsgBox "Not Coded Yet"
Exit Sub
End If
If strApp = "WIR-Deploy" Then
ImportData strApp, importFile
Else
MsgBox "Not Coded Yet"
Exit Sub
End If
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.StatusBar = False
End Sub
然后这将导入图纸:
Option Explicit
Sub ImportData(strApp, importFile)
Dim WB2 As Workbook
Dim WS3 As Worksheet
Dim lRow, lCol, ImportRow As Long
Dim rngAsset As Range
Set WB2 = Workbooks.Open(importFile)
If strApp = "WIR-Deploy" Then
WB2.Sheets(1).Copy Before:=WS2
WB2.Close False
Set WS3 = WB1.ActiveSheet
WS3.Columns(1).EntireColumn.Delete
lRow = Cells(Rows.Count, 1).End(xlUp).Row
lCol = Cells(1, Columns.Count).End(xlToLeft).Column
With WS3
.Sort.SortFields.Add Key:=Range("A1"), Order:=xlAscending
.Sort.SetRange Range(.Cells(1, 1), .Cells(lRow, lCol))
.Sort.Header = xlYes
.Sort.Apply
End With
For ImportRow = 2 To lRow
Set rngAsset = WS1.Range("A:A").Find(WS3.Cells(ImportRow, 1))
If rngAsset Is Nothing Then
WS3.Rows(ImportRow).EntireRow.Delete
ImportRow = ImportRow - 1
lRow = lRow - 1
End If
Application.StatusBar = "[Deploy Import] " & lRow & " left to process. " & ImportRow & " Retained"
Set rngAsset = Nothing
Next
Else
MsgBox "This has not been coded yet", vbOKOnly + vbCritical
Exit Sub
End If
'WS3.Delete
WB1.RefreshAll
End Sub
有什么方法可以加快这个过程吗?有更好的方法吗?我有限的知识告诉我,我会努力让它更快,但我愿意接受任何关于让它更好的想法,比如:
Dim m, rngDel As Range, numDel As Long
'...
numDel = 0
For importrow = lRow To 2 Step -1
'Match is much faster than Find...
m = Application.Match(ws3.Cells(importrow, 1).Value, WS1.Range("A:A"), 0)
If IsError(m) Then
numDel = numDel + 1 '<< count rows added
If rngDel Is Nothing Then
Set rngDel = ws3.Rows(importrow)
Else
Set rngDel = Application.Union(rngDel, ws3.Rows(importrow))
End If
'delete in batches
If numDel > 1000 Then
rngDel.Delete
Set rngDel = Nothing
numDel = 0
End If
End If
'don't update statusbar too often
If importrow Mod 1000 = 0 Then
Application.StatusBar = "On row " & importrow
End If
Next
'delete last batch of rows
If Not rngDel Is Nothing Then rngDel.Delete
Dim m,rngDel作为范围,numDel作为长度
'...
numDel=0
对于importrow=lRow至2步骤-1
“匹配比查找快得多。。。
m=Application.Match(ws3.Cells(importrow,1).Value,WS1.Range(“A:A”),0)
如果IsError(m)那么
numDel=numDel+1'类似这样的内容:
Dim m, rngDel As Range, numDel As Long
'...
numDel = 0
For importrow = lRow To 2 Step -1
'Match is much faster than Find...
m = Application.Match(ws3.Cells(importrow, 1).Value, WS1.Range("A:A"), 0)
If IsError(m) Then
numDel = numDel + 1 '<< count rows added
If rngDel Is Nothing Then
Set rngDel = ws3.Rows(importrow)
Else
Set rngDel = Application.Union(rngDel, ws3.Rows(importrow))
End If
'delete in batches
If numDel > 1000 Then
rngDel.Delete
Set rngDel = Nothing
numDel = 0
End If
End If
'don't update statusbar too often
If importrow Mod 1000 = 0 Then
Application.StatusBar = "On row " & importrow
End If
Next
'delete last batch of rows
If Not rngDel Is Nothing Then rngDel.Delete
Dim m,rngDel作为范围,numDel作为长度
'...
numDel=0
对于importrow=lRow至2步骤-1
“匹配比查找快得多。。。
m=Application.Match(ws3.Cells(importrow,1).Value,WS1.Range(“A:A”),0)
如果IsError(m)那么
numDel=numDel+1'创建一个Union
范围并立即删除所有行。不要一次删除一个。我也会使用Application.Match
而不是Find
,因为它速度更快,并且在循环时会产生影响。显示您的整个代码。我没有看到应用程序。屏幕更新关闭,变量类型声明等。您在不完全限定排序范围方面也有一些问题。您犯了一个典型的错误。您正在删除for循环中的行。这意味着,当您删除(例如)第6行时,前一行7现在变为第6行,但您的循环计数器不知道这一点,因此您将跳过行。当从一个范围/集合中删除行时,您应该总是从最高索引重复到最低索引。<代码>应用程序。StassBar < /代码>也会使事情慢下来,所以只考虑更新每一行(例如)100行或SO。请看:制作一个<代码>联合< /代码>范围,并同时删除所有行。不要一次删除一个。我也会使用Application.Match
而不是Find
,因为它速度更快,并且在循环时会产生影响。显示您的整个代码。我没有看到应用程序。屏幕更新关闭,变量类型声明等。您在不完全限定排序范围方面也有一些问题。您犯了一个典型的错误。您正在删除for循环中的行。这意味着,当您删除(例如)第6行时,前一行7现在变为第6行,但您的循环计数器不知道这一点,因此您将跳过行。当从一个范围/集合中删除行等时,您应该总是从最高索引重复到最低索引。<代码>应用程序。StassBar < /代码>也会使事情慢下来,所以只考虑每一个更新(例如)。大约100行。看:有没有一种方法可以在我努力寻找的时候计算联盟中的条目?有没有一种方法可以在我努力寻找联盟的时候计算联盟中的条目