Access交流中心

北京 | 上海 | 天津 | 重庆 | 广州 | 深圳 | 珠海 | 汕头 | 佛山 | 中山 | 东莞 | 南京 | 苏州 | 无锡 | 常州 | 南通 | 扬州 | 徐州 | 杭州 | 温州 | 宁波 | 台州 | 福州 | 厦门 | 泉州 | 龙岩 | 合肥 | 芜湖 | 成都 | 遂宁 | 长沙 | 株洲 | 湘潭 | 武汉 | 南昌 | 济南 | 青岛 | 烟台 | 潍坊 | 淄博 | 济宁 | 太原 | 郑州 | 石家庄 | 保定 | 唐山 | 西安 | 大连 | 沈阳 | 长春 | 昆明 | 兰州 | 哈尔滨 | 佳木斯 | 南宁 | 桂林 | 海口 | 贵阳 | 西宁 | 乌鲁木齐 | 包头 |

Access平台使用浅析

朱朱  发表于:2010-01-31 20:32:38  
复制

 

Access平台使用浅析

看完了钱玉炜的报销教程,现在将一点体会写下来,希望对初学的朋友有些用处.
此偏教程侧重平台中对数据的新增和修改并结合自己对平台的一些认识来解释相关的代码,并解释一下整个代码工作的流程是怎么样.ok,我们开始吧.例子是以钱玉炜的报销示例来讲解的.

先来解释新增窗体中的代码.首先看到下面一段
Private Sub ToolbarFrm_ButtonClick(ByVal Button As Object)
        Select Case Button
               Case "保存"
                     cmd_Save
               Case "关闭"
                     DoCmd.Close
         End Select
End Sub
当打开新增窗体后,如果点击上面的保存或者关闭按钮之后就会触发该过程.
从过程的名称,细心的朋友已经知道,这是一个Toolbar控件对象的ButtonClick事件.
该过程用一个Select Case语句对保存和关闭进行处理. Select Case Button,实际应该是
Select Case Button.Value 在VBA中,大多数对象默认引用的是其Value属性,所以初学者可
能在看这个Case语句时有一点不解. OK,我们再看到点击保存按钮后执行的代码过程.

Private Sub cmd_Save()
Dim rst As DAO.Recordset
If IsNull(Me.ygxm) Then
          MsgBox "请输入员工姓名!", vbCritical, "提示:"
          Me.ygxm.SetFocus
          Exit Sub
End If
Me.Refresh
If Acchelp_StrDataIsExist("tblCodeyg", "ygxm", Me.ygxm) = True Then
          MsgBox "你输入的数据已经存在,请重新输入", vbCritical, "警告"
          Me.ygxm.SetFocus
          Exit Sub
End If
If MsgBox("您确认要保存吗?", vbOKCancel + vbInformation, "提示") = vbOK Then

 

Top
朱朱 发表于:2010-01-31 20:34:14

If MsgBox("您确认要保存吗?", vbOKCancel + vbInformation, "提示") = vbOK Then
         Set rst = CurrentDb.OpenRecordset("tblCodeyg", dbOpenDynaset)
         rst.AddNew
         rst("ygId") = acchelp_autoid("Y",2, "tblCodeyg", "ygId")
         rst("ygxm") = Me.ygxm
         rst.Update
         rst.Close
        Set rst = Nothing
        '刷新数据
        If IsLoaded("usysfrmMain") Then
               DoCmd.Echo False
               Forms!usysfrmMain!frmChild.SourceObject = "frmyg_child"
               DoCmd.Echo True
        End If
        MsgBox "保存成功!", vbInformation, "提示"
        Me.ygxm = Null
End If
End Sub

    该段代码,首先声明一个RecordSet对象变量,接着对输入的数据的有效性作一个判断,
一是输入的数据不能为空,二是输入的数据在数据库中不能是已经存在的.当然对于一些复
杂的应用,数据的有效性检查可能也不就不是这么简单了,例如如果一个文档框只能输入数
字等等,实现这些字符匹配的检查比较方便的是使用正则表达式.之后一个MsgBox函数来决
定用户接下来的操作,如果选择是则会执行下面的代码,先调用CurrentDb方法得到一个
Database对象,在微软的帮助文档中,是这样描述CurrentDb方法的:
    在 Microsoft Access 中, CurrentDb 方法可建立对 Microsoft Access 数据库 
(.mdb) 中“Microsoft DAO 3.6 对象库”的隐含引用。在得到这个引用之后,就可以用
OpenRecordset方法来得到一个结果集,具体的方法使用及示例请参看微软的帮助文档,由于
要对结果集进行追加操作,所以当然设置类型为动态集类型,即dbOpenDynaset
    之后就是rst.AddNew,然后设置各字段的值,acchelp_autoid()方法是平台提供给我们
的一个方法,用来自动产生一个表的id值,以后还会看到不少以acchelp开头的方法,因为这
是平台提供给我们的方法,我们不妨称之为平台方法或者平台函数,当然如果你用自动增长
类型作为主键的话,就可以不用写这句代码了,同样rst("ygxm")= Me.ygxm也可以写成rst
("ygxm").Value=Me.ygxm ,
有参考书说加上.Value会加快一点访问速度,不过就这点好像也没有那个必要吧.
接着调用rst.Update更新结果集,进行数据的追加. 接下来,数据需要更新显示了,首选判断

接着调用rst.Update更新结果集,进行数据的追加. 接下来,数据需要更新显示了,首选判断
主窗体"usysfrmMain"是否已经加载了,可能很多朋友要问,为什么要判断主窗
体"usysfrmMain"是否已经加载了呢?当我们使用平台的时候,主窗体当然是已经加载的了,
这还需要判断什么呀,不是多此一举吗?我想,可能是当我们在用平台开发的时候,也就是按
住Shift进行入平台进行开发,这时候我们打开一个窗体,那么在这种情况下,主窗体就未必
是加载的了. 在判断了之后,首选关闭窗体的刷新,调用Docmd.Echo方法,设置参数为
False,Echo方法请初学的朋友自己看微软的帮助文档,也可以调用Application对象的Echo
方法,按照面向对象的思想,我们可以将Docmd的Echo方法是重写了Application方法的Echo
方法,从微软的帮助文档来看,还是建议使用Application对象的Echo方法,使用Docmd对象的
方法只是为了兼容性.接下来一句,Forms!usysfrmMain!frmChild.SourceObject = 
"frmyg_child" ,又有几个知识点啦,Forms!usysfrmMain是Access中用来引用窗体的一种方
式,还有其他的方式,根据微软的帮助文档,还有如下的形式
Forms![usysfrmMain]
Forms("usysfrmMain")
Forms(窗体的索引),根据微软的帮助文档,如果窗体的名称中有空格,则就要用方括号这一
形式
这句代码的意思是设置Forms集合中名称为usysfrmMain窗体中名称为frmChild这一子窗体
的源对象为"frmyg_child",之后在打开窗体刷新DoCmd.Echo Ture,最后清空相关的控件值,
如果控件很多的话,重复写Me.ygxm = Null这样的代码是很无聊的,可以循环控件,设置值为
空,做法是引用每个窗体对象都有的Controls集合,然后用循环控制语句对Controls集合进
行操作.

 

2)我们再来看看修改窗体是如何工作的
首选在设计好修改窗体的界面之后,先在一个模块中定义一个变量用来保存要修改的记录的
Id号,Public selectstr As String
之后来到frmyg_child窗体的设计界面,在这里,我们要说一下在程序中是如何得到要修改的
记录的id号的,当我们在平台中显示员工的信息表的时候,如果我们单击其中一条记录的id
号(也就是这里的ygid),这时就会触发ygid这个文本框的GotFocus事件.
可能有些朋友会觉得奇怪, 为什么在主界面上单击那个员工信息的表格记录时,怎么就会触
发文本框的获得焦点事件呢,从后面的教程我们可以知道.继续吧.
    用selectstr记录下所在修改的记录的ygid的值.
Public Sub ygId_GotFocus()
 On Error GoTo Err_ygId_GotFocus:
        selectstr = Me.ygId



朱朱 发表于:2010-01-31 20:34:50
        selectstr = Me.ygId
        Forms!usysfrmMain!labFind.Tag = 1
        Forms!usysfrmMain!btnEdit.Tag = 999
        Exit_ygId_GotFocus:
        Exit Sub
        Err_ygId_GotFocus:
        Resume Exit_ygId_GotFocus
End Sub
在这里,我还有一些想法想说一下,在Access中经常主子窗体来组织和显示数据,这对于以前
用VB来开发数据库应用的朋友来说可能感觉有点奇怪,在VB中我们一般都喜欢使用DataGrid
这个控件来显示一个二维表格显示数据,这个控件具体方便实用,编程简单的特点,是本人比较喜欢用的一种控件,但是很可惜啊,我一开始用Access开发的时候,也想
这样用,但是将控件拉到Access的窗体上时却不能成功,提示不支持,所以没办法了,只有用
子窗体的数据表视图来显示数据了.
selectstr = Me.ygId,这句代码我们理解了,那下面两句是用来干嘛的呢,当初我也是不能
理解啊
 Forms!usysfrmMain!labFind.Tag = 1
        Forms!usysfrmMain!btnEdit.Tag = 999
在平台中,usysfrmMain这个主窗体对于我们用户来说似乎是看不到它的设计界面的,当然我
们还是可以看到,进入VBE界面(alt+F11),当然首先要按住Shift进入平台,之后打开左侧的
Microsoft Office Access类对象,找到Form_usysfrmMain,点击选中,然后选择视图菜单,点
击对象窗口,怎么样主窗体的设计是不是一览无余啊,呵呵!这样各位对于平台就有了更加深
的理解了,其中我们就看到了labFind和btnEdit这两个控件了,一个是标签,一个是按钮,在
这里为什么要设置其值分别为1和999呢,这就又牵扯到平台的一些设计思想上的问题了,我
们总是在解决了一部分问题之后又发现许多新的问题. 这部分大家不妨参考钱玉炜的另一
个教程吧,网址:http://www.accessoft.com/bbs/showtopic.asp?Id=2783
因为平台的有些设计和细节是事先设计好的,所以我们没参加过平台培训的话,这些东西我
们不可能知道,只有通过自己看平台的部分代码去慢慢摸索.在这里,设置labFind.tag=1只
是用作一个判断条件,当其等于1时,点击查询按钮会打开平台的查询窗体.这是钱的教程中
这样写的,那么真的是这样吗?ok,我们进入平台设计界面,alt+F11,再ctrl+F,搜索一下
labFind,搜索之后我们会看到平台代码中有这样几句:

朱朱 发表于:2010-01-31 20:35:20

Case "查找"    '                                -----------系统代码,请勿修改--
---------
            If Forms!usysfrmMain!labFind.Tag = 1 Then    '---------系统代码,请
勿修改-----------
                Forms!usysfrmMain!frmChild.Form.btnFind    '-------系统代码,请
勿修改-----------
            Else    '                                   -----------系统代码,请
勿修改-----------
                g_usysfrmMenu_child_steelToolBar_Find    '---------系统代码,请
勿修改-----------
            End If    '                                 -----------系统代码,请
勿修改-----------

看到了吧,代码判断labFind.tag是否等于1,是则调用Forms!usysfrmMain!
frmChild.Form.btnFind这句来显示查询窗体
由此,我们就理解了为什么要设置labFind.tag=1了,可能有人还是要问,为什么要把这两句 代码写在这个GotFocus中呢,这大概是因为只有在GotFocus中处理比较方便吧.本从水平有限,有些东西也未能参透.对于btnEdit.tag=999,这个条件,当其大于1 时点击”修改”按钮时,平台就会自动打开_Edit窗体,真的是这样吗?可惜本人翻了一下平台的代码却没有像刚才那样找到踪迹.
 Ok,继续,接下来教程要我们打开frmyg_child的窗体属性,打开事件选项卡,在成为当前事件中输入: =selectrecord() 这句话有什么作用呢,这个selectrecord的定义在哪里,我们能一看究竟吗?很可惜啊,本人搜索了一下却没找到. 但是,如果你用搜索引擎的话,以selectrecord关键字搜索却可以搜索到, 在搜索到的第一项打开一看,正是Access软件网的竹笛大师写的这个函数,相关信息如下:

 时 间:2009-2-3 10:57:21
作 者:竹笛
摘 要:平台中在子窗体中用来整行选定记录。
正 文:
为了让子窗体打开时,实现两大效果:
1.整行变黑,方便操作员看是哪一条记录;
2.让某行的第一个字段获得焦点,从而触发焦点事件,来决定操作员是选择的哪一条记录。
Function selectRecord()
    On Error GoTo Err_selectRecord:
'鼠标单击时选定整行记录



朱朱 发表于:2010-01-31 20:35:51

   DoCmd.RunCommand acCmdSelectRecord
Exit_selectRecord:
    Exit Function
Err_selectRecord:
    Resume Exit_selectRecord
End Function


从以上代码可以知道,该函数主要调用DoCmd对象的RunCommand方法,并设置acCmdSelectRecord来达到想要的两大效果, 查询微软的帮助文档可知, DoCmd对象的RunCommand方法用于执行内置菜单命令或内置工具栏命令。它的使用说明中这样写到:
Microsoft Access 中的每个菜单命令和工具栏命令都有一个相关的常量,在 Visual Basic 中,可以将常量与 RunCommand 方法结合使用来执行该常量对应的命令。
不能使用 RunCommand 方法执行自定义菜单或工具栏上的命令,该方法只能用于内置菜单和工具栏。
RunCommand 方法可替换 DoCmd 对象的 DoMenuItem 方法。
那么在这里,我们要问我们怎么知道这些常量的信息在哪里,他们的作用又是什么?打开对象浏览器(F2),我们可以看到这个是属于AcCommand类下的成员,至于它作用,可以在Google上搜索到,这就不多说了.看到这里,之前那个文本框的获得焦点事件相信大家应该明白了吧,正是这个函数的作用才让第一个字段获得焦点并触发了文本框的获得焦点事件.
 至此,在frmyg_child中的代码告一段落,接下来我们想像一下,在主窗体中点击修改按钮,系统也就打开了frmyg_child_Edit窗体,这些代码工作的流程,有了上面的介绍,相信大家应该也很清楚了,如果朋友你真的有心用平台来作开发的话,我个人认为平台的一些代码你也应该尽力的弄懂,当然这可能是比较痛苦和困难的,有些引用的过程和函数我们还不一定能够看到,大多数都是引用Acchelp.umv这个文件,好像又扯远了,ok继续.
 当打开修改窗体之后,我们要将要修改的记录的内容赋值给修改窗体中的文本框了.在修改窗体的加载事件中我们先设置修改窗体的记录源为:
Me.RecordSource = "Select * FROM tblCodeyg Where ygId = '" & selectstr & "'"
这是一句SQL语句,不懂的朋友请自己看相关的SQL语言的教程.注意程序运行到这里,selectstr的值就有了,就是先前在GotFocus中赋予的. 按照钱的教程设计好修改窗体,设计好之后就要去那个关闭按钮进行编码了,这同样是一个Toolbar对象的ButtonClick事件



朱朱 发表于:2010-01-31 20:36:11

Private Sub ToolbarFrm_ButtonClick(ByVal Button As Object)
   If IsNull(Me.ygxm) Then
       MsgBox "请输入员工姓名!", vbCritical, "提示:"
       Me.ygxm.SetFocus
       Exit Sub
   End If
   Me.Refresh
   DoCmd.Echo False
   Forms!usysfrmMain!frmChild.SourceObject = "frmyg_child"
   DoCmd.Echo True
    '触发子窗体计时器事件
   Forms!usysfrmMain!frmChild.Form.TimerInterval = 300
   DoCmd.Close acForm, "frmyg_child_Edit"
   End Sub
首先对文本框数据有效性的判断,接着刷新一下自己,关闭屏幕刷新,设置主窗体中frmchild这个子窗体的源对象为frmyg_child.
下面一句代码关于计时器的是下一节才会用到的,这里可以不用去管它.最后关闭这个_Edit窗体,有朋友可能会问,在这里,似乎没有看到任何一句更新数据的代码啊,怎么会关闭这个Edit窗体回到主窗体之后,数据就会更新显示了呢,是Forms!usysfrmMain!frmChild.SourceObject = "frmyg_child"这句话起的作用吗?

下面,我们再来看一看修改记录后自动定位到修改的记录行的功能是如何具体实现的.
首先,我们用一个变量来保存我们所修改的记录的id值
Public g_CurrentSelectStrID As String   该句放在了variable模块当中.之后进行frmyg_child的代码界面,进入计时器触发事件,
在该事件中,首先调用平台函数Acchelp_FindstrRecord (g_CurrentSelectStrID),该函数的作用从名字上就可以看出是定位当前修改的记录,同样这个函数的定义我们无法知道,很可惜啊.
然后是这句话, Me.TimerInterval = 0,让计时器不再执行, 这里有朋友可能又不能理解了,写这句话让计时器不再执行是做什么? 从钱的后面的教程中我们可以知道,后面在frmyg_child_Edit窗体的关闭按钮事件代码中有这样一句话.
'触发子窗体计时器事件
        Forms!usysfrmMain!frmChild.Form.TimerInterval = 300
由此可见,一旦设置了窗体的记时间隔:TimerIntrval属性就会触发窗体的计时器事件,这里设置子窗体的计时间隔为300,300是一个什么概念呢?查询微软的帮助文档可知,1000代表1秒,那么300大约就是0.3秒了,所以每隔0.3秒计时器事件中的代码会执行一次.
 0.3秒后子窗体的Timer事件就会触发,回到frmyg_child的Timer事件中,由于计时器事件中的代码只要执行一次就可以了,所以在计时器事件最后,设置间隔为0, 计时器不再执行了.
注意程序如果运行到此时, g_CurrentSelectStrID是否有值了呢,从钱的教程可知,在Edit窗体的加载事件当中,还要要为g_CurrentSelectStrID进行赋值.
 如此,整个修改记录并自动定位到所修改的记录的功能就实现了,不知道大家清楚了没有.

关于数据的查询和删除部分,钱的教程介绍的比较详细.这里就不多说了

下面谈谈我用平台的一些体会,本人09年底才接触平台,自己本来有点VB基础,但也没开发过什么像样的数据库系统.由于公司的电脑不让装一些盗版的编程开发软件,无奈就想到了用Access进行开发,平台的出现是一个很好的工具.平台为我们开发好了一些功能,确实好用,但是如果不参加其培训,对我们的学习也就有了一定的难度,钱的教程也只能带领我们入门.这里确实要感谢钱的教程.

个人认为,如果想要用平台进行开发,除了能正确运用平台之外,应该对平台本身的代码和其代码的工作流程有一个认识,虽然许多的代码是引用Acchelp.umv文件,我们不可见,但是还是应该在现有能看到的代码中去读一读,对自己会有很大的提高,对于初学者必须去多看看微软提供的帮助文档.实际我自己也只能算是一个初学者,希望和大家一起进步.
  我的QQ:38951986



麥田 发表于:2010-02-01 12:51:07

呵呵  这位网友爱好者分析的很透彻  制作小一点软件  用这个教程学习后  用专业版平台就可以制作了

另:以后此类描述的文章发布在网站里面即可

登录网站首页→进入"个人管理中心"→专栏管理→发表文章→即可在Access网站首页\个人博客显示文章



总记录:6篇  页次:1/1 9 1 :