Fork me on GitHub

EXCEL中的And运算符与IF函数

注意:本文的讨论建立在前文《EXCEL中,将十六进制转换为十进制》的基础上。

一、And运算符

  在前一篇文章中,方法2的VBA子例程ConvertData_2中,有这样一段代码:

Do
    HexToDec Cells(cell.row, cell.column)
    Set cell = .FindNext(cell)
 
On Error Resume Next ' 开启错误处理开关
' 查找并转换完毕所有满足条件的单元格后,执行下面这行语句应该条件为假从而跳出循环;
' 但不知为何,实际情况是:此时会出错,所以特别增加了错误处理
Loop While Not cell Is Nothing And cell.Address <> firstAddress
If Err.Number <> 0 Then ' 如果出错,表明已经查找并转换完毕,退出
    Exit Sub
End If
On Error GoTo 0 ' 关闭错误处理开关(在函数结尾处,可以忽略)

   这是一个简单的Do...Loop循环,但在Loop语句(条件判断)的周围却存在错误处理代码,正如其中的注释所说:“查找并转换完毕所有满足条件的单元格后,执行下面这行语句应该条件为假从而跳出循环;但不知为何,实际情况是:此时会出错,所以特别增加了错误处理”。

  当时不仅不知道Loop语句在“查找完毕”时为何会执行出错,反而还感到非常奇怪,因为ConvertData_2例程中“使用Find方法查找以'0x'为前缀的单元格”的代码段其实是取自Excel 2007的帮助文档中关于“Range.Find方法”的示例:

示例

本示例在第一个工作表的单元格区域 A1:A500 中查找包含值 2 的所有单元格,并将这些单元格的值更改为 5。

Visual Basic for Applications
With Worksheets(1).Range("a1:a500")
  Set c = .Find(2, lookin:=xlValues)
  If Not c Is Nothing Then
    firstAddress = c.Address
    Do
      c.Value = 5
      Set c = .FindNext(c)
    Loop While Not c Is Nothing And c.Address <> firstAddress
  End If
End With

  但事实是,“Loop While Not c Is Nothing And c.Address <> firstAddress”这句代码在查找失败时(此时c Is Nothing)确实会出错:

  很明显该错误是在c.Address处发生的,此时因为c为Nothing,引用Nothing对象的属性必然会出错。

  但这就奇怪了,c为Nothing时,表达式“Not c Is Nothing”值为假,为什么还要去求值And后面的表达式呢?

  后来我仔细查看了Excel 2007帮助文档中关于“And运算符”的说明,结果发现“VBA中的And运算符”与“C语言中的&&运算符”的求值规则是不同的:

  1、我们习以为常的“C语言中的&&运算符”的求值规则是:如果&&左边的表达式为真,则继续求值&&右边的表达式,以便求取整个表达式的值;如果&&左边的表达式为假,则整个表达式的值为假,此时不需要继续求值&&右边的表达式;

  2、“VBA中的And运算符”的求值规则是:无论And左边的表达式为何值,都将对And右边的表达式进行求值,整个表达式的值由And左右两边表达式的求值结果共同决定。

  于是,前面所示ConvertData_2中的代码段就可以改为:

Do
    HexToDec Cells(cell.row, cell.column)
    Set cell = .FindNext(cell)
    
    If cell Is Nothing Then ' 首先单独判断cell是否为Nothing,如果是,则退出循环
        Exit Do
    End If
Loop While cell.Address <> firstAddress ' 然后再判断cell.Address的值(此时cell一定不为Nothing)

   实验证明,以上修改后的代码就不会再出错了。这么说来,Excel 2007的帮助文档中关于“Range.Find方法”的示例应该是有问题的。实践出真知,目前的结论就是如此。

二、IF函数

  在前一篇文章中,方法3的转换公式:

=HEX2DEC(RIGHT(A1, LEN(A1) - 2)) ' 针对A1单元格的转换公式

   当时谈到方法3的缺点时,说到该方法缺乏灵活性。今天又研究了一下,结果发现有一个IF函数可以实现简单的条件判断,进而可以做到使方法3具有与方法1、2同样的“只转换满足格式的数据,不满足格式的数据不会受影响”的效果。新的转换公式如下:

=IF(LEFT(A1, 2)="0x", HEX2DEC(RIGHT(A1, LEN(A1) - 2)), A1) ' 针对A1单元格的转换公式

附:IF函数说明

函数:IF

语法:=IF(logical_test, [value_if_true], [value_if_false])

说明:判断是否满足条件,如果满足返回一个值,如果不满足则返回另一个值。

posted on 2011-11-10 23:23  RussellLuo  阅读(2415)  评论(0编辑  收藏  举报

导航