我有一个msgbox,让用户输入一个值。然后,我的工作簿在另一个名为“值”的工作表中查找该值。在大多数情况下,该表中有多个此值的实例。
然后我从该行(ID)中取另一个值并使用格式“[InputValue] [ID]”在名为“Req Raw”的第三张表中查找它,其中ID是格式为“0000”的数字字符串”。
然后,工作簿会删除“Req Raw”和“Values”中的那一行并重复;继续在'Values'中查找输入值。
'SecDelete = Input Value
'VSect = Range in sheet 'Values'
'RReq = Range in sheet 'Req Raw'
With ThisWorkBook.Worksheets("Values")
For Each VSecT In .Range(.Cells(.Cells(Rows.count, 2).End(xlUp).Row, 2), .Cells(15, 2))
If LCase(VSecT.Value) = LCase(SecDelete) Then
'Identify ID
IDF = CStr(VSecT.Offset(columnOffset:=3).Value)
IDF = Format(IDF, "0000")
'Find offset ID in 'Req Raw'
For Each RReq In ThisWorkbook.Worksheets("Req Raw").Range(ThisWorkbook.Worksheets("Req Raw").Cells(ThisWorkbook.Worksheets("Req Raw").Cells(Rows.count, 1).End(xlUp).Row, 1), _
ThisWorkbook.Worksheets("Req Raw").Cells(2, 1))
If RReq.Value = VSecT.Value & " " & IDF Then
'Delete from 'Req Raw'
RReq.EntireRow.Delete
Exit For
End If
Next RReq
'Delete from 'Values'
VSecT.EntireRow.Delete
End If
Next VSecT
End With
我发现由于某种原因,删除了随机数量的行而不是输入值的所有行。
例如,如果我的输入值是“Test 1.0”,并且“Values”表中有10个实例,其中存在“Test 1.0”,相应的ID为0000,0001,0002,...,0010,只有一些每次运行sub时都会删除行。在删除所有包含“Test 1.0”的行之前,我必须运行7-8次。
请注意,我在两个For Each
语句中向后循环。
答案 0 :(得分:1)
以下是您的代码的一部分被重写,以适应向后行走。请注意,我也调整了字符串连接。
Dim rw1 As Long, rw2 As Long
With ThisWorkbook.Worksheets("Values")
For rw1 = .Cells(Rows.Count, 2).End(xlUp).Row To 15 Step -1
If LCase(VSecT.Value) = LCase(SecDelete) Then
'Identify ID
IDF = .Cells(rw1, 2).Value & Format(.Cells(rw1, 2).Offset(columnOffset:=3).Value, " 0000")
'Find offset ID in 'Req Raw'
With ThisWorkbook.Worksheets("Req Raw")
For rw2 = .Cells(Rows.Count, 1).End(xlUp).Row To 2 Step -1
If .Cells(rw2, 1).Value = IDF Then
'Delete from 'Req Raw'
.Rows(rw2).EntireRow.Delete
Exit For
End If
Next RReq
End With
'Delete from 'Values'
.Rows(rw1).EntireRow.Delete
End If
Next rw1
End With
简单地说,您可以将范围定义为.Range("A10:A1")
,但如果您使用For Each / Next爬行单元格,您仍将继续浏览A1,A2,A3 .... A10。步骤-1的数字行号是最好的(仅...?)方式向后处理数据集。
答案 1 :(得分:0)
这背后的原因是我相信的细胞寻址。如果你循环范围,例如像这样的a1到a10
range("a1:a10").select
for each cell in selection
if cell.value = something then
cell.entirerow.delete
end if
next cell
它类似于你的代码,那么当第2行被删除时会发生什么?所有单元格向上移动,因此下一次运行中的宏会跳过地址A2(实际上在删除之前为A3),因为循环已经通过了它。在algorythm中有一个洞,你需要的是每次宏删除一行时返回一行,所以你需要像这样重建宏(对于我的例子):
for i = 1 to 10
if range("a" & i ).value = something
range("a" & i).entirerow.delete
i = i - 1
next i ' so that each time something is deleted loop steps backward to catch shifted value
希望这会有所帮助,欢呼
答案 2 :(得分:0)
当我必须从设定范围中删除行时,我在混合If语句以搜索将要删除的行时所做的是,例如,更改给定列中的单元格的值(我知道总是有价值)空白。然后使用specialcells空白我选择所有新的空白单元格,然后删除整行。
答案 3 :(得分:0)
我不喜欢在循环中删除,此代码将构建范围引用(Rng)并在最后一次删除所有行。
Sub DeleteBlanks()
Dim Rng As Range, X As Long
For X = 1 To Range("A" & Rows.Count).End(xlUp).Row
If Range("A" & X).Text = "" Then
If Rng Is Nothing Then 'This has to be in here because you can't union a range if it is currently nothing
Set Rng = Range("A" & X)
Else
Set Rng = Union(Rng, Range("A" & X))
End If
End If
Next
If Not Rng Is Nothing Then Rng.Rows.Delete 'If no blanks are found, this will stop it erroring. Only delete when there is something in Rng
End Sub