Office中国论坛/Access中国论坛

标题: 【Access小品】大可不必--必填控件空值时不失去焦点示例 [打印本页]

作者: todaynew    时间: 2012-1-13 22:01
标题: 【Access小品】大可不必--必填控件空值时不失去焦点示例
本帖最后由 todaynew 于 2012-1-13 22:12 编辑

  我一直对美女版友简的执着感到无奈,那是一种钻牛角尖和撞南墙的精神,呵呵。对于细节从来都有两种说法,一种是不拘泥细节,这说的是说需要有大局和宏观的意思。但同时也有一种说法,叫做魔鬼隐藏于细节,或者细节决定成败。这看起来有些矛盾,其实不然。其中的玄妙只是在于是何种细节,关键的细节当然是重要的。不过版友简的问题大多都是些无关大局的细节,我以为大可不必过多的钻研。

  版友简这两日提出了一个关于必填控件为null时不得失去焦点的问题,这个问题在我看来并不重要。把数据表中的字段设置为必填应该就可以了。这样做的差别仅仅在于,整条记录更新时,系统将作出提示。同样可以保证必填字段的数据不出现null,因此说这是一个非关重要的细节。

  不过对于版友简的问题,讨论的版友很多,给出了许多种的答案,似乎版友简都不大满意。于是乎我觉得这是一个同志们都感兴趣的问题,便觉得可以做一个示例供大家参考。不过这个问题探讨的层度需要进一步加深,我想推导出处理的整体思路来。这个问题的处理有以下的逻辑:

  1、一个控件不失去焦点,可以理解为除这个控件外,其他控件一旦获得焦点事件触发,都将导致该控件获得焦点。这是一个有意思的反向思维,这种思维内涵了佛学的“舍得”,也揭示了人人为我我为人人的科学发展观。

  2、控件的输入过程是有一定秩序的,这种秩序体现在控件的TabIndex属性上。TabIndex属性不一定与控件的位置或者建立的前后相关,原因在于TabIndex属性是可以调整的。因此当前不能失去焦点的那个控件,就是其值为null且TabIndex值最小的控件。

  3、当窗体控件繁多时(记得版友简同志善于这样做),逐一编写各个控件的获得焦点事件是一件不道德的事件。简化相同的控件事件处理的捷径,是在窗体加载时给控件的事件赋值为一个函数。

  依据以上的逻辑,这个问题的一种有效而简洁的处理方法便隆重推出了。

Private Sub Form_Load()
Dim ctrls As Controls
Dim ctrl As Control
Set ctrls = Me.Controls
For Each ctrl In ctrls
    If ctrl.ControlType = acTextBox Or ctrl.ControlType = acComboBox Then
        ctrl.OnGotFocus = "=CtrlSetFocus()"
    End If
Next
End Sub

Function CtrlSetFocus()
Dim ctrls As Controls
Dim ctrl As Control
Dim i As Integer, m As Integer
m = 100
Set ctrls = Me.Controls

For i = 0 To ctrls.Count - 1
    'ControlType可根据需要进一步枚举,也可再套一层If用于排除非必填控件。
    If ctrls(i).ControlType = acTextBox Or ctrls(i).ControlType = acComboBox Then
        If IsNull(ctrls(i).Value) = True Then
            If ctrls(i).TabIndex < m Then
                Set ctrl = ctrls(i)
                m = ctrls(i).TabIndex
            End If
        End If
    End If
Next
If m <> 100 Then
    ctrl.SetFocus
End If
End Function

[attach]48099[/attach]

[attach]48100[/attach]
作者: Henry D. Sy    时间: 2012-1-13 22:11
视乎有点简单问题复杂化了
作者: fnsmydyang    时间: 2012-1-14 11:38
其实正如版主所说,大可不必,在保存时检查一下就好了,有一点复杂化了,不过精神可佳。
作者: Grant    时间: 2012-1-14 11:59
也是个好办法,如果能用数组控件会更简单些
作者: 简    时间: 2012-1-14 13:13
诶,不是我要钻牛角尖,我之所以要求控件不能为空值,一方面涉及到输入人员的习惯,还有生产中的不确定性,另外一方面是根据输入值进行断号的检查,所以才不得不这样处理。

具体效果等我晚上传附件上来,也许你们就明白了。
作者: JosephTan    时间: 2012-1-14 15:32
人人为我好啊
作者: Henry D. Sy    时间: 2012-1-15 09:18
  1. Dim ctl As Control
  2.     For Each ctl In Me.Controls
  3.         If TypeOf ctl Is TextBox Or TypeOf ctl Is ComboBox Then
  4.             If IsNull(ctl) Then
  5.                 MsgBox ctl.Name & "不可为空!"
  6.                 ctl.SetFocus
  7.                 Exit Sub
  8.             End If
  9.         End If
  10.     Next
复制代码

作者: todaynew    时间: 2012-1-15 19:51
Henry D. Sy 发表于 2012-1-15 09:18

呵呵,似乎不那么简单吧?
少考虑了两个问题,其一是由什么事件触发;其二是控件输入的秩序。

作者: JosephTan    时间: 2012-3-10 07:18
Grant 发表于 2012-1-14 14:59
也是个好办法,如果能用数组控件会更简单些

这个数组控件,能否给个例子?
作者: 李力军2    时间: 2013-4-16 22:58
ACCEss内似乎没有数组控件之说吧?
作者: 李力军2    时间: 2013-4-16 22:59
倒是这个共用函数及一个事件为所有相关控件加入事件代码的方法很好,简化了很多编程工作呀
作者: nncchh    时间: 2015-7-20 15:07
学习学习,谢谢分享!
作者: nncchh    时间: 2015-7-20 15:10
学习学习,谢谢分享!
作者: 灰太郎    时间: 2018-1-1 18:49
111111111111111111111
作者: 灰太郎    时间: 2018-1-1 18:49
44444444444444444444444444444444




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