vbscript 教程 vbscript视频教程
第2章 VBScript基础
本书主要通过大量实例讲解VBScript与JScript编程。从本章开始我们先用5章的篇幅讲解VBScript,以后各章再讲解JScript。本章我们先来初步认识VBScript的基本情况,并学习VBScript语言的基础知识,包括该语言的数据类型、常量和变量的一些规定、表达式与运算符等。
2.1 使用VBScript
VBScript作为一种脚本语言,可以自由嵌入任何支持该语言的应用程序中,以增强应用程序的功能,其应用领域十分广泛。本节我们通过一个实例,说明在HTML网页中使用VBScript的基本方法。
2.1.1 VBScript及其主要功能
VBScript是Visual Basic程序设计语言家族中的新成员,它以Visual Basic语言为基础提供了编程的功能,在脚本开发的场合中,VBScript得到了广泛的应用,其中包括在Internet Explorer浏览器上编写客户端脚本,也包括在Internet Information Server上编写服务器端脚本。
在最初的设计中,VBScript是通过编写事件驱动的脚本来扩大客户端HTML功能,编写客户端脚本最大的优点就在于由浏览器解释执行,不需要增大服务器的负担。例如,我们可以在客户端进行输入数据有效性验证,防止浏览器将无效数据发送给服务器。这样,一方面可以减轻服务器的负担,防止服务器陷入处理大量无意义数据的工作中,同样,也可以减轻网络的阻塞;另外一方面,也能够使客户减少等待时间,在验证的时候,浏览器能够立即作出响应,而如果在服务器上进行验证,那用户则不得不在浏览器前等待,服务器的处理和网络的传输都需要耗费一定的时间。
随着IIS 3.0和ASP技术的出现,VBScript将它的功能扩展到服务器上,VBScript开发的脚本可以在服务器上解释执行。在服务器端脚本开发的过程中,使用VBScript则没有客户端脚本开发时的局限性,当客户请求页面时,页面将在服务器上执行,然后再反馈给浏览器,浏览器所获得的只是标准HTML文件,这样就可以不受到浏览器不支持的限制。和Visual Basic语言一样,VBScript语言是大小写不敏感的,例如,当我们需要在页面中引用Server对象的时候,我们使用SERVER和server都是可以的,如果我们将两个变量定义为Book和book,在C语言中,这将被视为两个不同的变量,可是在VBScript中,它们只会被视为一个变量。
VBScript使用ActiveX Script(即ActiveX脚本)与宿主应用程序对话。使用ActiveX Script,浏览器和其他宿主应用程序不再需要每个Script部件的特殊集成代码。ActiveX Script使宿主可以编译Script、获取和调用入口点及管理开发者可用的命名空间。通过ActiveX Script,语言厂商可以建立标准Script运行时语言。
VBScript可以和HTML页面完美地结合在一起,运用VBScript可以控制HTML页面,并对页面中某些事件作出响应,例如,可以在页面的表单提交时进行数据有效性验证。VBScript还提供了许多对象和浏览器的对象,运用这些对象,可以方便地进行脚本的编写,实现一些其他语言所无法实现的功能。
那么,VBScript究竟有哪些用途呢?下面我们先列举几种情况,在实际使用中,读者也许会发现,还会有更多的情况下会用到VBScript。
(1) 创建生动的用户界面。在一个制作精美的页面中,为了使页面生动活泼,往往需要按钮在被按下时作出某些响应,那应该如何处理呢?当然我们可以采用表单中的按钮,这种按钮的确能够有效地实现所要实现的功能,但这种按钮往往会破坏整个页面的和谐美观。我们也可以采用超链接来实现,但超链接只能够实现按钮被按下的结果,而不能展现按钮从按下到弹起的整个过程。运用VBScript,我们可以采用图片来实现这个功能,首先我们应该制作两幅图片,一幅是按钮正常状态的图片,一幅是按钮被按下的图片,一开始时在页面上放置正常状态的图片,当鼠标在图片上按下时,图片切换为被按下的图片,当鼠标松开时再切换为正常状态的图片,这样就能够完美地解决这个问题,既保持页面的美观,又使页面变得生动活泼。
(2) 数据有效性验证工作。当用户填写表单并提交表单数据时,可能因为用户的疏忽而有所遗漏,或者由于用户的玩笑而填入了无效的数据,对这种情况应该如何处理呢?当然,表单的数据会送往服务器上的CGI程序,我们可以在CGI程序的处理时进行数据有效性验证,然后将结果反馈给用户,但如果是用户的疏忽而引起的,那么他将等待一段时间后才能得到反馈结果,用户当然不希望有这段时间的等待;如果是用户的玩笑而引起的,Web管理员也不希望这种毫无意义的数据送到服务器上加重服务器的负担。我们可以运用VBScript在客户端进行一次数据有效性验证,不论是遗漏了某些数据,还是填入了无效数据,都可以在表单提交前检验出来,立即反馈给用户,而不将无效的数据发向服务器。
(3) 数据查找。许多页面中都有搜索的功能。当用户填入关键词后,浏览器将关键词发送给服务器,服务器上的数据库搜索引擎立即开始工作,然后将检索结果以HTML页面的形式反馈给浏览器。这种方案当然没有什么不妥,但在数据量不大的情况下,比如只是在几十条数据中进行检索,虽然它也能够实现数据查找的功能,但和用户的等待时间、服务器加重的负载相比起来,采用这种方案是否有些得不偿失呢?既然数据量不大,运用VBScript,我们可以将数据存放在页面中,用户填入关键词后并不送往服务器,而是在客户端直接进行查找,然后直接在客户端将检索结果反馈给用户。
2.1.2 在HTML中页面使用VBScript
前面已经提到,VBScript不能用来编写单独的应用程序,它必须嵌入到HTML页面中去。嵌入时必须使用SCRIPT元素将VBScript代码添加到HTML页面中。同时,VBScript代码要写在成对的<SCRIPT>标记之间。例如,以下代码为一个测试传递日期的过程:
<SCRIPT LANGUAGE="VBScript">
<!--
Function CanDeliver(Dt)
CanDeliver = (CDate(Dt) - Now()) > 2
End Function
-->
</SCRIPT>
可以看到,代码的开始和结束部分都有<SCRIPT>标记。另外,LANGUAGE属性用于指定所使用的Script语言。由于浏览器能够使用多种Script语言,所以必须在此指定所使用的Script语言。当然,由于VBScript是IE浏览器使用的默认的脚本语言,所以当确保使用IE浏览器浏览时可以不使用LANGUAGE属性来指定VBScript,但为了能适应其他浏览器,建议用户还是指定一下。
如果我们再注意一下上述VBScript脚本,就会发现VBScript代码被加上了注释标记(<!-- 和 -->)。如:
<SCRIPT LANGUAGE=VBScript>
<!--
VBScript Code
-- >
</SCRIPT>
加上注释标记是因为对于不支持VBScript的浏览器来说,不能识别标签<SCRIPT>,如果不加上注释的话,VBScript脚本会被作为文本而直接显示在页面上,而加入了注释标签之后,这部分不被支持的代码就将被忽略,<SCRIPT>和</SCRIPT>标签也是不能被识别的,因此一概忽略。但是对于可以识别VBScript代码的浏览器而言,即使加了注释标签,也能识别出处于注释标签内的VBScript代码。一般,我们完全不必那样做,不过为了以防万一,我们最好养成这个好习惯。
因为以上测试传递日期的示例是一个通用函数,即不依赖于任何窗体控件,所以可以将其包含在HTML页面的HEAD部分:
<HTML>
<HEAD>
<TITLE>订购</TITLE>
<SCRIPT LANGUAGE="VBScript">
<!--
Function CanDeliver(Dt)
CanDeliver = (CDate(Dt) - Now()) > 2
End Function
-->
</SCRIPT>
</HEAD>
<BODY>
...
SCRIPT块可以出现在HTML页面的任何地方,如BODY或HEAD部分之中。然而,最好是将所有的一般目标Script代码放在HEAD部分中,以使所有Script代码集中放置。这样可以确保在BODY部分调用代码之前所有Script代码都被读取并解码。
上述规则的一个值得注意的例外情况是,在窗体中提供内部代码以响应窗体中对象的事件。例如,以下示例在窗体中嵌入Script代码以响应窗体中按钮的单击事件:
<HTML>
<HEAD>
<TITLE>测试按钮事件</TITLE>
</HEAD>
<BODY>
<FORM NAME="Form1">
<INPUT TYPE="Button" NAME="Button1" VALUE="单击">
<SCRIPT FOR="Button1" EVENT="onClick" LANGUAGE="VBScript">
MsgBox "按钮被单击!"
</SCRIPT>
</FORM>
</BODY>
</HTML>
该程序运行后的界面如图2.1(a)所示,单击其中的按钮,出现图2.1(b)的画面。
(a) 运行后的效果图 (b) 单击按钮后效果
图2.1 例程运行效果图
大多数Script代码在Sub或Function过程中,仅在其他代码要调用它时执行。然而,我们也可以将VBScript代码放在过程之外、SCRIPT块之中,这类代码仅在HTML页面加载时执行一次。这样就可以在加载Web页面时初始化数据或动态地改变页面的外观。
2.2 VBScript数据类型
虽然Visual Basic中有许多种数据类型,但是在VBScript中,只支持一种数据类型,即Variant。Variant是一种很特殊的数据类型,根据它使用方式的不同,可以代表各种数据类型。如果我们将一个变量赋值为数字,那么在引用这个变量的时候,它将作为数字使用;如果我们将一个变量赋值为字符串,那么我们可以对这个变量进行字符串的各种操作。在实际使用的过程中,VBScript可以根据在变量中存储的数据识别其类型。有关变量的概念和变量的赋值操作,我们随后讲解。
在VBScript识别的过程中,除了数字和字符串之外,还包括了布尔类型、时间类型、货币类型等等,我们将其称为子类型(Subtypes)。在表2.1中,列举了VBScript中的数据子类型:
表2.1 VBScript中数据子类型
类型 说明
Empty 空类型,代表未初始化的Variant变量值,如果变量是数字,那么它为0,如果变量是字符串,那么它为长度为0的字符串
Null 无效类型,这说明在变量中保存的是无效的数据
Boolean 布尔类型,取值为True或者False
Byte 字节类型,取值范围是从0到255的整数
Integer 整数类型,取值范围是从-32768到32767的整数
Currency 货币类型,取值范围从-922,337,203,685,477.5808到922,337,203,685,447.5807
Long 长整数类型,取值范围是从-2,147,483,648到2,147,483,647的整数
Single 单精度浮点类型,负数取值范围从-3.402823E38到-1.401298E-45,正数取值范围从1.401298E-45到3.402823E38
Double 双精度浮点类型,负数取值范围从-1.7779769312386232E308到-4.94065645841247E-324,正数取值范围从4.94065645841247E-324到1.7779769312386232E308
Date(Time) 日期类型,可以代表从100年1月1日到9999年12月31日的日期
String 字符串类型,字符串的长度是可变的,最长可达20亿个字符
Object 对象类型
Error 错误编号类型
无效类型对许多人来说,也许是比较难以理解的一种类型,它不象前面几种类型那样直观,无效类型的数据就是Null。
表2.2 VarType函数获取各种数据子类型变量的返回值
数据子类型 返回值
Empty 0
Null 1
Integer 2
Long 3
Single 4
Double 5
Currency 6
Date(Time) 7
String 8
Object 9
Error 10
Boolean 11
Variant 12
DataObject 13
Byte 17
Array 8192
例如,我们可以把Null赋值给变量theNull,其语句如下所示:
theNull = Null
一定不要把无效类型和数字类型中的0或者字符串类型中的空字符串混淆起来,Null意味着什么都没有,代表的是变量中并没有存储着有效的数据,而0代表的是一个数值,空字符串代表的是字符串长度为0,这两个值都是有效的。虽然无效类型有些令人难以理解,但在深入VBScript编程的过程中,也许你会慢慢发现,无效类型也是十分有用的一种数据类型。
我们如果需要查看变量的数据子类型,我们可以使用VarType函数获取。例如,如果我们定义了一个变量k,并且将其赋值为3,那么我们可以使用以下语句获取其类型:
VarType(k)
执行这个函数之后将会返回2,代表这个变量的子类型是整数类型,在表2.2中我们列举了使用VarType函数获取的各种数据子类型变量的返回值。
dyle_gg,2004-12-02 14:13:19
2.3 VBScript变量
使用脚本语言时,变量是其中最基本的元素,脚本执行过程中,往往需要用一个单元将信息存储起来,变量就是这样的一个命名的存储单元,存储在这个单元中的数据就是变量的值。例如,我们可以创建一个名称为Visitors的变量将访问站点的人数记录下来,这个变量的值是存储在计算机的内存中,但在使用的过程中,我们并不需要知道它的内存地址,只要通过Visitors,我们就可以直接获取该变量的值或者修改这个值。
后面我们还讲到常量的概念,虽然说常量和变量一样可以赋予数值,但是常量和变量有所不同,变量可以反复赋值,而常量的数值一旦确定下来之后就不能发生变化了。
使用变量时,一般要先声明变量,而命名变量时也要按照VBScript的命名要求才能正确命名变量。
2.3.1 声明变量
VBScript和Visual Basic一样,在使用变量前并可以不对变量声明,在例2.1中,我们用到了一个变量Message,但是我们并没有预先对它进行声明,这并不影响脚本的执行。
<HTML>
<HEAD>
<TITLE> Use variable without declare </TITLE>
<SCRIPT LANGUAGE="VBScript">
<!--
Message = “hello”
window.document.write(Message)
-->
</SCRIPT>
</HEAD>
<BODY>
</BODY>
</HTML>
例2.1 在脚本中未声明而使用一个变量
在这个页面中,执行的结果是在页面上显示字符串hello。在VBScript中,不声明而直接使用变量,我们称为对这是对变量的隐式声明。
2.3.1.1 Option Explicit
Optioin Explicit语句强制要求显式声明脚本中使用的所有变量,在使用这条语句之后,必须使用Dim、Private、Public或者ReDim语句声明所有变量。不过Option Explicit语句在页面中的位置很特殊,它必须放置于所有HTML文本和脚本命令之前,也就是说它必须作为ASP页面的起始语句之一。其语法如下所示:
Option Explicit
如果将这句脚本加入到例2.1中,那么在运行的过程中将会出现如下错误:
Microsoft VBScript 运行时错误 error ‘800a01f4’
变量未定义: ‘Message’
/message.asp, line 7
隐式声明变量并不是一个良好的编程习惯。因为在编写脚本的过程中,我们很有可能出现因为拼写疏忽而导致脚本执行出现意外错误,并且这种错误是难以被发现和改正的,例如,如果我们在开始对变量Message赋值,但是在后面脚本程序中,由于疏忽,我们将变量拼写成为Messag,在不要求变量显式声明的情况下,脚本执行将不会产生错误,Message和Messag会被视为两个不同的变量,然而结果明显和我们预期不符,这种错误是很难发现的。我们建议在脚本时使用Option Explicit语句,要求变量显式声明,这是一种良好的编程习惯。
2.3.1.2 Dim
在声明变量的时候,我们一般使用Dim语句,其语法如下所示:
Dim varname[([subscripts])]
其中,varname是变量的名称,在声明数组的时候,subscripts代表的是数组的上界。
我们在VBScript中声明变量时,不需要指定变量的数据类型,这是由于VBScript中,所有变量都是相同的数据类型,都是Variant类型变量,这是一种特殊的数据类型,它代表了Visual Basic中其他所有的数据类型。Variant类型可以根据存储在其中的信息自动识别实际数据类型。
例如,下面的声明中,我们声明了变量Message:
Dim Message
除了变量之外,我们还可以声明数组。在声明数组的时候,变量名后面带有括号,下面的语句中,我们声明了一个数组,名称为Items:
Dim Items(10)
对于这个数组,数组的上界是10,而下界总是默认为0,所以,数组中的元素是11个。在使用数组的时候,我们可以通过数组的下标引用数组,例如:
SomeData = Item(3)
在声明数组的时候,我们也可以不局限于一维数组,VBScript支持数组最大的维数是60。声明多维数组时需要用逗号分隔代表数组上界的数组,在下面的声明中,ItemTable是一个4行5列的二维数组:
Dim ItemTable(3, 4)
2.3.1.3 ReDim
使用ReDim语句,我们可以管理动态数组,上面我们声明数组的时候直接指定了数组的大小,这种类型的数组就是静态数组;动态数组和静态数组不同之处在于,动态数组的大小可以在脚本执行的过程中发生变化。
在声明动态数组的时候,我们需要首先使用Dim语句或者ReDim语句对数组进行声明,但不要指定数组的上界,也就是说,在数组声明的括号中不包含任何数字,例如:
Dim Visitors()
然后,再使用ReDim语句设置数组的大小,例如,在下面的声明中,我们将Visitors数组的上界设定为10:
ReDim Visitors(10)
在使用ReDim语句的过程中,我们还可以使用Preserve关键字,当使用Preserver关键字调整数组大小的时候,将会保留数组中的内容,例如,假设我们先将Visitors数组上界设定为10,然后我们再使用Preserve关键字将上界修改为20:
ReDim Preserve Visitors(20)
这样,在调整数组大小的过程中,数组中前11个元素还会保留。
注意:对于动态数组而言,调整数组大小的次数是没有限制的,但是,如果我们使数组的大小变小,那么数组中被删除元素的数据会丢失。
2.3.1.4 Public
使用Dim语句可以在脚本的过程中声明的变量,也可以在过程外声明变量,在过程中声明的变量称为过程级变量(Procedure level),在过程外声明的变量称为脚本级变量(Script level),过程级变量只能应用于过程中,脚本级变量可以应用于脚本中所有的过程。关于过程,我们会在后面的章节中进行详细讨论。
Public语句不能用于声明过程级变量,只能声明脚本级变量,运用Public声明的变量声明的变量可以运用于脚本的所有过程中。其语法如下所示:
Public varname[([subscripts])]
其中,varname代表的是变量名称,subscripts代表的是数组的上界。和Dim语句一样,Public语句也能够声明动态数组和静态数组,以及多维数组。
2.3.1.5 Private
Private语句和Public语句是相对的,Private语句也只能声明脚本级变量,运用Private语句声明的变量只能在声明该变量的脚本中使用。其语法如下所示:
Private varname[([subscripts])]
其中,varname代表的是变量名称,subscripts代表的是数组的上界。和Dim语句一样,Private语句也能够声明动态数组和静态数组,以及多维数组。
2.3.2 变量的命名规则
在变量命名的过程中,必须遵循以下几条规则:
1. 变量名称的第一个字符必须是字母,例如,BookName是合法的变量名称,而诸如_bookname、3bookname这些变量名称都是非法变量名称。
2. 不能包含嵌入的句号(.),例如,Book.Name就是非法的变量名称。
3. 变量名称的长度必须少于255个字符。
4. 在变量的作用域中,变量的名称要求唯一。变量的作用域是有声明变量的位置所决决定的,如果是在过程中声明变量,那么变量的作用域是整个过程;如果是在过程外声明变量,那么变量的作用域是整个脚本。这也就是说,如果具有相同名称的两个或者多个变量具有相同的作用域,那么将会出错。不过在两个过程中,我们可以将变量命名为相同的名称,例如,如果在两个过程中,我们都需要用到临时变量,那可以将这两个临时变量都命名为temp。
在一般情况下,我们在给变量命名时,希望能够使用有意义的变量名称,如果需要使用一个变量表示一本书的价格,虽然命名为j或book都没有什么错误,但若能命名为bookPrice会使得脚本有更好可读性,也可以方便脚本开发人员进行脚本的编写和调试工作。
这是我们对于变量命名的约定,并不是强制性要求,用户完全可以不按照我们的约定来做(只要不违反VBScript对于变量命名的要求就可以了),但养成良好的编程风格对于ASP页面开发人员来说,还是很有意义的。
2.3.3 给变量赋值
创建如下形式的表达式给变量赋值:变量在表达式左边,要赋的值在表达式右边。例如:
MyVariable=200
2.3.4 标量变量和数组变量
多数情况下,只需为声明的变量赋一个值。只包含一个值的变量被称为标量变量。有时候,将多个相关值赋给一个变量更为方便,因此可以创建包含一系列值的变量,称为数组变量。数组变量和标量变量是以相同的方式声明的,唯一的区别是声明数组变量时变量名后面带有括号( )。下例声明了一个包含11个元素的一维数组:
Dim A(10)
虽然括号中显示的数字是10,但由于在VBScript中所有数组都是基于0的,所以这个数组实际上包含11个元素。在基于0的数组中,数组元素的数目总是括号中显示的数目加1。这种数组被称为固定大小的数组。
在数组中使用索引为数组的每个元素赋值。从0到10,将数据赋给数组的元素,如下所示:
A(0) = 256
A(1) = 324
A(2) = 100
…
A(10) = 55
与此类似,使用索引可以检索到所需的数组元素的数据。例如:
…
SomeVariable = A(8)
…
数组并不仅限于一维。数组的维数最大可以为60(尽管大多数人不能理解超过3或4的维数)。声明多维数组时用逗号分隔括号中每个表示数组大小的数字。在下例中,MyTable变量是一个有6行和11列的二维数组:
Dim MyTable(5, 10)
在二维数组中,括号中第一个数字表示行的数目,第二个数字表示列的数目。
也可以声明动态数组,即在运行Script时大小发生变化的数组。对数组的最初声明使用Dim语句或ReDim语句。但是对于动态数组,括号中不包含任何数字。例如:
Dim MyArray()
ReDim AnotherArray()
要使用动态数组,必须随后使用ReDim确定维数和每一维的大小。在下例中,ReDim将动态数组的初始大小设置为25,而后面的ReDim语句将数组的大小重新调整为30,同时使用Preserve关键字在重新调整大小时保留数组的内容。
ReDim MyArray(25)
…
ReDim Preserve MyArray(30)
重新调整动态数组大小的次数是没有任何限制的,但是应注意:将数组的大小调小时,将会丢失被删除元素的数据。
2.4 VBScript常量
常量是具有一定含义的名称,用于代替数字或字符串,其值从不改变。此外,VBScript还定义了许多固有常量,这无疑大大方便了程序员的开发工作。
2.4.1 声明自定义常量
在VBScript中,我们可以声明常量,用来代替数字、日期或者字符串等数值,常量的数值在脚本运行的过程中不能发生变化。常量声明的语法如下所示:
Const constname = expression
其中,constname是常量的名称,expression是常量的值。
对于脚本开发人员来说,常量是很有用的,例如,如果在我们的脚本中需要使用到π,我们往往会将其定义为一个常量,赋值为3.14:
Const PI = 3.14
如果需要更高的精度,那么,我们可以将其设置为3.1415927:
Const PI = 3.1415927
在使用常量的情况下,我们只需要修改常量声明这一条语句就可以了,若我们不使用常量,那么我们则不得不将页面中用到π的地方全部进行修改。在使用常量的情况下,将会提高脚本的可读性与易维护性。
在常量声明的前面,我们也可以加上Public和Private前缀来设置其作用域,设置方式和变量是一样的。缺省情况下,在过程中声明的常量具有过程级作用域,在过程外声明的常量具有脚本级作用域。
在常量命名的过程中,也需要遵循变量的命名规则,并且不能和变量名称、VBScript内部函数名称和用户自定义函数名称相同。而且,在声明的时候,变量的值必须是一个简单常量,而不能是带有操作符的表达式。
我们建议在命名常量的时候,也使用一个命名方法,将常量和变量区分开来,这样可以避免将常量和变量混淆,不至于在脚本中对常量重新赋值,我们可以将常量的所有字母大写,例如,PI,或者使用“con”作为常量的前缀,例如,conPi。将常量和变量区分开是一个良好的编程风格,避免在脚本开发中出现混乱。
使用Const语句创建名称具有一定含义的字符串型常量时,通常需要将字符串文字包含在两个引号(" ")之间。例如:
Const MyString = "这是一个字符串。"
这也区分字符串型常量和数值型常量的最明显的方法。另外,日期文字和时间文字应当包含在两个井号(#)之间。例如:
Const CutoffDate = #6-1-97#
2.4.2 使用固有常量
刚刚提到,VBScript还定义了固有常量,设计人员可以在程序中定义并直接引用这些常量。VBScript定义的常量包括颜色常量、比较常量、日期和时间常量、日期格式常量、DriveType常量、FileAttributes常量、文件输入/输出常量、MsgBox常量、SpecialFolder常量、字符串常量、Tristate常量、VarType常量等。
例如,VBScript的颜色常量包括8个常量,各常量的名称、值和描述见表2.1。为便函于编程人员参考,我们在表2.1中一并给出了VBScript其他固有常量的名称、值和描述。
表2.1 VBScript的固有常量
颜色常数
常数 值 描述
vbBlack &h00 黑色
vbRed &hFF 红色
vbGreen &hFF00 绿色
vbYellow &hFFFF 黄色
vbBlue &hFF0000 蓝色
vbMagenta &hFF00FF 紫色
vbCyan &hFFFF00 青色
vbWhite &hFFFFFF 白色
比较常数
常数 值 描述
vbBinaryCompare 0 执行二进制比较。
vbTextCompare 1 执行文本比较。
vbDatabaseCompare 2 基于数据库所包含的信息,在数据库中进行比较。
日期和时间常数
常数 值 描述
vbSunday 1 星期日
vbMonday 2 星期一
vbTuesday 3 星期二
vbWednesday 4 星期三
vbThursday 5 星期四
vbFriday 6 星期五
vbSaturday 7 星期六
vbFirstJan1 1 使用包含1月1日的星期(默认)。
vbFirstFourDays 2 使用第一个至少包含新的年中四天的星期。
vbFirstFullWeek 3 使用某年的第一个整周。
vbUseSystem 0 使用计算机区域设置中的日期格式。
vbUseSystemDayOfWeek 0 由系统设置定义每周的第一天是星期几。
日期格式常数
常数 值 描述
vbGeneralDate 0 显示日期和/或时间。对于实数,显示日期和时间。如果没有小数部分,仅显示日期。如果没有整数部分,则仅显示时间。由系统设置决定日期和时间的显示。
vbLongDate 1 按计算机中区域设置指定的长日期格式显示日期。
vbShortDate 2 按计算机中区域设置指定的短日期格式显示日期。
vbLongTime 3 按计算机中区域设置指定的长时间格式显示时间。
vbShortTime 4 按计算机中区域设置指定的短时间格式显示时间。
DriveType常数
常数 值 描述
Unknown 0 无法确定驱动器类型。
Removable 1 可移动媒体驱动器,包括软盘驱动器和其他多种存储设备。
Fixed 2 固定(不可移动)媒体驱动器,包括所有硬盘驱动器(包括可移动的硬盘驱动器)。
Remote 3 网络驱动器,包括网络上任何位置的共享驱动器。
CDROM 4 CD-ROM驱动器,不区分只读和可读写的CD-ROM驱动器。
RAMDisk 5 RAM磁盘,在本地计算机中占用一块“随机存取内存”(RAM)虚拟为磁盘驱动器。
FileAttributes常数
常数 值 描述
Normal 0 普通文件。未设置属性。
ReadOnly 1 只读文件。
Hidden 2 隐藏文件。
System 4 系统文件。
Volume 8 磁盘驱动器卷标。
Directory 16 文件夹或目录。
Archive 32 上次备份后已更改的文件。
Alias 64 链接或快捷方式。
Compressed 128 压缩文件。
文件输入/输出常数
常数 值 描述
ForReading 1 以只读方式打开文件。不能向该文件写入内容。
ForWriting 2 以可读写方式打开文件。如果已存在同名的文件,则覆盖旧的文件。
ForAppending 8 打开文件并在文件末尾写入内容。
MsgBox常数
常数 值 描述
vbOKOnly 0 只显示确定按钮。
vbOKCancel 1 显示确定和取消按钮。
vbAbortRetryIgnore 2 显示终止、重试和忽略按钮。
vbYesNoCancel 3 显示是、否和取消按钮。
vbYesNo 4 显示是和否按钮。
vbRetryCancel 5 显示重试和取消按钮。
vbCritical 16 显示临界消息图标。
vbQuestion 32 显示警告询问图标。
vbExclamation 48 显示警告消息图标。
vbInformation 64 显示提示消息图标。
vbDefaultButton1 0 第一个按钮是默认按钮。
vbDefaultButton2 256 第二个按钮是默认按钮。
vbDefaultButton3 512 第三个按钮是默认按钮。
vbDefaultButton4 768 第四个按钮是默认按钮。
vbApplicationModal 0 应用程序模式。用户必须响应消息框,才能继续在当前应用程序中工作。
vbSystemModal 4096 系统模式。用户响应消息框前,挂起所有应用程序。
下列常数与MsgBox函数一起使用,标识用户选定的按钮
常数 值 描述
vbOK 1 确定按钮被单击。
vbCancel 2 取消按钮被单击。
vbAbort 3 终止按钮被单击。
vbRetry 4 重试按钮被单击。
vbIgnore 5 忽略按钮被单击。
vbYes 6 是按钮被单击。
vbNo 7 否按钮被单击。
SpecialFolder常数
常数 值 描述
WindowsFolder 0 Windows文件夹,包含由Windows系统安装的文件。
SystemFolder 1 System文件夹,包含库、字体和设备驱动程序文件。
TemporaryFolder 2 Temp文件夹,用于保存临时文件。可在TMP环境变量中找到该文件夹的路径。
字符串常数
常数 值 描述
vbCr Chr(13) 回车符
vbCrLf Chr(13) & Chr(10) 回车符与换行符
vbFormFeed Chr(12) 换页符;在MicrosoftWindows中不适用
vbLf Chr(10) 换行符
vbNewLine Chr(13) & Chr(10)或Chr(10) 平台指定的新行字符;适用于任何平台
vbNullChar Chr(0) 值为0的字符
vbNullString 值为0的字符串 与零长度字符串("")不同;用于调用外部过程
vbTab Chr(9) 水平附签
vbVerticalTab Chr(11) 垂直附签;在MicrosoftWindows中不适用
Tristate常数
常数 值 描述
TristateTrue -1 True
TristateFalse 0 False
TristateUseDefault -2 使用默认设置
VarType常数
常数 值 描述
vbEmpty 0 未初始化(默认)
vbNull 1 不包含任何有效数据
vbInteger 2 整型子类型
vbLong 3 长整型子类型
vbSingle 4 单精度子类型
vbDouble 5 双精度子类型
vbCurrency 6 货币子类型
vbDate 7 日期子类型
vbString 8 字符串子类型
vbObject 9 对象
vbError 10 错误子类型
vbBoolean 11 Boolean子类型
vbVariant 12 Variant(仅用于变量数组)
vbDataObject 13 数据访问对象
vbDecimal 14 十进制子类型
vbByte 17 字节子类型
vbArray 8192 数组
其他常数
常数 值 描述
vbObjectError &h80040000 自定义错误号应大于该值,例如,Err.Raise Number = vbObjectError + 1000
2.5 VBScript的表达式与运算符
在VBScript中,表达式可以将变量、常数、运算符和关键字结合起来,用于执行运算、处理字符或者测试数据,表达式运算返回的结果可能是数字类型的数据,也可能是字符串类型或者其他类型的数据。其实,我们对于表达式应该是十分熟悉的,例如,1+2就是一个简单的表达式。
在表达式运算的过程中,表达式里操作一个或两个变量、常量或者数据产生运算结果的符号称为运算符,被运算符操作的数据称作操作数,需要注意的是,操作数并不仅仅局限于数字和字符串等类型的数据,它本身也可以是表达式。VBScript支持一套完整的运算符,其中我们会用到算术运算符、关系运算符、逻辑运算符和连接运算符,下面我们就对这些操作符进行简要的介绍。
2.5.1 算术运算符
在VBScript中,算术运算符用以完成数学运算,一般情况下,算术运算符的语法如下所示:
Result = Exp1 Operator Exp2
其中,Result是表达式运算结果,Operator是算术运算符,Exp1和Exp2则是表达式中的操作数。
VBScript中能够使用的算术运算符如表2.2所示,下面我们分别展开介绍:
表2.2 VBScript算术运算符
运算符 说明
+ 加法运算符,将两个数相加
- 减法运算符,将两个数相减或者对一个数取负
* 乘法运算符,将两个数相乘
/ 除法运算符,将两个数相除
整除运算符,将两个数进行整除运算
^ 幂运算符,将两个数进行幂运算
Mod 模运算符,将两个数整除后进行取模操作
2.5.1.1 加法运算符(+)
加法运算符对应着数学运算中的加法运算,例如表达式1+2的运算结果为3。
加法操作符还可以对字符串类型的操作数进行运算,然后将两个字符串连接起来作为运算结果。例如,"How are "+"you!"的运算结果为"How are you!"。虽然加法运算符完全可以进行字符串连接,不过,我们并不建议这样使用,因为容易引起混淆,在字符串连接的时候,我们建议采用字符串连接的符号——&。
在加法运算的过程中,如果两个操作数都是数字类型,那么将进行加法操作:3+4的结果是7;如果两个操作数都是字符串类型,那么将进行字符串连接操作:“3”+“4”的结果是“34”;如果一个操作数是数字,另外一个操作数是字符串,那么会将字符串转化为数字之后进行加法操作:3+“4”的结果是7。
2.5.1.2 减法运算符(-)
减法运算符对应着数学运算中的减法运算,例如表达式2-1的运算结果为1。
同时,减法运算符还是一个取负运算符,当它作为取负运算符的时候,它只有一个操作数,取负运算符的功能是返回操作数的相反数。例如如果变量i的值为2,那么-i这个表达式的值为-2。
2.5.1.3 乘法运算符(*)
乘法运算符对应着数学运算中的乘法运算,例如表达式2*3的运算结果为6。
2.5.1.4 除法运算符(/)
除法运算符对应着数学运算中的除法运算,但VBScript中的除法运算有些特别,在VBScript中,除法运算后的结果是一个浮点数,而不象C语言或者Java语言那样在整数进行除法运算时将运算结果强行转化整数,在VBScript中,1/2=0.5,而在C语言中,1/2=0。
2.5.1.5 整除运算符()
整除运算符对应着数学运算中的整除运算,将两个操作数相除后返回结果的整数部分,例如表达式52的运算结果为2。不过在VBScript中,整除运算符并不局限于整数,如果操作数是浮点数,VBScript会先将其四舍五入转化为整数之后,然后再进行整除运算。例如5.41.5=2,而5.51.5=3。
2.5.1.6 幂运算符(^)
幂运算符对应着数学运算中的幂运算,可以用于计算第一个操作数的指数次方,例如,表达式3^2的运算结果为9。在幂运算中,指数还可以是小数,例如,3^0.5= 1.73205080756888,不过必须在第一个操作数为非负数字的时候,指数才能够是小数,因为在VBScript的运算中,并不支持复数运算。例如,如果表达式是(-3)^0.5,那么将会出现错误。
2.5.1.7 模运算符(Mod)
模运算符对应着数学运算中的取模运算,将两个操作数进行整除操作之后返回其余数,例如,表达式5 Mod 2的运算结果为1。和整除运算符一样的是,进行取模运算的时候,VBScript也会先将两个操作数四舍五入之后,然后再取模。例如,5.4 Mod 1.5=1,而5.5 Mod 1.5=0。
模运算符主要用于判断一个数字是否能被另外一个数字整除,例如,如果我们希望知道某个年份是否是闰年,我们可以采用如下判断方法:如果这个年份能够被4整除,并且不能被100整除,那么,这个年份是闰年,另外,如果这个年份能够被400整除,那么这个年份也是闰年。假设年份变量的名称为theYear,那么判断是否为闰年的表达式如下所示:
((theYear Mod 4 = 0) And (theYear Mod 100 <> 0)) Or (theYear Mod 400 = 0)
其中And代表的是逻辑运算中的与运算,Or代表的是逻辑运算中的或运算,关于逻辑运算,我们会在以后部分中进行介绍。
dyle_gg,2004-12-02 14:13:51
2.5.2 关系运算符
关系运算符将两个操作数进行比较,判断其关系,然后返回一个逻辑值,表明这个比较操作的结果是真还是假。其语法形式如下所示:
Result = Exp1 Operator Exp2
其中Result是表达式的判断结果,结果可能是True、False或者Null,Operator是关系运算符,Exp1和Exp2则是表达式中的操作数。在使用的时候,我们会发现,如果判断结果为True,那么返回的是-1,如果判断结果为False,那么返回的是0,如果判断结果为Null,那么什么也不返回。
VBScript支持的关系运算符如表2.3所示:
表2.3 VBScript关系运算符
运算符 说明
= 等于关系,判断两个操作数是否相等
<> 不等于关系,判断两个操作数是否不相等
> 大于关系,判断前一个操作数是否大于后一个操作数
< 小于关系,判断前一个操作数是否小于后一个操作数
>= 大于等于关系,判断前一个操作数是否大于等于后一个操作数
<= 小于等于关系,判断前一个操作数是否小于等于后一个操作数
IS 对象关系,用来比较对象类型
注意:如果关系运算中的任何一个操作数为Null,那么表达式返回的结果既不为True,也不为False,而是Null。
在关系运算中,如果两个操作数都是数值,那么将进行数值比较。如果两个操作数都是字符串,那么将进行字符串比较。如果一个操作数是数值,另外一个操作数是字符串,VBScript则假定任何数值都比字符串要小。
2.5.2.1 等于关系(=)
等于关系比较两个操作数是否相等,如果两个操作数相等,返回True,否则返回False。例如,3=3.0的返回结果为True,3=4的返回结果为False,
2.5.2.2 不等于关系(<>)
不等于关系比较两个操作数是否不相等,如果两个操作数不等,返回True,否则返回False。如果操作数相同,等于关系和不等于关系判断的结果完全相反。例如,3<>3.0的返回结果为False,3<>4的返回结果为True。
2.5.2.3 大于关系(>)
如果左操作数大于右操作数,返回True,否则返回False。例如,3>2的返回结果为True,而3>3的返回结果为False。
2.5.2.4 小于关系(<)
如果左操作数小于右操作数,返回True,否则返回False。例如,3<4的返回结果为True,3<3的返回结果为False。
2.5.2.5 大于等于关系(>=)
如果左操作数大于等于右操作数,返回True,否则返回False。在两个操作数完全相同的情况下,大于等于关系和小于关系的返回结果完全相反。例如,3>=4的返回结果为False,3>=3的返回结果为True。
2.5.2.6 小于等于关系(<=)
如果左操作数小于等于右操作数,返回True,否则返回False。在两个操作数完全相同的情况下,小于等于关系和大于关系的返回结果完全相反。例如,3<=2的返回结果为False,3<=3的返回结果为True。
2.5.2.7 对象关系(IS)
对象关系用于比较两个变量引用的对象,如果两个对象引用同一个变量,那么返回True,否则返回False。对象关系只能比较对象类型,而不能比较其他类型。例如,请看下面的语句:
Set ObjA = ObjB
在这个语句中,执行的结果是使得ObjA引用ObjB所引用的同一个对象,在这种情况下,ObjA IS ObjB的返回结果为True。
2.5.2.8 字符串类型的比较
在关系运算中,如果两个操作数都是字符串,那么将进行字符串类型的比较。在比较字符串的过程中,VBScript把字符串中的每个字母转换成相应的ASCII码值,然后从第一个字符开始比较两个字符串中相应的字符,比较它们的ASCII码值。例如, “hello”=“Hello”的返回结果为False,因为左操作数的第一个字符为h,右操作数的第一个字符为H,h的ASCII码值为104,H的ASCII码值为72,从第一个字符开始就不相等了,所以表达式的值为False。
如果有两个表达式:“hello”>“Hello”和“hello”>=“Hello”,返回结果都为True,因为左操作数第一个字符的ASCII码值为104,而右操作数的第一个字符的ASCII码值为72,104>72(当然同样104>=72),所以两个表达式的值都为True。
而如果表达式为“came”>=“come”,首先,比较两个操作数的第一个字符,都是c,这样,不能直接判定两个操作数的大小,然后再比较两个操作数的第二个字符,左操作数为a,右操作数为o,a的ASCII码值为97,o的ASCII码值为111,当然97<111,所以对于这个表达式来说,它的返回结果为False。
字符串类型的比较情况下,我们用得最多的是判断某个字符串类型的变量是否为空串,假设我们判断变量的名称为theString,那么对于theString=“”这个表达式来说,如果theString为空串,则表达式为True,否则为False。
2.5.3 逻辑运算符
逻辑运算符可以把布尔类型的表达式组合起来,完成逻辑运算操作,然后返回其结果——真或假,这样就可以完成比较复杂的逻辑判断工作,一般情况下,逻辑运算符的语法如下所示:
Result = Exp1 Operator Exp2
其中,Result是表达式运算结果,Operator是逻辑运算符,Exp1和Exp2则是表达式中的操作数。而对于逻辑运算符中的非运算符(Not),则只有一个操作数。
在VBScript中,逻辑运算符十分丰富,如表2.4所示:
表2.4 VBScript逻辑运算符
运算符 说明
And 与运算符,执行逻辑与运算
Or 或运算符,执行逻辑或运算
Not 非运算符,执行逻辑非运算
Xor 异或运算符,执行逻辑异或运算
Eqv 等价运算符,执行逻辑等价运算
Imp 蕴涵运算符,执行逻辑蕴涵运算
2.5.3.1 与运算符(And)
在执行逻辑与运算的过程中,只有当两个操作数均为True的时候,返回结果才为True,如果有一个操作数为False,则返回结果为False。不过和一般的逻辑操作不同,在VBScript中,还有可能操作数为Null,在表2.5中列举了逻辑与运算的条件和结果:
表2.5 逻辑与运算的条件和结果
左操作数 右操作数 逻辑运算结果
True True True
True False False
False True False
False False False
True Null Null
Null True Null
False Null False
Null False False
Null Null Null
例如,表达式 (3>2) And (3<4)的结果为True,表达式(3>2) And (3>4)的结果为False,而表达式(3>2) And Null的结果为Null,表达式(3>4) And Null的结果为False。
与运算符还可以对数值进行运算操作,如果两个操作数是数值的话,那么VBScript先将其转化为二进制,再从最低位开始,按位进行与运算,最后再将运算的结果以十进制的形式返回。运算的时候遵循以下规则:只有1 And 1的结果为1,否则,结果均为0。例如,4 And 3的结果是0,因为4的二进制形式是100,而3的二进制形式是011,按位与操作之后结果是000,所以返回结果是0。
2.5.3.2 或运算符(Or)
在执行逻辑或运算的过程中,只有当两个操作数均为False的时候,返回结果才为False,如果有一个操作数为True,则返回结果为True。当然,也存在操作数为Null的情况,在表2.6中列举了逻辑或运算的条件和结果:
表2.6 逻辑或运算的条件和结果
左操作数 右操作数 逻辑运算结果
True True True
True False True
False True True
False False False
True Null True
Null True True
False Null Null
Null False Null
Null Null Null
例如,表达式 (2>3) Or (3>4)的结果为False,表达式(2<3) Or (3>4)的结果为True,而表达式(3>4) Or Null的结果为Null,表达式(2<3) Or Null的结果为True。
当或运算符对数值进行运算的时候,对于二进制数的每一位进行或运算,运算的时候遵循以下规则:只有0 Or 0的结果为0,其他情况下结果均为1。例如,4 Or 3的结果是7,因为4的二进制形式是100,而3的二进制形式是011,按位与操作之后结果是111,所以返回结果是7。
2.5.3.3 非运算符(Not)
非运算符只有一个操作数,在执行逻辑非运算的过程中,如果操作数为True,返回结果False;如果操作数为False,返回结果为True;如果操作数为Null,则返回结果也为Null,如表2.7所示:
表2.7 逻辑非运算的条件和结果
操作数 逻辑运算结果
True False
False True
Null Null
例如,表达式 Not (2>3)的结果为True,表达式Not (2<3)的结果为False,而如果变量theNull = Null,那么Not theNull的结果仍然是Null。
当非运算符对数值进行运算的时候,对二进制的每一位进行非运算:Not 0的结果是1,而Not 1的结果是0。例如,Not 4的结果是-5,在运算的时候,4的二进制形式是00000000 00000100,由于前面的0在与运算、或运算中均为0,不影响运算结果,所以在前面的例子中,我们将这些0忽略了,而在进行非运算的时候,这些0必须保留,运算结果的二进制形式是11111111 11111011,十进制形式是-5。
2.5.3.4 异或运算符(Xor)
异或运算符用于判断两个表达式的结果是否不同,在执行逻辑异或运算的过程中,如果两个操作数同为True或同为False,返回结果为False,否则返回结果为True。如果有操作数为Null,那么返回的结果为Null,在表2.8中列举了逻辑异或运算的条件和结果:
表2.8 逻辑异或运算的条件和结果
左操作数 右操作数 逻辑运算结果
True True False
True False True
False True True
False False False
True Null Null
Null True Null
False Null Null
Null False Null
Null Null Null
例如,表达式 (2>3) Xor (3>4)的结果为False,表达式(2<3) Xor (3>4)的结果为True,而表达式(2>3) Xor Null的结果为Null。
当异或运算符对数值进行运算的时候,对于二进制数的每一位进行异或运算,运算的时候遵循以下规则:0 Xor 0的结果为0,1 Xor 1的结果为0,其他情况下,结果为1。例如,4 Xor 5的结果是1,因为4的二进制形式是100,而5的二进制形式是101,按位异或操作之后结果是001,所以返回结果是1。同样,在异或操作中,4和5的二进制形式前面的0异或运算之后仍然是0,并不影响结果。
2.5.3.5 等价运算符(Eqv)
等价运算符和异或运算符正好相反,在等价运算的过程中,如果两个操作数同为True或同为False,返回结果为True,否则返回结果为False。如果有操作数为Null,那么返回的结果为Null,在表2.9中列举了逻辑等价运算的条件和结果:
表2.9 逻辑等价运算的条件和结果
左操作数 右操作数 逻辑运算结果
True True True
True False False
False True False
False False True
True Null Null
Null True Null
False Null Null
Null False Null
Null Null Null
例如,表达式 (2>3) Eqv (3>4)的结果为True,表达式(2<3) Eqv (3>4)的结果为False,而表达式(2>3) Eqv Null的结果为Null。
当等价运算符对数值进行运算的时候,对于二进制数的每一位进行等价运算,运算的时候遵循以下规则:0 Eqv 0的结果为1,1 Eqv 1的结果为1,其他情况下,结果为0。例如,4 Eqv 5的结果是-2,因为4的二进制形式是00000000 00000100,而5的二进制形式是00000000 00000101,按位异或操作之后结果是11111111 11111110,所以返回结果是-2。
2.5.3.6 蕴涵运算符(Imp)
蕴涵运算符实现了逻辑中的蕴涵运算,在蕴涵运算中,只有当前提为True并且结果为False的情况下结果为False,在其余的情况下结果均为True。再考虑操作数为Null的情况之后,逻辑蕴涵运算的条件和结果如表2.10所示:
表2.10 逻辑蕴涵运算的条件和结果
左操作数 右操作数 逻辑运算结果
True True True
True False False
False True True
False False True
True Null Null
Null True True
False Null True
Null False Null
Null Null Null
例如,表达式 (2>3) Imp (3>4)的结果为True,表达式(2<3) Imp (3>4)的结果为False,而表达式Null Imp (2>3)的结果为Null。
当蕴涵运算符对数值进行运算的时候,对于二进制数的每一位进行蕴涵运算,运算的时候遵循以下规则:只有在1 Imp 0的情况下结果为0,其他情况下结果均为1。例如,4 Imp 3的结果是-5,因为4的二进制形式是00000000 00000100,而3的二进制形式是00000000 00000011,按位蕴涵操作之后结果是11111111 11111011,所以返回结果是-5。
2.5.4 连接运算符
VBScript中有两种连接运算符:&运算符和加法运算符。连接运算符可以将字符串相连,组合成为一个字符串。不过加法运算符也可以应用与数值运算,在某些情况下,很容易引起混淆,所以我们建议连接的时候使&运算符。由于我们已经介绍过了加法运算符,下面我们就来讨论一下&运算符:
&运算符的语法如下所示:
Result = Exp1 & Exp2
其中,Result是表达式运算结果,Exp1和Exp2则是表达式中的操作数。
&运算符的功能是将两个字符串相连,如果有操作数是非字符串类型,那么VBScript先将其转换为字符串类型,然后再进行字符串连接操作。如果操作数为Null或者Empty,那么将会被转换成为空字符串(“”),只有在两个操作数都为Null的情况下,不会进行字符串连接,而是返回Null。例如:
“ASP ” & “World” = “ASP World”
3 & “a” = “3a”
3 & 4 = “34”
在对于字符串操作的时候,加法运算符也能够进行字符串连接,不同的地方在于,加法运算符进行运算的时候,不会如同连接字符串一样将非字符串转换为字符串,特别是,如果一个操作数是字符串,另外一个操作数是数值的时候,VBScript会将字符串转换为数值,然后进行加法运算,例如:
3 + “4” = 7
在ASP页面中进行数据库编程的时候,我们常常需要建立复杂的SQL语句,在这时候,我们可以先将SQL语句的各个部分以相对独立而且较短小的字符串表示,然后再将这些字符串连接起来,组合成一条SQL语句。
2.5.5 运算符优先级
在VBScript中,一个表达式中可以存在多个运算符,当表达式具有多个运算符的时候,VBScript将按照预定的顺序计算表达式的各个部分,这个预定顺序被称为运算符优先级。如果在表达式中有括号,那么首先将对括号内的表达式进行运算,在括号内表达式的运算过程中,仍然遵循运算符的优先级关系。
在优先级顺序中,算术运算符的优先级最高,然后是连接运算符,再往后是关系运算符,逻辑运算符的优先级最低,在表2.11中列举了运算符的优先级顺序,在表中自上至下是优先级从高到低的顺序:
表2.11 VBScript运算符优先级顺序(优先级从高到低顺序排列)
运算符类型 运算符符号 运算符说明
算术运算符 ^ 幂运算符
算术运算符 - 被用作取负运算符的减法运算符
算术运算符 *和/ 乘法运算符和除法运算符
算术运算符 整除运算符
算术运算符 Mod 模运算符
算术运算符 +和- 加法运算符和减法运算符
连接运算符 &
关系运算符 =、<>、>、>=、<、<=、IS 所有关系运算符优先级相同
逻辑运算符 Not 非运算符
逻辑运算符 And 与运算符
逻辑运算符 Or 或运算符
逻辑运算符 Xor 异或运算符
逻辑运算符 Eqv 等价运算符
逻辑运算符 Imp 蕴涵运算符
在表达式运算的过程中,括号内的表达式总是最先运算的,然后根据运算符的优先顺序从高到低开始运算,如果有几个运算符优先级一样高,那么则按照运算符从左到又的顺序进行计算。
例如,表达式7/3*2的结果是4.66666666666667,因为除法运算符和乘法运算符的优先级相同,在运算的时候从左到右,先执行除法运算,然后再进行乘法运算。而表达式73*2的结果是1,这则是因为整除运算符的优先级比乘法运算符的优先级要低,首先进行乘法运算2*3=6,再进行整除运算76=1。
不过在这中情况下,也容易引起歧义,因为对于表达式73*2而言,我们并不能判断开发人员的用意是希望先进行整除运算还是先进行乘法运算,VBScript会根据优先级设定作出自己的解释,可这种解释并不一定符合我们预先的设想,所以为了程序逻辑清晰起见,建议在容易引起歧义的部分加上合适的括号。例如对于表达式73*2,如果我们希望先进行整除运算,则改为(73)*2,这个括号是必需的;如果我们希望先进行乘法运算,则改为7(3*2),在这里的括号则属于解释性的括号。对于优先级设定十分清楚的开发人员而言,完全可以不必加上解释性括号,但是我们还是建议加上解释性括号,这可以增强程序的可读性和易维护性,也是一种良好的编程风格。
dyle_gg,2004-12-02 14:15:52
第3章 VBScript语句和过程
前面的章节中已经详细地介绍了有关VBScript语句的数据类型、常量、变量,但是,仅仅了解这些知识还是远远不够的,也无法完成符合用户需求的页面。所以,在这一章节中我们将进一步学习VBScript的知识,主要包括VBScript的一些基本语句,如选择语句和循环语句等,以及在VBScript中使用过程的具体方法等。学习这些知识也有助于读者加深对不同程序结构的理解。
3.1 VBScript语句中的基本语句
对于一般程序,有三类基本的程序结构可以控制程序的流程:顺序结构,分支结构和循环结构。顺序结构的流程是按照事务完成的先后次序依次执行语句,而且总是在完成前一句语句之后再执行后一句语句,并且执行过的语句不再执行,这就与分支结构和循环结构有所区别。分支结构相当于在实际生活中,我们对于判断进行选择一样,如果出现某些情况,我们将会如何做,如果不出现这些情况,我们将作如何打算。但是在程序中,分支结构并不一定只有“是”或“否”这两种选择,也可以存在多种选择的结构。循环结构是对于某一些语句进行反复执行,循环语句结束的关键往往是:当符合某些条件,或不符合某些条件,或在重复执行一定次数之后。一般而言,任何程序总是同时包含这三种结构来对程序的流程进行控制。在VBScript语句中,顺序结构最简单,一般不需要程序进行什么控制;分支结构可以使用选择语句来实现;循环结构可以使用循环语句来实现。在下文中将具体介绍选择语句和循环语句。
需要指出的是,在许多结构化语言中,一般来说不提供Goto语句直接在程序中跳转,因为这将会极大地损害程序的可读性,另外有一些结构化语言虽然提供了Goto语句,但是不建议使用这条语句,而是建议使用Break、Continue等跳转语句来代替,这些语句和Goto语句不同之处就在于,Goto语句是任意跳转的,而Break、Continue语句并不能任意跳转,只是实现了循环的中断退出功能。VBScript也不支持Goto语句,但在VBScript中,提供了Exit语句和On Error语句来实现程序流程的跳转。
3.1.1 选择语句
在VBScript中,有两种条件语句:If…Then…Else语句和Select…Case语句(表3.1),这两种条件语句执行的时候,先对条件进行判断,然后根据条件执行相应的脚本。If…Then…Else语句只会形成两重分支,如果条件满足,执行其中的一个分支,如果条件不满足,则执行其中的另外一个分支。Select…Case语句会形成多重分支,根据条件的结果选择其中相应的分支执行。
表3.1 VBScript语句中的分支语句
If...Then...Else语句 二值分支语句
Select Case语句 多值分支语句
3.1.1.1 使用If...Then...Else语句
VBScript中最常用的条件语句就是If…Then…Else语句,一般If…Then…Else语句用来检查一个布尔条件,然后根据结果为True或者False执行相应的脚本,如果为True,则执行Then后面的脚本,如果为False,则执行Else后面的脚本。
If…Then…Else语句有两种形式:单行形式和多行形式(也称块形式),单行形式中整条语句都需要在一行中完成,其中也包括条件和判断后执行的脚本,其语法如下所示:
If condition Then statements [Else elsestatements]
多行形式的语法如下所示:
If condition Then
statements
[Else
elsestatements]
End If
其中,condition是测试条件,statements是条件为True的情况下所执行的脚本,elsestatements是条件为False的情况下所执行的脚本,如果条件为Null,那么执行的脚本仍然是elsestatements。通常情况下,测试条件是使用比较运算符对值或变量进行比较的表达式。在这两种语法中,Else都是可选的,如果没有Else,则表明如果判断条件为True,执行Then后面的脚本,如果条件为False,则不执行任何脚本。
注意:在多行形式中,语句结束的最后一行中有一句End If,而单行形式则不需要。
对于比较短小而简单的测试,我们可以使用单行形式。例如,如果学生成绩大于60分,则判定成绩为Pass,否则判定其成绩为Fail,如以下脚本所示:
If Score >= 60 Then Status = “Pass” Else Status = “Fail”
不过,在编写脚本的过程中,多行形式比单行形式的结构化更强,更加容易阅读、维护和调试。对于上面单行形式的语句,我们可以改写为多行形式如下:
If Score >= 60 Then
Status = “Pass”
Else
Status = “Fail”
End If
在VBScript中,还可以扩展If…Then…Else语句的功能,通过添加ElseIf子句,我们可以对多个条件进行判断和分支选择,其语法如下所示:
If condition Then
statements
ElseIf conditin-n Then
elseifstatements
Else
elsestatements
End If
在条件语句中,如果条件是True时要执行多个语句,条件是False时也需要执行多个语句的时候,则就可以使用If...Then...Else语句来定义两个语句块:在Then后面的语句块在条件是True时被执行;在Else后面的语句块在条件是False时被执行。
Dim nTemp1, nTemp2
Dim nBigValue, nSmallValue
nTemp1 = CDbl ( InputBox ( “请输入第一个数值:” ) )
nTemp2 = CDbl ( InputBox ( “请输入第二个数值:” ) )
If ( nTemp1 > nTemp2 ) Then
nBigValue = nTemp1
nSmallValue = nTemp2
Else
nBigValue = nTemp2
nSmallValue = nTemp1
End If
有时候,单个条件语句并不能满足在多种选择中做決定,所以用户要采用If...Then...Else 语句的变形,从多种选择中选取一种选择。这种变形形式是在原来的条件语句上加上ElseIf子句,以扩充其原有的功能,这样能让用户的程序有多种不同的流程,方便了对于程序代码行的控制。举例如下:
Sub ReportValue(value)
If value = 0 Then
MsgBox value
ElseIf value = 1 Then
MsgBox value
ElseIf value = 2 then
Msgbox value
Else
Msgbox "Value out of range!"
End If
用户可以根据需要加上多个ElseIf子句以提供其它选项。但是,有时ElseIf子句用得太多,也常常会变成一种麻烦。经常我们所采用的方法是使用可以进行多种选择的Select Case语句。
3.1.1.2 使用Select Case 语句
如果需要实现多重分支选择,一般我们使用Select Case语句,而不使用If…Then…Else语句,尽管后者也完全能够实现这些功能。Select Case语句的功能就是根据表达式的值执行几组脚本当中的一组。其语法如下所示:
Select Case testexpression
Case expressionlist
statements…
Case Else expressionlist
elsestatements
End Select
其中,testexpression是语句的判断条件,可以是任何数值或者字符串表达式,expressionlist则是可能出现的表达式的值,statements和elsestatements是根据表达式结果执行的脚本。
如果testexpression的表达式结果和某一个Case子句中列举的值相符合,那么则执行这一个Case子句和下一个Case子句之间的脚本,如果和任何列举出的值都不符合,则执行Case Else子句和End Select之间的脚本,如果再没有Case Else语句,那么将会直接执行End Select之后的脚本。如果表达式的结果和多个Case子句中的值相符合,则只会执行第一个匹配后的语句。
其实,Select Case语句提供了除了 If...Then...ElseIf 以外的另外一种条件语句的形式,可允许用户从多个语句块中作出一个选择,并执行相应的语句。Select Case 语句提供的功能和 If...Then...Else 语句类似,但它可使整个程序代码行执行起来更加的有效率,而且也提高了程序的可读性。
Select Case语句在其前端,即Select Case子句后有一个测试运算式,这个运算式只会被执行一次。执行完后的结果将被用来和每一个 Case子句的值作比较。如果有相符的情况时,这个Case 子句后的语句块就将被执行,注意下面这个例子:
Select Case Document.Form1.CardType.Options(SelectedIndex).Text
Case "MasterCard"
DisplayMCLogo
ValidateMCAccount
Case "Visa"
DisplayVisaLogo
ValidateVisaAccount
Case "American Express"
DisplayAMEXCOLogo
ValidateAMEXCOAccount
Case Else
DisplayUnknownImage
PromptAgain
End Select
从上面的程序中可以注意到Select Case 语句只在前端执行一个运算式。而与此相反的是,If...Then...ElseIf条件语句则可在每一个ElseIf语句后面加上一个不同的比较运算式。对于这种格式的语句,只有在每一个ElseIf语句使用的都是同一个运算式时,才能用Select Case语句来取代If...Then...ElseIf语句。
与If语句相同,Select Case语句也可以嵌套,只是对于每一层嵌套的Select Case语句中必须有与其相对应的End Select语句。
3.1.2 循环语句
使用循环语句可以反复执行某段脚本,直到满足循环结束条件后才停止。如表3.2所示,在VBScript中,提供了四种循环语句:For…Next语句、Do…Loop语句、While…Wend语句和For Each…Next语句。在这四种循环语句中,For Each…Next语句是比较特殊的一种,它不是指定循环的次数、也没有指定循环的结束条件,而是提供了枚举集合中元素的一种方法。运用循环语句,可以极大地方便我们开发脚本的工作。
表3.2 VBScript语句中的循环语句
Do...Loop 当条件是 True 时执行循环,也可以是执行到条件为 True 时,停止循环。
While...Wend 当条件是 True 就执行循环。
For...Next 使用一个计数器,让语句重复执行某个固定的次数。
For Each...Next 对每个集合对象中的项目或数组中的元素重复执行一次循环。
3.1.2.1 For…Next语句
For…Next语句在循环的过程中,可以指定循环运行的次数,当到达循环运行次数之后,退出循环。其语法如下所示:
For counter = start To end Step stepsize
statements
Next
其中,counter是用作循环计数器的数值变量,start是循环变量的初值,end是循环变量的终值,stepsize是循环变量的步长,在默认条件下stepsize=1,statements是循环内反复执行的脚本。
在执行For…Next语句有以下几个步骤:
1. 将初值赋给循环变量,即执行counter=start;
2. 判断循环条件,如果循环步长大于等于0,则循环条件是counter<=end,如果循环步长小于0,则循环条件是counter>=end,如果循环条件为True,则执行循环中的语句,如果循环条件为False,则跳出循环;
3. 执行循环代码,再将步长累加到循环计数器上,即执行counter=counter+stepsize,然后返回步骤2判断循环条件。
举个例子。下面的程序会计算从1到50所有数值相乘的结果。这个For语句指定了一个计数器I,同时指定了该计数器的起始值和结束值。Next语句会使计数器的值在每次循环执行时自动递增1。使用Visual Basic的编程人员注意,在VB语句中的For语句在Next语句之后必须跟有作为计数器的变量,而在VBScript语句中,该变量不必再写了。
Dim I, nResult
nResult = 1
For I = 1 To 50
nResult = nResult * I
Next
MsgBox “结果为:” & nResult
使用Step关键字,用户就可以随自己的需要来递增或是递减计数器变量。在下面的例子中,计数器变量j会在每次循环执行后递增2。当循环执行完时,变量nResult將是2、4、6、8和10的总和。
Dim j, nResult
nResult = 0
For j = 2 To 10 Step 2
total = total + j
Next
MsgBox “结果为:” & nResult
如果用户要使计数器变量递减时,则可以使用负的Step值。此时,结束值必须小于起始值。在下面例子中,计数器变量myNum会在每次循环执行过后递减2。当这个循环结束时,变量total的值将会是16、14、12、10、8、6、4和2的总和。
Dim nStep nResult
nResult = 0
For nStep = 16 To 2 Step -2
nResult = nResult + nStep
Next
MsgBox “结果为:” & nResult
用户可以使用Exit For语句在计数器到达其结束值之前跳离For...Next语句。因为通常用户只会希望在某些特定的情形发生时,才要跳离循环,比如像发生了错误时。所以用户应该把Exit Do语句放在If...Then...Else语句的Then子句之后的语句中。当条件是False时,循环就会照常执行。
需要指出的是,VBScript和Visual Basic的Next语句在使用上有所不同,Visual Basic中,Next语句后一般要求一个循环变量,但在VBScript中,Next语句后不要求循环变量,如果后面有循环变量,反而会导致错误的出现。
一般情况下,我们不建议在循环执行的过程中,使用语句改变循环计数器的值,因为这样会使得脚本的可读性变差,代码的调试和维护工作都会变得困难得多。
在循环中,我们还可以使用循环嵌套,不过循环嵌套的过程中,要求各重循环计数器的变量不同,例如:
For I = 1 To 10
For J = 1 To 10
……
Next
Next
3.1.2.2 Do…Loop语句
Do…Loop语句和For…Next语句有所不同,For…Next语句中,循环执行的次数是确定的,而Do…Loop中,循环执行的次数则往往是不确定的,如果循环条件为True或者循环条件变为True,循环将会一直执行。
Do…Loop语句有两种形式:Do While/Until…Loop和Do…Loop While/Until。
我们先来看第一种形式。Do While/Until…Loop的语法如下所示:
Do { While|Until} condition
statements
Loop
其中,condition是循环执行条件,statements是循环内反复执行的脚本。
Do While/Until…Loop循环的执行步骤如下所示:
1. 如果是Do While…Loop循环,则判断condition是否满足,如果满足,则进入步骤2执行循环内脚本,否则跳出循环;如果是Do Until…Loop循环,则判断condition是否不满足,如果不满足,则进入步骤2执行循环内脚本,如果满足condition,则跳出循环;
2. 执行循环中脚本,然后返回步骤1。
在Do...Loop语句中,需用While关键字来检查条件。用户可以在进入循环之前就先检查条件,或在循环至少执行过一次之后再检查,比如下面的ChkLastWhile例子。在ChkFirstWhile程序中,如果myNum不是设成20,而是设成9,那么在循环中的语句就永远不会被执行。在ChkLastWhile程序中,循环里的语句只会被执行一次。因为它的条件已经是False了。
Sub ChkFirstWhile()
Dim counter, myNum
counter = 0
myNum = 20
Do While myNum > 10
myNum = myNum - 1
counter = counter + 1
Loop
MsgBox "The loop made " & counter & " repetitions."
End Sub
Sub ChkLastWhile()
Dim counter, myNum
counter = 0
myNum = 9
Do
myNum = myNum - 1
counter = counter + 1
Loop While myNum > 10
MsgBox "The loop made " & counter & " repetitions."
End Sub
而如果我们将上述脚本中的While改为Until,再执行这段脚本,我们则会发现执行结果不一样了。这是由于Do Until…Loop中,在执行循环内代码前先判断循环条件是否不满足,只有在不满足的情况下,Do Until…Loop才会执行循环内脚本,而如果满足,则循环内代码一次也不会执行。
在Do...Loop语句中,用户有两种方法来使用Until关键字检查条件。用户可以在进入循环前先检查条件,或在循环至少执行过一次后再检查(如下面的ChkLastUntil例子)。只要在条件是False时,循环就会执行。
Sub ChkFirstUntil( )
Dim counter, myNum
counter = 0
myNum = 20
Do Until myNum = 10
myNum = myNum - 1
counter = counter + 1
Loop
MsgBox "The loop made " & counter & " repetitons."
End Sub
Sub ChkLastUntil()
Dim counter, myNum
counter = 0
myNum = 1
Do
myNum = myNum + 1
counter = counter + 1
Loop Until myNum = 10
MsgBox "The loop made " & counter & " repetitions."
End Sub
我们再来看第二种形式。Do…Loop While/Until的语法如下所示:
Do
statements
Loop { While|Until} condition
其中,condition是循环执行条件,statements是循环内反复执行的脚本。
Do…Loop While/Until循环的执行步骤如下所示:
1. 执行循环中脚本;
2. 对于Do…Loop While循环,则判断condition是否满足,如果满足,返回步骤1执行循环内脚本,否则跳出循环;如果是Do…Loop Until循环,则判断condition是否不满足,如果不满足,则返回步骤1执行循环内脚本,如果满足condition,则跳出循环。
如果我们将上述脚本中的While改为Until,再执行这些脚本,我们就会发现结果和Do Until…Loop的结果有所不同。这是由于在Do…Loop Until循环中,首先将执行一次循环内脚本,然后再对循环条件进行判断,这也就是说,不论循环条件如何设定,Do…Loop While/Until循环都将至少执行一次循环内的脚本。
注意,在Do…Loop循环中一定要有改变循环条件中变量的语句,否则,很有可能会陷入死循环而不能终止。就技术上来说,用户可以在Do...Loop中使用Exit Do语句来跳离循环。因为通常用户只会希望在某些特定的情形发生时,才需要跳离循环语句,比如像要避免死循环时,用户应该把Exit Do语句放在If...Then...Else语句的Then之后的语句块中。当条件是False时,循环就会照常执行,而当条件为True时,即满足离开循环的条件时,将执行Exit Do语句。
在下面的例子中,myNum将会被指定成一个会造成无限循环的值。其中的If...Then...Else语句将会检查这个条件,以避免无限死循环的发生。
Sub ExitExample()
Dim counter, myNum
counter = 0
myNum = 9
Do Until myNum = 10
myNum = myNum - 1
counter = counter + 1
If myNum < 10 Then Exit Do
Loop
MsgBox "The loop made " & counter & " repetitions."
End Sub
3.1.2.3 While…Wend语句
While…Wend语句和Do…Loop语句十分类似,但不如Do…Loop语句那样灵活,在While…Wend语句中,如果条件为True,则执行循环内脚本。其语法如下所示:
While condition
statements
Wend
其中,conditin是循环执行条件,statements是循环内执行的脚本。
While…Wend语句的执行步骤如下所示:
1. 判断condition是否为True,如果为True,则进入步骤2执行循环内脚本,如果为False或者为Null,则跳出循环;
2. 执行循环中脚本,然后返回步骤1。
与Do … Loop语句不同的是,While循环语句没有任何可以跳离循环的语句,用户不能想当然地使用Exit While语句。
不过,和Do…Loop语句比较而言,While…Wend语句的灵活性要差一些,脚本的清晰程度则是相同的,所以我们建议,在同样的情况下,还是使用Do…Loop语句。
3.1.2.4 For Each…Next语句
For Each…Next语句和上述三个循环语句都有所不同,它既不指定循环执行的次数,也不指定循环结束条件,而是对数组和集合中的元素进行枚举,当枚举结束之后才会退出循环。其语法如下所示:
For Each element In group
statements
Next
其中,group是我们进行枚举的数组或者集合,element是枚举变量的名称,statements是对于每个元素都会执行的循环脚本。
For Each...Next和For...Next循环非常相似。它们的不同之处在于,For Each...Next循环是针对集合对象中的每一个对象或数组中的每一个元素重复执行一次循环,而ForEach...Next循环语句是依指定的数字重复执行循环的次数。当用户不知道集合对象中有几个元素时,For Each...Next循环语句将会特別的有用。
在下面的HTML程序范例中,Dictionary对象的功能是要将文字放到数个文本框中:
<HTML>
<HEAD>
<TITLE>简单例子</TITLE>
</HEAD>
<SCRIPT LANGUAGE="VBScript">
<!--
Sub btnFill_OnClick
Dim d ‘定义一个对象变量
Set d = CreateObject("Scripting.Dictionary") ‘建立一个Dictionary对象
d.Add "0", "Sanders" ‘将有关信息放入该对象之中
d.Add "1", "Shirley"
d.Add "2", "Winfred"
For Each I in d
Document.Form.Elements(I).Value = D.Item(I)
‘将文字放入文本框之中
Next
End Sub
-->
</SCRIPT>
<BODY>
<CENTER>
<FORM NAME="Form"
<Input Type = "Text"><p>
<Input Type = "Text"><p>
<Input Type = "Text"><p>
<Input Type = "Text"><p>
<Input Type = "Button" NAME=btnFill VALUE="填入信息"><p>
</FORM>
</CENTER>
</BODY>
</HTML>
3.1.2.5 Exit语句
在结构化程序设计的过程中,Goto语句的取消可以极大地增强程序的可读性,便于程序的阅读与维护,不过,也不可避免带来了一些不足之处。在某些循环嵌套的程序中,在合适的地方使用Goto语句能够使程序显得简洁明了,并且代码效率高,在禁止使用Goto语句的场合中,虽然不使用Goto语句也完全能够实现同样的功能,但是却使得程序的可读性和代码效率形成了一种矛盾,要么追求代码的高效率而使得程序晦涩难懂,要么追求程序结构清晰而降低了代码的效率。所以在C语言中提供了break、continue、Exit等半结构化语句,这些语句能够实现一定的跳转功能,保持代码的高效,也能够使得程序保持较强的可读性。
在VBScript中也提供了类似的语句,使用Exit语句能够停止程序当前正在执行的逻辑,退出循环或者当前过程。它能够退出Do…Loop、For…Next循环,也能够退出Function和Sub的过程处理,关于Function定义的函数和Sub定义的过程,我们会在下一节中介绍。
Exit语句有以下四种语法形式:
1. Exit Do:提供了一种退出Do…Loop循环的方法,Exit Do只能在Do…Loop语句中使用,执行Exit Do语句之后将控制权转移到Loop语句之后。
2. Exit For:提供了一种退出For循环的方法,Exit For语句只能在For…Next语句或者For Each…Next循环中使用,执行Exit For语句之后将控制权转移到Next语句之后。
3. Exit Function:执行Exit Function语句之后退出当前函数。
4. Exit Sub:执行Exit Sub语句之后退出当前过程。
例如,我们可以使用Exit Do语句实现一个死循环中的退出,在下面的脚本中,当循环计数器大于10之后,退出循环处理,而循环本身并不具备结束循环的功能:
counter = 0
Do While True
counter = counter + 1
If counter > 10 Then Exit Do
Loop
当然上面的脚本完全不需要使用Exit Do语句,但是在许多场合中,使用Exit语句之后能够显著提高脚本的执行效率。
3.2 VBScript语句中的过程
掌握了一些基本概念后,程序设计和编制就变成了一个不断重复的过程。用户需要多次重复某些步骤,或是某些语句来完成某一所需处理的任务。出于程序的可读性、可调试性和简单性的考虑,在实际的编程过程中,我们会将这些用于实现某一特定功能,而且相对集中的语句放在一个子程序中,称为过程。在过程中的语句一般和其他过程中的语句,或和主程序(相对于子程序而言)中语句没有什么直接联系。在VBScript中,过程被分为两类:Sub过程和Function过程。前面的举例程序中我们已经接触过这两个过程,但我们没有展开介绍。下面就具体谈谈这两种类型的过程。
3.2.1 Sub过程
Sub过程是由一些功能实现相对集中的VBScript语句组成。这些语句以Sub语句作为过程的开头,以End Sub语句作为其结束。这些语句被执行操作时并不返回任何数值,这一点和后面所谈到的Function过程有本质的区别,所以有些书上也将Sub过程称为子程序。Sub过程可以使用参数(由调用过程的主程序将所需的常量、变量或表达式传递给过程)。如果Sub过程无任何参数,则Sub语句必须包含空括号( ),该括号不能省略。
比如我们希望写一段程序,用于弹出一个对话框,并在对话框上显示一段提示信息。在这个程序中,关于对话框的实现在程序的任何地方都是一致的,所不同的是相应的提示信息。我们可以写一段Sub过程,来处理这一特定的功能。
<SCRIPT LANGUAGE="VBScript">
<!--
Sub CreateMessageBox( strInfo )
Dim strComplete
StrComplete = “提示信息:” & strInfo & “!”
MsgBox strComplete
End Sub
-->
</SCRIPT>
在这段程序中,CreateMessageBox是过程名称,strInfo是参数,整个过程包含在Sub和End Sub之中。该过程相当简单,只有三行语句。第一句定义了一个变量strComplete,该变量将用于对话框上的提示信息;第二句是根据参数的内容组织成一个完整的提示信息,并将该值赋给变量strComplete;第三句是将该信息用对话框的形式来提供给用户。
以后用户在程序中的任何地方只要写:
CreateMessageBox “Hello, World”
或者
Call CreateMessageBox (“Hello, World”)
即可调用该过程。
对于通过值传递的参数,在调用过程的时候,VBScript会在过程内部暂时建立一个变量,并将参数值复制给这个变量,这样就可以把过程外部的数值传递到过程内部中,不过这个变量只是在过程内部有效的,在脚本中改变变量的值的时候,并不会对参数造成任何影响,当脚本结束过程调用的时候,这个变量将被删除。
而对于通过地址传递的参数,在调用过程的时候,VBScript将参数的地址传递到过程中去,过程中的变量名称实际是对于这一块地址的引用,当过程中变量的值发生变化的时候,也就意味着该地址中的数据发生了变化。
在脚本中调用过程有两种方法:一种是使用Call语句的显式调用,另外一种是不使用Call语句的隐式调用。这两种调用方法的效果其实是一样的,隐式调用的时候,只需要在脚本中输入过程的名称和参数的名称就可以了,参数之间用逗号进行分隔,而在显式调用的时候,必须在过程名称之后加上括号,并且使得参数包含在括号中,即:
CreateMessageBox “Hello, World”
Call CreateMessageBox (“Hello, World”)
上面的两条语句中,前面一条语句是过程的显式调用,后面是隐式调用。
在过程执行的时候,如果希望满足某种条件后直接退出过程的处理逻辑,返回主程序,我们可以使用Exit Sub语句,执行Exit Sub语句,脚本的执行将立即从过程中退出,这样可以极大地方便我们脚本的编写,提高程序的灵活性。
在Windows操作系统中,由于采取的是一种使用消息机制来驱动程序,所以我们往往将一些对于消息或是事件的处理语句作为一个Sub过程。关于消息机制和事件驱动的概念由于不是本书的内容,这里不再赘述。如果需要了解这方面内容,可以参阅有关Windows编程的书籍。在这里我们只需要知道触发某一事件之后的代码写在哪个Sub过程中即可。
请看下面这个例子。我们要放置一个按钮,按下这个按钮之后将会弹出一个对话框。这是一个简单的程序,但这个程序反映了如何使用控件和Sub过程。我们首先要在页面上放置一个按钮,代码如下:
<INPUT id=btnMsg name=btnMsg type=button value="提示信息">
该语句定义了一个按钮,该按钮的名字为btnMsg,按钮上的文字为“提示信息”。
<SCRIPT LANGUAGE="VBScript">
<!--
Sub btnMsg_onClick()
Dim MsgInfo
MsgInfo = “Hello, World”
CreateMessageBox MsgInfo
End Sub
-->
</SCRIPT>
这段语句是用于在按下按钮之后所需要执行的代码。由于在VBScript中不像MFC中对于任何的Windows消息有相应的消息映射,而是简化成了一些直观的过程。这些过程往往在名称上就直接反映了其与各类消息之间的联系。例如在上述的例子中我们就可以看到关于btnMsg按钮的点击事件中的语句是写在一个名为btnMsg_onClick( )的过程中,其中btnMsg是按钮的名称,onClick说明了在该按钮点击后所需要响应的代码。我们可以根据这个例子触类旁通,知道凡是带有这样结构命名的Sub过程都是系统指定的消息函数,希望用户自定义的函数不要和该名称冲突。在该过程中,又调用了上述定义的CreateMessageBox过程,当然该语句也可以写成Call CreateMessageBox(MsgInfo),注意,括号不要漏掉。
3.2.2 Function过程
Function过程与Sub过程相类似,也是由一系列VBScript语句所组成,这些语句是以Function语句作为该Function过程的开头标记,以End Function语句作为结束。Function过程在操作执行结束后,可以返回值,这一点和Sub过程相区别,所以有的书上将Function过程称为函数,以与子程序相对应。在本书中,仍然称作Sub过程和Function过程。Function过程可以使用参数(由调用过程的主程序将过程所需要的常量、变量或表达式传递给过程)。如果Function过程无任何参数,则Function语句必须包含空括号( )。Function过程通过函数名返回一个值,这个值是在过程的语句中赋给函数名的。Function返回值的数据类型总是Variant。这一点和其他的程序中所定义的函数返回类型所不同。调用Function过程时,函数名必须用在变量赋值语句的右端或表达式中。
这里有一个简单的例子,但基本上反映了Function过程的使用情况:
<SCRIPT LANGUAGE="VBScript">
<!—
Function AddSum(Value1, Value2)
AddSum = Value1 + Value2
End Function
-->
</SCRIPT>
最后对于Function过程要说明的是,Function过程的返回值是直接对于该过程名称进行赋值,而不是像其他语言中使用Return语句。
dyle_gg,2004-12-02 14:16:37
3.2.3 参数说明
关于过程引用的参数,这里还需要说明的是,参数作为主程序和过程之间进行数据通信的途径和手段而存在。参数名可以是任何有效的变量名。使用Sub语句或Function语句创建过程时,过程名之后必须紧跟括号。括号中包含所有参数,参数间用逗号分隔。
要从过程中获取数据,必须使用Function过程。请记住,Function过程可以返回值;Sub过程不返回值。但是如果我们要求一个过程返回多个数值的时候,只依靠Function过程返回的一个数值是远远不够的,在这种情况下,有些C++编程人员会使用指针参数来解决这个问题,而在VBScript语句中,并没有指针类型这个概念,但我们依然可以使用相类似的方法来解决这个问题。这时候我们只需要在过程的参数前面加上ByRef的关键字,该参数如果在过程中被修改,在主程序中相对应的变量的值也将被修改;如果在参数前面什么也不加,或是加上ByVal,即使该参数在过程中被改变,也不会影响到主程序中的变量。这是因为ByRef是将变量的引用传递给过程,这样主程序和过程中调用的是同一个变量;而使用ByVal或则什么也不使用,则是将主程序中的变量的副本传递给过程,这样在过程中,该参数即使改变,也只是改变这个变量的副本,在过程结束后,这个副本将随之一起消失,那么其对于主程序的变量而言是没有一点影响的。这样我们可以使用ByRef关键字来进行主程序和过程之间多个数值的传递。
看一下下面这个例子,这个例子中我们需要写一个函数,该函数是要将两个数值进行相加,然后对于每个相加的加数进行自增运算。如果不使用ByRef关键字,我们是无法在一个函数中同时返回三个数值的。
<SCRIPT LANGUAGE="VBScript">
<!--
Function AddSum(ByRef Value1, ByRef Value2)
AddSum = Value1 + Value2
Value1 = Value1 + 1
Value2 = Value2 + 2
End Function
Sub btnSum_onClick()
Dim a,b
a = 10
b = 20
txtSum.value = AddSum(a,b)
End Sub
-->
</SCRIPT>
由于AddSum函数中使用了在每个加数前都使用了ByRef关键字,所以该加数在AddSum函数中修改其值,将直接影响到主程序中a和b的值。完整的程序如下:
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE></TITLE>
<SCRIPT LANGUAGE="VBScript">
<!--
Function FillterNum(NumValue)
If (IsNumeric(NumValue)) Then
FillterNum = NumValue
Else
FillterNum = 0
End If
End Function
Function AddSum(ByRef Value1, ByRef Value2)
AddSum = Value1 + Value2
Value1 = Value1 + 1
Value2 = Value2 + 2
End Function
Sub btnSum_onClick()
Dim a,b
a = FillterNum(txtValue1.value)
b = FillterNum(txtValue2.value)
txtSum.value = AddSum(a,b)
txtValue1.value = a
txtValue2.value = b
End Sub
-->
</SCRIPT>
</HEAD>
<BODY>
<P>数值1 = <INPUT id=txtValue1 name=text1
></P>
<P>数值2 = <INPUT id=txtValue2 name=text2
></P>
<P>总和 = <INPUT id=txtSum name=text3></P>
<P><INPUT id=btnSum name=button1 type=button value="自增求和"></P>
</BODY>
</HTML>
该程序中的FillterNum函数是一个用于处理文本框中输入信息,约束该信息必须为数值信息,否则作为0处理。
该程序中使用浏览器打开,将会出现三个文本框和一个按钮。在第一和第二个文本框中填入数值,按下按钮,在第三个文本框中将会出现上面两个文本框的数值之和,而第一和第二个文本框中的数值也会进行自增操作。如果用户有兴趣,可以将AddSum函数中参数前的ByRef该为ByVal,或是干脆去掉,再看一下效果,就会对上述文字有进一步的了解。
3.2.4 相关语句的语法
在本章节中使用到一些语句,这些语句主要用于过程的调用和定义。
3.2.4.1 Call语句
调用Sub过程时,可以使用Call语句。在调用过程时,不必使用Call关键字。然而,如果使用Call关键字调用要求参数的过程,则必须用括号将argumentlist括起来。如果省略Call关键字,那么必须也同时省略argumentlist参数两边的括号。使用Call语法调用内部函数或使用用户自定义函数,函数返回值都会被放弃。
Call 语句的语法:
[Call ] name [argumentlist]
各组成部分的解释见表3.3。
表3.3 Call 语句语法的组成部分:
组成部分 描述
Call 可选关键字。如果指定此关键字,则必须用括号把 argumentlist 括起来。
Name 必选。要调用的过程名。
Argumentlist 可选。传递给过程的变量、数组或表达式列表,用逗号分隔每一项。
3.2.4.2 Function语句
该语句用于声明Function过程的名称、参数以及构成其主体的代码。
如果在该语句中没有明确指定使用Public或Private,则Function过程默认为公用,即它们对于Script中的所有其他过程是可见和可用的。Function中局部变量的值在对过程的调用中不被保留。
此外,所有可执行的代码必须包含于过程中,用户不能在另一个Function或Sub过程中定义Function过程。
使用Exit Function语句可以从Function过程中立即退出,而程序将继续执行调用Function过程的语句之后的语句。用户可在Function过程的任何位置出现任意个Exit Function语句。
与Sub过程类似,Function过程是可以获取参数、执行一系列语句并改变其参数值的独立过程。与Sub过程的不同之处是:当要使用由函数返回的值时,可以在表达式的右边使用Function过程,这与内部函数的使用方式一样,例如Sqr、Cos或Chr。
在表达式中,可以通过使用函数名,并在其后用圆括号给出相应的参数列表来调用Function过程。有关调用Function过程的详细信息,请参阅Call语句。
需要注意的是,Function过程可以是递归的,即该过程可以调用自身以完成某个给定的任务。但是,递归可能会导致堆栈溢出。
如要从函数返回一个值,则将值赋给函数名即可。在过程的任意位置都可以出现任意个这样的赋值。如果没有给name赋值,则过程将返回一个默认值:数值函数返回0,字符串函数返回零长度字符串(" ")。如果在Function中没有对象引用被指定给name(使用Set),则返回对象引用的函数将返回Nothing。
在Function过程中使用的变量分为两类:一类是在过程内显式声明的,另一类则不是。在过程内显式声明的变量(使用Dim或等效方法)总是过程的局部变量。被使用但没有在过程中显式声明的变量也是局部变量,除非在该过程外更高级别的位置显式声明它们。
过程可以使用没有在过程内显式声明的变量,但如果在Script级中任何定义的名称与之相同,则会发生名称冲突。如果过程中使用的未声明的变量与另一个过程、常量或变量的名称相同,则会认为过程使用的是Script级的名称。显式声明变量可以避免这类冲突。可以使用Option Explicit语句来强制显式声明变量。
VBScript可能会重新排列数学表达式以提高内部效率。当Function过程修改数学表达式中变量的值时,应避免在同一表达式中使用该函数。
Function语句的语法:
[Public | Private] Function name [(arglist)]
[statements]
[name = expression]
[Exit Function]
[statements]
[name = expression]
End Function
Function 语句的语法包含表3.4所示的各部分。
表3.4 Function 语句的语法组成
组成部分 说明
Public 表示Function过程可被所有Script中的所有其他过程访问。
Private 表示Function过程只可被声明它的Script中的其他过程访问。
Name Function的名称,遵循标准的变量命名约定。
Arglist 代表调用时要传递给Function过程的参数的变量列表。用逗号隔开多个变量。
Statements 在Function过程的主体中执行的任意语句组。
Expression Function的返回值。
arglist参数包含下列语法和部分(表3.5):
[ByVal | ByRef] varname[( )]
表3.5 arglist语法的组成部分
组成部分 说 明
ByVal 表示该参数按值传递。
ByRef 表示该参数按引用传递。
Varname 代表参数变量的名称;遵循标准的变量命名约定。
3.2.4.3 Sub语句
该语句用于声明Sub过程的名称、参数以及构成其主体的代码。
如果在定义Sub过程中,没有明确指定使用Public或Private,则Sub过程默认为公用,即它们对于Script中的所有其他过程都是可见的。
所有可执行代码必须包含于过程中。不能在另一个Sub或Function过程中定义一个Sub过程。
使用Exit Sub语句可以立即从Sub过程中退出。程序继续执行调用Sub过程的语句之后的语句。可以在Sub过程中任意位置出现任意个Exit Sub语句。
与Function过程相似之处是:Sub过程是一个可以获取参数,执行一系列语句以及可改变其参数的值的独立过程。而与Function过程不同之处是:Function过程可以返回值,而Sub过程不能用于表达式中。
可以使用过程名并跟随相应的参数列表来调用Sub过程。关于如何调用Sub过程的详细说明信息,请参阅Call语句。
需要说明的是,Sub过程可以是递归的,即该过程可以调用自己来完成某个给定的任务。但是递归可能会导致堆栈溢出。
在Sub过程中使用的变量分为两类:一类是在过程内显式声明的,另一类则不是。在过程内显式声明的变量(使用Dim或等效方法)总是局部变量。对于那些没有在过程中显式声明的变量也是局部的,除非在该过程外更高级别的位置显式地声明它们。
另外,过程可以使用没有在过程内显式声明的变量,但只要有任何script级定义的名称与之同名,就会产生名称冲突。如果过程中引用的未声明的变量与其他的过程、常量或变量的名称相同,则会认为过程引用的是Script级的名称。显式声明变量可以避免这类冲突,使用Option Explicit语句可强制显式声明变量。
Sub语句的语法如下,组成见表3.6。
[Public | Private] Sub name [(arglist)]
[statements]
[Exit Sub]
[statements]
End Sub
表3.6 Sub 语句的语法的组成部分
组成部分 说明
Public 表示Sub过程可被所有Script中的所有其他过程访问。
Private 表示Sub过程只可被声明该过程的Script中的其他过程访问。
Name Sub的名称,遵循标准变量命名约定。
arglist 代表在调用时要传递给Sub过程的参数的变量列表。用逗号隔开多个变量。
statements 在Sub过程主体内所执行的任何语句组。
arglist参数包含下列语法和部分(表3.7):
[ByVal | ByRef] varname[( )]
表3.7 arglist语法的组成部分
组成部分 说明
ByVal 表示该参数按值传递。
ByRef 表示该参数按引用传递。
varname 代表参数变量的名称;遵循标准的变量命名约定。
3.3 综合例子
学习了上述的基本语句和过程的使用方法,现在来看一个例子,以帮助大家对于已经学习过的知识加深了解。
下面这个例子是可以允许用户提供开始值和终止值,计算这些数值的连加或连乘;同时也允许用户进行页面背景颜色的调整。
首先我们完成计算功能,在页面上放置三个文本框,这三个文本框分别用于允许用户填入开始数值,终止数值,以及返回显示计算结果。再放置一个多行选择列表框,可以选择连加或是连乘的不同功能。三个文本框的名称分别为:txtBegin,txtEnd,txtResult;列表框的名称为:selectOption。所有的控件的属性都采用默认值。
<P>起始值:
<INPUT id=txtBegin name=txtBegin
style ="HEIGHT: 22px; WIDTH: 60px">
终止值:
<INPUT id=txtEnd name=txtEnd
style ="HEIGHT: 22px; WIDTH: 60px">
</P>
<P>计算功能:</P>
<P>
<SELECT id=selectOption name=selectOption
size = 2>
</SELECT>
</P>
<P>计算结果:
<INPUT id=txtResult name=txtResult>
</P>
下面的代码可以对于列表框进行初始化,使其具有两个具体选项,可供用户选择。
Sub InitOptionSelect
Dim d
Set d = CreateObject("Scripting.Dictionary")
d.Add "0", "从起始值到终止值的连加"
d.Add "1", "从起始值到终止值的连乘"
Dim i
Dim e
For Each i in d
Set e = Document.createElement("OPTION")
e.Text = d.Item(i)
e.Value = d.Item(i)
frmFORM.selectOption.Options.Add e
Next
End Sub
如果我们希望在每次选择列表框中的选项时,就能对输入的开始数值和终止数值进行计算,那么,就要将有关代码写在该列表的onChange事件函数中。
Sub selectOption_onChange
Dim nBegin, nEnd, nResult
nBegin = FilterNumber(frmFORM.txtBegin.value)
nEnd = FilterNumber(frmFORM.txtEnd.value)
Dim i
i = nBegin
if (frmFORM.selectOption.value = "从起始值到终止值的连加") Then
nResult = 0
For i = nBegin To nEnd
nResult = nResult + i
Next
Elseif (frmFORM.selectOption.value = "从起始值到终止值的连乘") Then
nResult = 1
For i = nBegin To nEnd
nResult = nResult * i
Next
End If
frmFORM.txtResult.value = nResult
End Sub
再来看如何修改页面的背景颜色,同样先在页面上放置一个下拉列表框,其属性设为默认,名称为SelectBkColor。
<P>选择背景颜色:
<SELECT id=selectBkColor name=selectBkColor
style ="HEIGHT: 22px; WIDTH: 110px">
</SELECT>
</P>
进行有关的下拉列表的初始化。在该列表中填入六个颜色值,可供用户选择。
Sub InitOptionSelect
Dim d
Set d = CreateObject("Scripting.Dictionary")
d.Add "0", "从起始值到终止值的连加"
d.Add "1", "从起始值到终止值的连乘"
Dim i
Dim e
For Each i in d
Set e = Document.createElement("OPTION")
e.Text = d.Item(i)
e.Value = d.Item(i)
frmFORM.selectOption.Options.Add e
Next
End Sub
修改颜色值的代码也写在下拉列表的onChange事件的过程中。
Sub InitColorSelect
Dim d
Set d = CreateObject("Scripting.Dictionary")
d.Add "0", "红色"
d.Add "1", "绿色"
d.Add "2", "蓝色"
d.Add "3", "黄色"
d.Add "4", "蓝绿"
d.Add "5", "紫色"
Dim i
Dim e
For Each i in d
Set e = Document.createElement("OPTION")
e.Text = d.Item(i)
e.Value = d.Item(i)
frmFORM.selectBkColor.Options.Add e
frmFORM.selectBkColor.value = d.Item(i)
Next
End Sub
这样,我们就完成了所有的功能。如果读者希望能进一步改善该页面的外观,可以使用FrontPage98来进行艺术性的美化,但网页的主要功能已经完成。
综上所述,我们给出完整的程序清单如下:
<HTML>
<HEAD>
<META name=VI60_defaultClientScript content=VBScript>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE>第四章节的一个例子:关于选择语句和循环语句的使用</TITLE>
</HEAD>
<SCRIPT ID=clientEventHandlersVBS LANGUAGE=vbscript>
<!--
Sub InitColorSelect
Dim d
Set d = CreateObject("Scripting.Dictionary")
d.Add "0", "红色"
d.Add "1", "绿色"
d.Add "2", "蓝色"
d.Add "3", "黄色"
d.Add "4", "蓝绿"
d.Add "5", "紫色"
Dim i
Dim e
For Each i in d
Set e = Document.createElement("OPTION")
e.Text = d.Item(i)
e.Value = d.Item(i)
frmFORM.selectBkColor.Options.Add e
frmFORM.selectBkColor.value = d.Item(i)
Next
End Sub
Sub InitOptionSelect
Dim d
Set d = CreateObject("Scripting.Dictionary")
d.Add "0", "从起始值到终止值的连加"
d.Add "1", "从起始值到终止值的连乘"
Dim i
Dim e
For Each i in d
Set e = Document.createElement("OPTION")
e.Text = d.Item(i)
e.Value = d.Item(i)
frmFORM.selectOption.Options.Add e
Next
End Sub
Function FilterNumber(NumValue)
If ( IsNumeric(NumValue) ) Then
FilterNumber = NumValue
else
FilterNumber = 0
End If
End Function
Sub selectBkColor_onchange
Dim ColorValue
Select Case frmFORM.selectBkColor.Value
Case "红色"
ColorValue = RGB(255, 0, 0)
Case "绿色"
ColorValue = RGB(0, 255, 0)
Case "蓝色"
ColorValue = RGB(0, 0, 255)
Case "黄色"
ColorValue = RGB(255, 255, 0)
Case "蓝绿"
ColorValue = RGB(0, 255, 255)
Case "紫色"
ColorValue = RGB(255, 0, 255)
End Select
document.bgColor = ColorValue
End Sub
Sub selectOption_onChange
Dim nBegin, nEnd, nResult
nBegin = FilterNumber(frmFORM.txtBegin.value)
nEnd = FilterNumber(frmFORM.txtEnd.value)
Dim i
i = nBegin
if (frmFORM.selectOption.value = "从起始值到终止值的连加") Then
nResult = 0
For i = nBegin To nEnd
nResult = nResult + i
Next
Elseif (frmFORM.selectOption.value = "从起始值到终止值的连乘") Then
nResult = 1
For i = nBegin To nEnd
nResult = nResult * i
Next
End If
frmFORM.txtResult.value = nResult
End Sub
-->
</SCRIPT>
<BODY bgColor=moccasin>
<FORM NAME = "frmFORM">
<P>选择背景颜色:
<SELECT id=selectBkColor name=selectBkColor
style ="HEIGHT: 22px; WIDTH: 110px">
</SELECT>
</P>
<P>起始值:
<INPUT id=txtBegin name=txtBegin
style ="HEIGHT: 22px; WIDTH: 60px">
终止值:
<INPUT id=txtEnd name=txtEnd
style ="HEIGHT: 22px; WIDTH: 60px">
</P>
<P>计算功能:</P>
<P>
<SELECT id=selectOption name=selectOption
size = 2>
</SELECT>
</P>
<P>计算结果:
<INPUT id=txtResult name=txtResult>
</P>
<SCRIPT LANGUAGE=vbscript>
<!--
InitColorSelect
InitOptionSelect
-->
</SCRIPT>
</FORM>
</BODY>
</HTML>
dyle_gg,2004-12-02 14:17:21
第4章 VBScript的函数
我们已经对VBScript的基本知识有所了解,本章我们将进一步学习VBScript的各类函数。由于学习抽象的函数知识近似于学习理论知识,会让人感到十分的枯燥和乏味,所以在这一章中,我们先从总体上对VBScript的函数作一综合介绍,然后再通过一些典型的例子,来详细讲解较常用到的VBScript函数。
4.1 VBScript函数综述
在VBScript中,函数包含在Function和End Function之间,函数和过程有许多相同之处,同样可以获取一定的参数,执行一系列的语句,并完成一定的操作,但和过程不同之处在于,函数会有一个返回值,其语法如下所示:
Public|Private Function name [(argulist)]
statements
name = expression
End Function
和过程一样,使用Private和Public可以表示函数是是公有的还是私有的,缺省情况下,函数默认是公有的。name是函数的名称,其命名需要遵循VBScript关于变量命名的规定。argulist是函数的参数列表,多个参数之间通过逗号进行分隔,参数传递有两种传递方式:ByVal进行值传递、ByRef进行地址传递。statements是函数内执行的脚本。
name=expression语句则将expression的结果返回给调用该函数的语句,其中返回的结果数据类型是Variant类型。
如果需要在函数执行的过程中,满足某种条件后直接退出函数的处理逻辑,返回主程序,应该使用Exit Function语句。
例如,我们可以编写函数完成将温度的华氏度换算为摄氏度,如下所示:
<!--
Function CDegree(ByVal fDegree)
CDegree = (fDegree – 32) * 5 /9
End Function
-->
然后我们可以调用这个函数进行获取华氏温度相应的摄氏温度,在下面的语句,我们将华氏100度进行转换:
<!--
Temperature = CDegree(100)
-->
VBScript提供的函数通常称为内部函数,以与用户定义的函数即外部函数相区分。这些内部函数可以完成数学运算、数据子类型的转换、数据格式化等操作。我们可以在脚本中直接调用这些函数完成数据处理而不需要任何预先的声明。下面,我们就对这些函数综合起来进行简要的介绍。
4.1.1 数据类型判断
VBScript中只有一种数据类型Variant,数据类型判断函数可以判断变量的子类型,运用这些函数,我们能够根据变量的子类型,对变量进行合适的处理:
1. IsArray:IsArray函数判断变量是否是一个数组,如果是数组,则返回True,否则返回False。
2. IsDate:IsDate函数判断表达式是否能够转换为日期,如果能够转换,则返回True,否则返回False。例如,如果变量Today = “12-30-2000”,那么使用IsDate(Today)的返回值为True。
3. IsEmpty:IsEmpty函数用于指明变量是否已经被初始化,在声明变量之后,变量将自动被赋值为Empty,这时候使用IsEmpty判断,返回值为True;当变量经过赋值操作之后,调用IsEmpty函数,则返回False。
4. IsNull:IsNull函数可以判断变量中存储的是否为Null,如果为Null,返回值为True,否则返回值为False。
需要说明的是,Null并不是0,也不是空字符串,而是代表无效数据。
5. IsNumeric:IsNumeric函数指明表达式是否能够被转换为数字表达式,如果转换能成功,则返回True,否则返回False。例如,如果字符串Num = “31.24”,那么IsNumeric(Num)的返回值为True。
6. IsObject:IsObject函数可以判断变量是否是ActiveX对象,如是ActiveX对象则返回True,否则返回False。
7. TypeName和VarType:TypeName和VarType函数都能够返回变量的子类型,不同的是,TypeName返回的是一个指示变量子类型的字符串,而VarType返回的是指示变量子类型的数字。
4.1.2 格式化函数
VBScript中引入了格式化函数,这些函数可以对货币类型数据、时间类型数据、数字和百分比数值等进行格式转换和处理,这些处理是基于控制面板中的区域设置属性完成的。
1. FormatCurrency:FormatCurrency函数返回格式化后的货币类型数值,货币符号的设置基于控制面板的区域属性设置中。其语法如下所示:
formatCurrency(expression[,NumDigitsAfterDecimal[,IncludeLeadingDigit[,UseParensForNegativeNumbers[,GroupDigits]]]])
其中,expression代表将被格式化的表达式,NumDigitsAfterDecimal代表的是小数点后数字位数,IncludeLeadingDigit指示是否将显示数字前面的零,UseParensForNegativeNumbers指示是否使用括号代替负号,GroupDigits指示是否使用区域设置中指定的数字分组符号将数字分组。其信息来源是控制面板中区域设置属性的货币部分,其中,后面三个参数可以有以下取值:
(1) TristateTrue,代表选项值为True;
(2) TristateFalse,代表选项值为False;
(3) TristateUseDefault,代表根据控制面板中的区域设置来进行处理。
例如,我们可以将以下货币-12345.78进行格式化显示:
FormatCurrency(-12345.78, 1, TristateTrue, TristateTrue, TristateTrue)
函数的可能返回值是-¥12345.8。
2. FormatDateTime:运用FormatDateTime函数,可以用5种日期/时间格式来显示一个日期表达式,其语法如下所示:
FormatDateTime(Date [,NamedFormat])
其中,Date是将要格式化的日期表达式,NamedFormat是指示日期/时间格式的值,它可以有以下5种取值:
(1) vbGeneralDate,如果表达式中只有日期部分,则显示为短日期格式,如果表达式中只有时间部分,则显示为长时间格式,如果两部分都存在,则全部显示;
(2) vbLongDate,根据区域设置属性以长日期格式显示日期;
(3) vbShortDate,根据区域设置属性以短日期格式显示日期;
(4) vbLongTime,根据区域设置属性以长时间格式显示时间;
(5) vbShortTime,根据区域设置属性以短时间格式显示时间。
例如,我们可以在以下脚本中将2000年12月20日以长日期格式显示:
FormatDateTime(“2000/12/20”, vbLongDate)
不过,上述语句在不同的计算机上可能运行会得出不同的结果,因为在控制面板中的区域设置属性可能会各不相同。如果长日期样式设置为yyyy‘年’M‘月’d‘日’,那么,上述语句返回的结果将是2000年12月20日。
3. FormatNumber:FormatNumber函数可以用于一个数字表达式的自定义显示,其语法如下所示:
FormatNumber(expression[,NumDigitsAfterDecimal[,IncludeLeadingDigit[,UseParensForNegativeNumbers[,GroupDigits]]]])
其中的参数和FormatCurrency完全相同,不同的是它所有的信息均来自控制面板中区域设置属性的数字部分。
例如,FormatNumber(-12.3456, 2, TristateFalse, TristateFalse, TristateFalse)的可能反馈结果是-12.35。
4. FormatPercent:FormatPercent函数用于返回一个表达式的百分比数值,其语法如下所示:
FormatPercent(expression[,NumDigitsAfterDecimal[,IncludeLeadingDigit[,UseParensForNegativeNumbers[,GroupDigits]]]])
其中参数和FormatCurrency完全相同,不同之处在于它的信息均来自控制面板中区域设置属性的数字部分。
例如,FormatPercent(-12.3456, 2, TristateFalse, TristateFalse, TristateFalse)的可能反馈结果是-1234.56%。
4.1.3 数据类型转换函数
运用VBScript的数据类型转换函数,我们可以方便地把数据进行子类型的转换,可以将字符串转换为日期,也可以将数字转换为字符串等等。
1. CBool:CBool函数将表达式转换为布尔子类型的数据。
2. CByte:CByte函数将表达式转换为字节子类型的数据,例如,CByte(“12”)=12。
3. CCur:CCur函数将表达式转换为货币子类型的数据。
4. CDate:CDate函数将表达式转换为日期子类型的数据。
5. CDbl:CDbl函数将表达式转换为双精度浮点子类型的数据。
6. CInt:CInt函数将表达式转换为整数类型的数据。
7. CSng:CSng函数将表达式转换为单精度浮点子类型的数据。
8. CStr:CStr函数将表达式转换为字符串子类型的数据。例如,CStr(12.34)=“12.34”。
9. Hex:Hex函数将数值转换为表示十六进制值的字符串,例如,Hex(31)=“1F”。
10. Oct:Oct函数将数值转换为表示八进制值的字符串,例如,Oct(31)=“37”。
当然,在上述类型转换中并不能无限制地进行类型转换,比如说,CDate类型转换的表达式必须是能够被识别为日期子类型的表达式,比如说,如果执行CDate(“nothing”)函数,那么将会返回类型不匹配的错误。
4.1.4 数学运算函数
VBScript还提供了一定的数学运算函数,可以完成简单的数学运算功能,当然,由于VBScript的主要应用并不在数学运算中,所以其数学运算功能并不是十分强大,不过灵活运用这些函数也能够极大地方便我们脚本开发:
1. Atn:Atn函数用于计算数值的反正切值。
2. Cos:Cos函数用于计算角度的余弦值。
3. Sin:Sin函数用于计算角度的正弦值。
4. Tan:Tan函数用于计算角度的正切值,在这些计算角度的函数中,角度的表达形式应该是弧度,例如,计算30°的正切值,我们需要使用如下方式:Tan(30*3.1415927/180)。
5. Exp:Exp函数用于计算自然指数的幂次。
6. Log:Log函数用于计算数值的自然对数。
7. Sqr:Sqr函数用于计算数值的平方根。
8. Randomize:Randomize函数用于初始化随机数生成器。在VBScript中,生成的随机数并不是真正意义上的随机数,而是伪随机序列,在生成第一个随机数的时候,它需要一个数值作为种子值来生成伪随机序列。Randomize函数有一个参数number,Randomize函数执行后可以初始化Rnd函数的随机数生成器,并以number作为其种子值,如果函数省略number,则缺省使用系统计时器返回的值作为种子值。
注意,如果不使用Randomize函数,则第一次调用Rnd函数的时候,它将使用相同的数字作为种子值,这样就不能起到生成随机数的作用了。
9. Rnd:Rnd函数用于生成一个随机数,这个随机数是一个小于1但大于等于0的小数。Rnd函数也有一个参数number,如果number大于0,则返回伪随机序列中的下一个数值,如果number小于0,则每次都会返回以number为种子值的随机数,如果number等于0,则返回最近生成的数。例如,如果我们需要生成一个5到10之间的随机数,我们可以采用如下公式:
Int((10 – 5 + 1) * Rnd + 5)
10. Abs:Abs返回数值表达式的绝对值。
11. Int:Int函数返回数值表达式的整数部分。
12. Fix:Fix函数同样返回数值表达式的整数部分,如果数值表达式结果大于等于0,则Int函数和Fix函数并没有什么区别,同样返回其整数部分,如果数值表达式结果小于0,则Int函数返回的是小于或等于这个数值的第一个负整数,而Fix函数返回的是大于或等于这个数值的第一个负整数,例如,Int(-2.4)=-3,而Fix(-2.4)=-2。
13. Round:Round函数对数值表达式进行四舍五入取整。
14. Sgn:Sgn函数返回代表数值表达式的整数,如果数值表达式的值大于0,则返回1,如果等于0,则返回0,如果小于0,则返回-1。
4.1.4 日期时间处理函数
VBScript的日期时间处理函数能够获取当前系统的日期和时间,也能够对日期和时间中的各个部分单独取出进行处理:
1. Date:Date函数返回当前系统日期。
2. Time:Time函数返回当前系统时间。
3. DateAdd:DateAdd函数能够将给定日期添加时间间隔然后返回,其语法如下所示:
DateAdd(interval, number, date)
其中,interval是表示时间间隔部分的字符串,其取值可以是:“yyyy”,代表年份;“q”,代表季度;“m”,代表月份;“y”,代表一年的日数;“d”,代表日;“w”,代表一周的日数;“ww”,代表周;“h”,代表小时;“n”,代表分钟;“s”,代表秒。number是需要添加的时间间隔,date则是给定的日期。例如,我们可以获取当前日期的100天后的日期:
DateAdd(“y”, 100, Date)
4. DateDiff:DateDiff函数能够返回两个给定日期之间的差异,其语法如下所示:
DateDiff(interval, date1, date2[, firstdayofweek[, firstweekofyear]])
其中,interval是表示时间间隔部分的字符串,取值和DateAdd函数一样,date1和date2分别代表开始日期和结束日期,firstdayofweek可以指定哪一天是一个星期的开始,其取值如表4.1所示:
表4.1 firstdayofweek参数取值
常数 取值 说明
vbUseSystem 0 根据区域属性设置而定
vbSunday 1 星期天(默认设置)
vbMonday 2 星期一
vbTuesday 3 星期二
vbWednesday 4 星期三
vbThursday 5 星期四
vbFriday 6 星期五
vbSaturday 7 星期六
firstweekofyear可以指定一年中第一周的情况,其取值如表4.2所示:
表4.2 firstweekofyear参数取值
常数 取值 说明
vbUseSystem 0 根据区域设置属性而定
vbFirstJan1 1 从1月1日所在的星期开始(默认)
vbFirstFourDays 2 新年中至少有四天的第一个星期开始
vbFirstFullWeek 3 新年中完整的第一个星期开始
firstdayofweek和firstweekofyear这两个参数都是可选的。例如,我们可以计算1999年12月31日和2000年12月31日间相差的天数:DateDiff(“d”, “1999/12/31”, “2000/12/31”)=366,也可以计算相差年份:DateDiff(“yyyy”, “1999/12/31”, “2000/12/31”)=1。
5. DatePart:DatePart函数可以返回日期的指定部分,其语法如下所示:
DatePart(interval, date1, date2[, firstdayofweek[, firstweekofyear]])
其中参数和DateDiff函数的参数完全相同。例如,我们可以获知2000年5月26日是星期几:DatePart(“w”, “2000/5/26”)=6,6代表的正是vbFriday常数,表明这一天是星期五。
6. DateSerial:给定年、月和日各部分,DateSerial函数可以将其合成为日期子类型的数据。例如对于2000年12月31日,我们可以使用DateSerial函数如下合成:DateSerial(2000, 12, 31)。
7. DateValue:运用DateValue函数,能够将用以描述日期的字符串转化成为日期子类型的数据,其中包含的就是字符串所描述的日期。
8. Day:Day函数返回指定日期的日部分。例如,可以获取当前日期的日部分:Day(Date)。
9. Month:Month函数返回指定日期的月份部分。
10. Year:Year函数返回指定日期的年份部分。
11. MonthName:MonthName返回代表指定月份的字符串,例如,MonthName(1)=“一月”,这个返回值是和系统相关的。
12. WeekDay:WeekDay函数可以返回指定日期是星期几,例如,WeekDay(Now)函数可以获取系统当前日期是星期几。
13. WeekDayName:WeekDayName函数可以返回一个字符传,指定星期中的某一天。
14. Hour:Hour函数返回指定时间的小时部分。例如,可以获取当前时间的小时部分:Hour(Time)。
15. Minute:Minute函数返回指定时间的分钟部分。
16. Second:Second函数返回指定时间的秒钟部分。
17. Now:Now函数获取当前系统日期和时间值。
18. TimeSerial:给定小时、分钟和秒钟,TimeSerial函数可以将其合成为日期子类型的数据。例如对于11点59分59秒,我们可以使用TimeSerial函数如下合成:TimeSerial(11, 59, 59)。
19. TimeValue:运用TimeValue函数,能够将用以描述时间的字符串转化成为日期子类型的数据,其中包含的就是字符串所描述的时间。
4.1.5 字符串处理函数
VBScript中字符串处理函数可以完成截取字符串、字符串大小写转换等功能,虽然我们完全可以自己编写脚本来实现同样的功能,但是直接调用VBScript的函数可以在脚本编写的过程中提供给我们不少方便。
1. Asc:Asc函数可以获取字符串中第一个字母的ASCII码,例如,Asc(“AB”)=65。
2. Chr:Chr函数可以返回指定数字对应的ASCII码字符,例如,Chr(65)=“A”。
3. Instr:运用Instr函数,我们可以判断在一个字符串中是否包含另外一个字符串,它返回的是被搜索字符串第一次出现的位置,例如,Instr(“acabc”, “ab”)=3。
4. InstrRev;InstrRev函数的功能和Instr的功能类似,不同之处在于InstrRev函数是从字符串尾开始搜索,而Instr函数是从字符串首开始搜索,例如,Instr(“acabc”, “c”)=2,而InstrRev(“acabc”, “c”)=5。
5. Len:Len函数返回字符串的长度,例如,Len(“abc”)=3。
6. LCase:LCase函数将字符串中的字母转换为小写字符,例如,LCase(“Case”)=“case”。
7. UCase:UCase函数和LCase函数的功能正好相反,UCase函数将字符串中的字母转换为大写字符,例如,UCase(“Case”)=“CASE”。
8. Left:Left函数可以从字符串左边开始截取指定长度的字符,例如,Left(“Case”, 2)=“Ca”。
9. Right:Right函数可以从字符串右边开始截取指定长度的字符,例如,Right(“Case”, 2)=“se”。
10. Mid:Mid函数的功能比Left函数和Right函数的功能要强大得多,它能够从字符串的指定位置截取指定长度的字符,例如,我们可以截取“Case”字符串从第二个位置开始的两个字符:Mid(“Case”, 2, 2)=“as”。
11. LTrim、RTrim和Trim:LTrim函数删除字符串中的前导空格,RTrim函数删除字符串中的后续空格,Trim函数则删除字符串中的前导和后续空格,例如,LTrim(“ Case ”)=“Case ”,RTrim(“ Case ”)=“ Case”,Trim(“ Case ”)=“Case”。
12. StrReverse:StrReverse函数将指定的字符串一逆序的形式排列,例如,StrReverse(“Case”)=”esaC”。
13. String:String函数返回指定长度并以相同字符组成的字符串,例如,我们可以生成一个长度为5,并且全部由字符a组成的字符串:String(5, “a”)=“aaaaa”。
14. StrComp:StrComp函数对两个字符串执行字符串比较,并返回比较结果,如果前者小于后者返回-1,如果前者大于后者返回1,如果两个字符串相等返回0,如果两个字符串中有一个字符串为Null,则返回Null。例如,StrComp(“good”, “ok”)=-1,这是因为“g”的ASCII码小于“o”的ASCII码,所以“good”<“ok”。
15. Space:Space函数返回由指定空格组成的字符串,例如,Space(2)=“ ”。
16. Replace:Replace函数可以将字符串中指定的子串替换为另外的子串,例如,我们可以将字符串“window”中的w替换为k,Replace(“window”, “w”, “k”)=“kindok”。
4.2 程序范例:Hello
几乎所有介绍编程语言的书上的第一个范例都是Hello, world。所以,我在这里也使用Hello作为VBScript函数学习的第一个范例。这是一个简单的程序,通过这个程序的学习,可以对于MsgBox函数有所了解。
4.2.1 范例介绍
使用浏览器(这里使用IE)将该网页打开后如图4.1所示。
图4.1 VBScript程序范例:Hello
用户可以单击“问好”按钮,将弹出一个对话框。仅此而已,相当简单。这个程序的源代码也相当简单,仅几句话而已:
<SCRIPT LANGUAGE="VBScript">
<!—
Sub BtnHello_OnClick
MsgBox "嗨,你好!", 0, "第一个程序"
End Sub
-->
</SCRIPT>
从上述代码中可以看出,在按钮单击事件中只有一行代码,在这行代码中使用了MsgBox函数。该函数的作用是将弹出一个对话框,对话框中可以写一些用户想要表示的信息。这个方法虽然简单,但相当有用。
4.2.2 函数介绍——MsgBox函数
MsgBox函数用于弹出一个对话框,并在对话框中显示一些用户信息,并等待用户单击按钮。该函数的返回值用于表示用户单击的按钮。
关于该函数的语法如下:
MsgBox (prompt[, buttons][, title][, helpfile, context])
关于该函数中的一些参数的说明如下:
(1) Prompt。作为消息显示在对话框中的字符串表达式。prompt 的最大长度大约是1024个字符,这取决于所使用的字符的宽度。如果 prompt 中包含多个行,则可在各行之间用回车符 (Chr(13))、换行符 (Chr(10)) 或回车换行符的组合 (Chr(13) & Chr(10)) 分隔各行。
(2) Buttons。数值表达式,是表示指定显示按钮的数目和类型、使用的图标样式,默认按钮的标识以及消息框样式的数值的总和。有关数值,请参阅下文。如果省略,则 buttons 的默认值为 0。
(3) Title。显示在对话框标题栏中的字符串表达式。如果省略 title,则将应用程序的名称显示在标题栏中。
(4) Helpfile。字符串表达式,用于标识为对话框提供上下文相关帮助的帮助文件。如果已提供 helpfile,则必须提供 context。在 16 位系统平台上不可用。
(5) Context。数值表达式,用于标识由帮助文件的作者指定给某个帮助主题的上下文编号。如果已提供 context,则必须提供 helpfile。在 16 位系统平台上不可用。
Helpfile和Context两个参数必须同时出现,这样用户就可以按下F1键来查看与上下文相对应的帮助主题。如果对话框显示“取消”按钮,则按ESC键与单击“取消”按钮的效果相同。如果对话框包含“帮助”按钮,则有为对话框提供的上下文相关帮助。
此外对于参数Button,这里还需要说明一下。在VBScript语言中,提供了一些常量来代替Button中枯燥而且没有任何意义的数值表达式,下面我们就介绍一下这些组常量。
第一组常量用于描述对话框中显示的按钮类型与数目(表4.3):
表4.3 常量表示
常量表示 代表数值 含义
vbOKOnly 0 只显示确定按钮。
vbOKCancel 1 显示确定和取消按钮。
vbAbortRetryIgnore 2 显示放弃、重试和忽略按钮。
vbYesNoCancel 3 显示是、否和取消按钮。
vbYesNo 4 显示是和否按钮。
vbRetryCancel 5 显示重试和取消按钮。
第二组常量用于描述图标的样式(表4.4):
表4.4 常量表示
常量表示 代表数值 含义
vbCritical 16 显示临界信息图标。
vbQuestion 32 显示警告查询图标。
vbExclamation 48 显示警告消息图标。
vbInformation 64 显示信息消息图标。
第三组常量用于确定默认按钮,如表4.5所示。
表4.5 常量表示
常量表示 代表数值 含义
vbDefaultButton1 0 第一个按钮为默认按钮。
vbDefaultButton2 256 第二个按钮为默认按钮。
vbDefaultButton3 512 第三个按钮为默认按钮。
vbDefaultButton4 768 第四个按钮为默认按钮。
第四组常量用于决定消息框的样式,如表4.6所示。
表4.6 常量表示
常量表示 代表数值 含义
vbApplicationModal 0 应用程序模式:用户必须响应消息框才能继续在当前应用程序中工作。
vbSystemModal 4096 系统模式:在用户响应消息框前,所有应用程序都被挂起。
在使用buttons 参数值时,只需要从每组值中取用一个数字或常量来表示按钮即可。
MsgBox函数的返回值也是一些数值信息,而且是通用的。同时,这些返回值也可以用一定的常量来表示其具体的含义,具体如表4.7所示。
表4.7 常量表示
常量表示 代表数值 含义
vbOK 1 确定
vbCancel 2 取消
vbAbort 3 放弃
vbRetry 4 重试
vbIgnore 5 忽略
vbYes 6 是
vbNo 7 否
4.2.3 程序清单
<SCRIPT LANGUAGE="VBScript">
<!--
Sub BtnHello_OnClick
MsgBox "嗨,你好!", 0, "第一个程序"
End Sub
-->
</SCRIPT>
更多阅读
vbscript 教程 vbscript视频教程
[转帖]vbscript 教程 dyle_gg,2004-12-02 14:10:46第2章 VBScript基础本书主要通过大量实例讲解VBScript与JScript编程。从本章开始我们先用5章的篇幅讲解VBScript,以后各章再讲解JScript。本章我们先来初步认识VBScript的基本情况,并
ASP(vbscript)视频教程 asp vbscript msgbox
如需要与本人联系 QQ:125110341ASP是一种未经编译的开放式的应用软件,是微软公司推出的一种用以取代CGI(公共网关接口即CommonGatewayInterface)的技术,它实质是一种服务器端脚本环境。通过ASP,用户可以结合HTML网页、ASP指令建立动态、
手工编织小乌龟 手工编织乌龟视频教程
几年前的一个早晨,去菜市场买菜,远远看到一个摊位有很多人围着看,我过去一看,那么多毛线编织的小动物。有小狗、小猪、海豚、小乌龟,大乌龟等,越看越喜欢,那个都想学。卖家说:“只要买我的毛线,我就教她织”。一听这话,我菜也不买了,就蹲那里先
艾略特波浪理论图解及视频教程 艾略特波浪理论原著
波浪理论由艾略特(R·N·Elliott)在1934年他63岁时创立。艾略特波浪理论是最常用的趋势分析工具之一。群体心理是该理论的重要依据,清淡的交易市场难以发挥它的作用。
打“袼褙” 打袼褙方法视频教程
丰采园大连姐妹群群主迎春姐姐提议:我们要做儿童村孩子的奶奶的建议,得到大家一致同意。姐姐提出来的第一个活动就是做手工鞋垫,让孩子感到家的温暖,感到有奶奶的温暖。我和菩萨心的妹妹快乐土猫一说,她也表示要积极参加,我们姐妹俩有缝