分享

Excel VBA解读(41):藏得再好也能找到——使用Find方法实现查找

 L罗乐 2016-10-14

 

生活中有许多怪现象,例如,我就经常碰到这样的事情,当我想要某件东西时,找半天也总是找不到,可不想要它时,却冒了出来,你说气不气人!

找东西绝不是一件有趣的事儿!

 

Excel考虑得很周全,为你准备了查找功能,能够在大量的工作表数据中找出特定的数据。下面的图演示了我们在Excel中常用的查找操作:


                           

在图示工作表中,我们要查找内容为“1”的单元格,在查找与替换对话框的查找内容中输入“1”,单击查找全部按钮,即可显示所查找到的详细信息,并且工作表中会选择查找到的第一个单元格。

如果单击对话框中查找下一个按钮,那么活动单元格会在查找到的单元格中循环移动。

 

我们来看看宏录制器录制上述操作后生成的代码。如果仅单击查找全部按钮,宏录制器不会生成任何代码,只有当单击相找下一个按钮时,宏录制器才会录制代码。我单击了查找下一个按钮三次,即依次选择包含“1”的单元格A1D2B3。录制的代码如下:

 

Sub 5()

'

' 5

'

 

'

    Cells.Find(What:='1',After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _

        xlPart, SearchOrder:=xlByRows,SearchDirection:=xlNext, MatchCase:=False _

        , MatchByte:=False,SearchFormat:=False).Activate

    Cells.FindNext(After:=ActiveCell).Activate

    Cells.FindNext(After:=ActiveCell).Activate

End Sub

 

与录制的操作相对照,分析录制的代码。Find方法负责在工作表单元格区域中执行查找,FindNext方法向指定的单元格后继续进行查找。

 

可以看到,Find方法有很多参数,部分参数所对应的含义如下图所示。


 

仍然以上面所示的工作表为例,自已编写代码,查找单元格内容为“1”的单元格并显示地址。代码如下:

Sub testFind1()

    Dim rng As Range

   

    Set rng =Range('A1:D3').Find(What:='1')

    MsgBox '查找到内容为1的单元格为: '& rng.Address(RowAbsolute:=False, ColumnAbsolute:=False)

End Sub

运行代码后的结果如下图所示。


可以看到,虽然内容为“1”的单元格有A1D2B3三个,但只显示查找到单元格D2

 

现在,我们指定Find方法的参数SearchOrder为按列查找(xlByColumns),代码如下:

Sub testFind2()

    Dim rng As Range

   

    Set rng =Range('A1:D3').Find(What:='1', SearchOrder:=xlByColumns)

    MsgBox '查找到内容为1的单元格为: '& rng.Address(RowAbsolute:=False, ColumnAbsolute:=False)

End Sub

运行代码后,将返回单元格B3。因此,如果不指定参数SearchOrder,将默认按行查找,所以上例查找到的单元格为D2

并且,由于我们没有指定参数After,默认为从单元格区域的左上角即单元格A1开始搜索。我们可以看到,虽然单元格A1包含内容“1”,但按行或按列查找均没有显示找到的单元格是A1。因此,Find方法是在参数After指定的单元格或默认的起始单元格之后开始进行搜索的。

 

接下来再看示例。如下图所示的工作表。


我们要在单元格区域A1:B4查找内容为的单元格,代码如下:

Sub testFind3()

    Dim rng As Range

   

    Set rng =Range('A1:B4').Find(What:='')

    MsgBox '查找到内容为[]的单元格为: '& rng.Address(RowAbsolute:=False, ColumnAbsolute:=False)

End Sub

运行代码后,返回的单元格为A2。为什么会得到这个结果呢?为什么不是单元格B1B3。原因为:

  • 虽然Find方法默认为按行查找,但由于之前我运行了代码testFind2,而在这里的代码中没有指定参数SearchOrder,所以Excel仍按之前的代码设定的参数运行,即修改为按列查找,所以先找到单元格A2

  • Find方法的参数LookAt的默认值为xlPart,即只要单元格中的部分内容与所查找的内容相匹配就认为已经找到了单元格。所以虽然例子中我们想查找的理想单元格是B3,但实际找到的是单元格A2。下面是指定参数LookAt后的代码:

 

Sub testFind4()

    Dim rng As Range

   

    Set rng =Range('A1:B4').Find(What:='',LookAt:=xlWhole)

    MsgBox '查找到内容为[]的单元格为: '& rng.Address(RowAbsolute:=False, ColumnAbsolute:=False)

End Sub

运行代码后,将返回单元格B3,即完全与所查找内容相匹配的单元格。

 

通过学习和试验上面的例子后,我们不难理解Find方法的语法。

Find方法的语法如下:

Range对象.Find(What,After,LookIn,LookAt,SearchOrder,SearchDirection,MatchCase,MatchByte,SearchFormat)

说明:

  • Range对象代表要查找的单元格区域。

  • 参数What:该方法的众多参数中唯一一个必须指定的参数,设置要查找的值。

  • 参数After:指定一个单元格。将从该单元格之后开始查找,即开始时该单元格并不在查找范围直到查找操作返回到该单元格。如果没有指定该参数,将从单元格区域左上角的单元格之后开始查找。

  • 参数LookIn:设置查找的类型,包括xlFormulas(公式,默认值)、xlValues(值)、xlComments(批注)。

  • 参数LookAt:设置是与所查找的内容完全匹配还是部分匹配,即wlWholexlPart(默认值)。

  • 参数SearchOrder:设置查找的顺序是按行还是按列查找,即xlByRows(默认值)或xlByColumns

  • 参数SearchDirection:设置查找的方向,是向前查找(xlPrevious)还是向后查找(xlNext,默认值)。

  • 参数MatchCase:设置是否区分大小写。设置为True则在查找时区分大小写,默认值为False

  • 参数MatchByte:与双字节语言设置有关。

  • 参数SearchFormat:是否查找设定的格式,默认值为False

  • 该方法返回一个单元格对象,代表找到的第一个单元格。如果没有找到单元格,则返回Nothing

  • 该方法不会影响到当前所选择的单元格区域或活动单元格。

  • 在使用该方法时,将保存对参数LookInLookAtSearchOrderMatchByte的设置值。如果在下次使用该方法时,没有指定这些参数的值,那么将使用上次所设置的值。此外,在查找与替换对话框中所设置的相应的参数的值将会一直保存,除非你在该对话框中修改相应的值或者在代码中使用Find方法修改这些值。

因此,每次使用该方法时,建议明确地设置这些参数的值。

  • 可以结合FindNext方法和FindPrevious方法重复查找单元格区域。当搜索到单元格区域末尾时,将返回到单元格区域开头重新搜索。因此,要结束查找,可以保存所找到的第一个单元格的地址,然后将每一个查找到的单元格地址与该地址相比较,如果相同则停止查找。

 

下面是FindNext方法的语法:

    Range对象 .FindNext(After)

其中,参数After指定一个单元格,搜索将从该单元格之后开始。如果没有指定该参数,则从单元格区域左上角的单元格之后开始搜索。当搜索到单元格区域末尾时,将返回到单元格区域开始重新搜索。这些特征都与Find方法一样。

 

正如上文所指出的,FindNext方法让我们能够查找到单元格区域中所有与查找内容相符的单元格。以本文开头的工作表为例,查找单元格区域A1:D3中包含内容“1”的所有单元格,并将其背景设置为红色。

代码如下:

Sub testFind5()

    Dim rng As Range '声明对象变量

    Dim firstRng As String '声明字符串变量用来存放变量地址

   

    '将查找到的第一个单元格赋值给变量

    Set rng =Range('A1:D3').Find(What:='1', LookIn:=xlValues)

   

    '判断是否找到了单元格

    If Not rng Is Nothing Then

        '若找到,则将其地址保存到变量中

        firstRng = rng.Address

        Do

            '给找到的单元格设置红色背景色

            rng.Interior.ColorIndex = 3

            '查找下一个单元格

            Set rng =Range('A1:D3').FindNext(After:=rng)

            '如果找到单元格并且不是最先找到的单元格,则继续循环操作

        Loop While Not rng Is Nothing Andrng.Address <> firstRng

    End If

End Sub

代码运行结果如下图所示:


 

在代码中已进行了详细的注释,可以帮助你理解,并且在《Excel VBA解读(16):VBA的运算符》中介绍了Is运算符,用于对象变量的判断,可参阅。

这段代码给出了查找多个单元格的框架,在很多实用程序中都可借鉴,建议详细研究理解。

 

FindNext方法相似,也可以使用FindPrevious方法实现连续查找。与FindNext方法不同的是,FindPrevious方法从指定的单元格之前开始查找,一直到单元格区域的开头后,再从单元格区域的结尾开始向开头方向查找。

下面的代码实现与上例相同的功能,只是单元格添加背景色的顺序不同:

Sub testFind6()

    Dim rng As Range '声明对象变量

    Dim firstRng As String '声明字符串变量用来存放变量地址

   

    '将查找到的第一个单元格赋值给变量

    Set rng =Range('A1:D3').Find(What:='1', LookIn:=xlValues)

   

    '判断是否找到了单元格

    If Not rng Is Nothing Then

        '若找到,则将其地址保存到变量中

        firstRng = rng.Address

        Do

            '给找到的单元格设置红色背景色

            rng.Interior.ColorIndex = 3

            '查找下一个单元格

            Set rng =Range('A1:D3').FindPrevious(After:=rng)

            '如果找到单元格并且不是最先找到的单元格,则继续循环操作

        Loop While Not rng Is Nothing Andrng.Address <> firstRng

    End If

End Sub

 

你可以使用F8键逐行调试代码,观察VBA是按什么顺序给这三个单元格添加背景色的,以此来加深对FindNext方法和FindPrevious方法的理解。

 

--------------------------------------

 

如果您对本文介绍的内容有什么建议或好的示例,欢迎发送邮件给我:xhdsxfjy@163.com

 

通过下列方式可以更快地了解完美Excel更新:

 

关注《完美Excel》微信公众账号:

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多