寻找在另一张纸上包含特定值的单元格

时间:2013-12-31 10:39:26

标签: excel-vba vba excel

我有两张纸,其中Sheet 1在C列中有许多帐户名,而Sheet 2在B列中有一个帐户名列表。

我想在Sheet 1 C列中搜索所有单元格,其中值包含Sheet 2 B列中的单元格值,高亮显示黄色。

以下是我的代码,我不断收到错误消息“Objectiv Variable或With Block variable not set”或“Subsript without range”。

Sub search_name() ' ' search_name Macro
    Dim a As Range
    Set a = Sheets("NAMES").Range("B1")
    For Each a In Sheets("NAMES").Range("B1:B88")
      Sheets("MASTER").Select
      Columns("C:C").Select
      Selection.Find(a, After:=ActiveCell, LookIn:=xlFormulas, _
        LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
        MatchCase:=False, SearchFormat:=False).Activate
      Application.CutCopyMode = False
      With ActiveCell.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .Color = 65535
        .TintAndShade = 0
        .PatternTintAndShade = 0
      End With
    Next a
End Sub

4 个答案:

答案 0 :(得分:1)

如果在主表单中找不到名称表单中的值,则会出现“对象变量或未设置块变量”错误。

您需要在代码中添加错误处理

Sub search_name() ' ' search_name Macro
    Dim a As Range
    Set a = Sheets("NAMES").Range("B1")
    For Each a In Sheets("NAMES").Range("B1:B3")
      Sheets("MASTER").Select
      Columns("C:C").Select
  On Error GoTo err: 'added this
      Selection.Find(a, After:=ActiveCell, LookIn:=xlFormulas, _
        LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
        MatchCase:=False, SearchFormat:=False).Activate
      Application.CutCopyMode = False
      With ActiveCell.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .Color = 65535
        .TintAndShade = 0
        .PatternTintAndShade = 0
      End With

  err: ' added this
    Next a
End Sub

答案 1 :(得分:1)

您可以使用conditional formatting来获得相同的结果。

C的{​​{1}}栏上添加以下规则并设置格式(例如黄色背景)

MASTER

如果您要在=NOT(ISNA(VLOOKUP(C1,Names!$B$1:$B$3,1,FALSE))) 和/或NAMES工作表中添加名称,则会更有帮助,因为您无需继续运行宏。

答案 2 :(得分:1)

Vasim说要添加错误处理,但提供的解决方案只是忽略了你收到错误的原因(下一步使循环继续进行,好像什么也没发生),如果修改或扩展代码,可能会导致以后的错误。最好解决这个问题,即定义的搜索可能找不到要突出显示的值(这可能是意料之外的,但是您在搜索中包含列标题,因此如果它们不匹配则您找不到值对于搜索的第一次迭代)。

所以:首先你应该确保找到的值不是什么。 .Find返回一个范围值,因此您可以将找到的值分配给范围变量,并使用If语句确定找到的范围是否存在:If Not FoundRange is Nothing Then

此外,您通常应该(但特别是在使用两张不同的工作表或两本不同的工作簿时)明确定义范围,因此如果所选范围不是正在处理的工作表,则不会出现错误。通过设置WorkbookWorksheet变量并将其用于所有.Range声明来完成此操作:wb.wsA.Range("C:C")

最后,考虑尽可能不使用Select方法(几乎总是如此)。作为Excel的用户,我们必须在使用它们之前选择单元格,但VBA没有这个限制,如果您的代码在使用它们之前没有选择或激活单元格,它会快得多。

我已经重写了你的代码,包含了所有三个建议。希望这有助于您了解正在发生的事情。

Sub search_name2() '' search_name Macro

    '~~>dim variables and initial values
        Dim wb As Workbook
            Set wb = ActiveWorkbook
        Dim wsM As Worksheet
            Set wsM = wb.Worksheets("MASTER")
        Dim wsA As Worksheet
            Set wsA = wb.Worksheets("NAMES")
        Dim rngA As Range
            Set rngA = wsA.Range("B1", wsA.Range("B65536").End(xlUp))
        Dim rngCell As Range
        Dim rngFound As Range

    '~~>loop to find matches between worksheet ranges
        For Each rngCell In rngA
          Set rngFound = wsM.Range("C:C").Find(rngCell.Value, After:=wsM.Range("C1"), _
            LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
            MatchCase:=False, SearchFormat:=False)
          Application.CutCopyMode = False
          If Not rngFound Is Nothing Then
            With rngFound.Interior
              .Pattern = xlSolid
              .PatternColorIndex = xlAutomatic
              .Color = 65535
              .TintAndShade = 0
              .PatternTintAndShade = 0
            End With
          End If
        Next rngCell

End Sub

答案 3 :(得分:0)

您应该清理变量声明。试试这个:

Dim ws1 as Worksheet, ws2 as Worksheet
Dim search_range as Range, search_value as Range
Dim acct_name as Range, foundcell as Range, lastcell as Range
Dim firstaddr as String

Set ws1 = Thisworkbook.Sheets("NAMES")
Set ws2 = Thisworkbook.Sheets("MASTER")
Set search_value = ws1.Range("B1:B" & ws1.Range("B" & Rows.Count).End(xlUp).Row)
Set search_range = ws2.Range("C1:C" & ws2.Range("C" & Rows.Count).End(xlUp).Row)
Set lastcell = search_range.Cells(search_range.Cells.Count)

For Each acct_name In search_value

    Set foundcell = search_range.Find(What:=acct_name, After:=lastcell)

    If Not foundcell Is Nothing Then firstaddr = foundcell.Address

    Do Until foundcell Is Nothing
        With foundcell.Interior
            .Pattern = xlSolid
            .PatternColorIndex = xlAutomatic
            .Color = 65535
            .TintAndShade = 0
            .PatternTintAndShade = 0
        End With

        Set foundcell = search_range.FindNext(After:=foundcell)

        If foundcell.Address = firstaddr Then Exit Do
    Loop
Next acct_name

希望这接近你所需要的。没办法测试它,所以我留给你。