最近为兄弟单位出Office竞赛试题,考虑到参加的人员比较多,所以花了一些精力,在出试题的同时,也对每一试题写了相应的VBA来自动评分,以方便最后的分数统计。
第一次接触VBA,刚开始也是没有方向,幸好有网络的支持,才得以弄懂,现将本人在开发VBA自动评分试题过程中需要注意的事项列举出来,方便同仁在需要时可以多多查看,少走弯路!
第一部分: 打开文件的密码保护
考虑到是一场正式的比赛,参赛人员比较多,为了体现公平,保密试题,每一个测试文件都简单的设置一个打开密码,这样只有在监考员公布密码后各测试人员才可以打开试题进行考试。
加密文件的操作比较简单,过程是:
Office文件-->工具-->选项-->安全性-->在“打开时的密码” 后面输入相应的密码。
第二部分:VBA代码查看加密
考虑到各单位选出来的选手可能有“高手”存在,会懂得进入VBA代码里面做什么改动,从而影响公平性,需要对VBA代码查看做些保护。
给VBA代码加密码过程:
进入Visual Basic 编辑器-->左边“project ( ******)” -->右键-->Project属性-->保护
在“查看时锁定工程”前打勾;并且在下面的密码框里输入相应的密码。
第三部分:评分按钮的保护
既然是自动评分,则肯定在每一个文档的上面有评分按钮。为了能够让评分按钮只能够由裁判员使用,则需要在按钮里加一个密码保护,我是这样来实现的。
起先是用一个InputBox对话框,从InputBox中输入密码,然后在按钮中判断是不是符合要求,若是的话执行评分程序,若不是则什么也不做。但是这样也存在问题,就是InputBox对话框是一个明文对话框,我在输入密码时,密码以明文的形式在上面显示,这样也不是很好,所以只能够自己定义一个密文的输入对话框,代码如下:(函数来自网络)
Option Explicit
'API宣告
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
'timeSetEvent函数请参考:http://msdn2.microsoft.com/en-us/library/ms713423.aspx
Private Declare Function timeSetEvent Lib "winmm.dll" (ByVal uDelay As Long, ByVal uResolution As Long, _
ByVal lpFunction As Long, ByVal dwUser As Long, ByVal uFlags As Long) As Long
Private Declare Function timeKillEvent Lib "winmm.dll" (ByVal uID As Long) As Long
Private Const EM_SETPASSWORDCHAR = &HCC
Dim lTimeID As Long 'Timer ID
Const pswdInputBoxTitle = "pswdInputBox" '输入密码的对话框标题
'TimeProc callback 函数请参考:http://msdn2.microsoft.com/en-us/library/ms713420.aspx
Sub TimeProc(ByVal uID As Long, ByVal uMsg As Long, ByVal dwUser As Long, _
ByVal dw1 As Long, ByVal dw2 As Long)
Dim hwd As Long '输入密码的对话框句柄
'VBA InputBox对话框之Class Name是 "#32770",
'标题为 "pswdInputBox", 这是在InputBox函数的Title引述中自订的
'请注意Application.InputBox方法所出现的对话框Class Name是 "bosa_sdm_XL9"
hwd = FindWindow("#32770", pswdInputBoxTitle)
If hwd <> 0 Then '若对话框存在
'取得输入的文字框句柄, 该文字框的Class Name是"Edit", 无标题,
'而Application.InputBox方法所出现的对话框之文字框的Class Name是"EDTBX"
hwd = FindWindowEx(hwd, 0, "Edit", vbNullString)
'设定密码字符为 "*", "*"的ASCII码为42
SendMessage hwd, EM_SETPASSWORDCHAR, 42, 0
'设定完成, 取消定时器
timeKillEvent lTimeID
End If
End Sub
'自定义函数pswdInputBox, 是一个输入密码使用的InputBox, 输入的内容都以 "*" 显示.
Function pswdInputBox() As Variant
'启动一个特定的Timer事件, 0.01秒延迟, 0.05秒看一次
lTimeID = timeSetEvent(10, 50, AddressOf TimeProc, 1, 1)
'显示InputBox对话框
pswdInputBox = InputBox(prompt:="请输入编辑密码", Title:=pswdInputBoxTitle)
End Function
需要注意事项:必须把上面的代码放入自己工程的“模块”中才可以使用!具体操作如下:VB编辑器-->选中左边自己的工程“ Project (******)",右键-->插入-->模块;然后将上面的代码放入模块中保持即可,切不可放入”normal“的模块中。
函数的调用,只要做如下写:
s=pswdinputbox() 即可,s里面就是你输入的密码啦,^_^
第四部分: Word打字自动评分中禁止复制的实现
原本是想用Delphi写一个打字测试软件,但是时间太紧,后来就没有去做,最后决定用word来实现!其实在word中打字是最基本的功能。但是在 word中做打字测试就需要注意复制的问题。打字测试的宗旨是让测试人员照着文字输入相同的文字,但是若不做什么保护,word中的样板文字是可以复制 的,这样一来,测试人员就可以作弊,通过复制和粘贴的方式将空的地方填满,当然这样就失去了打字测试的意义。为了解决这个问题,我只有将word中所有与 复制有关的功能禁止。具体可以查看我的另一篇文章: 打字测试自动阅卷的实现(Word) ,里面有详尽的说明 。
第五部分: 未完待续......
第一次接触VBA,刚开始也是没有方向,幸好有网络的支持,才得以弄懂,现将本人在开发VBA自动评分试题过程中需要注意的事项列举出来,方便同仁在需要时可以多多查看,少走弯路!

第一部分: 打开文件的密码保护
考虑到是一场正式的比赛,参赛人员比较多,为了体现公平,保密试题,每一个测试文件都简单的设置一个打开密码,这样只有在监考员公布密码后各测试人员才可以打开试题进行考试。
加密文件的操作比较简单,过程是:
Office文件-->工具-->选项-->安全性-->在“打开时的密码” 后面输入相应的密码。
第二部分:VBA代码查看加密
考虑到各单位选出来的选手可能有“高手”存在,会懂得进入VBA代码里面做什么改动,从而影响公平性,需要对VBA代码查看做些保护。
给VBA代码加密码过程:
进入Visual Basic 编辑器-->左边“project ( ******)” -->右键-->Project属性-->保护
在“查看时锁定工程”前打勾;并且在下面的密码框里输入相应的密码。
第三部分:评分按钮的保护
既然是自动评分,则肯定在每一个文档的上面有评分按钮。为了能够让评分按钮只能够由裁判员使用,则需要在按钮里加一个密码保护,我是这样来实现的。
起先是用一个InputBox对话框,从InputBox中输入密码,然后在按钮中判断是不是符合要求,若是的话执行评分程序,若不是则什么也不做。但是这样也存在问题,就是InputBox对话框是一个明文对话框,我在输入密码时,密码以明文的形式在上面显示,这样也不是很好,所以只能够自己定义一个密文的输入对话框,代码如下:(函数来自网络)
Option Explicit
'API宣告
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
'timeSetEvent函数请参考:http://msdn2.microsoft.com/en-us/library/ms713423.aspx
Private Declare Function timeSetEvent Lib "winmm.dll" (ByVal uDelay As Long, ByVal uResolution As Long, _
ByVal lpFunction As Long, ByVal dwUser As Long, ByVal uFlags As Long) As Long
Private Declare Function timeKillEvent Lib "winmm.dll" (ByVal uID As Long) As Long
Private Const EM_SETPASSWORDCHAR = &HCC
Dim lTimeID As Long 'Timer ID
Const pswdInputBoxTitle = "pswdInputBox" '输入密码的对话框标题
'TimeProc callback 函数请参考:http://msdn2.microsoft.com/en-us/library/ms713420.aspx
Sub TimeProc(ByVal uID As Long, ByVal uMsg As Long, ByVal dwUser As Long, _
ByVal dw1 As Long, ByVal dw2 As Long)
Dim hwd As Long '输入密码的对话框句柄
'VBA InputBox对话框之Class Name是 "#32770",
'标题为 "pswdInputBox", 这是在InputBox函数的Title引述中自订的
'请注意Application.InputBox方法所出现的对话框Class Name是 "bosa_sdm_XL9"
hwd = FindWindow("#32770", pswdInputBoxTitle)
If hwd <> 0 Then '若对话框存在
'取得输入的文字框句柄, 该文字框的Class Name是"Edit", 无标题,
'而Application.InputBox方法所出现的对话框之文字框的Class Name是"EDTBX"
hwd = FindWindowEx(hwd, 0, "Edit", vbNullString)
'设定密码字符为 "*", "*"的ASCII码为42
SendMessage hwd, EM_SETPASSWORDCHAR, 42, 0
'设定完成, 取消定时器
timeKillEvent lTimeID
End If
End Sub
'自定义函数pswdInputBox, 是一个输入密码使用的InputBox, 输入的内容都以 "*" 显示.
Function pswdInputBox() As Variant
'启动一个特定的Timer事件, 0.01秒延迟, 0.05秒看一次
lTimeID = timeSetEvent(10, 50, AddressOf TimeProc, 1, 1)
'显示InputBox对话框
pswdInputBox = InputBox(prompt:="请输入编辑密码", Title:=pswdInputBoxTitle)
End Function
需要注意事项:必须把上面的代码放入自己工程的“模块”中才可以使用!具体操作如下:VB编辑器-->选中左边自己的工程“ Project (******)",右键-->插入-->模块;然后将上面的代码放入模块中保持即可,切不可放入”normal“的模块中。
函数的调用,只要做如下写:
s=pswdinputbox() 即可,s里面就是你输入的密码啦,^_^
第四部分: Word打字自动评分中禁止复制的实现
原本是想用Delphi写一个打字测试软件,但是时间太紧,后来就没有去做,最后决定用word来实现!其实在word中打字是最基本的功能。但是在 word中做打字测试就需要注意复制的问题。打字测试的宗旨是让测试人员照着文字输入相同的文字,但是若不做什么保护,word中的样板文字是可以复制 的,这样一来,测试人员就可以作弊,通过复制和粘贴的方式将空的地方填满,当然这样就失去了打字测试的意义。为了解决这个问题,我只有将word中所有与 复制有关的功能禁止。具体可以查看我的另一篇文章: 打字测试自动阅卷的实现(Word) ,里面有详尽的说明 。
第五部分: 未完待续......