协助循环效率
Assistance with loop efficiency
首先让我说谢谢你的帮助,因为我对 VBA 还比较陌生。
目前我有一个 loop
贯穿 5 columns
以清除任何在 Column A
中没有价值的 rows
然后它贯穿其他 4 columns
以匹配同一 workbook
中另一个 sheet
的数据。我已经研究了多种方法来更有效地做到这一点,但没有运气。下面是我目前正在使用的loop
。我想要一些想法,以便代码更有效地运行。
Dim wsDE As Worksheet
Dim wsMasterList As Worksheet
Dim City As Range
Dim State As Range
Dim AgeL As Range
Dim AgeU As Range
Dim Gender As Range
Dim x As Long
Dim lastx As Long
Set wsDE = ThisWorkbook.Sheets("DataEntry")
Set wsMasterList = ThisWorkbook.Sheets("MasterList")
Set City = wsDE.Range("B1")
Set State = wsDE.Range("C1")
Set AgeL = wsDE.Range("D1")
Set AgeU = wsDE.Range("E1")
Set Gender = wsDE.Range("F1")
lastx = wsMasterList.Range("A" & wsMasterList.Rows.Count).End(xlUp).Row
wsMasterList.Range("A1").Select
For x = 2 To lastx
If wsMasterList.Range("A" & x) = vbNullString Then
wsMasterList.Range("A" & x).EntireRow.Delete
GoTo NX
End If
If City <> "N/A" Then
If wsMasterList.Range("I" & x).Value <> UCase(City) Then
wsMasterList.Range("I" & x).EntireRow.Delete
GoTo NX
End If
End If
If State <> "N/A" Then
If wsMasterList.Range("J" & x).Value <> UCase(State) Then
wsMasterList.Range("J" & x).EntireRow.Delete
GoTo NX
End If
End If
If AgeL <> "N/A" Then
If wsMasterList.Range("E" & x) < AgeL Then
wsMasterList.Range("E" & x).EntireRow.Delete
GoTo NX
End If
End If
If AgeU <> "N/A" Then
If wsMasterList.Range("E" & x) > AgeU Then
wsMasterList.Range("E" & x).EntireRow.Delete
GoTo NX
End If
End If
If Gender = "Male" Then
If wsMasterList.Range("D" & x) <> "M" Then
wsMasterList.Range("D" & x).EntireRow.Delete
GoTo NX
End If
End If
If Gender = "Female" Then
If wsMasterList.Range("D" & x) <> "F" Then
wsMasterList.Range("D" & x).EntireRow.Delete
GoTo NX
End If
End If
NX:
Next x
我唯一的建议是订购您的支票,以确保它们是按最常见的删除行的情况订购的。这减少了必须检查的 "If" 语句的数量。因此,如果 AgeL 通常删除最多的记录,这应该是您的第一次检查,然后是下一个最常见的成功检查,依此类推。这样您就可以减少必须执行的检查次数。这不是一个巨大的收获,但它会帮助一些人。
我不知道这是否更好:交易 space 复杂性...
它确实展示了如何构建单个删除范围。
Sub Tester()
Dim wsDE As Worksheet
Dim wsMasterList As Worksheet
Dim City As Range
Dim State As Range
Dim AgeL As Range
Dim AgeU As Range
Dim Gender As Range
Dim x As Long
Dim lastx As Long, rngDel As Range, rw As Range
Set wsDE = ThisWorkbook.Sheets("DataEntry")
Set wsMasterList = ThisWorkbook.Sheets("MasterList")
Set City = wsDE.Range("B1")
Set State = wsDE.Range("C1")
Set AgeL = wsDE.Range("D1")
Set AgeU = wsDE.Range("E1")
Set Gender = wsDE.Range("F1")
lastx = wsMasterList.Range("A" & wsMasterList.Rows.Count).End(xlUp).Row
For x = 2 To lastx
Set rw = wsMasterList.Rows(x)
'Only really one criteria for this check, so just pass True for crit1 ...
' If CheckIt returns True, then we've already flagged this row for deletion
' and the other checks can be skipped
If CheckIt(rngDel, rw, True, rw.Cells(1, "A") = vbNullString) Then GoTo NX
If CheckIt(rngDel, rw, City <> "N/A", rw.Cells(1, "I") <> UCase(City)) Then GoTo NX
If CheckIt(rngDel, rw, State <> "N/A", rw.Cells(1, "J") <> UCase(State)) Then GoTo NX
If CheckIt(rngDel, rw, AgeL <> "N/A", rw.Cells(1, "E") < AgeL) Then GoTo NX
If CheckIt(rngDel, rw, AgeU <> "N/A", rw.Cells(1, "E") > AgeU) Then GoTo NX
If CheckIt(rngDel, rw, Gender = "Male", rw.Cells(1, "D") <> "M") Then GoTo NX
If CheckIt(rngDel, rw, Gender = "Female", rw.Cells(1, "D") <> "F") Then GoTo NX
NX:
Next x
If Not rngDel Is Nothing Then rngDel.Delete
End Sub
'Function to check two criteria to see if a row should be deleted or not
' returns true if the row is to be deleted.
'rngDelete: the range we're building for eventual deletion
'rw: the current row being checked
'crit1: first check (something that evaluates to True or False)
'crit2: second check (something that evaluates to True or False)
Function CheckIt(ByRef rngDelete As Range, rw As Range, crit1 As Boolean, crit2 As Boolean) As Boolean
CheckIt = False '<< by default returns false
If crit1 Then '<< check the first and second criteria
If crit2 Then
'both criteria passed, so collect the row for later deletion
If rngDelete Is Nothing Then
'if "rngDelete" has no rows then use the passed row
Set rngDelete = rw
Else
'add the passed row to the range to be deleted
Set rngDelete = Application.Union(rng, rw)
End If
CheckIt = True '<< return True so we can skip any other checks for deletion
End If
End If
End Function
首先让我说谢谢你的帮助,因为我对 VBA 还比较陌生。
目前我有一个 loop
贯穿 5 columns
以清除任何在 Column A
中没有价值的 rows
然后它贯穿其他 4 columns
以匹配同一 workbook
中另一个 sheet
的数据。我已经研究了多种方法来更有效地做到这一点,但没有运气。下面是我目前正在使用的loop
。我想要一些想法,以便代码更有效地运行。
Dim wsDE As Worksheet
Dim wsMasterList As Worksheet
Dim City As Range
Dim State As Range
Dim AgeL As Range
Dim AgeU As Range
Dim Gender As Range
Dim x As Long
Dim lastx As Long
Set wsDE = ThisWorkbook.Sheets("DataEntry")
Set wsMasterList = ThisWorkbook.Sheets("MasterList")
Set City = wsDE.Range("B1")
Set State = wsDE.Range("C1")
Set AgeL = wsDE.Range("D1")
Set AgeU = wsDE.Range("E1")
Set Gender = wsDE.Range("F1")
lastx = wsMasterList.Range("A" & wsMasterList.Rows.Count).End(xlUp).Row
wsMasterList.Range("A1").Select
For x = 2 To lastx
If wsMasterList.Range("A" & x) = vbNullString Then
wsMasterList.Range("A" & x).EntireRow.Delete
GoTo NX
End If
If City <> "N/A" Then
If wsMasterList.Range("I" & x).Value <> UCase(City) Then
wsMasterList.Range("I" & x).EntireRow.Delete
GoTo NX
End If
End If
If State <> "N/A" Then
If wsMasterList.Range("J" & x).Value <> UCase(State) Then
wsMasterList.Range("J" & x).EntireRow.Delete
GoTo NX
End If
End If
If AgeL <> "N/A" Then
If wsMasterList.Range("E" & x) < AgeL Then
wsMasterList.Range("E" & x).EntireRow.Delete
GoTo NX
End If
End If
If AgeU <> "N/A" Then
If wsMasterList.Range("E" & x) > AgeU Then
wsMasterList.Range("E" & x).EntireRow.Delete
GoTo NX
End If
End If
If Gender = "Male" Then
If wsMasterList.Range("D" & x) <> "M" Then
wsMasterList.Range("D" & x).EntireRow.Delete
GoTo NX
End If
End If
If Gender = "Female" Then
If wsMasterList.Range("D" & x) <> "F" Then
wsMasterList.Range("D" & x).EntireRow.Delete
GoTo NX
End If
End If
NX:
Next x
我唯一的建议是订购您的支票,以确保它们是按最常见的删除行的情况订购的。这减少了必须检查的 "If" 语句的数量。因此,如果 AgeL 通常删除最多的记录,这应该是您的第一次检查,然后是下一个最常见的成功检查,依此类推。这样您就可以减少必须执行的检查次数。这不是一个巨大的收获,但它会帮助一些人。
我不知道这是否更好:交易 space 复杂性...
它确实展示了如何构建单个删除范围。
Sub Tester()
Dim wsDE As Worksheet
Dim wsMasterList As Worksheet
Dim City As Range
Dim State As Range
Dim AgeL As Range
Dim AgeU As Range
Dim Gender As Range
Dim x As Long
Dim lastx As Long, rngDel As Range, rw As Range
Set wsDE = ThisWorkbook.Sheets("DataEntry")
Set wsMasterList = ThisWorkbook.Sheets("MasterList")
Set City = wsDE.Range("B1")
Set State = wsDE.Range("C1")
Set AgeL = wsDE.Range("D1")
Set AgeU = wsDE.Range("E1")
Set Gender = wsDE.Range("F1")
lastx = wsMasterList.Range("A" & wsMasterList.Rows.Count).End(xlUp).Row
For x = 2 To lastx
Set rw = wsMasterList.Rows(x)
'Only really one criteria for this check, so just pass True for crit1 ...
' If CheckIt returns True, then we've already flagged this row for deletion
' and the other checks can be skipped
If CheckIt(rngDel, rw, True, rw.Cells(1, "A") = vbNullString) Then GoTo NX
If CheckIt(rngDel, rw, City <> "N/A", rw.Cells(1, "I") <> UCase(City)) Then GoTo NX
If CheckIt(rngDel, rw, State <> "N/A", rw.Cells(1, "J") <> UCase(State)) Then GoTo NX
If CheckIt(rngDel, rw, AgeL <> "N/A", rw.Cells(1, "E") < AgeL) Then GoTo NX
If CheckIt(rngDel, rw, AgeU <> "N/A", rw.Cells(1, "E") > AgeU) Then GoTo NX
If CheckIt(rngDel, rw, Gender = "Male", rw.Cells(1, "D") <> "M") Then GoTo NX
If CheckIt(rngDel, rw, Gender = "Female", rw.Cells(1, "D") <> "F") Then GoTo NX
NX:
Next x
If Not rngDel Is Nothing Then rngDel.Delete
End Sub
'Function to check two criteria to see if a row should be deleted or not
' returns true if the row is to be deleted.
'rngDelete: the range we're building for eventual deletion
'rw: the current row being checked
'crit1: first check (something that evaluates to True or False)
'crit2: second check (something that evaluates to True or False)
Function CheckIt(ByRef rngDelete As Range, rw As Range, crit1 As Boolean, crit2 As Boolean) As Boolean
CheckIt = False '<< by default returns false
If crit1 Then '<< check the first and second criteria
If crit2 Then
'both criteria passed, so collect the row for later deletion
If rngDelete Is Nothing Then
'if "rngDelete" has no rows then use the passed row
Set rngDelete = rw
Else
'add the passed row to the range to be deleted
Set rngDelete = Application.Union(rng, rw)
End If
CheckIt = True '<< return True so we can skip any other checks for deletion
End If
End If
End Function