ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 65355|回复: 37

[转帖] FIND,FINDNEXT的用法

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2014-10-10 09:26 | 显示全部楼层 |阅读模式
本帖最后由 HAPPY_1117 于 2014-10-10 10:00 编辑

本文整理了以前的一些关于Find方法的文章,作为Excel VBA应用大全的一部分。
转自http://www.excelperfect.com/index.php/2009/08/16/findmethod/
1. Find方法的作用
使用VBA在工作表或单元格区域中查找某项数据时,我们通常使用For…Next循环,这在小范围中使用还可以,但应用在大量数据中查找时,会耗费较多时间。
而在Excel工作表中,通常使用菜单“编辑>>查找”命令或按Ctrl+F组合键,在“查找和替换”对话框中来迅速查找所需的数据。在VBA中,我们也能使用这种方法,即Find方法,这在下面的内容中介绍。
Find方法将在指定的单元格区域中查找包含参数指定数据的单元格,若找到符合条件的数据,则返回包含该数据的单元格;若未发现相匹配的数据,则返回Nothing。该方法返回一个Range对象,在使用该方法时,不影响选定区域或活动单元格。
为什么要使用Find方法呢?最主要的原因是查找的速度。如果要使用VBA代码在包含大量数据的单元格区域中查找某项数据,应该使用Find方法。
例如,在工作表Sheet1的单元格IV65536中输入fanjy,然后运行下面的代码:
Sub QuickSearch()   
If Not Sheet1.Cells.Find("fanjy") Is Nothing Then MsgBox "已找到fanjy!"
End Sub

再试试下面的代码:
Sub SlowSearch()   
Dim R As Range   
For Each R In Sheet1.Cells        
If R.Value = "fanjy" Then MsgBox "已找到fanjy!"   
Next R
End Sub

比较一下两段代码的速度,可知第一段代码运行很快,而第二段代码却要执行相当长的一段时间。
2. Find方法的语法
[语法]
<单元格区域>.Find (What,[After],[LookIn],[LookAt],[SearchOrder],[SearchDirection],[MatchCase],[MatchByte],[SearchFormat])

[参数说明]
(1)<单元格区域>,必须指定,返回一个Range对象。
(2)参数What,必需指定。代表所要查找的数据,可以为字符串、整数或者其它任何数据类型的数据。对应于“查找与替换”对话框中,“查找内容”文本框中的内容。
(3)参数After,可选。指定开始查找的位置,即从该位置所在的单元格之后向后或之前向前开始查找(也就是说,开始时不查找该位置所在的单元格,直到Find方法绕回到该单元格时,才对其内容进行查找)。所指定的位置必须是单元格区域中的单个单元格,如果未指定本参数,则将从单元格区域的左上角的单元格之后开始进行查找。
(4)参数LookIn,可选。指定查找的范围类型,可以为以下常量之一:xlValues、xlFormulas或者xlComments,默认值为xlFormulas。对应于“查找与替换”对话框中,“查找范围”下拉框中的选项。
(5)参数LookAt,可选。可以为以下常量之一:XlWhole或者xlPart,用来指定所查找的数据是与单元格内容完全匹配还是部分匹配,默认值为xlPart。对应于“查找与替换”对话框中,“单元格匹配”复选框。
(6)参数SearchOrder,可选。用来确定如何在单元格区域中进行查找,是以行的方式(xlByRows)查找,还是以列的方式(xlByColumns)查找,默认值为xlByRows。对应于“查找与替换”对话框中,“搜索”下拉框中的选项。
(7)参数SearchDirection,可选。用来确定查找的方向,即是向前查找(XlPrevious)还是向后查找(xlNext),默认的是向后查找。
(8)参数MatchCase,可选。若该参数值为True,则在查找时区分大小写。默认值为False。对应于“查找与替换”对话框中,“区分大小写”复选框。
(9)参数MatchByter,可选。即是否区分全角或半角,在选择或安装了双字节语言时使用。若该参数为True,则双字节字符仅与双字节字符相匹配;若该参数为False,则双字节字符可匹配与其相同的单字节字符。对应于“查找与替换”对话框中,“区分全角/半角”复选框。
(10)参数SearchFormat,可选,指定一个确切类型的查找格式。对应于“查找与替换”对话框中,“格式”按钮。当设置带有相应格式的查找时,该参数值为True。
(11)在每次使用Find方法后,参数LookIn、LookAt、SearchOrder、MatchByte的设置将保存。如果下次使用本方法时,不改变或指定这些参数的值,那么该方法将使用保存的值。
在VBA中设置的这些参数将更改“查找与替换”对话框中的设置;同理,更改“查找与替换”对话框中的设置,也将同时更改已保存的值。也就是说,在编写好一段代码后,若在代码中未指定上述参数,可能在初期运行时能满足要求,但若用户在“查找与替换”对话框中更改了这些参数,它们将同时反映到程序代码中,当再次运行代码时,运行结果可能会产生差异或错误。若要避免这个问题,在每次使用时建议明确的设置这些参数。
3. Find方法使用示例
3.1 本示例在活动工作表中查找what变量所代表的值的单元格,并删除该单元格所在的列。
Sub Find_Error()  
Dim rng As Range  
Dim what As String  
what = "Error"  Do   
Set rng = ActiveSheet.UsedRange.Find(what)   
If rng Is Nothing Then      
Exit Do   
Else       Columns(rng.Column).Delete   
End If  
Loop
End Sub

3.2 带格式的查找
本示例在当前工作表单元格中查找字体为”Arial Unicode MS”且颜色为红色的单元格。其中,Application.FindFormat对象允许指定所需要查找的格式,此时Find方法的参数SearchFormat应设置为True。
Sub FindWithFormat()  
With Application.FindFormat
        .Font
        .Name = "Arial Unicode MS"
        .ColorIndex = 3
  End With
  Cells.Find(what:="", SearchFormat:=True).Activate
End Sub

[小结] 在使用Find方法找到符合条件的数据后,就可以对其进行相应的操作了。您可以:




  • 对该数据所在的单元格进行操作;
  • 对该数据所在单元格的行或列进行操作;
  • 对该数据所在的单元格区域进行操作;

4. 与Find方法相联系的方法
可以使用FindNext方法和FindPrevious方法进行重复查找。在使用这两个方法之前,必须用Find方法指定所需要查找的数据内容。
4.1 FindNext方法
FindNext方法对应于“查找与替换”对话框中的“查找下一个”按钮。可以使用该方法继续执行查找,查找下一个与Find方法中所指定条件的数据相匹配的单元格,返回代表该单元格的Range对象。在使用该方法时,不影响选定区域或活动单元格。
4.1.1 语法
<单元格区域>.FindNext(After)

4.1.2 参数说明
参数After,可选。代表所指定的单元格,将从该单元格之后开始进行查找。开始时不查找该位置所在的单元格,直到FindNext方法绕回到该单元格时,才对其内容进行查找。所指定的位置必须是单元格区域中的单个单元格,如果未指定本参数,则将从单元格区域的左上角的单元格之后开始进行查找。
当查找到指定查找区域的末尾时,本方法将环绕至区域的开始继续查找。发生环绕后,为停止查找,可保存第一次找到的单元格地址,然后测试下一个查找到的单元格地址是否与其相同,作为判断查找退出的条件,以避免出现死循环。当然,如果在查找的过程中,将查找到的单元格数据进行了改变,也可不作此判断,如下例所示。
4.2 FindPrevious方法
可以使用该方法继续执行Find方法所进行的查找,查找前一个与Find方法中所指定条件的数据相匹配的单元格,返回代表该单元格的Range对象。在使用该方法时,不影响选定区域或活动单元格。
4.2.1 语法
<单元格区域>.FindPrevious(After)

4.2.2 参数说明
参数After,可选。代表所指定的单元格,将从该单元格之前开始进行查找。开始时不查找该位置所在的单元格,直到FindPrevious方法绕回到该单元格时,才对其内容进行查找。所指定的位置必须是单元格区域中的单个单元格,如果未指定本参数,则将从单元格区域的左上角的单元格之前开始进行查找。
当查找到指定查找区域的起始位置时,本方法将环绕至区域的末尾继续查找。发生环绕后,为停止查找,可保存第一次找到的单元格地址,然后测试下一个查找到的单元格地址是否与其相同,作为判断查找退出的条件,以避免出现死循环。
4.2.3 示例
在工作表中输入如下图1所示的数据,至少保证在A列中有两个单元格输入了数据“excelhome”。
图1:测试的数据
在VBE编辑器中输入下面的代码测试Find方法、FindNext方法、FindPrevious方法,体验各个方法所查找到的单元格位置。
Sub testFind()
Dim findValue As Range
  Set findValue = Worksheets("Sheet1").Columns("A").Find(what:="excelhome")
  MsgBox "第一个数据发现在单元格:" & findValue.Address
  Set findValue = Worksheets("Sheet1").Columns("A").FindNext(After:=findValue)
  MsgBox "下一个数据发现在单元格:" & findValue.Address
  Set findValue = Worksheets("Sheet1").Columns("A").FindPrevious(After:=findValue)
  MsgBox "前一个数据发现在单元格" & findValue.Address
End Sub


评分

6

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-10-10 09:30 | 显示全部楼层
本帖最后由 HAPPY_1117 于 2014-10-10 09:57 编辑

5. 综合示例
[示例1]查找值并选中该值所在的单元格
[示例1-1]
Sub Find_First()
    Dim FindString As String
    Dim rng As Range
    FindString = InputBox("请输入要查找的值:")
    If Trim(FindString) <> "" Then
        With Sheets("Sheet1").Range("A:A")
            Set rng = .Find(What:=FindString, _
                            After:=.Cells(.Cells.Count), _
                            LookIn:=xlValues, _
                            LookAt:=xlWhole, _
                            SearchOrder:=xlByRows, _
                            SearchDirection:=xlNext, _
                            MatchCase:=False)
            If Not rng Is Nothing Then
                Application.Goto rng, True
            Else
                MsgBox "没有找到!"
            End If
        End With
    End If
End Sub

示例说明:运行程序后,将在工作表Sheet1的A列中查找InputBox函数输入框中所输入的值,并查找该值所在的第一个单元格,如果没有找到该值,则显示消息框“没有找到!”。语句Application.Goto rng, True的作用是将窗口滚动至该单元格,即该单元格位于当前窗口的左上方。
[示例1-2]
Sub Find_Last()   
Dim FindString As String   
Dim rng As Range   
FindString = InputBox("请输入要查找的值")   
If Trim(FindString) <> "" Then      
With Sheets("Sheet1").Range("A:A")            
Set rng = .Find(What:=FindString, _                           
                            After:=.Cells(1), _
                            LookIn:=xlValues, _
                            LookAt:=xlWhole, _
                            SearchOrder:=xlByRows, _
                            SearchDirection:=xlPrevious, _
                            MatchCase:=False)
            If Not rng Is Nothing Then
                Application.Goto rng, True
            Else
                MsgBox "Nothing found"
            End If
        End With
  End If
End Sub

示例说明:与上面的程序不同的是,运行该程序后,将在工作表Sheet1的A列中查找InputBox函数输入框中所输入的值,并选中该值所在的最后一个单元格。请比较代码中Find方法的参数。
[示例1-3]
Sub Find_Todays_Date()
    Dim FindString As Date
    Dim rng As Range
    FindString = Date    With Sheets("Sheet1").Range("A:A")
        Set rng = .Find(What:=FindString, _
                        After:=.Cells(.Cells.Count), _
                        LookIn:=xlFormulas, _
                        LookAt:=xlWhole, _
                        SearchOrder:=xlByRows, _
                        SearchDirection:=xlNext, _
                        MatchCase:=False)
        If Not rng Is Nothing Then
            Application.Goto rng, True
        Else
            MsgBox "没有找到!"
       End If
    End With
End Sub

示例说明:运行程序后,将在工作表Sheet1的A列中查找日期所在的单元格,并选中第一个日期单元格。
[示例2]在B列中标出A列中有相应值的单元格
Sub Mark_cells_in_column()
    Dim FirstAddress As String
    Dim myArr As Variant
    Dim rng As Range
    Dim I As Long
     Application.ScreenUpdating = False
    myArr = Array("VBA")    '也能够在数组中使用更多的值,如下所示    'myArr = Array("VBA", "VSTO")
    With Sheets("Sheet2").Range("A:A")
         .Offset(0, 1).ClearContents        '清除右侧单元格中的内容
         For I = LBound(myArr) To UBound(myArr)
            Set rng = .Find(What:=myArr(I), _
                            After:=.Cells(.Cells.Count), _
                            LookIn:=xlFormulas, _
                            LookAt:=xlWhole, _
                            SearchOrder:=xlByRows, _
                            SearchDirection:=xlNext, _
                            MatchCase:=False)            '如要想查找rng.value中的一部分,可使用参数值xlPart            '如果使用LookIn:=xlValues,也会处理公式单元格中与条件相同的值
             If Not rng Is Nothing Then
                FirstAddress = rng.Address
                Do
                    rng.Offset(0, 1).Value = "X"                    '如果值VBA找到,则在该单元格的右侧列中的相应单元格作上标记
                    Set rng = .FindNext(rng)
                Loop While Not rng Is Nothing And rng.Address <> FirstAddress
            End If
        Next I
    End With
    Application.ScreenUpdating = True
End Sub

示例说明:运行程序后,将查找工作表Sheet2上A列中的每个单元格,并在值为“VBA”所在的单元格的右侧单元格中作出标记“X”。
[示例3]为区域中指定值的单元格填充颜色
Sub Color_cells_in_Range()
    Dim FirstAddress As String
    Dim MySearch As Variant
    Dim myColor As Variant
    Dim rng As Range
    Dim I As Long
     MySearch = Array("VBA")
    myColor = Array("3")     '也能在数组中使用多个值    'MySearch = Array("VBA", "Hello", "OK")    'myColor = Array("3", "6", "10")
     With Sheets("Sheet3").Range("A1:C4")         '将所有单元格中的填充色改为无填充色
        .Interior.ColorIndex = xlColorIndexNone
          For I = LBound(MySearch) To UBound(MySearch)
            Set rng = .Find(What:=MySearch(I), _
                            After:=.Cells(.Cells.Count), _
                            LookIn:=xlFormulas, _
                            LookAt:=xlWhole, _
                            SearchOrder:=xlByRows, _
                            SearchDirection:=xlNext, _
                            MatchCase:=False)            '如果想查找rng.value的一部分,则使用参数值xlPart            '如果使用LookIn:=xlValues,则也会处理公式单元格
             If Not rng Is Nothing Then
                FirstAddress = rng.Address
                Do
                    rng.Interior.ColorIndex = myColor(I)
                    Set rng = .FindNext(rng)
                Loop While Not rng Is Nothing And rng.Address <> FirstAddress
            End If
        Next I
    End With
End Sub

示例说明:运行程序后,将在工作表Sheet3上的单元格区域A1:C4中查找含有“VBA”的单元格,并将这些单元格填充为红色。如示例中的注释所提示的,也可以使用数组,将不同的值所在的单元格标记为不同的颜色。
也可以添加下面的语句,改变单元格中文本的颜色:
.Font.ColorIndex=0.Font.ColorIndex=myColor(I)

[示例4]为工作表中指定值的单元格填充颜色
Sub Color_cells_in_Sheet()
    Dim FirstAddress As String
    Dim MySearch As Variant
    Dim myColor As Variant
    Dim rng As Range
    Dim I As Long
     MySearch = Array("VBA")
     myColor = Array("3")     '也能在数组中使用多个值    'MySearch = Array("VBA", "Hello", "OK")    'myColor = Array("3", "6", "10")
     With Sheets("Sheet4").Cells         '将所有单元格中的填充色改为无填充色
        .Interior.ColorIndex = xlColorIndexNone
         For I = LBound(MySearch) To UBound(MySearch)
            Set rng = .Find(What:=MySearch(I), _
                            After:=.Cells(.Cells.Count), _
                            LookIn:=xlFormulas, _
                            LookAt:=xlWhole, _
                            SearchOrder:=xlByRows, _
                            SearchDirection:=xlNext, _
                            MatchCase:=False)           '如果想查找rng.value的一部分,则使用参数值xlPart           '如果使用LookIn:=xlValues,则也会处理公式单元格
             If Not rng Is Nothing Then
                FirstAddress = rng.Address
                Do
                    rng.Interior.ColorIndex = myColor(I)
                    Set rng = .FindNext(rng)
                Loop While Not rng Is Nothing And rng.Address <> FirstAddress
            End If
        Next I
    End With
End Sub

示例说明:运行程序后,将在工作表Sheet4中查找含有“VBA”的单元格,并将这些单元格填充为红色。如示例中的注释所提示的,也可以使用数组,将不同的值所在的单元格标记为不同的颜色。
也可以添加下面的语句,改变单元格中文本的颜色:

TA的精华主题

TA的得分主题

发表于 2014-10-10 09:54 | 显示全部楼层
HAPPY_1117 发表于 2014-10-10 09:30
5. 综合示例
[示例1]查找值并选中该值所在的单元格
[示例1-1]

你这样能上人看吗,太吃力了
[示例4]为工作表中指定值的单元格填充颜色
  1. Sub Color_cells_in_Sheet()
  2.     Dim FirstAddress As String
  3.     Dim MySearch As Variant
  4.     Dim myColor As Variant
  5.     Dim rng As Range
  6.     Dim I As Long

  7.     MySearch = Array("VBA")
  8.     myColor = Array("3")

  9.     '也能在数组中使用多个值
  10.     'MySearch = Array("VBA", "Hello", "OK")
  11.     'myColor = Array("3", "6", "10")

  12.     With Sheets("Sheet4").Cells

  13.         '将所有单元格中的填充色改为无填充色
  14.         .Interior.ColorIndex = xlColorIndexNone

  15.         For I = LBound(MySearch) To UBound(MySearch)
  16.             Set rng = .Find(What:=MySearch(I), _
  17.                             After:=.Cells(.Cells.Count), _
  18.                             LookIn:=xlFormulas, _
  19.                             LookAt:=xlWhole, _
  20.                             SearchOrder:=xlByRows, _
  21.                             SearchDirection:=xlNext, _
  22.                             MatchCase:=False)
  23.            '如果想查找rng.value的一部分,则使用参数值xlPart
  24.            '如果使用LookIn:=xlValues,则也会处理公式单元格

  25.             If Not rng Is Nothing Then
  26.                 FirstAddress = rng.Address
  27.                 Do
  28.                     rng.Interior.ColorIndex = myColor(I)
  29.                     Set rng = .FindNext(rng)
  30.                 Loop While Not rng Is Nothing And rng.Address <> FirstAddress
  31.             End If
  32.         Next I
  33.     End With
  34. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-10-10 09:58 | 显示全部楼层
wj2368 发表于 2014-10-10 09:54
你这样能上人看吗,太吃力了
[示例4]为工作表中指定值的单元格填充颜色

恩恩 ,我已经改过来了

TA的精华主题

TA的得分主题

发表于 2014-10-10 10:02 | 显示全部楼层
善于实践并总结的人,最终必将成功.
楼主还可以深入一步,关于时间的查找(分使用xlvalues和xlformulas两种情况).

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-10-10 10:11 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
liu-aguang 发表于 2014-10-10 10:02
善于实践并总结的人,最终必将成功.
楼主还可以深入一步,关于时间的查找(分使用xlvalues和xlformulas两种情 ...

FIND我只会皮毛,你说的时间查询以后我会试试看看

TA的精华主题

TA的得分主题

发表于 2015-3-29 23:11 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2015-4-4 00:11 | 显示全部楼层
wj2368 发表于 2014-10-10 09:54
你这样能上人看吗,太吃力了
[示例4]为工作表中指定值的单元格填充颜色

谢谢分亨。

TA的精华主题

TA的得分主题

发表于 2015-4-4 08:04 | 显示全部楼层
学习、总结、分享、交流,支持楼主的精神。

TA的精华主题

TA的得分主题

发表于 2015-5-6 21:38 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-20 10:59 , Processed in 0.057746 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表