2.某单位招考公务员,2010年和2011年分别有4020名和2000名考生报名,下列VB程序用于统计两次考试都参加的考生信息。
程序界面设计如图所示,2010年和2011年的考生信息分别显示在List1和List2中,点击“统计”按钮,在List3中显示两次考试都参加的考生信息和总人数。
(1)实现上述功能的VB程序如下,请在横线处填入合适代码。
Dima(1To4020) As String
Dimb(1To2000) As String
Private Sub Form_Load()
DimconnAsNewADODB.Connection
DimrsAsNewADODB.Recordset
DimconstrAsstring
constr=“Provider=Microsoft.ace.OLEDB.12.0;”
constr=constr&“DataSource=”&App.Path+“\data\KaoSheng.accdb”
conn.ConnectionString=constr
conn.open()
DimsqlAsString
’将参加2010年下半年考试的考生的身份证号码按升序存放在a数组中
sql=“select*fromkaoshengInfo where year=‘2010’orderbysfzhasc”
rs.Opensql,conn
i=0
DoWhileNotrs.EOF
i=i+1
a(i)=rs(“sfzh”)
List1.additem(a(i))
rs.MoveNext
Loop
’将参加2011年下半年考试的考生的身份证号码按升序存放在b数组中
sql=“select*fromkaoshengInfo whereyear=‘2011’orderbysfzhasc”
rs.Opensql,conn
i=0
DoWhileNotrs.EOF
i=i+1
b(i)=rs(“sfzh”)
List2.additem(b(i))
rs.MoveNext
Loop
rs.Close
EndSub
PrivateSubCommand1_Click()
Dim bot AsInteger,top As Integer,m As Integer
Dim i As Integer,ans As Integer
ans=0
For i=1 To 2000
bot=1
①
Do While bot<=top
m=Fix((bot+top)/2)
If a(m)=b(i) Then
List3.AddItem a(m)
②
Exit Do
ElseIf ③ Then
top=m-1
Else
bot=m+1
EndIf
Loop
Next i
List3.AddItem“总计”+str(ans)+“人次”
End Sub
(2)分析上述代码,在数据库中用于存放考试信息的数据表名称是 。
答案
(1)①top=4000 ②ans=ans+1 ③a(m)>b(i)
(2)kaoshengInfo
解析 本题考查数据库的使用和对分查找。
(1)题目中需要找出两年都参加的人数,采取的做法是枚举考生较少的一年的人,也就是b数组,同时利用对分法去验证枚举到的人在另一年(a数组中)是否存在。
对分的上界为bot,下界为top,分别为1和4000,若查找到则输出并将ans加1,否则当查找值b(i)小于中间值a(m)时,改变下界,是一个标准的对分查找程序。
(2)注意到程序中的“select*fromkaoshengInfo whereyear=‘2011’orderbysfzhasc”。
这是数据库查询语句,表示从kaoshengInfo这张数据表中查询,whereyear=‘2011’表示查询所有2011年的记录。
3.小王为学校教务处编写了一个排考场座位的VB程序。
考场采用“6排5列”共30人的模式。
程序执行后,考生的考号与姓名显示在列表框List1中,单击“考场座位”按钮Command1,考场号与座位显示在Text1中,程序运行界面如图a所示,考生数据存放在数据库文件“kaochang.accdb”中,数据表如图b所示。
实现上述功能的VB程序如下,请回答下列问题:
(1)当“Form_Load()”事件处理过程运行结束时,变量x的值为 。
(2)请在横线处填入合适的代码。
PrivateSubCommand1_Click()
DimyAsInteger
DimstartAsInteger ’考场第1位数据元素的下标
DimpaAsInteger’数据库导入VB时学生数据下标
DimpbAsInteger’考场座位数据下标
DimiAsInteger,jAsInteger,kAsInteger,mAsInteger
start=1
pa=start
recCount=x-1
IfrecCountMod30<>0Then
①
Fori=1Toy ’将当前考生人数添加到30的整数倍
recCount=recCount+1
sName(recCount)=“”
Nexti
EndIf
Forj=1TorecCount/30
pa=start
pb=start
Fori=1To30
kcsName(pb)=sName(pa)
pb=pb+1
IfiMod5=0Then
pa=start+i\5
Else
②
EndIf
Nexti
start=start+30
Nextj
Text1.Text=""
start=1
Fork=1TorecCount/30
m=start
Text1.Text=Text1.Text+“第”+Str(k)+“考场”+vbCrLf
’vbCrLf为换行标志符,实现Text1中内容换行显示
Fori=1To6
Forj=1To5
Text1.Text=Text1.Text+“”+kcsName(m)
m=m+1
Nextj
Text1.Text=Text1.Text+vbCrLf
Nexti
Text1.Text=Text1.Text+vbCrLf+vbCrLf
③
Nextk
EndSub
PrivateSubform_load()
DimmyconnAsNewADODB.Connection
DimmyrecordAsNewADODB.Recordset
myconn.ConnectionString=“provider=microsoft.ace.oledb.12.0;datasource=e:
\kaochang.accdb”
myconn.Open
strsql="select*from三中"
myrecord.Openstrsql,myconn
x=1
List1.AddItem“考号 姓名”
List1.AddItem“--------------”
DoWhileNotmyrecord.EOF
’读取数据库数据,存入数组kh(x)、sName(x)中,代码略
List1.AddItemkh(x)+“”+sName(x)
x=x+1
myrecord.MoveNext
Loop
myrecord.Close
EndSub
答案
(1)43
(2)①y=30-recCountMod30
②pa=pa+6
③start=start+30
解析
(1)数据库名称是kaochang.accdb,数据表名称是“三中”,注意数据表是没有扩展名的。
变量x记录读取到的学生数据的数组下标,当x=42时,DoWhileNotmyrecord.EOF是指到数据表的最后一条记录后退出循环,当前条件成立,还在数据表内,所以继续执行,x=x+1,x为43,跳出循环。
(2)①IfrecCountMod30<>0Then
y=30-recCountMod30
Fori=1Toy
recCount=recCount+1
sName(recCount)=""
Nexti
EndIf
选择嵌套循环结构的作用:
首先判断学生人数是不是30的倍数,若不是,求出相差人数,通过循环结构将加入的数组元素赋值为空字符串。
②IfiMod5=0Then
pa=start+i\5
Else
pa=pa+6
EndIf
本段选择结构的作用:
当i不是5的倍数时,是考场中的一行,根据题图示意,应该下标加6。
③Fork=1TorecCount/30
m=start
Text1.Text=Text1.Text+“第”+Str(k)+“考场”+vbCrLf
’vbCrLf为换行标志符,实现Text1中内容换行显示
Fori=1To6
’此处略
Nexti
Text1.Text=Text1.Text+vbCrLf+vbCrLf
start=start+30
Nextk
此处程序段的作用:
分考场显示学生姓名,Fork=1TorecCount/30表示根据考场个数确定循环次数。
第2考场时,开始的kcsName数组下标加30。