VBA|变量的类型、声明、作用域
yuyutoo 2024-12-13 17:00 1 浏览 0 评论
一般来说,现代编程语言的变量都区分不同的数据类型,由数据类型确定需要的内存单元字节数量需求,编码标准,以及由此确定的值域和可以施加其上的操作(使用的运算符及相应的优先级和结合性)。
一些编程语言强制要求变量在使用前声明和定义,如C、C++、Java,以便在编译阶段由编译器做类型检查(避免推迟到运行阶段做类型检查,从而提高运行效率)。一些编程语言不要求强制数据类型声明,由编译器或解释器根据右值来推断左值类型,在运行时做类型检查(简便了程序员的代码编写,但影响了运行时效率,且类型相关的问题不能在运行前提前处理),如VB(VBA)、Python等。
一般来说,编程语言对于变量都有作用域的定义。编程语言因应大型复杂项目的需要,如何组织代码就很重要,包括如何定义模块(如函数、类等都是一种模块单元,模块可以分解,也可以组合),模块如何组合?文件如何组织?如C使用函数+文件(头文件和实现文件)+工程项目的方式来组织模块,C++使用函数+类+文件(头文件和实现文件)+工程项目的方式来组织模块。VB(VBA)通过过程+函数+模块(代码模块、类模块)+工程项目的方式来组织模块。编程语言由模块的定义来区分变量作用域的定义,由此,各类编程语言的变量作用域的定义稍有不同。
目录如下:
一、变量的概念
二、变量的命名
三、变量的声明
四、变量的类型
五、变量的作用域
六、变量的赋值
七、变量的存活期
八、正确声明变量类型对运行时间的影响
一、变量的概念
变量是是一块命名的并指定了特定数据类型的内存单元,其值可以迭代改变。
变量有两种:动态变量和静态变量。
动态变量:过程每运行一遍,动态变量的值会重置(因为保存在栈区,每一个过程运行都有一个相应的栈帧);
静态变量:过程每运行一遍,静态变量的值还是上一次过程运行的结果(静态变量存储在全局\静态内存区)。
注意静态变量是在程序加载到内存时即分配的内存单元,而动态变量是存储在栈上的,程序运行时动态分配程序栈上的某一个位置。
Sub 静态和动态变量()
Dim a As Integer
Static b As Integer '静态局部变量
a = a + 1
b = b + 1
Debug.Print a; b
End Sub
二、变量的命名
在VBA中,可以使用名称来表示内存的位置,这个名称就是标识符,可以理解为变量的名字。
变量命名的注意事项:
1、第一个字符必须使用英文字母或中文字符(中文版EXCEL支持中文字符);
2、名称长度不超过255个字符;
3、名称不能与VBA本身的Function过程、语句、即方法的名称相同,避免冲突;
4、不能在同一范围的相同层级中使用重复的名称。
三、变量的声明
在使用变量时,需要告诉VBA程序,变量的名称和数据类型,即声明变量。
通常用Dim语句来声明动态变量,用Static语句来声明静态变量。
声明数据类型后,可以在计算机内按确定的内存需求分配内存单元,这样在运行代码时程序无须做类型推断,内存利用效率也很高,否则,计算机会耗费较大的内存统一按variant类型来存储,运行速度也会比较慢。
1、声明变量的写法
声明变量通常都是在程序开始处,可以在同一行声明多个变量,用英文逗号间隔即可。写法如下:
Dim 变量1 As 变量类型,变量2 As 变量类型,……
Static 变量1 As 变量类型,变量2 As 变量类型,……
2、强制声明变量
要强制声明变量,直接在输入代码时最顶头输入【Option Explicit】,就可以。
① 未设置强制声明变量,在未声明变量的状态下,代码可以正常执行;
② 设置了强制声明变量,在未声明变量的状态下,无法执行代码,提醒变量未定义;
③ 设置了强制声明变量,在声明了变量的状态下,代码执行通过。
扩展:如果不会写【Option Explicit】,是否有快捷方法实现强制声明变量呢?当然有。
VBE编辑器菜单的工具→选项→编辑器→勾选要求变量声明。确定后,每次插入模块,都会在模块前面增加【Option Explicit】
四、变量的类型
变量类型主要有:
类型 | 小类 | 关键字 | 类型声明符 | 储存空间 | 值范围 | detail |
数值型 | 整型 | Integer | % | 2个字节 | -32768-32767 | 不带小数的数,包括正整数、负整数和零 |
数值型 | 长整型 | Long | & | 4个字节 | -21亿-21亿 | 不带小数的数,包括正整数、负整数和零 |
数值型 | 单精度型 | Single | ! | 4个字节 | 带有小数的数值,可以表示7位有效数字 | |
数值型 | 双精度型 | Double | # | 8个字节 | 带有小数的数值,可以表示15位有效数字 | |
数值型 | 字节型 | Byte | 1个字节 | 0-255 | 表示无符号的整数 | |
布尔型 | Boolean | 2个字节 | True 或 False | |||
日期型 | Date | 8个字节 | 1/1/100 -12/21/9999 | |||
字符串 | String | $ | 字符串长 | 用双引号引起来的一串字符串,在VBA中,一个汉字为1个字符 | ||
小数型 | Decimal | 14个字节 | 用于储存由10次冪换算的有符号整数 | |||
货币型 | Currency | @ | 8个字节 | |||
变体型 | Variant | 按需分配 | 可变的数据类型,可以存放任何类型的数据,当指定为变体型时,不必在数抿类型间转換,VBA会自动转换。注:在程序中不特别说明,默认为变体型,由于变体型存放空间大,因此不在特殊情况下不适用。 | |||
对象型 | Object | 4个字节 | 表示应用程序中的对象,如单元格、工作表 | |||
数组 | Array | |||||
字典 | Dictionary |
VBA中的变量类型及相关参数,详见上表,我们在声明变量时,要选择合适的变量类型。
比如变量的值为整数,就把变量声明为Integer型;
如果变量的值是大于32767的整数,就要把变量声明为Long型;
如果变量是时间,就要把变量声明为Date型(在工作表中,时间是数值的一种;但是在VBA中,要根据情况明确;声明数值时,还要根据数值的形式、范围选择合适的数值类型)
注意:
1、Variant型(变体型)可以存放任何类型的数据,当指定为变体型时,不必在数据类型间转换,VBA会自动转换;
2、在程序中不特别说明时,均默认为变体型;
3、由于变体型内存需求较大,因此,除非特殊情况,否则不要使用该类型。
五、变量的作用域
作用域就是变量使用范围,VBA中有三种级别的作用域:过程级变量、模块级变量和全局级变量。
1、过程级变量
过程级变量声明在过程内,只在变量所在的过程中有效。
Sub Test()
Dim a As Integer
Debug.Print a + 1
End Sub
如上面这个Test过程,这里声明的变量a,就只能用于此过程中。
2、模块级变量
模块级变量是声明在过程前的private(或dim,默认为private,非public)变量,在同一个模块内不同过程或函数中有效。
与过程级变量声明的不同方式在于,写过程前先声明变量,模块级代码的声明方式如下:
Dim 变量 As 变量类型 '方法①,默认为private
Private 变量 As 变量类型 '方法②
在强制声明变量状态下:
'模块1
Option Explicit
Dim a As Integer
Sub test1()
Debug.print a+1
End Sub
'模块2
Option Explicit
'Private b As Integer
Sub test2()
Debug.print a+1
End Sub
① 在模块1中声明了外部变量a,在模块1中运行通过;
② 切换到模块2,Test2过程中有一个未声明的变量a,直接运行,提示变量未申请;
③ 在模块2中用Private声明了变量b,然后将模块1和模块2过程中的变量都修改为b,在模块2中运行通过,在模块1中运行错误。
④通过演示得出结论,这两种声明变量的方式生成的都是模块级变量,只能在当前模块中使用,跨模块使用无效。
3、全局级变量
全局级变量在该工程内通用的变量。
全局变量与过程级变量声明的方式相同,都是写过程前先声明变量,全局变量的声明方式如下:
Public 变量 As 变量类型
code demo:
'模块1
Option Explicit
Public a As Integer
Sub test1()
Debug.print a+b
End Sub
'模块2
Option Explicit
Public b As Integer
Sub test1()
Debug.print a+b
End Sub
① 在模块1中声明了全局变量a,在模块2中声明了全局变量b;
② 模块1种Test过程中有变量a和b,运行通过;
③ 模块2种Test2过程中有变量a和b,运行通过;
注意:
① 对于不同级的变量使用的原则,尽量使用过程级变量;
② 如果不同过程之间有共享值时,才使用全局级变量;
③ 要控制全局级变量的使用数量。
六、变量的赋值
1、给文本、数值、日期等数据类型变量赋值
语句为:
Let 变量名称 = 变量值 '(这里的Let可以省略,即:变量名称=变量值)
例如:
Sub 非对象变量赋值()
Dim str As String
Let str = "hi"
End sub
2、给对象变量(Object型,例如单元格)赋值
语句为:
Set 变量名称 = 对象 '(这里Set千万不能少。)
例如:
Sub 对象变量赋值()
Dim rng As Range
Set rng = Worksheets("sheet1").Range("A1") '分配堆内存
rng.Value = "hi"
Set rng = Nothing '减少一引用计数,当引用计数为0时,释放堆内存
End Sub
七、变量的存活期
变量的存活期就是指变量在内存中保留的时间,这个与变量的作用域有很大的关系。
1、过程级变量:
出现:当Sub过程开始执行时,过程级变量在程序的栈空间中分配内存单元;
结束:Sub过程执行完成时,变量占用的内存就会立即释放。
2、模块级变量:
出现:在程序运行前,加载时即分配了全局性的内存单元,只是其作用域限制到模块内部;
结束:当关闭工作薄时,变量占用的内存才会释放。
3、全局级变量:
出现:在程序运行前,加载时即分配了全局性的内存单元,作用域跨模块。
结束:当关闭工作薄时,变量占用的内存才会释放。
4、静态过程级变量:
出现:在程序运行前,加载时即分配了全局性的内存单元,作用域仅限于过程。
结束:当关闭工作薄时,变量占用的内存才会释放。
八、正确声明变量类型对运行时间的影响
code demo:
Sub 要声明变量()
Dim t, a, b, c As Integer
t = Timer
For a = 1 To 20000
For b = 1 To 20000
c = a - b
Next
Next
printf.debug timert
End Sub
解析:
1、当不声明变量类型时,运行完成需要9.17秒;
2、当正确声明变量类型时,运行完成需要5..61秒;
3、如果换成更大量的数据、更复杂的运算,运行时间上的差距还会更大;
4、所以大家可以看到正确声明变量的重要性。
不同的数据类型,占用大小不同的字节,因此计算时对内存的占用和运算效率有所不同。因此,定义变量数据类型以后,可能的好处是少占用一些内存以及大量重复运算是提高计算速度。
由于各种类型占用字节的限制,它所能代表的数值范围受到了限制!如果初学者试图去使用定义变量类型的方法时,往往尚未得到实际好处,即【运算速度提高】的好处(但实际运算量小时速度的差别很小、很小可以完全忽略不计)却首先受到了因为不能恰如其份地定义好变量类型,而造成了变量溢出或冲突导致代码无法运行的严重后果。
比如:如果你不了解Integer的范围,在超出变量范围的情况下使用就会提示出错。比如“溢出”:
Sub demo()
Dim i As Integer
Dim rng As Range
Set rng = Range("A2", "A32767")
rng.Value = 6
i = Range("A" & Cells.Rows.Count).End(xlUp).Row + 1 '溢出
Debug.Print i
End Sub
运行结果,对话框提示:
运行时错误‘6’:
溢出
ref:
https://www.toutiao.com/article/6808577371080229388/
-End-
- 上一篇:MySQL字段类型最全解析
- 下一篇:MySQL的10种常用数据类型
相关推荐
- 自卑的人容易患抑郁症吗?(自卑会导致抑郁吗)
-
Filephoto[Photo/IC]Lowself-esteemmakesusfeelbadaboutourselves.Butdidyouknowthatovert...
- 中考典型同(近)义词组(同义词考题)
-
中考典型同(近)义词组...
- BroadcastReceiver的原理和使用(broadcast-suppression)
-
一、使用中注意的几点1.动态注册、静态注册的优先级在AndroidManifest.xml中静态注册的receiver比在代码中用registerReceiver动态注册的优先级要低。发送方在send...
- Arduino通过串口透传ESP 13板与java程序交互
-
ESP13---是一个无线板子,配置通过热点通信Arduino通过串口透传ESP13板与java程序交互...
- zookeeper的Leader选举源码解析(zookeeper角色选举角色包括)
-
作者:京东物流梁吉超zookeeper是一个分布式服务框架,主要解决分布式应用中常见的多种数据问题,例如集群管理,状态同步等。为解决这些问题zookeeper需要Leader选举进行保障数据的强一致...
- 接待外国人英文口语(接待外国友人的英语口语对话)
-
接待外国人英文口语询问访客身份: MayIhaveyourname,please? 请问您贵姓? Whatcompanyareyoufrom? 您是哪个公司的? Could...
- 一文深入理解AP架构Nacos注册原理
-
Nacos简介Nacos是一款阿里巴巴开源用于管理分布式微服务的中间件,能够帮助开发人员快速实现动态服务发现、服务配置、服务元数据及流量管理等。这篇文章主要剖析一下Nacos作为注册中心时其服务注册与...
- Android面试宝典之终极大招(android面试及答案)
-
以下内容来自兆隆IT云学院就业部,根据多年成功就业服务经验,以及职业素养课程部分内容,归纳总结:18.请描述一下Intent和IntentFilter。Android中通过Intent...
- 除了Crontab,Swoole Timer也可以实现定时任务的
-
一般的定时器是怎么实现的呢?我总结如下:1.使用Crontab工具,写一个shell脚本,在脚本中调用PHP文件,然后定期执行该脚本;2.ignore_user_abort()和set_time_li...
- Spark源码阅读:DataFrame.collect 作业提交流程思维导图
-
本文分为两个部分:作业提交流程思维导图关键函数列表作业提交流程思维导图...
- 使用Xamarin和Visual Studio开发Android可穿戴设备应用
-
搭建开发环境我们需要做的第一件事情是安装必要的工具。因此,你需要首先安装VisualStudio。如果您使用的是VisualStudio2010,2012或2013,那么请确保它是一个专业版本或...
- Android开发者必知的5个开源库(android 开发相关源码精编解析)
-
过去的时间里,Android开发逐步走向成熟,一个个与Android相关的开发工具也层出不穷。不过,在面对各种新鲜事物时,不要忘了那些我们每天使用的大量开源库。在这里,向大家介绍的就是,在这个任劳任怨...
- Android事件总线还能怎么玩?(android实现事件处理的步骤)
-
顾名思义,AndroidEventBus是一个Android平台的事件总线框架,它简化了Activity、Fragment、Service等组件之间的交互,很大程度上降低了它们之间的耦合,使我们的代码...
- Android 开发中文引导-应用小部件
-
应用小部件是可以嵌入其它应用(例如主屏幕)并收到定期更新的微型应用视图。这些视图在用户界面中被叫做小部件,并可以用应用小部件提供者发布。可以容纳其他应用部件的应用组件叫做应用部件的宿主(1)。下面的截...
你 发表评论:
欢迎- 一周热门
-
-
前端面试:iframe 的优缺点? iframe有那些缺点
-
带斜线的表头制作好了,如何填充内容?这几种方法你更喜欢哪个?
-
漫学笔记之PHP.ini常用的配置信息
-
推荐7个模板代码和其他游戏源码下载的网址
-
其实模版网站在开发工作中很重要,推荐几个参考站给大家
-
[干货] JAVA - JVM - 2 内存两分 [干货]+java+-+jvm+-+2+内存两分吗
-
正在学习使用python搭建自动化测试框架?这个系统包你可能会用到
-
织梦(Dedecms)建站教程 织梦建站详细步骤
-
【开源分享】2024PHP在线客服系统源码(搭建教程+终身使用)
-
2024PHP在线客服系统源码+完全开源 带详细搭建教程
-
- 最近发表
-
- 自卑的人容易患抑郁症吗?(自卑会导致抑郁吗)
- 中考典型同(近)义词组(同义词考题)
- WPF 消息传递简明教程(wpf messagebox.show)
- BroadcastReceiver的原理和使用(broadcast-suppression)
- Arduino通过串口透传ESP 13板与java程序交互
- zookeeper的Leader选举源码解析(zookeeper角色选举角色包括)
- 接待外国人英文口语(接待外国友人的英语口语对话)
- 一文深入理解AP架构Nacos注册原理
- Android面试宝典之终极大招(android面试及答案)
- 除了Crontab,Swoole Timer也可以实现定时任务的
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)