ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 131953|回复: 227

我是如何用EXCEL+ACCESS+WORD做出一个适合自己使用的东东的

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2006-6-10 13:07 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:Access协同
前言 前一段时间很少来这里,是因为花了很长一段时间用EXCEL+ACCESS+WORD做了一个适合本部门使用的东东,这个东东做出来后,简化了本部门的很多工作,得到领导的口头表扬:(。本应把东东传上来让大家批评批评,但由于涉及到本部门的一些小小秘密,要改大量的东东,而且代码又太乱,也就懒得上传了。我就以做一个通讯录并可以用通讯录的地址打印信封为例,把我做这个东东的过程弄出来和大家分享分享。 首先申明: 1、本帖不是教学帖,请大家不要问我为什么代码要这样写,因为有的也我不知道为什么,我只知道这样可以达到目的。 2、偶不是科班出身,所以在写代码时有很多陋习,还请大家不要扔偶鸡蛋。 3、虽然费了九牛二虎之力整出来个东东,但很多代码写得比较幼稚,请各位大虾不要笑话,知道如何简化的还请告知一声。 4、请大家不要催我,因为我要把代码测试过没问题才能弄上来,而世界杯又到了。不过不管如何我一定会全部弄出来的。

评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2006-6-10 13:07 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
第一步 建三个文件 一个当然是ACCESS数据库了(以前用EXCEL来保存数据,而又需要可以多人可以编辑,所以共享了EXCEL,让我饱受文件经常损坏和速度奇慢之苦,用ACCESS做数据库后,幸福多了),我把它命名为“通讯录“,在ACCESS中建一个表,也命名为“通讯录”,“通讯录”表包括13个字段(ID、姓名、办公电话、手机、小灵通、传真、家庭电话、QQ号码、工作单位、单位地址、邮政编码、电子邮件、MSN),其中ID是自动编号,其它十二个字段均为非必填字段、允许空字符串;字段大小分别是:姓名为8、所有的电话和QQ号码为12、邮政编码为6、其它均为50(请根据字段长度分别设置文本框的maxlength属性)。 另一个是EXCEL文件,我也把它命名为通讯录,这个EXCEL文件主要是用来做界面,对ACCESS数据库的操作全在这里进行了,在EXCEL里插入一个窗体,窗体再插入12个标签、12个文本框和10个命令按钮(为方便操作,我将textbox1~textbox12的顺序根据“通讯录”表的字段排列,即工作单位的文本框为textbox8、单位地址的文本框为textbox9、邮政编码的文本框为textbox10等),标签的caption属性分别设为姓名、办公电话、手机、小灵通、传真、家庭电话、QQ号码、工作单位、单位地址、邮政编码、电子邮件、MSN;命令按钮的caption属性为别为首条、前条、后条、末条、添加、修改、删除、查找、打印、退出,如下图: 最后一个是WORD文件,命名为信封,以后用来打信封用。在我的实际工作中,这个WORD文件是帮了我的大忙,以前我打一封文书的时候,要分别打开草拟稿纸、XXX文书、送达回证(两份),逐个修改后再打印,尤其是那个文书,需要修改的地方不下二十处,又有好几个时间,害得我经常搞错[em06],用我做的那个东东后,一键就搞定了四个文书,既加快了速度,又减少了修改过程中容易发生的错误。
[此贴子已经被作者于2006-6-13 19:58:42编辑过]
9YZFJcvI.jpg
1oFe5RIT.jpg

TA的精华主题

TA的得分主题

 楼主| 发表于 2006-6-10 13:07 | 显示全部楼层
第二步 我考虑的是如何向数据库里添加数据,所以就先搞定“添加”按钮(即CommandButton5)。 我把添加分为两步进行,一是按下CommandButton5按钮后,才可以在文本框输入数据,在文本框输入数据后再按一下CommandButton5按钮才把数据输入到ACCESS数据库,那如何判断是向文本框输入数据,还是向数据库输入数据呢?我是根据CommandButton5按钮的caption属性来判断的,如果CommandButton5按钮的caption属性是“添加”二字,就把所有的文本框的enabled属性都设为true,好让我向文本框输入数据,并且此时把CommandButton5按钮的caption属性改为“保存”二字。如果CommandButton5按钮的caption属性为“保存”,就把文本框里的数据保存入ACCESS数据库。 在添加时有时突然不想添加了,怎么办?我就用另一个按钮("退出"按钮,即CommandButton10)来判断,是否取消添加,即按下CommandButton5后,把CommandButton10的caption属性改为取消,如果在CommandButton10的属性为取消时按下它,就取消添加。 在添加过程中,为防止误按其它按钮,我就把除CommandButton5和CommandButton10之外的按钮全禁止了。 如何添加到数据库,当然用ADO来实现了(这是我研究了N久的http://club.excelhome.net/dispbbs.asp?boardID=2&ID=70082&page=1&px=0后,才搞定的) 代码如下: Dim Stpath As String Dim Strsql As String Dim A(12) Dim i% If CommandButton5.Caption = "添加" Then For i = 1 To 12 Me.Controls("textbox" & i).Enabled = True Me.Controls("textbox" & i) = "" Next For i = 1 To 9 Me.Controls("commandbutton" & i).Enabled = False Next CommandButton5.Enabled = True CommandButton5.Caption = "保存" CommandButton10.Caption = "取消" TextBox1.SetFocus Else For i = 1 To 12 A(i) = Me.Controls("textbox" & i).Value Next [U]Set cnn = CreateObject("Adodb.Connection") Set rst = CreateObject("Adodb.Recordset") Stpath = ThisWorkbook.Path & Application.PathSeparator & "通讯录.mdb" cnn.Provider = "Microsoft.Jet.OLEDB.4.0" cnn.Open "Data Source =" & Stpath & ";Jet OLEDB:Database Password=" & ""[/U] Strsql = "Insert Into 通讯录(姓名,办公电话,手机,小灵通,传真,家庭电话,QQ号码,工作单位,单位地址,邮政编码,电子邮件,MSN) " & _ "Values('" & A(1) & "','" & A(2) & "','" & A(3) & "','" & A(4) & "','" & A(5) & "','" & A(6) & "','" & A(7) & "','" & A(8) & "','" & A(9) & "','" & A(10) & "','" & A(11) & "','" & A(12) & "')" cnn.Execute Strsql Strsql = "Select * From 通讯录" rst.Open Strsql, cnn, 1, 3 rst.movelast myID = rst.Fields(0) Set rst = Nothing Set cnn = Nothing MsgBox "数据已输入!", vbOKOnly + 64, "温馨提示" For i = 1 To 12 Me.Controls("textbox" & i).Enabled = False Next For i = 1 To 9 Me.Controls("commandbutton" & i).Enabled = True Next CommandButton5.Caption = "添加" CommandButton10.Caption = "退出" End If 上面有下划线的部分以后经常用到,所以我在EXCEL里插入一模块,把下划线部分写在模块里,以后可以少写很多东东,也方便维护。如下: Public stpath Public cnn Public rst Sub mycnn() Set cnn = CreateObject("Adodb.Connection") Set rst = CreateObject("Adodb.Recordset") stpath = ThisWorkbook.Path & Application.PathSeparator & "通讯录.mdb" cnn.Provider = "Microsoft.Jet.OLEDB.4.0" cnn.Open "Data Source =" & stpath & ";Jet OLEDB:Database Password=" & "" End Sub 并把下划线改成Call mycnn,并去掉 Dim Stpath As String
[此贴子已经被作者于2006-6-13 20:43:35编辑过]

TA的精华主题

TA的得分主题

 楼主| 发表于 2006-6-10 13:07 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

第三步
窗体初始化
当数据库有了数据后,我想到的是显示窗体时,不要让文本框空当当的,就让它显示数据库里的数据吧。显示窗体时,如果数据库里没有数据,除了“添加”和“退出”按钮,其它按钮好像都没什么用,我就让它们失效;如果数据库里只有一条数据,那首条、末条、向前、向后按钮好像也没什么用,我也让它们失效;不管数据库里有多少条数据,我只能让它显示第一条,首条、向前按钮我也让它失效了。所以就有了下面的代码。

有个另外的情况,如果是经过查询再返回到这个主窗口时,因为我没想到特别好的办法,办能就让所有的按钮都有效,我是根据myid来判断,是否是经过查询再返回到这个主窗口的。

代码如下:
Private Sub UserForm_Initialize()    '窗口初始化

    Dim Strsql As String
    Dim i%

    Call mycnn

    If myID = 0 Then
        Strsql = "Select * From 通讯录"
        rst.Open Strsql, cnn, 1, 3

        If rst.RecordCount = 0 Then
            For i = 1 To 9
                Me.Controls("commandbutton" & i).Enabled = False
            Next
            CommandButton5.Enabled = True
        Else
            If rst.RecordCount = 1 Then
                For i = 1 To 4
                    Me.Controls("commandbutton" & i).Enabled = False
                Next
            Else
                For i = 1 To 2
                    Me.Controls("commandbutton" & i).Enabled = False
                Next
            End If
        End If
    Else
        Strsql = "Select * From 通讯录 where ID=" & myID
        rst.Open Strsql, cnn, 1, 3
        For i = 1 To 4
            Me.Controls("commandbutton" & i).Enabled = True
        Next
    End If
   
    myID = rst.Fields(0)
    For i = 1 To 12
        Me.Controls("textbox" & i) = rst.Fields(i)
        Me.Controls("textbox" & i).Enabled = False
    Next

    Set rst = Nothing
    Set cnn = Nothing

End Sub

[此贴子已经被作者于2006-6-27 21:05:15编辑过]

TA的精华主题

TA的得分主题

 楼主| 发表于 2006-6-10 13:07 | 显示全部楼层
第四步 修改 修改和添加差不多,根据CommandButton6的catiion属性来判断修改还是修改后的保存。当CommandButton6的caption属性为修改时,按下CommandButton6按钮,就让所有的textbox可以编辑为防止意外,把除CommandButton6按钮和CommandButton10按钮之外的按钮禁止,并把CommandButton10的caption改为“取消”,好让不想修改时取消修改,同时,把CommandButton6的caption属性改为保存。 当CommandButton6的caption属性为保存时把textbox中的值用update修改到数据库中去,根据什么来修改,才能修改到我想修改的记录?因为12个文本框都有可能被修改,如果用当年任一文本框中值来搜寻数据库中的内容,都有可能搜索不到,或者即使搜索到,都有可能是另外(或重复)的记录,而不是我想修改的记录,这时,我考虑的是,必须根据一个唯一值到数据库来搜寻我想修改的记录,正好ID字段(自动编号的那个)符合这个要求,这就要求每当textbox显示一条记录时,公共变量myID都要等于这条记录ID字段的值。前面初始化窗体时,已经做到了,但在添加时,还没有做到,我发现,每当添加一条记录时,都是添加在数据库的末尾,那就在添加按钮中增加使公共变量myID等于刚添加记录的ID值(即最后一条记录的ID值,添加的红色代码部分)。 CommandButton6的代码如下: Private Sub CommandButton6_Click() '修改 Dim Strsql As String Dim A(12) Dim i% If CommandButton6.Caption = "修改" Then For i = 1 To 12 Me.Controls("textbox" & i).Enabled = True Next For i = 1 To 9 Me.Controls("commandbutton" & i).Enabled = False Next CommandButton6.Enabled = True CommandButton6.Caption = "保存" CommandButton10.Caption = "取消" TextBox1.SetFocus Else For i = 1 To 12 A(i) = Me.Controls("textbox" & i).Value Next Call mycnn Strsql = "Update 通讯录 set 姓名='" & A(1) & "',办公电话='" & A(2) & "',手机='" & A(3) & "',小灵通='" & A(4) & "',传真='" & A(5) & "',家庭电话='" & A(6) & "',QQ号码='" & A(7) & "',工作单位='" & A(8) & "',单位地址='" & A(9) & "',邮政编码='" & A(10) & "',电子邮件='" & A(11) & "',MSN='" & A(12) & "' where ID = " & myID cnn.Execute Strsql Set rst = Nothing Set cnn = Nothing MsgBox "数据已修改!", vbOKOnly + 64, "温馨提示" For i = 1 To 12 Me.Controls("textbox" & i).Enabled = False Next For i = 1 To 9 Me.Controls("commandbutton" & i).Enabled = True Next CommandButton6.Caption = "修改" CommandButton10.Caption = "退出" End If End Sub
[此贴子已经被作者于2006-6-13 20:44:22编辑过]

TA的精华主题

TA的得分主题

 楼主| 发表于 2006-6-10 13:08 | 显示全部楼层
第五步 删除 删除相对来说简单一点,当然,按下删除前最好提示一下,否则一不小心按错了就惨了,所以我用一个msgbox进行提示,如果在msgbox上按“是”则删除,按“否”则不删除。 删除是根据ID字段(因为它唯一,不用担心删了其他相同的值)在数据库中找到记录并删除的。 删除文本框中的记录后,清除文本框中的值,并搜索数据库,如果有记录,就显示到文本框中来,如果没有,就只有添加和退出按钮有用,其它禁用(和初始化窗体类似)。 代码如下: Private Sub CommandButton7_Click() '删除 Dim ts Dim Strsql As String Dim i% ts = MsgBox("您是否真的删除该记录?", vbYesNo + 64, "温馨提示!") If ts = vbNo Then Exit Sub Else Call mycnn Strsql = "delete * from 通讯录 where ID = " & myID cnn.Execute Strsql For i = 1 To 12 Me.Controls("textbox" & i) = "" Next Strsql = "Select * From 通讯录" rst.Open Strsql, cnn, 1, 3 If rst.RecordCount = 0 Then For i = 1 To 9 Me.Controls("commandbutton" & i).Enabled = False Next CommandButton5.Enabled = True Else If rst.RecordCount = 1 Then For i = 1 To 4 Me.Controls("commandbutton" & i).Enabled = False Next Else For i = 1 To 2 Me.Controls("commandbutton" & i).Enabled = False Next End If myID = rst.Fields(0) For i = 1 To 12 Me.Controls("textbox" & i) = rst.Fields(i) Next Set rst = Nothing Set cnn = Nothing End If For i = 1 To 12 Me.Controls("textbox" & i).Enabled = False Next Set rst = Nothing Set cnn = Nothing End If End Sub
[此贴子已经被作者于2006-6-15 20:00:08编辑过]

TA的精华主题

TA的得分主题

 楼主| 发表于 2006-6-10 13:08 | 显示全部楼层

第六步
退出

因为我用退出按钮来取消添加或删除,所以按下退出按钮时,有两种情况,一是当退出按钮的caption属性是“取消”时,使文本框的值为原记录,其他按钮均恢复为可用,添加按扭和修改按钮的caption属性分别恢复为“添加”和“修改”。
当退出按钮的caption属性是“退出”时,卸载窗体。
有了退出代码后,我就把右上角的那个叉给禁止了
代码如下:
Private Sub CommandButton10_Click()    '退出或者取消添加和修改
    Dim Strsql As String
    Dim i%
    If CommandButton10.Caption = "取消" Then
        CommandButton10.Caption = "退出"
        Call mycnn
        Strsql = "Select * From 通讯录 where ID=" & myID
        rst.Open Strsql, cnn, 1, 3
        myID = rst.Fields(0)
        For i = 1 To 12
            Me.Controls("textbox" & i) = rst.Fields(i)
            Me.Controls("textbox" & i).Enabled = False
        Next
        Set rst = Nothing
        Set cnn = Nothing
        CommandButton5.Caption = "添加"
        CommandButton6.Caption = "修改"
        For i = 1 To 9
            Me.Controls("commandbutton" & i).Enabled = True
        Next
    Else
        Unload Me
    End If
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)‘禁止那个X
    If CloseMode <> 1 Then Cancel = 2

 myID = 0'退出窗口时,把myid值也清掉吧。
End Sub

[此贴子已经被作者于2006-6-27 21:15:25编辑过]

TA的精华主题

TA的得分主题

 楼主| 发表于 2006-6-10 13:08 | 显示全部楼层

第七步

 

前条、首条

 

数据库中有了数据后,我开始想实现简单的查询,想想还是一条一条查吧,于是就整了前条,所谓前条,就是当年记录的前一条记录,我的思路是,先从数据库中把所有记录查询出来,然后用循环找到当前显示在文本框中的记录(我是用ID字段来比较的,因为它不会重复),然后前移一条记录,显示在文本框中,如果是第一条记录,就把前条、首条按钮禁止掉,当然,向前移了,后条、末条按钮当然不能再禁止了。

首条就相对容易一点了,先从数据库中把所有记录查询出来,然后移到第一条记录后,显示在文本框中就行了。

代码如下:

Private Sub CommandButton2_Click()    '前条

    Dim Strsql As String

    Call mycnn

    Strsql = "Select * From 通讯录"
    rst.Open Strsql, cnn, 1, 3

    Do Until rst.Fields(0) = myID
        rst.movenext
    Loop
    rst.MovePrevious
    If rst.BOF Then
        CommandButton1.Enabled = False
        CommandButton2.Enabled = False
        rst.movenext
    End If

    myID = rst.Fields(0)
    For i = 1 To 12
        Me.Controls("textbox" & i) = rst.Fields(i)
    Next

    Set rst = Nothing
    Set cnn = Nothing

    CommandButton3.Enabled = True
    CommandButton4.Enabled = True
   
End Sub

 

Private Sub CommandButton1_Click()    '首条
    Dim Strsql As String

    Call mycnn

    Strsql = "Select * From 通讯录"
    rst.Open Strsql, cnn, 1, 3
    rst.movefirst

    myID = rst.Fields(0)
    For i = 1 To 12
        Me.Controls("textbox" & i) = rst.Fields(i)
    Next

    Set rst = Nothing
    Set cnn = Nothing

    CommandButton1.Enabled = False
    CommandButton2.Enabled = False
    CommandButton3.Enabled = True
    CommandButton4.Enabled = True
End Sub

 

PS:后面的后条和前条的思路类似,都是用循环,感觉效率有点低,但我实在想不出其他办法了。哪位仁兄仁姐知道的,就告诉我哈,多谢先。

再PS:由于世界杯,我有小小慢,不好意思哈,偶肯定会完成的。希望乱七八糟的文字和代码没有倒了大家伙的胃口哈。

[此贴子已经被作者于2006-6-22 21:38:29编辑过]

TA的精华主题

TA的得分主题

 楼主| 发表于 2006-6-10 13:08 | 显示全部楼层

第八步

 

后条、末条

 

后条的思路和前条一样,先从数据库中把所有记录查询出来,然后用循环找到当前显示在文本框中的记录(我是用ID字段来比较的,因为它不会重复),然后向后移一条记录,显示在文本框中,如果是最后一条记录,就把后条、末条按钮禁止掉。前条、首条按钮不再禁止。

首条,先从数据库中把所有记录查询出来,然后移到最后一条记录后,显示在文本框中就行了。

代码如下:

Private Sub CommandButton3_Click()    '后条

    Dim Strsql As String

    Call mycnn

    Strsql = "Select * From 通讯录"
    rst.Open Strsql, cnn, 1, 3

    Do Until rst.Fields(0) = myID
        rst.movenext
    Loop
    rst.movenext
    If rst.EOF Then
        CommandButton3.Enabled = False
        CommandButton4.Enabled = False
        rst.MovePrevious
    End If

    myID = rst.Fields(0)
    For i = 1 To 12
        Me.Controls("textbox" & i) = rst.Fields(i)
    Next

    Set rst = Nothing
    Set cnn = Nothing

    CommandButton1.Enabled = True
    CommandButton2.Enabled = True

End Sub

Private Sub CommandButton4_Click()    '末条

    Dim Strsql As String

    Call mycnn

    Strsql = "Select * From 通讯录"
    rst.Open Strsql, cnn, 1, 3

    rst.movelast

    myID = rst.Fields(0)
    For i = 1 To 12
        Me.Controls("textbox" & i) = rst.Fields(i)
    Next
   
    Set rst = Nothing
    Set cnn = Nothing

    CommandButton1.Enabled = True
    CommandButton2.Enabled = True
    CommandButton3.Enabled = False
    CommandButton4.Enabled = False

End Sub

[此贴子已经被作者于2006-6-22 21:47:45编辑过]

TA的精华主题

TA的得分主题

 楼主| 发表于 2006-6-10 13:08 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

第九步

 

查找(分4步吧)

 第九步(一)

在做这个东东的过程中,我感觉查找是非常麻烦的,总是很难达到让我满意的效果。最后实在没办法的情况下,就糊弄了一下自己,反正做出来能用就行了,至于小小瑕疵就懒得理它了。

我觉得仅仅这一个窗口很难实现一些复杂的查找工作,没办法,只能再插入一个窗体,在窗体上插入三个标签、一个列表框、一个文本框、三个命令按钮和一个ListView控件。如下图:


[此贴子已经被作者于2006-6-27 21:26:05编辑过]
CYTAw2kX.jpg
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-3-29 16:37 , Processed in 0.053859 second(s), 9 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表