【VBA研究】VBA做了个简单的试题生成工具

作者:iamlasong

单位对新上岗的员工进行培训,培训结束后,需要进行考试,需要一个简单的考试系统,让新员工既可以自己练习,也可以进行测试,为此,我们做了一个题库,员工可以自己生成一套考题,测试自己的掌握程度,也可以集中起来进行考试,测试培训效果。

系统数据库很简单,主要有两个表,一个是题库,一个是成绩。

create table EMSAPP_TEST_QUESTION

(

type                  CHAR(1),

id                    NUMBER(4),

question              VARCHAR2(400),

choice_a              VARCHAR2(200),

choice_b              VARCHAR2(200),

choice_c              VARCHAR2(200),

choice_d              VARCHAR2(200),

answer                VARCHAR2(8),

remark                VARCHAR2(20)

);

create table EMSAPP_TEST_RESULT

(

city                  VARCHAR2(10),

bureau_code           VARCHAR2(40),

bureau_name           VARCHAR2(40),

staff_code            VARCHAR2(10),

staff_name            VARCHAR2(10),

testdate              DATE,

score                 number(3)

);

1、界面

分两块,考试部分和试题录入修改部分,下图是考试部分,上半部分是历史成绩查询工具,下半部分是试题生成和答案提交,生成的试题分别放在不同的工作表中,做完题目后提交答案,系统给出分数,同时,给出对错。

2、生成试题

生成的试题和标准答案都放在相应的工作表中,以便核对答案。

' 生成考试题
Public Sub get_question()
    '
    On Error GoTo ErrMsg1:

    Dim i, j, k, tp, lineno As Integer
    Dim OraOpen As Boolean
    Dim RndNumber, TempRnd(20), Recno, Maxno As Integer
    Dim stName As String

    Worksheets("系统参数").Select
    For i = 7 To 11
        If Len(Cells(i, 2)) < 3 Then
            msg = MsgBox("请填写完整揽投员信息后再生成试题!", vbOKOnly, "iamlaosong")
            Exit Sub
         End If
    Next i
    ActiveSheet.unprotect password = "iamlaosong"
    Cells(i, 2) = ""       '清除以前的分数
    ActiveSheet.protect password = "iamlaosong"

    Set cnn = CreateObject("ADODB.Connection")
    Set rst = CreateObject("ADODB.Recordset")
    sqls = "connect database"

    cnn.Open "Provider=msdaora;Data Source=dl580;User Id=emssxjk;Password=emssxjk;"
    OraOpen = True '成功执行后,数据库即被打开

    'If OraOpen Then lineno = [D65536].End(xlUp).Row Else lineno = 0       '行数

    Randomize (Timer)           '初始化随机数生成器
    '生成试题
    For tp = 0 To 2
        If tp = 1 Then
            Maxno = 20
            stName = "单选"
        ElseIf tp = 2 Then
            Maxno = 20
            stName = "多选"
        Else
            Maxno = 10
            stName = "判断"
        End If
        sqls = "select count(*) from EMSAPP_TEST_QUESTION where type ='" & tp & "'"
        Set rst = cnn.Execute(sqls)
        Recno = rst(0)

        k = 1
        Worksheets(stName).unprotect password = "iamlaosong"   '工作表解锁以便写入题目和答案
        Do While k <= Maxno
            RndNumber = Int(Recno * Rnd) + 1
            TempRnd(k) = RndNumber
            For i = 1 To k - 1
                If TempRnd(i) = RndNumber Then Exit For
            Next i
            If i = k Then    ' no repeat
                sqls = "select question,choice_a,choice_b, choice_c,choice_d,answer from emsapp_test_question "
                sqls = sqls & "where type ='" & tp & "' and ID =" & RndNumber
                Set rst = cnn.Execute(sqls)
                If Not (rst.EOF) Then   'exists
                    k = k + 1
                    For j = 1 To 6
                        Worksheets(stName).Cells(k, j) = rst(j - 1)
                    Next j
                    Worksheets(stName).Cells(k, j) = ""        '清理上一次答案
                    Worksheets(stName).Cells(k, j + 1) = ""    '清理上一次评分
                End If
            End If
        Loop
        Worksheets(stName).protect password = "iamlaosong", AllowFormattingRows:=True    '工作表加锁,防止修改
    Next tp

    rst.Close
    Set rst = Nothing
    cnn.Close
    Set cnn = Nothing

    msg = MsgBox("试题生成完毕,请答题!", vbOKOnly, "iamlaosong")

    Exit Sub
ErrMsg1:
    OraOpen = False
    MsgBox sqls, vbCritical, "操作失败 ,请检查!"

End Sub

3、提交答案

根据标准答案给出每题得分并算出总分,保存到数据库中。

' 评分并提交结果
Public Sub get_answer()
    '
    On Error GoTo ErrMsg1:

    Dim i, j, k, tp, score As Integer
    Dim OraOpen As Boolean
    Dim stName, staff_inf As String

    '根据成绩栏判断是否重复提交,生成新题时该单元格清空,提交答案后里面保存总分。
    If Cells(12, 2) <> "" Then
        msg = MsgBox("考试成绩已提交,请重新生成考题!", vbOKOnly, "iamlaosong")
        Exit Sub
    End If

    Set cnn = CreateObject("ADODB.Connection")
    Set rst = CreateObject("ADODB.Recordset")
    sqls = "connect database"

    cnn.Open "Provider=msdaora;Data Source=dl580;User Id=emssxjk;Password=emssxjk;"
    OraOpen = True '成功执行后,数据库即被打开

    'If OraOpen Then lineno = [D65536].End(xlUp).Row Else lineno = 0       '行数

    sqls = "get score"
    score = 0
    '评分
    For tp = 0 To 2
        If tp = 1 Then
            Maxno = 20
            stName = "单选"
        ElseIf tp = 2 Then
            Maxno = 20
            stName = "多选"
        Else
            Maxno = 10
            stName = "判断"
        End If

        For k = 2 To Maxno + 1
            If UCase(Worksheets(stName).Cells(k, 6)) = UCase(Worksheets(stName).Cells(k, 7)) Then
                score = score + 2
                Worksheets(stName).Cells(k, 8) = 2
            Else
                Worksheets(stName).Cells(k, 8) = 0
            End If
        Next k

    Next tp

    ActiveSheet.unprotect password = "iamlaosong"
    Cells(12, 2) = score       '分数保存在12行
    ActiveSheet.protect password = "iamlaosong"
    For i = 7 To 12
        staff_inf = staff_inf & " '" & Worksheets("系统参数").Cells(i, 2) & "',"
    Next i

    staff_inf = staff_inf & "to_date('" & Date & "','yyyy-mm-dd') "
    sqls = "insert into emsapp_test_result (city,bureau_code,bureau_name,staff_code,staff_name,score,testdate) values ("
    sqls = sqls & staff_inf & ")"
    'MsgBox sqls
    Set rst = cnn.Execute(sqls)

    cnn.Close
    Set cnn = Nothing
    msg = MsgBox("考试成绩为:" & score, vbOKOnly, "iamlaosong")

    Exit Sub
ErrMsg1:
    OraOpen = False
    MsgBox sqls, vbCritical, "操作失败 ,请检查!"

End Sub

4、管理部分

主要功能是题目的录入和修改,没有这个管理部分并不影响试题部分的使用,只要人工将题目导入即可。这部分内容较多,涉及用户登录、密码修改、试题录入、修改等等,就不一一叙说了。

下面是登录界面和程序:

Private Sub CommandButton1_Click()
    '用户名和密码校验
    On Error GoTo ErrMsg1:

    Dim i, j, lineno As Integer
    Dim OraOpen As Boolean

    Set cnn = CreateObject("ADODB.Connection")
    Set rst = CreateObject("ADODB.Recordset")
    sqls = "connect database"

    cnn.Open "Provider=msdaora;Data Source=dl580;User Id=emssxjk;Password=emssxjk;"
    OraOpen = True '成功执行后,数据库即被打开

    'If OraOpen Then lineno = [D65536].End(xlUp).Row Else lineno = 0       '行数

    id = TextBox1.Value
    pwd = TextBox2.Value
    sqls = "select city from emsapp_tb_user where flag='1' and id ='" & id & "' and pwd ='" & pwd & "'"
    Set rst = cnn.Execute(sqls)
    'MsgBox sqls
    If Not (rst.EOF) Then
        thiscity = rst(0)
        msg = MsgBox("登录成功,用户名:" & id & "(" & thiscity & ")", vbOKOnly, "iamlaosong")
        UserForm1.Hide
    Else
        msg = MsgBox("登录失败,请核对用户名和密码!", vbOKOnly, "iamlaosong")
    End If

    rst.Close
    Set rst = Nothing
    cnn.Close
    Set cnn = Nothing

    Exit Sub
ErrMsg1:
    OraOpen = False
    MsgBox sqls, vbCritical, "操作失败 ,请检查!"

End Sub
Private Sub CommandButton2_Click()
    Application.Quit
End Sub

Private Sub TextBox2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    CommandButton1_Click
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Application.Quit
End Sub

【VBA研究】VBA做了个简单的试题生成工具

时间: 2024-08-29 20:32:20

【VBA研究】VBA做了个简单的试题生成工具的相关文章

【VBA研究】VBA产生不重复随机数

作者:iamlasong VBA编程实现不重复随机数输出.VBA里的随机函数是RND,在工作表中随机函数是RAND,一字之差,可要记好了.RND取值范围是[0,1),意思是0和1之间的一个随机数,包含0,但不包含1. 1.用法 语法:Rnd[(number)] 如果 number 的值是 Randomize 生成 小于 0 ,每次都使用 number 作为随机数种子得到的相同结果. 大于 0 ,以上一个随机数为种子产生下一个随机数. 等于 0 ,产生与最近生成的随机数相同的随机数. 省略, 以上

【VBA研究】VBA通过HTTP协议实现邮件轨迹跟踪查询

作者:iamlasong 1.接口说明 通过互联网訪问,运单跟踪信息查询接口基于HTTP协议开发,接口为RESTFul风格的Web Service,信息交互过程为用户按我方提供的web service地址进行调用,我方接到调用请求后,为用户返回JSON格式组织的数据信息.用户根据约定的接口规范对数据进行解析. 接口调用为HTTP请求的方式,每一次由用户发起的HTTP请求,须要设置验证信息,详细方法是,在HTTP Header部分添加version及authenticate属性,属性值在联调測试之

利用KBEngine +U3D 做的一个简单MMO手游Demo

利用KBE +U3D 做的一个简单MMO手游Demo目前只完成到一个普通攻击和一个火球术,  火球术需要点击怪物后才能释放.点击npc后会跳到一个副本.里面有一只半兽人. 欢迎大家来试玩 并提出宝贵意见.http://pan.baidu.com/s/1dDtVjnb 感谢kbe 一直以来的帮助.

用PyQt5和python3.6做一个最简单的GUI的程序

一般的程序都要有个GUI来实现人机交互的功能,今天我们来用PyQt来做一个最简单的程序 软件需求:python3.6 用的是Anaconda3.6(自带PyQt5,pip)    pycharm PyQt5    QtTools 环境安装和配置 由于Anaconda自带了PyQt5,不用再安装,但要用pip下载QtTools. pip install PyQt5-tools 如果装的不是Anaconda,可以在pycharm里查一下有没有装pyqt的模块,没有的话直接pip下载安装 pip in

Android多线程研究(4)——从一道面试题说起

有一道这种面试题:开启一个子线程和主线程同一时候运行,子线程输出10次后接着主线程输出100次,如此重复50次.先看以下代码: package com.maso.test; /** * * @author Administrator * 两个线程,当中是一个主线程,第一个线程先运行输出10次,主线程接着运行输出100次,如此重复50次 */ public class ThreadTest3 implements Runnable{ private static Test test; @Overr

第一次编写简单的中间件测试工具(1) - 记一次新员工训练营

去年11月,我加入了N记,紧接着进入新员工训练营. 开始一次简单的中间件测试工具编写任务. 这次训练营体验给我的感觉就是:大公司不愧是大公司,这回我终于可以安心学点核心技术了. 任务: 这个训练营有两个任务,一是熟悉这边的敏捷开发流程:二是在训练营里做一定的编码,用python编写一个测试工具(桩,stub). 我们要做的这个工具,是用来测试我们一种通信设备(B)上运行的程序(某种中间件),这个工具模拟另一种通信设备(A),发送一些按特定协议编码的消息给另一种通信设备B,并能反编码设备B返回的消

简单Modbus协议数据源工具实现(一)WinForm

这是一个学习C#.Winform的自我回顾过程,用来发现存在的不足,也为了推动自己继续学习. 大学通信专业毕业之后,进入了一家电力科技公司从事软件开发工作,主要用的是Delphi语言进行电力通信协议的上位机开发.因为上位机需要与下位机通信才好进行测试,而事实上没有那么多现成的装置给你借用调试,加上公司慢慢的开始推行C#/WPF来做一些定制软件,所以想学习一下C#,刚好现在也有一个自身的需求出现--上位机程序调试困难,所以就从最易入手的winform程序切入,慢慢的加深对于C#语言的理解.于是就打

新手做2D手游该用哪些工具?

全球手游行业规模将突破250亿美元,越来越多的开发者开始进入手游研发领域,而作为一名菜鸟,很多时候,如果没有其他开发者的建议,会走很多弯路.一开始进入游戏研发领域的时候,你很难知道该选择什么工具.什么程序语言以及哪些框架,你会面临许许多多的选择和建议,所以这里提供一些经验,希望给做手游的新手们一些帮助. 框架 选择的所有架构,要么是开源的,要么就是有开放的代码,因为在必要的时候可以进行紧急修改和优化. Cocos2d-x:我们所有的跨平台研发都是使用开源Cocos2d-x框架完成,在Eras O

简单主机批量管理工具

题目:简单主机批量管理工具 需求: 主机分组 登录后显示主机分组,选择分组后查看主机列表 可批量执行命令.发送文件,结果实时返回 主机用户名密码可以不同 流程图: 说明: ### 作者介绍: * author:lzl ### 博客地址: * http://www.cnblogs.com/lianzhilei/p/5881434.html ### 功能实现 题目:简单主机批量管理工具 需求: 主机分组 登录后显示主机分组,选择分组后查看主机列表 可批量执行命令.发送文件,结果实时返回 主机用户名密