第22章 电视抽奖程序   现在电视节目都有丰富多彩的电视抽奖活动。当主持人宣布开始抽奖时,电话号码、手机号码、姓名等数值随机显示在电视屏幕上,主持人宣布停止,中奖的电话号码将显示在电视屏幕上。本章中将以一个电视抽奖程序为例,具体介绍建立一个完整的电视抽奖程序的设计过程。 22.1 项 目 分 析   项目分析是对整个工程项目的功能和模块设计进行分析,决定如何开发项目和实现功能。电视抽奖程序包括如何实现电视抽奖信息录入、修改、删除及程序运行时中奖号码自动录入数据并显示在屏幕上。 22.1.1 项目功能分析   项目功能分析是在项目开发总体任务基础上进行的。电视抽奖程序总体任务是实现随机数值抽取。本项目中需要实现的功能如下: * 抽奖电话号码信息录入; * 抽奖电话号码信息修改; * 抽奖电话号码信息删除; * 抽奖电话号码中奖号码自动录入; * 抽奖电话号码显示。 22.1.2 项目功能模块分析   根据以上项目功能进行集中分析可以得到如下项目功能模块图,如图22.1所示。 22.2 数据库设计与实现   数据库在电视抽奖程序中占有非常重要的地位。合理的数据库结构可以提高数据存储的效率,保证数据的完整性和一致性。电视抽奖程序项目数据库主要包括电话号码信息和中奖电话号码信息。电话号码信息储存电视抽奖程序查询的基本电话信息。当程序运行时,中奖电话号码信息自动储存便于查询。 22.2.1 数据库需求分析   数据库结构数据体现用户的需要和功能要求。电视抽奖系统数据库包括电话号码信息表和中奖号码信息表,用于存储基本电话号码信息和中奖电话号码信息。通过分析电视抽奖程序需求,将得到如图22.2所示的程序流程图。 图22.2 项目数据流程图   根据电视抽奖程序的项目需求,通过对电视抽奖过程的内容和数据流程分析,设计如下的数据结构。 * 电话号码基本信息:字段包括序号、电话号码、姓名、地址。 * 中奖电话号码基本信息:字段包括序号、电话号码、姓名、地址。   本程序相对功能实现比较简单,只包括数据库结构完全相同的两个数据表。 22.2.2 数据库结构设计   电视抽奖系统数据库结构包括电话号码信息表和中奖电话号码信息表。根据数据库结构内容,可以设计出满足用户需求的各种实体,为后面的逻辑结构设计奠定基础。主要包括电话号码信息实体、中奖电话号码信息实体。电话号码信息实体如图22.3所示。 图22.3 电话号码信息实体图   中奖电话号码信息实体如图22.4所示。   实体与实体之间E-R关系图如图22.5所示。 图22.4 中奖电话号码信息实体图 图22.5 实体E-R图 22.2.3 数据库结构实现   数据库结构设计好以后,需要将其转化为Access数据库所支持的数据库模型。电视抽奖程序数据库中电话号码信息表名为Phone,中奖电话号码信息表名为Award。电话号码信息表设计结构如表22.1所示。 表22.1 电话号码信息表 列 名 数 据 类 型 可 否 为 空 说 明    No 数字 否 序号    Phone 文本 否 电话号码    Name 文本 可 姓名    Address 文本 可 地址      中奖电话号码信息表与电话号码信息表完全相同在此不再赘述。具体操作步骤如下:   (1)选择“开始”|“所有程序”|Microsoft Office 2003|Microsoft Office Access 2003命令,打开Access程序。   (2)选择“文件”|“新建”|“空数据库”命令,弹出设计窗体,如图22.6所示。   (3)选择“使用设计器创建表”选项,在弹出的设计器窗体中输入表22.1所示内容,如图22.7所示。 图22.6 Access数据库设计窗体 图22.7 Access数据库设计器窗体   (4)单击窗体右上角关闭图标,输入表名称Phone。至此,电话号码信息表创建完毕。   中奖电话号码信息表与此完全类似,不再赘述。 22.3 程序窗体的设计与实现   数据库内各表设计完成后,有关数据库的后台工作已经完成。现在将通过电视抽奖程序各个功能模块的实现,讲解如何使用Visual Basic来设计和编写抽奖程序的窗体代码。   本程序主要使用图形来显示电话号码。在设计程序之前使用Photoshop等图形图像处理软件来设计抽奖的背景图片和0~9所有的数字的图片。关于图像设计的相关内容请参看其他资料。 22.3.1 “抽奖主程序”模块   “抽奖主程序”模块主要包括四个CommandButton控件:开始抽奖、关于本程序、电话号码程序、电话号码录入。分别调用运行其他程序模块。“抽奖主程序”模块设计操作步骤如下:   (1)选择“文件”|“新建工程”命令,选择Stand EXE图标,Visual Basic将自动建立一个标准Form窗体,属性为默认设置。选择“文件”|“保存工程”命令,保存工程项目名称为cj。   (2)选择“工程”|“添加窗体”命令,弹出“添加窗体”窗体,选择“窗体”图标。添加一个标准窗体,Name属性为“frmmain”。   (3)单击工具箱中的CommandButton图标,添加4个CommandButton控件,设置其Caption属性为“开始抽奖”、“关于本程序”、“电话号码录入”、“电话号码查询”。   (4)双击空白窗体,弹出代码编辑窗口,输入以下代码:    Private Sub Command1_Click() '抽奖窗体 frmcj.Show End Sub Private Sub Command2_Click() '查询窗体 frmsearch.Show End Sub Private Sub Command3_Click() '录入窗体 frminput.Show End Sub Private Sub Command4_Click() '关于窗体 frmAbout.Show End Sub      (5)设计窗体如图22.8所示。 22.3.2 “抽奖录入窗体”模块   所有抽奖电话号码在进行抽奖之前必须录入到数据库的Phone表。“抽奖录入”窗体模块主要用于导航、显示、输入电话号码信息。“抽奖录入”窗体模块设计操作步骤如下:   (1)选择“工程”|“添加窗体”命令,弹出“添加窗体”对话框,选择“窗体”图标。添加一个标准窗体,Name属性为frminput。   (2)单击工具箱中的CommandButton图标,添加八个CommandButton控件,设置其Caption属性为“第一个”、“向前”、“向后”、“最后一个”、“新增”、“删除”、“查询”、“关闭”。前四个为导航按钮,后四个为功能按钮。   (3)单击工具箱中的Label图标,添加3个标签控件,其Caption属性为“姓名”、“电话号码”、“地址”。   (4)单击工具箱中的TextBox图标,添加3个文本框控件,默认属性不变。   (5)双击空白窗体,弹出代码编辑窗口,输入以下代码:    '声明aDo记录集 Dim Rs As ADODB.Recordset Private Sub Command1_Click() '移动到记录头 Rs.MoveFirst '显示记录 Call disprecord End Sub Private Sub Command2_Click() '向前移动一个记录 Rs.MovePrevious Call disprecord End Sub Private Sub Command3_Click() '向后移动一个记录 Rs.MoveNext Call disprecord End Sub Private Sub Command4_Click() '移动到记录尾部 Rs.MoveLast Call disprecord End Sub Private Sub Command5_Click() '调用函数基础数据是否符合要求 If checkdata = False Then Exit Sub End If '判断是否空数据库 If Rs.RecordCount > 0 Then Rs.MoveLast '最后一笔记录序号 ixh = Rs.Fields("no") Else ixh = 0 End If '增加一笔记录 Rs.Addnew Rs.Fields("no") = ixh + 1 Rs.Fields("Name") = Trim(Text1.Text) Rs.Fields("Phone") = Trim(Text2.Text) Rs.Fields("address") = Trim(Text3.Text) Rs.Update MsgBox "新增数据成功!" End Sub Private Sub Command6_Click() '删除一笔记录 Rs.Delete Rs.MoveNext Call disprecord End Sub Private Sub Command7_Click() '查询窗体显示 frmsearch.Show End Sub Private Sub Command8_Click() '退出程序 UnLoad Me End Sub Private Sub Form_Load() Set Rs = New ADODB.Recordset '建立记录集 Rs.CuRsortype = adopenKeyset '游标方式为adopenKeyset Rs.LockType = adLockOptimistic '锁定方式 sqlConnection = "provider=microsoft.jet.oledb.4.0;data source=" & App.Path & "\cj.mdb" '打开数据库 Rs.Open "Select * from Phone", sqlConnection '打开记录集 Call disprecord End Sub Private Sub disprecord() If Rs.EOF Then Rs.MoveLast '记录集尾部 If Rs.BOF Then Rs.MoveFirst '记录集头部 Text1.Text = Rs.Fields("Name") '字段内容赋予text控件 Text2.Text = Rs.Fields("Phone") Text3.Text = Rs.Fields("address") End Sub Private Function checkdata() As Boolean '判断数据是否为空 If Len(Trim(Text1.Text)) <= 0 Or Len(Trim(Text2.Text)) <= 0 Or Len(Trim(Text3.Text)) <= 0 Then MsgBox "“姓名”、“电话号码”、“地址”不能为空!" checkdata = False Else checkdata = True End If '电话号码必须为数字 If IsNumeric(Trim(Text2.Text)) = False Then MsgBox "电话号码必须为数字!" checkdata = False Else checkdata = True End If End Function      (6)窗体上3个文本框内容分别对应数据库中Phone表的3个字段“姓名”、“电话号码”、“地址”。按钮“第一个”、“向前”、“向后”、“最后一个”分别导航数据库记录。按钮“新增”、“删除”、“查询”、“关闭”分别在数据库中增加、删除一个记录,运行查询窗体,关闭窗体。   Disprecord过程主要来为3个文本框中赋予数据库记录数据。Checkdata()函数在新增一个记录时,主要用来判断3个文本框数据格式是否正确,电话号码必须为数字,所有数据不能为空。如果出现错误自动弹出错误提示。设计窗体如图22.9所示。 22.3.3 “抽奖窗体”模块   “抽奖窗体”模块主要以图形化数字来动态显示电话号码。当按下空格键时,停止运行并出现“祝您中奖”的图片,显示中奖电话号码。“抽奖窗体”模块设计操作步骤如下:   (1)选择“工程”|“添加窗体”命令,弹出“添加窗体”窗体,选择“窗体”图标。添加一个标准窗体,Name属性为frmcj。   (2)单击工具箱中的Image图标,添加一个图像控件数组。用于显示7位数字。其Name属性为“img”,index属性为0~6。   (3)单击工具箱中的Image图标,添加2个图像控件。其Name属性为显示背景图片imgbj、显示提示信息imgjx。   (4)双击空白窗体,弹出代码编辑窗口,输入以下代码:    Option Explicit Dim i As Integer Dim j As Integer Dim db As ADODB.Connection Dim Rs As ADODB.Recordset '中奖记录集 Dim Rsaward As ADODB.Recordset Dim iPhone As Integer Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) 'Esc键退出 If KeyCode = 27 Then UnLoad Me End If '空格键继续运行 If KeyCode = 32 Then 'Timer控件运行循环显示数据,否则显示中奖电话号码 If Timer1.Enabled = False Then 'Timer控件运行 Timer1.Enabled = True '显示祝您中奖 Set imgjx.Picture = imglist.ListImages(14).Picture Else 'Timer1.Enabled = False '显示一等奖 Set imgjx.Picture = imglist.ListImages(12).Picture '保存中奖电话号码 Call insertdata End If End If End Sub Private Sub Form_Load() Set db = New Connection '建立数据库连接 db.CuRsorLocation = adUseClient db.Open "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\cj.mdb;" Set Rs = New Recordset '建立记录集 Rs.Open "Select no ,Name,Phone,address from Phone", db, aDOpenStatic, adLockOptimistic  '调用setimg过程显示图片  Call setimg End Sub Private Sub setimg() '初始赋值为0 For i = 0 To 6 img(i).Visible = True Set img(i).Picture = imglist.ListImages(1).Picture Next '显示祝您中奖、公司名称 Set imgbj.Picture = imglist.ListImages(11).Picture Set imgjx.Picture = imglist.ListImages(14).Picture End Sub Private Sub dispNumber(ByVal s As String) For i = 0 To 6 '读取电话号码数字 j = Mid(Rs.Fields("Phone"), i + 1, 1) '显示对应数字图片 Set img(i).Picture = imglist.ListImages(j + 1).Picture Next End Sub Private Sub insertdata() Set Rsaward = New Recordset '建立记录集 Rsaward.Open "Select no ,Name,Phone,address from award", db, aDOpenStatic, adLockOptimistic  '增加中奖记录  Rsaward.Addnew  Rsaward.Fields("Phone") = Rs.Fields("Phone")  Rsaward.Fields("Name") = Rs.Fields("Name")  Rsaward.Fields("address") = Rs.Fields("address")  Rsaward.Update '更新记录 End Sub Private Sub Timer1_Timer() '数据库内有数据 If Rs.RecordCount > 0 Then '循环读取记录 Do While Not Rs.EOF '移动到下一个 Rs.MoveNext '显示数字对应图片 Call dispNumber(Rs.Fields("Phone")) '第二次按空格键停止 If Timer1.Enabled = False Then Exit Sub End If If Rs.EOF Then '移动到记录尾部,重新移动到记录头部 Rs.MoveFirst End If DoEvents Loop End If End Sub      (5)本窗体中Load事件创建一个Db连接和Rs记录集,并使用Setimg过程初始设置窗体为等待抽奖状态。   代码主要集中在窗体keyDown事件中。按下Esc键时自动退出窗体。按下空格键开始调用时钟控件Timer进行抽奖,再次按下空格键Timer事件停止并显示中奖电话号码。自动添加记录到award表中。时钟控件Timer1的Timer事件,每隔200毫秒读取数据库下一笔数据,并显示在窗体上。设计窗体如图22.10所示。 图22.10 抽奖设计窗体 22.3.4 “抽奖查询窗体”模块   “抽奖查询窗体”模块主要用于根据姓名、电话号码、地址查询数据库记录信息。“抽奖查询窗体”模块设计操作步骤如下:   (1)选择“工程”|“添加窗体”命令,弹出“添加窗体”窗体,选择“窗体”图标。添加一个标准窗体,其Name属性为frmsearch。   (2)单击工具箱中的CommandButton图标,添加2个CommandButton控件,其Caption属性为“查询”、“关闭”。   (3)单击工具箱中的Datagrid图标,添加一个Datagrid控件,默认属性不变。   (4)单击工具箱中的ComboBox图标,添加一个下拉框控件,List属性添加“姓名”、“电话号码”、“地址”。   (5)单击工具箱中的TextBox图标,添加一个文本框控件,默认属性不变。   (6)双击空白窗体,弹出代码编辑窗口,输入以下代码:    Private Rs As ADODB.Recordset '声明记录集 Private cn As Connection '声明数据库连接 Private Sub Command1_Click() sql = "" '初始字符串为空 Select Case Trim(Combo1.Text) '判断combo控件内容 Case "姓名" sql = "Name = '" & Trim(Text1.Text) & "'" Case "电话号码" sql = "Phone =" & Trim(Text1.Text) & "" Case "地址" sql = "address = '" & Trim(Text1.Text) & "'" End Select Call dispgrid(sql) 'datagrid控件显示记录 End Sub Private Sub Command2_Click() Rs.Close '关闭记录集 Set Rs = Nothing '清空记录集 UnLoad Me '卸载窗体 End Sub Private Sub Form_Load() Set cn = New Connection '建立数据库连接 cn.CuRsorLocation = adUseClient '建立客户端游标 cn.Open "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\cj.mdb;" '打开数据库 sql = "" Call dispgrid(sql) 'datagrid控件显示查询记录 End Sub Private Sub dispgrid(ByVal s As String) If Len(Trim(s)) <= 0 Then '判断查询字符串长度 Set Rs = New Recordset '建立记录集 Rs.Open "Select * from Phone", cn, aDOpenStatic, adLockOptimistic '打开记录集 Set Datagrid1.Datasource = Rs 'datagrid控件数据源 Else Set Rs = New Recordset '建立记录集 Rs.Open "Select * from Phone where " & s, cn, aDOpenStatic, adLockOptimistic '查询指定条件 'Datagrid控件数据源为Rs Set Datagrid1.Datasource = Rs End If End Sub      (7)窗体中下拉列表框为查询字段名称,文本框接收查询数据,单击“查询”在Datagrid控件中显示数据记录。Dispgrid过程使用s参数来判断接收字符串是否为空。如果为空显示所有数据记录,否则显示查询数据。设计窗体如图22.11所示。 22.3.5 “关于窗体”模块   “关于窗体”模块主要用来声明程序名称、版本、公司等。本节将使用“关于窗体”模板来创建一个标准Visual Basic中的About窗体。   选择“工程”|“添加窗体”命令,在弹出的“添加窗体”中选择“关于”对话框图标。自动添加如图22.12所示的关于窗体。设置lblDEscription标签控件为“一个电视抽奖程序,由天空飞翔网站出品”。 22.3.6 运行程序   电视抽奖程序各窗体设计好后,可以查看整个程序的运行状况。运行程序,出现如图22.13所示的电视抽奖主窗体。单击“开始抽奖”按钮,运行窗体如图22.14所示的电视抽奖窗体。 图22.13 电视抽奖主窗体 图22.14 电视抽奖窗体   单击“电话号码录入”按钮,运行窗体如图22.15所示的电话号码录入窗体。单击“电话号码查询”按钮,运行窗体如图22.16所示的电话号码查询窗体。   单击“关于本程序”按钮,运行窗体如图22.17所示的关于窗体。 图22.15 电话号码录入窗体 图22.16 电话号码查询窗体 图22.17 关于窗体 22.3.7 编译程序   完成了电视抽奖程序的编程和调试工作,最后进行程序编译。编译程序涉及到程序项目属性的设置、可执行应用程序的生成。在程序编译和发行之前需要设置项目的属性。选择“工程”|“工程1属性”命令,弹出如图22.18所示工程属性设置窗体。   设置工程项目为“标准EXE”,启动对象为frmmain。在版本信息设置中,可以更改程序的版本号。设置公司名称、产品名称、版权信息等,如图22.19所示。 图22.18 工程属性窗体 图22.19 工程属性窗体   最后选择“文件”|“生成cj.exe”命令,开始编译程序。编译结束后,生成了该程序的可执行文件。测试该发布文件运行无误后,便可以发布运行了。 22.4 小 结   本章介绍了当前非常流行的电视抽奖程序的开发过程。在本章中详细介绍了如何设计和实现系统程序,包括功能模块设计、数据库设计、窗体设计。最终创建了一个功能完整的电视抽奖程序。第23章将介绍网络聊天程序实例的编程技巧。 第5篇 实战篇    第22章 电视抽奖程序    ·334·       ·325·