[英]Delete all rows containing values outside of a specified numeric range
I am completely new to visual basic.我对视觉基础完全陌生。 I have a few spreadsheets containing numbers.我有一些包含数字的电子表格。 I want to delete any rows containing numbers outside of specific ranges.我想删除任何包含特定范围之外的数字的行。 Is there a straightforward way of doing this in visual basic?在visual basic中是否有一种简单的方法来做到这一点?
For example, in this first spreadsheet (image linked) I want to delete rows that contain cells with numbers outside of these two ranges: 60101-60501 and 74132-74532.例如,在第一个电子表格(图像链接)中,我想删除包含数字超出这两个范围的单元格的行:60101-60501 和 74132-74532。
Can anyone give me some pointers?谁能给我一些指示? Thanks!谢谢!
Code代码
You need to call it for your own needs as shown on the routine "Exec_DeleteRows".您需要根据自己的需要调用它,如例程“Exec_DeleteRows”所示。 I assumed that you needed if it is equals or less to the one that you state on your routine.我假设你需要它是否等于或小于你在例行程序中的 state。 In this example, I will delete the rows where values are between 501-570 and then the ones between 100-200在此示例中,我将删除值介于 501-570 之间的行,然后删除值介于 100-200 之间的行
Sub Exec_DeleteRows()
Call Exec_DeleteRowsInRangeBasedOnNumberValue(Range("C8:H11"), 501, 570)
Call Exec_DeleteRowsInRangeBasedOnNumberValue(Range("C8:H11"), 100, 200)
End Sub
Sub Exec_DeleteRowsInRangeBasedOnNumberValue(RangeToWorkIn As Range, NumPivotToDeleteRowBottom As Double, NumPivotToDeleteRowTop As Double)
Dim RangeRowsToDelete As Range
Dim ItemRange As Range
For Each ItemRange In RangeToWorkIn
If IsNumeric(ItemRange.Value) = False Then GoTo SkipStep1
If ItemRange.Value >= NumPivotToDeleteRowBottom And ItemRange.Value <= NumPivotToDeleteRowTop Then ' 1. If ItemRange.Value >= NumPivotToDeleteRowBottom And ItemRange.Value <= NumPivotToDeleteRowTop
If RangeRowsToDelete Is Nothing Then ' 2. If RangeRowsToDelete Is Nothing
Set RangeRowsToDelete = RangeToWorkIn.Parent.Rows(ItemRange.Row)
Else ' 2. If RangeRowsToDelete Is Nothing
Set RangeRowsToDelete = Union(RangeToWorkIn.Parent.Rows(ItemRange.Row), RangeRowsToDelete)
End If ' 2. If RangeRowsToDelete Is Nothing
End If ' 1. If ItemRange.Value >= NumPivotToDeleteRowBottom And ItemRange.Value <= NumPivotToDeleteRowTop
SkipStep1:
Next ItemRange
If Not (RangeRowsToDelete Is Nothing) Then RangeRowsToDelete.EntireRow.Delete
End Sub
Demo演示
A1
of worksheet Sheet1
in the workbook containing this code ( ThisWorkbook
) and has a row of headers ( 2
).假设数据从包含此代码 ( ThisWorkbook
) 的工作簿中的工作表Sheet1
的A1
开始,并具有一行标题 ( 2
)。If
statements.这只是熟悉变量、数据类型、对象、循环和If
语句的基本示例。 It can be improved on multiple accounts.它可以在多个帐户上进行改进。Option Explicit
Sub DeleteWrongRows()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim ws As Worksheet: Set ws = wb.Worksheets("Sheet1") ' worksheet
Dim rg As Range: Set rg = ws.Range("A1").CurrentRegion ' range
Application.ScreenUpdating = False
Dim rrg As Range ' Row Range
Dim rCell As Range ' Cell in Row Range
Dim rValue As Variant ' Value in Cell
Dim r As Long ' Row
Dim DoDelete As Boolean
' Loop backwards through the rows of the range.
For r = rg.Rows.Count To 2 Step -1
Set rrg = rg.Rows(r)
' Loop through cells in row.
For Each rCell In rrg.Cells
rValue = rCell.Value
If IsNumeric(rValue) Then ' is a number
If rValue >= 60101 And rValue <= 60501 Then ' keep
ElseIf rValue >= 74132 And rValue <= 74532 Then ' keep
Else ' delete (outside the number ranges)
DoDelete = True
End If
Else ' is not a number
DoDelete = True
End If
If DoDelete Then ' found a cell containing a wrong value
rCell.EntireRow.Delete
DoDelete = False
Exit For ' no need to check any more cells
'Else ' found no cell containing a wrong value (do nothing)
End If
Next rCell
Next r
Application.ScreenUpdating = True
MsgBox "Rows with wrong numbers deleted.", vbInformation
End Sub
Using Range.Delete is the built-in way of completely erasing a row in Excel VBA.使用Range.Delete是完全擦除 Excel VBA 中的一行的内置方法。 To check an entire row for numbers meeting a certain criteria, you would need a Loop and an If Statement .要检查一整行是否有符合特定条件的数字,您需要一个Loop和一个If 语句。
To evaluate a lot of values at a faster pace, it is smart to first grab the relevant data off the Excel sheet into an Array.为了以更快的速度评估大量值,明智的做法是首先将 Excel 表中的相关数据抓取到一个数组中。 Once in the array, it is easy to set up the loop to run from the first element ( LBound ) to the final element ( UBound ) for each row and column of the array.进入数组后,很容易将循环设置为从数组的每一行和每一列的第一个元素 ( LBound ) 运行到最后一个元素 ( UBound )。
Also, when deleting a lot of Ranges from a worksheet, it is faster and less messy to first collect ( Union ) the ranges while you're still looping, and then do the delete as a single step at the end.此外,当从工作表中删除大量 Ranges 时,在您仍在循环时首先收集( Union )范围,然后在最后作为单个步骤执行删除操作会更快且更简洁。 This way the Range addresses aren't changing during the loop and you don't need to re-adjust in order to track their new locations.这样,范围地址在循环期间不会改变,您无需重新调整以跟踪它们的新位置。 That and we can save a lot of time since the application wants to pause and recalculate the sheet after every Deletion.这可以节省大量时间,因为应用程序希望在每次删除后暂停并重新计算工作表。
All of those ideas put together:所有这些想法放在一起:
Sub Example()
DeleteRowsOutside Min:=60101, Max:=60501, OnSheet:=ThisWorkbook.Worksheets("Sheet1")
DeleteRowsOutside Min:=74132, Max:=74532, OnSheet:=ThisWorkbook.Worksheets("Sheet1")
End Sub
Sub DeleteRowsOutside(Min As Long, Max As Long, Optional OnSheet As Worksheet)
If OnSheet Is Nothing Then Set OnSheet = ActiveSheet
'Find the Bottom Corner of the sheet
Dim BottomCorner As Range
Set BottomCorner = OnSheet.Cells.Find("*", After:=OnSheet.Range("A1"), SearchDirection:=xlPrevious)
If BottomCorner Is Nothing Then Exit Sub
'Grab all values into an array
Dim ValArr() As Variant
ValArr = OnSheet.Range(OnSheet.Cells(1, 1), BottomCorner).Value
'Check each row value against min & max
Dim i As Long, j As Long, DeleteRows As Range
For i = LBound(ValArr, 1) To UBound(ValArr, 1) 'For each Row
For j = LBound(ValArr, 2) To UBound(ValArr, 2) 'For each column
Dim v As Variant: v = ValArr(i, j)
If IsNumeric(v) Then
If v < Min Or v > Max Then
'v is outside the acceptable range! Mark row for deletion
If DeleteRows Is Nothing Then
Set DeleteRows = OnSheet.Rows(i)
Else
Set DeleteRows = Union(DeleteRows, OnSheet.Rows(i))
End If
Exit For 'skip to next row
End If
End If
Next j
Next i
If Not DeleteRows Is Nothing Then DeleteRows.EntireRow.Delete
End Sub
Here's some code with Regex and with scripting dictionary that I've been working on.这是我一直在研究的带有正则表达式和脚本字典的一些代码。 I made this for my purposes, but it may be useful here and to others.我这样做是为了我的目的,但它在这里和其他人可能有用。
I found a way for selecting noncontinguous cells based on an array and then deleting those cells.我找到了一种基于数组选择非连续单元格然后删除这些单元格的方法。
In this case, I selected by row number because VBA prevented deletion of rows due to overlapping ranges.在这种情况下,我按行号选择,因为 VBA 由于重叠范围而阻止删除行。
Sub findvalues()
Dim Reg_Exp, regexMatches, dict As Object
Dim anArr As Variant
Dim r As Range, rC As Range
Set r = Sheets(3).UsedRange
Set r = r.Offset(1).Resize(r.Rows.Count - 1, r.Columns.Count)
Set Reg_Exp = CreateObject("vbscript.regexp")
With Reg_Exp
.Pattern = "^[6-6]?[0-0]?[1-5]?[0-0]?[1-1]?$|^60501$" 'This pattern is for the 60101 to 60501 range.
End With
Set dict = CreateObject("Scripting.Dictionary")
For Each rC In r
If rC.Value = "" Then GoTo NextRC ''skip blanks
Set regexMatches = Reg_Exp.Execute(rC.Value)
If regexMatches.Count = 0 Then
On Error Resume Next
dict.Add rC.Row & ":" & rC.Row, 1
End If
NextRC:
Next rC
On Error GoTo 0
anArr = Join(dict.Keys, ", ")
Sheets(3).Range(anArr).Delete Shift:=xlShiftUp
End Sub
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.