ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 17332|回复: 16

给对象变量赋值“Set 变量名称=数据”跟“变量名称=Range().Value”有什么区别?

[复制链接]

TA的精华主题

TA的得分主题

发表于 2013-2-1 19:57 | 显示全部楼层 |阅读模式
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
A1单元格里有好多个名字,想把他们复制到sheet2工作表里且每一个名字只占一个单元格,我写的VBA代码为:
Sub 按钮1_单击()
Dim A As Variant
Dim B As Variant     

Set B = Range("A1")  
A = Split(B, ",")         
Worksheets("SHEET2").Range("A1:E1").Value = A
End Sub

“Set B =Range("A1")”这句我换写成“B = Range("A1").Value”也行:
书上53页写的给对象变量赋值set是一定不可省略的
现在我搞糊涂了:①Set B = Range("A1")
                ②B = Range("A1").Value
                ③Range("A1").Value=B
这三句有什么区别啊?我换写成第③句,结果A1单元格的名字不见了,即A1单元格为空了,为什么啊?

TA的精华主题

TA的得分主题

发表于 2013-2-2 00:38 | 显示全部楼层
①Set B = Range("A1")
将变量B赋值,值为A1单元格,注意是单元格。指的是这个单元格的整体。
②B = Range("A1").Value
将变量B赋值,值为A1单元格的数值,即如果A1里面写的是“54215”,那么此时变量B的值为:54215
③Range("A1").Value=B
A1单元格的值写为变量B的值。

老实说我也是菜鸟,正在学习中,不知道解释的对不对

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-2-2 00:41 | 显示全部楼层
如果你将蓝色底纹换成③,即表示将A1单元格的值写为变量B的值,而此时变量B你还没有给其赋值,所以A1单元格就成空啦。。。

TA的精华主题

TA的得分主题

发表于 2013-2-2 12:47 | 显示全部楼层
首先解答你的前面2个问题:
1. 为什么 ①Set B = Range("A1"),②B = Range("A1").Value 都工作呢?书上不是讲过对象变量赋值Set 是不可省略的嘛?
答:从变量声明语句开始看,Dim B As Variant    这句话声明B 是一个变量。是一个变体型变量。变体型是VB 所支持的一种特殊变量,也是被低水平的刚入门学习者(包括我在内)所钟爱的一种变量类型。变体型变量的特点是声明的时候As  Variant  或者不as 任何类型,比如语句 Dim B 。或者不声明直接用,系统都默认为变体型变量。所谓变体型的概念,就是变量一旦产生,系统按最大的变量内存分配给这个变量分配内存空间。以确保任何的变量类型,都装的下。变体型变量是如何变的呢,是根据你的赋值语句,系统来判断变量类型。如上文语句: Set B = Range("A1")  系统会判断前面有Set 那么B 一定是对象变量,这时候变体型变量B 就被系统看作一个对象变量了,严格的说是一个单元格对象。而这句: ②B = Range("A1").Value,B 是根据赋值的内容改变自己的类型的,那就会根据单元格A1 的内容进行改变,看你的例子好像A1 里面是一些姓名信息,那么B 现在就是String 类型的变量了。属于基础变量的赋值,当然就不用Set 了,用Set 反而不对了。
这里说下变体型变量优缺点,初学者概念混淆的时候最喜欢用,因为用了之后基本上可以告别"类型不匹配错误了"。在菜鸟阶段对数据类型,特别是对象变量理解不清楚,经常声明了变量之后张冠李戴,用变体型让系统替你去判断,省事。本论坛VBA 区讨论的热火朝天一个帖子就是初学者是否要声明变量,如果不声明变量直接拿过来用,就全是变体型变量。这样就可以绕开理解变量的关口,直接去学后面的内容了。我的个人观点是这一课在初学的时候必须理解清楚,否则将来养成了坏习惯很难纠正。
说说变体型变量的缺点:
第一、效率非常低。因为系统变量要确保能变成任何的类型,所以分配最大的内存资源,造成绝大多数情况的浪费。打个比方,你要去打瓶酱油。那你声明个变量酱油瓶就可以了,这样拎着就去了。结果你用的变体型,给你一个水缸。你只能背着了,仅仅对打酱油这件事,酱油瓶和水缸都能装酱油,完成这点上是没有区别的,效率上一目了然。
第二、易发生逻辑错误,就拿上面的例子来说。比如说你的本意是定义B 为一个单元格对象变量,将来可能要调用该单元格变量的其他属性。你定义为变体变量了,就像你帖子里那样。然后呢,你赋值语句又不小心忘了写Set ,你的赋值语句写成了 B = Range("A1") 你会认为,没错啊我把B 设成一个单元格变量。其实呢 B = Range("A1") 被系统理解成: B = Range("A1").Value (因为通常情况下.value 属性是可以省略的)。你认为B 是一个对象变量,其实系统给你把B 弄成了一个字符串。将来你再按单元格对象访问B,比如对B 的高度,宽度背景色等属性进行修改,对单元格变量B 所在行,列进行访问等等操作,肯定会出错的。然后你还很难找出错误来,拿着程序夜里一点给老师打电话 “老师我真的声明了变量,我真的赋值了,系统都没报错,可为什么不对呢?“ 相信我,这种程序调起来非常困难,让人帮你找错,那人也会一边看一边骂娘的。

所以既然要声明变量何不声明的准确一点,比如你本意就是声明一个单元格对象。何不声明为:
Dim B as Range  这样 当你手误没有输入Set 的时候,系统就会提醒你类型不匹配。确保你正确的赋值。
同理,你如果想让B 是访问A1 的值而不是A1 单元格对象,何不声明为 Dim B as String, (本例A1 是一些姓名)这样B = Range("A1").Value 即使你不写.value 属性,系统也不会错误理解你的意思的。自己动手试试看,学习写程序就是一点一点,动手编写出来的。

至于第3个问题,楼上朋友已经讲的很清楚了,我就不再多废话了。变量在没赋予初值之前,默认是空值。


评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-2-2 14:22 | 显示全部楼层
hehex 发表于 2013-2-2 12:47
首先解答你的前面2个问题:
1. 为什么 ①Set B = Range("A1"),②B = Range("A1").Value 都工作呢?书上不是 ...

如果“B=RANGGE("A1:F1")”,那么“Dim B As Variant”是不是必须要用变体型Variant啊?(书本63页的“通过Range对象直接创建数组”必须用Variant型)
是不是说给变量赋值数组就要一定要用Variant,如果不是数组就可以基础类型的数据类型?
A1单元格里有好多个名字,那不算是数组?要单元格区域才算是数组?

TA的精华主题

TA的得分主题

发表于 2013-2-2 15:36 | 显示全部楼层
Lucky啊 发表于 2013-2-2 14:22
如果“B=RANGGE("A1:F1")”,那么“Dim B As Variant”是不是必须要用变体型Variant啊?(书本63页的“通 ...

B = RANGGE("A1:F1") 属于把单元格区域对象的引用赋给一个二维数组B。这种直接通过Range 对象来赋值数组,声明B 的时候是必须声明为变体型变量的。
是不是说给变量赋值数组就要一定要用Variant,如果不是数组就可以基础类型的数据类型?
没太明白你的意思,只是说通过单元格对象直接创建数组是必须声明为变体型的。
数组创建有多种方式,赋值也有多种。建议你先看看书中关于数组定义的基础概念,就是酱油瓶相关的内容。
A1单元格里有好多个名字,那不算是数组?要单元格区域才算是数组?
你对数组的基本概念还是模糊不清,还是先看书吧。
A1 单元格有好多名字,每个名字用","分开 A = Split(B, ",")   
A 就是一个一维数组,数组的每个成员是一个名字。 A1 单元格是一个单元格对象,当然不是一个数组。
还有你定义A 是数组的语句是定义为变体型变量,这当然是可以的。但是如果明确A 是一个数组并且用来装A1单元格中的姓名信息,可以 Dim A() as String  这是动态数组的定义方法。比用变体型定义效率要高的多。
你对于什么是对象,什么是数组还完全搞不清楚,建议先通读书上的内容,特别是关于数组的基本概念描述的相关章节,按照书上的例子慢慢体会。这些基本概念混乱的问题,我就不在这里详细说了。

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-2-2 16:38 | 显示全部楼层
{:soso_e105:}看了好几遍了,还是不懂!
数组:同种类型的多个变量的集合。
书上解释的“一维数组”:排成一个横排的数组,称为一维数组;
           “二维数组”:由多个横排组成的数组,称为二维数组。
61页的“课堂小练习”:因为1个单元格存储一个学生姓名,所以把存储100个学生姓名的一维数组写入excel工作表中应占同一行里的连续的100个单元格,如:A1:CV1.
(1)“B = RANGGE("A1:F1") 属于把单元格区域对象的引用赋给一个二维数组B”:Range("A1:F1")不是位于第一行么?怎么变量B是二维数组?
(2)多个同类型的集合不就是数组么?那么有多个名字排在A1单元格里不是数组(一维数组)么?要单元格区域才算是数组?
(3):“但是如果明确A 是一个数组并且用来装A1单元格中的姓名信息,可以 Dim A() as String  这是动态数组的定义方法”,我看了书上关于“动态数组”的介绍,可我在本贴的例子中不知该怎么样写动态数组代码,大侠你写给我看看,好么?
{:soso_e149:}我好笨的啦,谢谢大侠您的耐心解释!

TA的精华主题

TA的得分主题

发表于 2013-2-2 17:44 | 显示全部楼层
Lucky啊 发表于 2013-2-2 16:38
看了好几遍了,还是不懂!
数组:同种类型的多个变量的集合。
书上解释的“一维数组”:排成 ...

我现在要出去,等回来找几个例子说明一下。

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-2-2 18:14 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
{:soso_e154:}不胜感激,谢谢大侠还没放弃我这超级笨蛋小白

TA的精华主题

TA的得分主题

发表于 2013-2-3 16:29 | 显示全部楼层
本帖最后由 hehex 于 2013-2-3 16:30 编辑
Lucky啊 发表于 2013-2-2 18:14
不胜感激,谢谢大侠还没放弃我这超级笨蛋小白

1.首先要了解什么是VBA 数组:
VBA数组就是储存一组数据的数据空间。数据类型可以数字,可以是文本,可以是对象,甚至可以是另一个VBA数组.
2. VBA 数组的存在形态:
VBA数组是以变量形式存放的一个空间,它也有行有列,也可以是三维空间。
可以理解为内存中开辟的一个连续区域。
一维数组在内存中的存贮方式就是一行.。比如数组x(2),就是x(0) x(1) 这样行排列的两个变量的组合
注意:数组默认的下标是从 0开始的,除非你定义VBA数组下标从1 或者从其他数字开始。
二维数组就像一张excel 表格(注意是像,而不是,这个只是帮助理解不要混淆).
比如定义一个二维数组 Dim x (1 to 2, 1 to 2) ' 定义二维数组x ,一、二维下标都从1 开始每个维度都有2个元素。
在内存中是这样排列的就像一张表 X(1,1)  X(1,2)
                                                     X(2,1)  X(2,2)
你可以把这个存贮理解成一张excel 表,第一行第一列就是数组的(1,1) 第一个维度1 代表是在第一行,第2格维度代表列。  再次强调:这个只是帮助理解,无论是工作表对象,还是单元格对象和数组都不是一回事。
三维数组可以理解成为一个立体空间。具体就不详述了,其实在VBA 设计中主要用的是一、二维的VBA 数组。

Okay 首先了解了什么是VBA 数组的基本概念和数组的存贮方式,下面看看如何定义VBA 数组以及VBA 数组的分类:
VBA 数组分为以下几种:
1. 常量数组 使用Array 函数生成的数组。 比如 Array(1,2) 生成一个一维数组,数组成员的值分别是1和2.
2. 静态数组 在使用之前定义好数组的空间。比如 Dim x(5) 是定义一个数组装有5个数组元素,下标是从0-4
再比如 Dim X(1 to 10) 则是定义数组X 一共有10个数组元素,下标从1 开始到10结束。Dim X(1 to 10,1 to 10) 是定义一个二维静态数组,一二维度都有10个元素,下标都从1 开始。
3. 动态数组 Dim x() 这样的语句,在声明的时候数组的元素多少未知,数组维度未知。而在将来在程序中需要使用的时候使用Redim 语句进行重新设置之后使用。

讲完VBA 数组的类型之后,粗浅讲一讲VBA 数组的赋值。
1.首先 看下面的语句
       Dim X(2)
       X(0) = 5
       x(1)  = 7
  这是最简单的给一维数组进行赋值的例子,将一个有2个元素的数组赋值,第一个赋值为5,第二个位置赋值为7.
  
  2. 使用循环往数组里赋值的例子:
       Dim x(1 to 5) ,i as Integer '声明一个从1开始的5 个元素的数组,声明一个整数变量i
       for i  = 1 to 5
            x(i) = Cells (i,1)
       next
     上面这段程序是通过循环把单元格A1-A5 的值赋给数组X 。如果对单元格对象Range,Cell 不了解,请自行查书。通过循环来对数组进行赋值是最常用的方式。
   
   3. 最后我们看看直接通过单元格对象的引用来给数组赋值的例子:
      假设我们有一张excel 表 需要导入数组进行运算以提高工作效率。
      假设该区域是5行3列,就是A1:C5 这个区域要导入
      如果按照上面的方法如何把整张表格导入数组呢
      很明显我们要先按行或者列进行循环(通常是把第二维作为内循环),然后再用另一维进行循环。
      就是要做一个循环嵌套,语句麻烦而且效率比较低。(还有定义单元格对象的for each in 循环的方  法,这里就不讨论了)
      于是excel 给我们提供了一种直接从单元格区域写入数组的方法:
       就是 arr = Range ("A1: C5") 我们前面讲过二维数组的存贮模式,是不是很像一个excel 的二维区域?
       arr(1,1) 就是单元格A1 的值。arr(2,1) 自然就是单元格B1 的值了。这样直接写入数组简单快速,效率高,容易理解。
       直接导入方法有几点要注意下:
         1. 直接从单元格导入数组,必然是二维数组。哪怕是你只导入一行 。系统也默认是一个一行多列的二维数组,这是系统设定的。牢记它。   
                         2. 从单元格导入的数组的维度下标都是从1 开始的。 arr = Range ("A1: F1")
                               arr(1,1) 是A1 的值, arr(1,2) 是B1 以此类推,在这种情况下不会出现arr(0,0)
        

总之,VBA 数组的认识是学习VBA 程序设计的非常重要的组成部分,是提高程序效率必不可少的工具。所以想学习VBA 的人都不是不能绕过的环节。我上面这点粗浅的入门只是讲了最最初级的一点点部分,想加深理解还是要反复看叶枫老师书上对于数组的讲解。另外推荐山菊花老师经典的数组教程“墙上的红辣椒” 可自行去VBA 版精品区查找。

最后,任何教程都只是给你讲个概念,要学会必须自己动手尝试。如果不动手,再好的教程还是白搭,知识还是老师的而不是你自己的。刚开始学习VBA 数组编程的时候,特别是动态数组设计的时候。下标越界这个错误会像影子一样的缠绕着你,动脑子,为什么会发生下标越界,哪里越界了,下标的上下界到底是什么,逐渐想清楚了。在思考中你的数组功力也就小成了。      
         

评分

2

查看全部评分

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-27 21:36 , Processed in 0.044245 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表