VBA,使用find() 和 match() 进行查找时,可能出现的各种错误(我犯的各种错误总结)

最近因为在窗体里要做对工作表sheet的操作,出现了各种低级错误

我逐一在这总结下,希望自己反思,并以后引以为戒

 

 

数据源

 

1 正确的代码

应该也有多种写法

Sub test5032()
Dim a As Range
in1 = InputBox("请输入一个电影名")
Set a = Range("a1:a15").Find(in1)
If a Is Nothing Then
    Range("A" & 1 + Range("a65536").End(xlUp).Row).Value = in1
Else
    MsgBox "内容重复了"
End If
End Sub

 

2 典型错误1:判断 range().find() 返回值乱用null,err这些

2.1 使用   range().if()  查找时,对其返回值不合适的 判断函数

2.1.1 这3种用法的结果不同

  • range().find()
  • 如果查得到,返回的是rang()
  • 如果查不到,返回的是nothing()

 

  • 判断条件只能是 :   
  • dim a as range
  • set a =range().find()   
  • if a is nothing        
  • 语法不能写成 if a =nothing
  • a.value is nothing  也报对象变量错误,因为nothing  是专门给对象变量用的

 

  • 错误的判断条件, 查不到返回 nothing 而不是 err ,用 a=err等判断,始终都会为否
  • if a=err   then
  • if iserror(a)  then

 

  • 错误的判断条件, 不明白为啥 nothing 不是 null 或 empty ? 用isnull() ispempty() 判断始终都为否
  • 都是判断变量的值的函数
  • if  isnull()     then
  • if isempty()  then 

 

2.1.2 错误代码举例:如果用 isnull() 和  isempty(),下面的if 始终只会判断为否

错误原因

  • empty        有效的空值,如0  ""
  • null            无效的控制,比如二选一之外的空
  • nothing      对象变量的空值

Sub test50411()
Dim a As Range
in1 = InputBox("请您输入1个电影名")
Set a = Range("a1:a15").Find(in1)

If IsNull(a) Then
   Range("A" & 1 + Range("a65536").End(xlUp).Row) = in1
Else
    MsgBox "内容重复了"
End If
End Sub

 

2.1.3 empty null  nothing 三者的区别

 

3 典型错误:使用range().find()  必须先做错误处理,再处理正常流程

3.1 range().find()如果查不到,或者查找的类型不匹配会报错

  • 因为  range().find() 不事先处理报错导致的报错
  • 典型错误,没有先做异常处理会导致报错,想到find()函数的应该先进行出错处理,再处理正常流程

 

3.1.1 思路的学习,以后用 find() 和if  要考虑全面点,先考虑出错可能和如何处理出错

新思路:应该先考虑异常逻辑和进行异常处理,然后再处理正常逻辑。

  • 分析出错的原因:
  • 我的老思路:用 find() 来查找,先判断是否重复,如果重复就报错,如果不重复就新增1条记录
  • 问题是
  • range().find()   如果查找不到会报错。
  • 所以应该先判断,是否会出错,然后马上解决出错后如何处理。然后再去处理正常逻辑。

 

  • 以后使用range().find()  必须先做错误处理,否则可能会先跳出报错而中断
  • 先要考虑出错的可能
  • 还要想到如何处理出错的手段
  • 而不是上来开始正常的逻辑过程

 

3.1.2  中间变量挺重要

  • 中间变量很重要
  • 不光是把一些数据存起来
  • 而且防止了传送过程中数据发生变化

 

3.2.1 错误代码

Sub test50323()    '这是一个错误代码,举例
Dim a As Range
in1 = InputBox("请输入一个电影名")
Set a = Range("a1:a15").Find(in1)
If Range("a1:a15").Find(in1) = in1 Then           '一旦这个找不到就会报错
    MsgBox "内容重复了"
Else
    Range("A" & 1 + Range("a65536").End(xlUp).Row).Value = in1
End If
End Sub

 

 

3.2.2 修正代码---还是错的---不知道为什么还是只走一个分支

  • 加了 on error resume next
  • if 先判断了find()到
  • 结果还是只走上面的分支?
Sub test50323()
Dim a As Range
in1 = InputBox("请输入一个电影名")
Set a = Range("a1:a15").Find(in1)

On Error Resume Next

Debug.Print "Range("" a1: a15 "").Find(in1)="
Debug.Print "Range("" a1: a15 "").Find(in1)=" & Range("a1:a15").Find(in1).Address '因为出错,整句都不会打印?

If Range("a1:a15").Find(in1) = in1 Then    '不知道为什么这么改了,为什么还只有一个分支?
    MsgBox "内容重复了"
Else
    Range("A" & 1 + Range("a65536").End(xlUp).Row).Value = in1
End If
End Sub

 

4 典型低级错误

4.1 使用语法错误:设置变量对象时,赋值语法不对,没有用set

  • 对象变量没设置好也会报错,也是报错,对象变量或with变量未设置
  • 虽然报错一样,但是和  range().find()  方法查不到而报错,本质不一样

 

Sub test50311()

' 典型错误,没有保存变量的
Dim a As Range
Set a = Range("a1:a15").Find(InputBox("请输入一个电影名"))
If a Is Nothing Then
    Range("A" & 1 + Range("a65536").End(xlUp).Row).Value = InputBox("请输入一个电影名")   'TextBox1 不在窗体里报错,不应该在initial做歌词初始化
Else
    MsgBox "内容重复了"
End If

End Sub

 

4.2  典型错误:多用中间变量保存数据,然后再传递和使用,而不是每次临时处理。

  • 我这又犯了新手常犯的错误
  • 输入的数据应该用变量保存下来,装到变量盒子里
  • 典型错误,没有保存变量值,多次使用inputbox,这样是不对的
Sub test50311()

' 典型错误,没有使用中间变量保存和传递数据
' 错误的使用2次inputbox() ,第2个input和第一次木关系了
' 典型新手会犯的错误

Dim a As Range
Set a = Range("a1:a15").Find(InputBox("请输入一个电影名"))
If a Is Nothing Then
    Range("A" & 1 + Range("a65536").End(xlUp).Row).Value = InputBox("请输入一个电影名")   'TextBox1 不在窗体里报错,不应该在initial做歌词初始化
Else
    MsgBox "内容重复了"
End If

End Sub

 

4.3  典型错误:用 分支判断时,谁的值?

  • If Err Then                          ’典型错误,这种纯粹SX的错误  if  谁?=err? then
  • If a = Err Then                    '记得应该是判断某个变量,或者 表达式的值 为err 
  • 另外 false <> err
  • if true then      '这是故意的写法,就是故意只执行false的分支!

 

  • 不要随便混用
  • true  false        '这个是bool值
  • error                '错误值

 

5  不合适的功能函数,使用application.find() 导致的错误

5.1  application.find()  和worksheetfunction.find() 本质是工作表函数 ---查找的范围主要还是 字符串内string

  • 如果使用的功能函数,是工作表函数,会出问题
  • 工作表函数, application.find() 返回的是 查找内容在 字符串 string 内的 第几个位置。

 

  • application.find() 返回值,用 isempty()  iserror() =null =err 判断了都不行,不知道怎么搞
Sub test504()   ---错误代码,举例

On Error Resume Next
in1 = InputBox("请您输入1个电影名")
a = Application.Find(in1, Range("a1:a15"))

If IsError(a) Then        '尝试过 isempty()  =err  =null 等都不行
    Debug.Print "没找到"
   Range("A" & 1 + Range("a65536").End(xlUp).Row) = in1
Else
    Debug.Print "找到了"
    MsgBox "内容重复了"
End If

End Sub

 

6 使用match() 函数也会遇到类似的问题

  • application.match()  本质也是工作表函数
  • 和 range().find() 不一样,rang().find()返回的是 range() 对象,find不到位空对象变量是  is  nothing
  • 而application.match() 查到的是一个index 对应的数。如果查不到会报错,而报错是err=0

6.1 错误的写法

  • 错误的思路:没有先考虑出错处理
  • application.match() 查不到会报错,无法取得 match 属性

 

正确代码

  • 使用查找,匹配函数时,要先进行错误处理
  • 但同时要对错误值和空值有区分,
  • 如果需要处理错误值,则要可能要先加一个语句  on error resume next
  • 如果要处理空值,得注意是对象变量是 is nothing ,其他变量 则可能是 empty 或者 null 等
Sub aa31()
On Error Resume Next
in1 = Int(InputBox("请输入1个要查的数字"))
a = WorksheetFunction.Match(in1, Array(1, 2, 3, 4, 5), 0)

If Err = 0 Then
   Debug.Print a
Else
   Debug.Print "没找到!"
End If
End Sub

err的具体值

  • 最初猜想:err是布尔值?err=0  表示没错误, err=1 表示是出错了
  • 测试代码,换ERR=1,且调换IF判断次序,结果找不到就不反馈,有问题
Sub aa32()   ---测试代码,换ERR=1,且调换IF判断次序,结果找不到就不反馈,有问题
On Error Resume Next
in1 = Int(InputBox("请输入1个要查的数字"))
a = WorksheetFunction.Match(in1, Array(1, 2, 3, 4, 5), 0)

If Err = 1 Then
   Debug.Print "没找到!"
Else
   Debug.Print a
End If
End Sub

 

err 其实是 err.number

  • err=0 表示 err.number=0 没出出错
  • err.number有很多出错数字

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值