Office中国论坛/Access中国论坛

标题: 【新手入门】之七:嵌套与并列——再谈If流程问题 [打印本页]

作者: roych    时间: 2013-3-17 18:28
标题: 【新手入门】之七:嵌套与并列——再谈If流程问题
       早在一年前,我便写了一系列VBA扫盲贴,其中就有If分支语句。只是当时写得较为简单,大家的体会也没那么深刻。而在近日,ycxchen重新提出这个问题,我觉得,如果进一步细说的话,可能大家会更加清楚如何规范一个流程【详见判断语句】。
       为了方便代码的阅读,我把源代码加以缩进【建议大家在写代码时也这样做,方便阅读和调试】。先附上代码:
分支语句 嵌套语句
  1. If IsNull([姓名]) Then
  2. MsgBox "请输入姓名"
  3. Exit Sub
  4. End If

  5. If IsNull([出生日期]) Then
  6. MsgBox "请输入出生日期"
  7. Exit Sub
  8. End If
  9. '…………余下几个分支语句省去
  10.   
复制代码
  1. If IsNull([姓名]) Then
  2.     MsgBox "请输入姓名" '第一层
  3. Else
  4.        '第二层
  5.         If IsNull([出生日期]) Then
  6.            MsgBox "请输入出生日期"
  7.          Else
  8.            '…………余几个嵌套省去
  9.          End If
  10.             End If
复制代码
       代码优劣就不说了,不在本文讨论范围内。我们先来比较这两段代码的不同之处。现在开始讨论分支语句和嵌套语句的区别。
       分支语句中,显然第一步会先判断有没有填入姓名,如果没填就弹出提示然后退出,接下来执行第二个分支语句,看看有没有填出生日期,再判断第三个……直至所有语句成立了才会跳到GoToReCord语句。由于分支语句是并行关系,因此只要有一个没填完,就会跳回来继续提醒直至全部为真。

       接下来,我们来看嵌套语句。显然第一步是一样的,先判断有没有填入姓名,如果没填,那么就弹出对话框,接下来判断有没有填出生日期,如果没有填继续弹出对话框。然后判断第三个……是吗?会判断第三个吗?我们回过头来看点别的东西:

       这两个细节看起来微不足道,但对流程来说却极有意思。假定设置了必填字段,显然不管流程怎么写,问题应该都不太大。反正是必填的,不填就无法保存,不提示顶多不够人人性化而已,但对结果并无太大影响,不是么?设置默认值的话,也是同样原因,设置了,用户不输入那么默认就好了,反正也算是填了。

       然而没有这两点,那这段程序就有问题了:

       前面说了判断姓名是没问题的,判断出生日期,显然默认情况下是空值,也是会弹出对话框的。但是,也正因为由于这一步成立,因此Else部分就不会再进行判断了。这么一来,这段程序自然就只判断到出生日期为空这部分。而又因为第1点,保存记录当然是没问题的。这么一来,这段程序是不会判断第3层和之后的语句,而直接跳转到GotoRecord。换句话说,第三层以后的语句完全是“防君子不防小人”的。

       流程到此结束。可能大家有这样的疑惑:
       问题1:理论上应该是可以嵌套的。但不管从正向还是逆向判断【即不成立时】都需要考虑到各种组合的可能性,因此代码会写得相当复杂。

       问题2:如果想要简化,除了逻辑And运算,大概别无他法了。用了这个方法之后,就只能知道用户到底有没有填完,但具体哪个没填就不好判断了,即“只见森林不见树木”。

[attach]51456[/attach]【新手进阶】之一:If分支语句
【新手进阶】之二:分支语句总结
【新手进阶】之三:循环语句For
【新手进阶】之四:循环语句Do和死循环
【新手进阶】之五:递归算法
【新手进阶】之六:冒泡排序
【新手进阶】之七:从四脚腾空的奔马谈起——原来界面可以这样设计
【新手进阶】之八:公共变量与传址过程、传值过程
【新手进阶】之九:仓库管理系统
【新手进阶】之十:从百钱百鸡谈起——浅谈“规划求解”兼答lingjiang问
【新手进阶】之十一:“庖丁解牛”和“纪昌学射”——浅谈表格式文本数据的导入
【新手进阶】之十二:嵌套与并列——再谈If流程问题
【新手进阶】之十三:记录集的“凌迟”——逐条导出记录集
【新手进阶】之十四:“不明觉厉”——浅谈左侧导航栏的设计
【新手进阶】之十五:浅谈ADO之序言
【新手进阶】之十六:浅谈ADO之Connection
【新手进阶】之十七:浅谈ADO之Conmmand(上)
【新手进阶】之十八:浅谈ADO之Command(下)
【新手进阶】之十九:Outlook风格导航界面
【新手进阶】之二十:浅谈ADO之Recordset(上)
【新手进阶】之二十一:浅谈ADO之Recordset(下)
【新手进阶】之二十二:浅谈不绑定数据源操作记录

作者: huangli0356    时间: 2013-3-18 10:05
沙发..帮主辛苦了..
作者: tmtony    时间: 2013-3-18 11:25
谢谢分享
作者: ycxchen    时间: 2013-3-18 11:44
本帖最后由 ycxchen 于 2013-3-18 18:01 编辑

有劳版主!我觉得, DoCmd.GoToRecord , , acNewRec语句在end if语句后面的,但程序判断到出生日期为空这部分就不会判断第3层和之后的语句,为何直接跳转到GotoRecord,这是为什么呢?
作者: roych    时间: 2013-3-18 19:32
本帖最后由 roych 于 2013-3-18 19:33 编辑
ycxchen 发表于 2013-3-18 11:44
有劳版主!我觉得, DoCmd.GoToRecord , , acNewRec语句在end if语句后面的,但程序判断到出生日期为空这部 ...

If语句是这样执行的:
If 条件成立 Then
  执行语句1
Else
  执行语句2
End If
条件成立是不会执行语句2的
这样一来,我们再回头看看右边那段代码。从顺序上,肯定是先执行If部分,然后才到GotoRecord。
第一个If显然条件成立【姓名为空】,因此弹出对话框,并进入嵌套语句【即判断出生日期】。而对于出生日期,条件显然也是成立的【出生日期为空】,这时候显然就MsgBox提示框了。
接下来还会执行里面的嵌套语句吗?当然不会了,因为条件不成立。换句话说,只有出生日期输入后才会进行下一步检查
作者: ycxchen    时间: 2013-3-19 09:20
本帖最后由 ycxchen 于 2013-3-19 09:33 编辑
roych 发表于 2013-3-18 19:32
If语句是这样执行的:
If 条件成立 Then
  执行语句1


版主,我的理解的与你的一样,对有一定VBA基础的人来说,这是很容易理解的。但是,你试过没有,条件不成立也会执行里面的嵌套语句,例如,当出生日期为空,出现提示,按确定后,程序并不是再进入判断参加工作日期是否为空值的语句,而是直接 运行到DoCmd.GoToRecord , , acNewRec语句,就是说程序不执行If部分已经到GotoRecord了,为什么呢?
作者: ycxchen    时间: 2013-3-19 12:06
是不是与msgbox函数“确定”按钮获得焦点事件有关?
作者: ljp518    时间: 2013-3-19 13:11
{:soso_e163:}
作者: roych    时间: 2013-3-19 19:51
ycxchen 发表于 2013-3-19 09:20
版主,我的理解的与你的一样,对有一定VBA基础的人来说,这是很容易理解的。但是,你试过没有,条件不成 ...

按确定后就表示If语句已经执行完毕了呀【】。当然就直接跳到GotoRecord部分了。
你只有输入了出生日期,才是Else部分做的事情,即进行工作日期的判断。
作者: ycxchen    时间: 2013-3-20 11:08
本帖最后由 ycxchen 于 2013-3-20 11:12 编辑

[attach]51473[/attach][attach]51474[/attach]     [attach]51475[/attach]加入了“出生日期.SetFocus”语句,情况一样,什么原因呢?
作者: roych    时间: 2013-3-20 21:05
ycxchen 发表于 2013-3-20 11:08
加入了“出生日期.SetFocus”语句,情况一样,什么原因呢?

这加不加setFocus没关系的。我简化下代码:
If 条件1 Then
  If 条件2 Then
     If 条件3 Then
        执行语句1
     end if
   end if
end if
如果要执行语句1,需要满足什么样的条件?显然是条件1、2和3都需要成立才会执行,否则就直接跳出外层语句了。
换句话说,嵌套语句需要全部都成立了,才会执行到最内层的语句(所有语句类似于And逻辑运算)。
同样地,如果非要每个Else都弹出提示,也是需要每个条件都不成立。输入姓名后,外层If不成立,进入第二层If语句。第二层语句成立【IsNull[出生日期]成立】,因此不执行Else部分。——这也就是说,第三层嵌套不再执行。但是,如果把出生日期改为必填字段,那么因为无法保存的问题,自然会因为产生错误而暂时停留在这一层。
作者: ycxchen    时间: 2013-3-21 08:55
衷心感谢roych版主的悉心指教!明白!
作者: 大白    时间: 2013-3-26 15:01
学习学习
作者: zhixingju    时间: 2016-5-13 21:59
谢谢




欢迎光临 Office中国论坛/Access中国论坛 (http://www.office-cn.net/) Powered by Discuz! X3.3