Vba 如何在sheet2中给定单元格值的情况下遍历sheet1中的行,并将sheet1中的行替换为sheet2中的行?
我必须在sheet2的同一列中找到并替换工作表1中给定匹配单元格值的行。列号为4 HELPPP 这就是我现在看到的,我在下一个x上得到一个错误Vba 如何在sheet2中给定单元格值的情况下遍历sheet1中的行,并将sheet1中的行替换为sheet2中的行?,vba,replace,Vba,Replace,我必须在sheet2的同一列中找到并替换工作表1中给定匹配单元格值的行。列号为4 HELPPP 这就是我现在看到的,我在下一个x上得到一个错误 Sub DeleteRows() Dim wb As Workbook Dim ws As Worksheet Dim ws2 As Worksheet Set wb = ActiveWorkbook Set ws = Sheets(Sheet1) Set ws2 = Sheets(sheet2)
Sub DeleteRows()
Dim wb As Workbook
Dim ws As Worksheet
Dim ws2 As Worksheet
Set wb = ActiveWorkbook
Set ws = Sheets(Sheet1)
Set ws2 = Sheets(sheet2)
With wb
For i = 1 To ws2.Cells(Rows.Count, 4).End(xlUp).Row
Dim lookupvalue As String
lookupvalue = ws2.Cells(i, 4).Value
For x = 1 To ws1.Cells(Rows.Count, 4).End(xlUp).Row
Dim rng As range
For Each rng In range("D:D")
If InStr(1, rng.Value, "lookupvalue") > 0 Then
rng.Delete
End If
Next x
exitloop:
Next i
End With
End Sub
正如A.S.H.所说,代码需要一些改进: 1) 这两个内部环路需要合并 2) 新的内部循环应该从下到上,因为您正在删除单元格,这可能就是为什么您有第二个内部循环,但这只会增加子循环的时间 3) 当前一次只删除一个单元格,其周围的任何数据都将保留。这可能是您想要的,所以我留下了它,但是如果您想删除整行,那么请取消注释执行该操作的行 4) 当使用instr函数进行测试时,变量不应在引号中,如果变量在引号中,它将查找特定单词“lookupvalues”,而不是指定给该变量的值 5) 正在使用的with块没有任何作用。使用with块时,使用with块的行必须以“.”开头。例如:在您的代码中,with是与工作簿一起使用的,因此每次使用工作表时,它都应该以“.”开头,如
.ws1…
等等。但是,通过使用工作簿声明工作表,这就不再需要了
Sub DeleteRows()
Dim wb As Workbook
Dim ws As Worksheet
Dim ws2 As Worksheet
Dim rng As Range
Dim lookupvalue As String
Set wb = ActiveWorkbook
Set ws = wb.Sheets("Sheet1")
Set ws2 = wb.Sheets("sheet2")
For i = 1 To ws2.Cells(Rows.Count, 4).End(xlUp).Row
lookupvalue = ws2.Cells(i, 4).Value
For x = ws.Cells(Rows.Count, 4).End(xlUp).Row To 1 Step -1
Set rng = ws.Cells(x, 4)
If InStr(1, rng.Value, lookupvalue) > 0 Then
rng.Delete 'this only deletes the cell
'You may want this instead
'rng.entirerow.delete
End If
Next x
Next i
End Sub
正如A.S.H.所说,代码需要一些改进: 1) 这两个内部环路需要合并 2) 新的内部循环应该从下到上,因为您正在删除单元格,这可能就是为什么您有第二个内部循环,但这只会增加子循环的时间 3) 当前一次只删除一个单元格,其周围的任何数据都将保留。这可能是您想要的,所以我留下了它,但是如果您想删除整行,那么请取消注释执行该操作的行 4) 当使用instr函数进行测试时,变量不应在引号中,如果变量在引号中,它将查找特定单词“lookupvalues”,而不是指定给该变量的值 5) 正在使用的with块没有任何作用。使用with块时,使用with块的行必须以“.”开头。例如:在您的代码中,with是与工作簿一起使用的,因此每次使用工作表时,它都应该以“.”开头,如
.ws1…
等等。但是,通过使用工作簿声明工作表,这就不再需要了
Sub DeleteRows()
Dim wb As Workbook
Dim ws As Worksheet
Dim ws2 As Worksheet
Dim rng As Range
Dim lookupvalue As String
Set wb = ActiveWorkbook
Set ws = wb.Sheets("Sheet1")
Set ws2 = wb.Sheets("sheet2")
For i = 1 To ws2.Cells(Rows.Count, 4).End(xlUp).Row
lookupvalue = ws2.Cells(i, 4).Value
For x = ws.Cells(Rows.Count, 4).End(xlUp).Row To 1 Step -1
Set rng = ws.Cells(x, 4)
If InStr(1, rng.Value, lookupvalue) > 0 Then
rng.Delete 'this only deletes the cell
'You may want this instead
'rng.entirerow.delete
End If
Next x
Next i
End Sub
我想提出另一种方法来处理这个问题,使用For-Each循环和Range对象的Find方法
Sub DeleteRows()
Dim wb As Workbook
Dim ws As Worksheet
Dim ws2 As Worksheet
Dim lookup_rng As Range
Dim lookupvalue As String
Dim search_rng As Range
Dim rng As Range
Dim match_rng As Range
Set wb = ActiveWorkbook
Set ws = wb.Sheets("Sheet1")
Set ws2 = wb.Sheets("Sheet2")
Set lookup_rng = Application.Intersect(ws2.Range("D:D"), ws.UsedRange)
Set search_rng = Application.Intersect(ws.Range("D:D"), ws2.UsedRange)
For Each rng In lookup_rng.Cells
lookupvalue = rng.Value
With search_rng
Set match_rng = .Find(lookupvalue, LookIn:=xlValues, LookAt:=xlPart, SearchDirection:=xlPrevious)
Do Until NoMoreMatches(match_rng)
match_rng.Delete 'Or match_rng.EntireRow.Delete if you want to delete the entire row.
Set match_rng = .FindPrevious
Loop
End With
Next
End Sub
Private Function NoMoreMatches(MatchRng As Range) As Boolean
NoMoreMatches = MatchRng Is Nothing
End Function
这种方法比Scott Craner的方法更浪费,因为Find方法总是从范围的末尾开始。然而,我认为它的优点是更容易阅读,也就是说,代码更直接地显示了它应该做什么
此外,使用此版本,您可以将循环提取到一个单独的子循环中,用于任意查找和搜索范围 我想提出另一种处理方法,使用For-Each循环和Range对象的Find方法
Sub DeleteRows()
Dim wb As Workbook
Dim ws As Worksheet
Dim ws2 As Worksheet
Dim lookup_rng As Range
Dim lookupvalue As String
Dim search_rng As Range
Dim rng As Range
Dim match_rng As Range
Set wb = ActiveWorkbook
Set ws = wb.Sheets("Sheet1")
Set ws2 = wb.Sheets("Sheet2")
Set lookup_rng = Application.Intersect(ws2.Range("D:D"), ws.UsedRange)
Set search_rng = Application.Intersect(ws.Range("D:D"), ws2.UsedRange)
For Each rng In lookup_rng.Cells
lookupvalue = rng.Value
With search_rng
Set match_rng = .Find(lookupvalue, LookIn:=xlValues, LookAt:=xlPart, SearchDirection:=xlPrevious)
Do Until NoMoreMatches(match_rng)
match_rng.Delete 'Or match_rng.EntireRow.Delete if you want to delete the entire row.
Set match_rng = .FindPrevious
Loop
End With
Next
End Sub
Private Function NoMoreMatches(MatchRng As Range) As Boolean
NoMoreMatches = MatchRng Is Nothing
End Function
这种方法比Scott Craner的方法更浪费,因为Find方法总是从范围的末尾开始。然而,我认为它的优点是更容易阅读,也就是说,代码更直接地显示了它应该做什么
此外,使用此版本,您可以将循环提取到一个单独的子循环中,用于任意查找和搜索范围 您在x上出现了什么错误?您错过了
下一个rng
之前的下一个x
。这应该可以修复错误,但我仍然高度怀疑这是否能让代码实现您想要的功能。x上的循环似乎没有用。x上出现了什么错误?在下一个x
之前,您错过了下一个rng
。这应该可以修复错误,但我仍然高度怀疑这是否能让代码实现您想要的功能。x上的循环似乎没用。谢谢大家的快速回复和评论。知道我为什么会出现编译错误吗:rng上的下一个控制变量引用无效?@ichoi opps,对不起,中途更改了循环,忘了更改下一个。我编辑了代码。是的,这是我最初认为你的意思,但如果我做了更改,我会得到另一个错误,即在Set ws=wb.Sheets(Sheet1)@ichoi上键入mistmatch,这是图纸的命名方式,它们需要用引号括起来。Sub DeleteRows()将wb设置为工作簿将ws2设置为工作表将ws2设置为工作表将rng设置为范围将查找值设置为变量集wb=ActiveWorkbook Set ws1=wb.Sheets(“Sheet1”)将ws2=wb.Sheets(“Sheet2”)设置为i=1到ws2.Cells(Rows.Count,4)的单元格(Rows.Count,4)结束(xlUp)。Row lookupvalue=ws2.Cells(i,4)。x=ws1.Cells(Rows.Count,4)的值结束(xlUp).Row To 1步骤-1设置rng=ws1。单元格(x,4)如果rng=lookupvalue,则为rng.EntireRow.Delete End如果Next x Next i End,则为快速回复和注释的所有子行。知道我为什么会出现编译错误吗:rng上的下一个控制变量引用无效?@ichoi opps,对不起,中途更改了循环,忘了更改下一个。我编辑了代码。是的,这是我最初认为你的意思,但如果我做了更改,我会得到另一个错误,即在Set ws=wb.Sheets(Sheet1)@ichoi上键入mistmatch,这是图纸的命名方式,它们需要用引号括起来。Sub DeleteRows()将wb设置为工作簿将ws2设置为工作表将ws2设置为工作表将rng设置为范围将查找值设置为变量集wb=ActiveWorkbook Set ws1=wb.Sheets(“Sheet1”)将ws2=wb.Sheets(“Sheet2”)设置为i=1到ws2.Cells(Rows.Count,4)的单元格(Rows.Count,4)结束(xlUp)。Row lookupvalue=ws2.Cells(i,4)。x=ws1.Cells(Rows.Count,4)的值结束(xlUp).Row To 1步骤-1设置rng=ws1。单元格(x,4)如果rng=lookupvalue,则rng.EntireRow.Delete End如果Next x Next i End Sub