zoukankan      html  css  js  c++  java
  • 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])

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

  • 相关阅读:
    qunar面试题及一位大牛的解答
    深入理解js里面的this
    用js实现的一个可拖动标签的例子
    Linux启动详细过程(开机启动顺序)
    linux下用top命令查看cpu利用率超过100%
    linux内核内存管理(zone_dma zone_normal zone_highmem)
    用户线程与内核线程如何映射?
    Linux用户空间与内核地址空间
    linux超级块和inode 详解 和 df 、du 命令详解与环境变量
    内核空间、进程和线程等概念
  • 原文地址:https://www.cnblogs.com/russellluo/p/2245042.html
Copyright © 2011-2022 走看看