Vba 如何在sheet2中给定单元格值的情况下遍历sheet1中的行,并将sheet1中的行替换为sheet2中的行?

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)

我必须在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)

    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