第七讲信息函数Msgbox

第七讲信息函数Msgbox

本节主要内容:

●Msgbox函数的功能及作用

●Msgbox函数的语法

●Msgbox函数的限制

今天的课程内容是信息函数Msgbox,本来打算和Inputbox一起讲的后来发现信息函数Msgbox的内容也比较多,所以今晚只讲信息函数Msgbox.。

输入输出语句是VBA中应用最广也是最简单的两种语句,本课时主要介绍两种输出语句的语法和思路,下一课时则介绍两种输入语句的语法和应用思路。

本课时内容摘自《Excel VBA程序开发自学宝典(第2版)》第10章。

7.1 Msgbox函数的功能及作用

VBA最常见的信息输出方式是使用Msgbox函数,在任何VBA的书籍中,它所出现的频率都是最高的,在英文中,Msg表示Message,即消息,而Msgbox 则表示信息框。

顾名思义,Msgbox是用于在屏幕中显示某些信息的对话框,告诉用户需要做什么,或者提示程序的运算结果,或者某操作的步骤说明等,它的作用极其广泛。站在VBA开发者立场,对Msgbox函数的功能可做以下分类:

7.1.1 返回运算结果

告诉用户VBA的运算结果通常有三种模式:存入工作表、打印到文件和利用消息框返回结果。

通常对于临时性的、不需要储存的信息可以利用对话框来展示,它的特点是关闭窗口后就完全消失,不占用任何内存空间。

7.1.2 询问执行方式

对于某些有多种执行选项的操作,例如“隔行着色工作表”工具,它可以对奇数行着色,也可以对偶数行着色,为了体现程序的通用性和灵活性时,往往弹出一个提示框让用户选择执行方式,这是最佳的程序开发思路。

例如上图中,用户单击不同按钮时,VBA会执行不同的着色方式。

7.1.3 提示执行步骤

在设计VBA程序时,如果后续需执行的操作较复杂,应该通过一个消息框来提示用户。包括该程序大概有多少步骤,各步骤中需要注意哪些问题,或者在什么情况下需要跳过什么步骤等,从而减少程序出错的机率。

7.1.4 告知错误原因

终端用户在执行VBA程序时,总会有或多或少的错误产生。有时是程序员粗心写错代码造成,有时是代码的兼容性造成,有时是代码完全正确但用户的数据不规范造成。而VBA很多时候返回的错误提示让人摸不着头脑,程序员有必要预先设置更有意义的错误提示,告诉用户产生此错误的可能情况。

例如,当工作表保护时执行以下语句,一定会产生错误提示:

Sub 赋值()

Range("a1") = 1

End Sub

请大家先保护一个工作表,然后在VBE界面中插入一个模块,并在模块中录入以上代码,然后按F5键执行代码你会发现执行结果如下:

从图片和代码进行分析,错误提示与代码实际出错的原因风马牛不相及,这完全不利于终端用户了解程序出错的原因。

为了避免这种差错,开发程序者需要通过一个信息框来展示更有意义的错误提示。

下图是修改后的提示框,用户可以立刻明白错误产生的原因。

Sub 赋值()

If ActiveSheet.ProtectContents Then

MsgBox "请不要在保护工作表时执行"

Else

Range("a1") = 1

End If

End Sub

可以用以上代码修改赋值方式,如果工作表处理保护状态时,将得到以下结果

利用Msgbox函数改造内部的错误提示

7.1.5 展示当前状态

类似于DOS程序中“请按任意键继续……”一样,VBA也可以在程序执行时显示当前的状态,然后当用户单击回车后再继续执行。

7.1.6 设计程序帮助

Excel自身的所有功能都有相应的说明信息,利用VBA开发程序时也需要设计一帮助系统,不管这个系统大小如何,一定要有相应的说明。通常包括三方面的内容:

(1)程序功能说明。

(2)程序版本及各版本修改内容阐述。

(3)本程序适用范围,即兼容哪些Office版本,或者适用哪个行业。

当然,利用Msgbox制作帮助界面受字符长度限制,只能提供一些简单且简短的信息。

接下来介绍Msgbox函数的语法

7.2 Msgbox函数的语法

Msgbox用于在对话框中显示消息,等待用户单击按钮,并返回一个Integer 类型的值。当用户单击其中的按钮后将返回信息给VBA,程序员可以根据这个返回值来决定后续的操作。

7.2.1 Msgbox的语法

Msgbox的具体语法如下:

MsgBox(prompt[, buttons] [, title] [, helpfile, context])

括号中的是Msgbox函数的参数。

带方括号[]的是可选参数

所以,大家可以观查以上语法表,只有第一个参数是必选参数,后面的全是可选参数。

这是每个参数的功能说明。

以下代码(放置位置:模块中)是Msgbox函数的最常用的一种形式,它使用了prompt、 buttons、title三个参数,不同参数决定了信息框中的不同位置的部件。

Sub 宏()

MsgBox "您喜欢VBA吗?", vbYesNo, "提示"

End Sub

大家可以同时观看代码、语法表和图片三者比较可以更快地明白语法。特别是语法中哪一部分代表按钮哪一部分代表信息哪一部分代码标题。

7.2.2 Msgbox的参数

Msgbox函数包含5个参数,都是可选参数。其中最重要的是第一参数,最简单的也是第一参数,第一参数所指定的字符串将显示在信息框中间。

最复杂的是第二参数,它是一个数值,用于表示信息框中按钮的个数和显示样式,且能通过它指定默认按钮。

下表展现了Msgbox函数所支持的按钮常数,以及对应的数值、显示的状态和外观。

对于上表需要补充四点:

其一:Msgbox的第二参数可以使用上表中的常数,也可以采用数值,它们功能一致。

其二:数值0到5用于确定按钮的个数和样式,16到64用于确定图标的样式,256和512用于分别代表默认按钮是第2个还是第3个。

所谓的默认按钮是指单击回车键时被选中的按钮,Excel会用特殊的外观标示这个默认的按钮。当不指定默认按钮时,第一个按钮为默认按钮。

其三:最后三行的示意图仅用于展示默认按钮的状态,三个常数的功能是指定哪一个按钮是默认按钮,而不是产生这三个图标。如果Msgbox第二参数采用3+512能产生“是”、“否”和“取消”三个按钮,且第三个按钮是默认按钮的效果。

其四:以上3段代码(0-5为第一段,16到64为第一段,256和512为第三段)可以相加,表示多种效果的混合应用。

例如实现下图所示的效果:

有两种办法可以实现

Sub 试一试()

MsgBox "VBA很棒!", 1 + 64

End Sub

Sub 试一试2()

MsgBox "VBA很棒!", vbOKCancel + vbInformation

End Sub

也就是,MSGBOX的第二参数可以使用数值,也可以使用VBA内部分指定的常量,使用数值的好处是书写简单,但难以看懂,使用常量一看就懂,代码更长。

实现下图所示的效果:

也有两种办法实现:

Sub 试一试3()

MsgBox "VBA很棒?", 4 + 32 + 256

End Sub

或者:

Sub 试一试4()

MsgBox "VBA很棒?", vbYesNo + vbQuestion + vbDefaultButton2

End Sub

请观察仔细,默认按钮是第二个。

以下效果(0到5段未指定则默认当作0处理,即“确定”按钮):

用这个代码实现:

Sub 试一试5()

MsgBox "VBA很棒!", vbExclamation

End Sub

请大家注意Msgbox的第二参数的写法。

Msgbox函数能弹出信息框,达到警示、通用、提示用户的作用,所以在工作中应用较广。同时,由于Msgbox函数具有返回值,可以根据返回值知道用户单击了信息框中的哪一个按钮,所以Msgbox函数也经常配合条件语句IF Then 使用。

在后面的课程将会有大量的关于Msgbox函数的案例。

7.2.3 Msgbox的按钮与图标

Msgbox的第二参数可以有多种组合,实现不同的按钮与图标样式。在下表中罗列出了VBA中Msgbox提示的常数列表:

需要显示一个两行信息且带一个OK按钮的对话框,那么可以使用以下代码:Sub 试一试6()

MsgBox "第一行" &Chr(10) & "第二行", vbOKOnly

End Sub

代码Chr(10) 表示换行符。

如果需要显示一个确定按钮与一个取消按钮,且标题显示为“提示”,那么可用以下代码:

Sub 试一试7()

MsgBox "现在开始执行?", vbOKCancel, "提示"

End Sub

如果同样是显示上图所示的效果,且需要默认选中第二个,那么代码可以修改如下:

Sub 试一试8()

MsgBox "现在开始执行?", vbOKCancel + vbDefaultButton2, "提示"

End Sub

重点在vbDefaultButton2参数,表示第二个按钮是默认按钮。

当用户直接单击回车键时是按下“取消”按钮而非“确定”按钮。

如果需要显示“是”和“否”按钮,再加入一个问号图标,且使用数字来表示按钮样式,那么代码如下:

Sub 试一试9()

MsgBox "继续执行下步?", 292, "继续"

End Sub

代码中292的计算方式是:4 + 32 + 256,其中4表示显示“是”和“否”的按钮,32代表显示问号图标,而256则表示默认按钮为第二个。

执行后效果如下:

当然,根据表格中的说明还可以有很多种组合,大家可以自行测试。

7.2.4 Msgbox的返回值

Msgbox主要作用是显示一些信息给终端用户,然而对于程序开发者来说,更重要的一个功能是它具有返回值,且可以根据返回值决定下一步操作。

Msgbox的返回值有7种。

Msgbox的返回值对于开发者来说比较有用。例如当用户单击“是”按钮时,执行后续的操作,如果单击“否”按钮则直接退出程序。

现在举一个关于Msgbox函数的返回值的案例:

Sub 工作表改名()

'如果用户单击“是”按钮

If MsgBox("将前表改名为今日期?", 292, "修改日期") = vbYes Then '将当前工作表改名为今天的日期

https://www.360docs.net/doc/ba19141656.html, = Format(Date, "yyyy-mm-dd")

Else '否则

Exit Sub '退出程序

End If

'其他更多代码.............

End Sub

请大家插入一个模块,然后在模块中录入以上代码,接着按F5键执行代码,出现如下提示:

这是对话框

如果直接单击回车键,那么程序立即退出,不做任何回应;如果用户单击“是”按钮,那么立即以当前日期命名工作表。

再举一个实例,仍然对工作表以当前日期重命名,如果遇到有重名工作表时弹出包括“重试”、“忽略”和“终止”的对话框。

Sub 工作表改名()

'声明变量, 用于获取Msgbox的返回值

Dim msgAsVbMsgBoxResult

'设置一个标签

err:

On Error Resume Next '防错, 当出现错误时执行下一步

https://www.360docs.net/doc/ba19141656.html, = Format(Date, "yyyy-mm-dd") '将当前工作表命名If err.Number> 0 Then '如果存在错误(即已经有工作表的名称等于当前日期)

'获取Msgbox的返回值

msg = MsgBox("存在同名工作表, 是否继续?", 2, "修改日期")

'如果用户单击"中断"则退出程序

If msg = vbAbort Then Exit Sub

'如果用户单击"忽略", 则将当前表命名为日期, 并添加左右括号

If msg = vbIgnore Then https://www.360docs.net/doc/ba19141656.html, = "(" &Format(Date, "yyyy-mm-dd") & ")"

'如果用户单击"重试"则清除错误设置, 然后返回Err标签处继续执行

If msg = vbRetry Then err.Clear: GoTo err

End If

End Sub

在以上代码中,Msgbox的第二参数使用2,即表示产生“终止”、“重试”、“忽略”三个按钮,而单击三个按钮时分别对应Abort、Retry 及Ignore三个返回值。

而单击三个按钮时分别对应Abort、Retry 及Ignore三个返回值。

大家测试代码时,请执行两次,即先对一个工作表命名,然后切换到另一个工作表再命名,此时由于工作簿中存在同名的工作表,所以会出错。那么就会弹出错误提示框。

只有存在同名的工作表的前提下才会出现上面的对话框。

当出现对话框时,如果用户单击对话框第一个按钮,则直接终止程序,利用“Exit Sub”来处理;如果用户单击第三个按钮,则会忽略错误,将工作表命名为日期加括号;如果用户单击第二个按钮,那么程序会继续返回首行继续执行程序,它将会循环产生同样的对话框,直到用户单击其他选项。

如果单击“忽略”,则程序执行结果如下

在使用Msgbox的返回值时,Msgbox的参数必须使用括号。仅仅通过Msgbox 函数弹出对话框时,它不是一个表达式,则不需要括号。

以下两种方式都是错误的Msgbox用法。

Sub 试一试10()

MsgBox( "你好! ", 64, "提示")

End sub

Sub 试一试11()

Result = MsgBox"你好! ", 64, "提示"

End sub

当掌握好Msgbox函数的返回值规律后,我们用Msgbox函数设计一个有趣

的过程吧:

Sub 求爱()

Dim MsgAsVbMsgBoxResult

求爱开始:

Msg = MsgBox("小芳,我很爱你,答应嫁给我吧!", vbYesNo, "求爱") If Msg = vbYes Then

MsgBox "嘢,我成功了!", vbCritical, "真开心"

Exit Sub

Else

GoTo求爱开始

End If

End Sub

请执行以上代码,是否很有趣?

程序首先弹出对话框让你选择“是”或者“否”,如果单击“否”就永远循环下去,直到你失去耐心…..如果单击“是”,马上就OK了,皆大欢喜。

7.3 Msgbox函数的限制

Msgbox函数用于将信息展示给用户,它的应用极其广泛。然而它有自身的一些限制,作为程序员有必要了解它的所有限制,才能恰当地运用好Msgbox。

总体来说,Msgbox具有三方面的限制。

7.3.1 字符数问题

Msgbox有最大高度与宽度限制,而且只有在字符超过它的限制时它才可以体现出来。因为Msgbox具有自动缩放功能,当信息少时它会自动缩小信息框以适应字符的宽度,此时无法目视它的可用范围。

要测试Msgbox可显示的最多字符数可以使用以下方式:

(1)在A1单元格中存放超过1000个英文字母,在a2单元格中存放超过1000个汉字;

这个大家都会吧?

=REPT("A",999)&"B"

=REPT("中",1999)&"国"

使用两个公式,自动产生1000个和2000个字符,最后一个字不一样,是为了便于识别。

(2)在模块中录入以下语句:

Sub Msgbox测试()

MsgBox [a1]

MsgBox [a2]

End Sub

执行以上代码后可以发现,英文字符可以显示1024个左右,而纯汉字只能显示511个。如果英文与汉字共用,那么按一个汉字占用两个英文宽度计算。

如果需要显示超过以上限制的字符信息,那么只能分屏显示,当然这不是好办法。通常采用窗体控件或者WScript技术来突破。

7.3.2 控制权问题

Msgbox对话框总是拥有焦点,且拥有绝对的控制权。即只要Msgbox对话框不关闭,那么代码都不会停止运行,只有关闭对话框后才会交还控制权给程序,继续执行其他语句。

明白这一点很重要,如果程序在执行过程中需要显示信息,例如需要当前执行进度,而且不能影响程序继续执行,那么Msgbox方式并非首选。建议使用状态栏信息或者无模式的窗体。

下图即为利用状态栏显示进度来替换Msgbox的效果。

Sub 提示日期()

Application.StatusBar = "今天的日期是" & Date

End Sub

将信息显示在对Msgbox话框中会影响其它程序操作,而显示在状态栏则不会。

7.3.3 时间性问题

Msgbox的对话框显示的对话框,如果用户不手动关闭,它会永远存在。如果用户需要它在指定时间自动关闭,那么Msgbox也无法达成需求。

通常采用三种方法来实现:用户窗体、WScript技术和API。

在后面小节中将进行演示。

7.3.4 利用WScript突破Msgbox限制

WScript是一种脚本语言,它也可以实现输出对话框信息,而且可以突破Msgbox的一些限制。

利用脚本语言显示信息可用WScript.Shell语言中的Popup方法。它的具体语法为:

WshShell.Popup(strText, [natSecondsToWait], [strTitle], [natType]) = intButton 方括号中的内容是可选的。

其中第一参数是显示的信息,第二参数是显示的时间,表示信息框在多少秒钟内自动关闭,第三参数是标题,第四参数是按钮与图标的状态。

WScript.Shell语言中的Popup方法相对于Msgbox有两个优点:

①可显示的字符远远超过1024

②可以自动关闭对话框

如果A1单元格超过2000个字符,那么可以使用以下语句显示A1字符串的文本框:

还是前面的方法,请大家用公式产生字符

=REPT("中",1999)&"国"

Sub 显示A1信息()

CreateObject("WScript.Shell").Popup [a1], , "提示", 64

End Sub

可以根据最后一个字判断它已经显示完整。

Sub 自动关闭()

CreateObject("WScript.Shell").Popup "三秒钟关闭", 3, "提示", 64

End Sub

但是相当遗憾

仅在Excel 2003中有效

所以为了体现通用性和稳定性,可以改用API来完成这个难题,让Excel 2003、2007和2010都可以顺利实现3秒关闭。

API实现的方式如下:

Public Declare Function SetTimer Lib "user32" (ByValhWnd As Long, ByValnIDEvent As Long, ByValuElaspe As Long, ByVallpTimerFunc As Long) As Long Public Declare Function KillTimer Lib "user32" ( _

ByValhWnd As Long, ByValnIDEvent As Long) As Long

Dim TID As Long

Const Sec = 3 '可以在这里修改时间

Sub CloseTest(ByValhWnd As Long, ByValuMsg As Long, ByValidevent As Long, ByValSystime As Long)

Application.SendKeys "~", true '发送回车符,即关闭窗口的命令

KillTimer 0, TID

End Sub

Sub 三秒钟自动关闭()

TID = SetTimer(0, 0, Sec * 1000, AddressOfCloseTest)

MsgBox Sec & " 秒钟自动关闭窗口", 65, "提示"

End Sub

目前不明白代码的含义不重要,知道有这个功能就可以了。

请大家测试以上代码,测试时有一个规则,代码要放在模块的最顶端。

最好是插入一个新的模块,然后粘贴代码

按下F5键执行

看看是不是3秒钟后自关闭?

自动关闭

第7章、VBScript的过程与函数

第7章、VBScript的过程与函数 7.1 过程(子程序) 1.子程序 子程序(Subroutines)是将一段具有某种特定功能的语句块单独撰写成一个独立的程序,给预特定名称,它的格式如下: Sub 子程序名称[(参数1,参数2,…)] 程序代码 End Sub 子程序一定要有名称,调用子程序时就会使用它的名称。如果没有调用它,子程序自己并不会执行,请看下面范例: 子程序1 在这个程序中,子程序“A”并不会执行,因为您没有调用它。 调用子程序有两种方法: 方法一:CALL 子程序名称[(参数1,参数2,…)] 调用子程序用括号 方法二:子程序名称参数1,参数2,…调用子程序不能用括号 子程序2 2.局部变量和全局变量 接下来,我们讲变量的有效范围,看实例:

子程序3 看另一个实例: 子程序4 只要在子程序外先用Dim声明变量或者先出现,变量便会变成“全局变量”,变量不管在程序的那一部分都有效。 若在子程序里面声明或是出现,就会变成子程序的“局部变量”,跳出该子程序便会失效。 由于局部变量是在子程序里才有效,因此,您可以在不同的过程里声明相同名称的变量,这样做的好处是提高程序的可读性,使日后调试更为方便。 1.终止执行子程序 一般子程序执行到“END SUB”就会结束,但也可以提早结束子程序,而直接跳回原来调用子程序的地方,请看下面的范例: 子程序6