我有两张纸,其中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
答案 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
。
此外,您通常应该(但特别是在使用两张不同的工作表或两本不同的工作簿时)明确定义范围,因此如果所选范围不是正在处理的工作表,则不会出现错误。通过设置Workbook
和Worksheet
变量并将其用于所有.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
希望这接近你所需要的。没办法测试它,所以我留给你。