为什么我有问题分配一个范围到一个variables数组

我有一些非常简单的代码行几个问题。 让我详细说明事实,看看是否有其他人可以复制这种行为。 如果任何人可以复制,我想解释为什么发生。

所以,让我从一个非常简单的代码行开始工作:

Dim arr() As Variant arr = Range("A1:A10") 

如预期的那样, arr被赋予A1:A10的值A1:A10

现在为什么不会有以下代码行?

 Dim arr() As Variant arr = WorkSheets("Sheet1").Range("A1:A10") 

我得到了运行时错误'13'types不匹配,即使相同的范围已成功地分配给数组,即使没有工作表值。

 Dim arr As Variant arr = Worksheets("Sheet1").Range("A1:A10") 

 Dim arr() As Variant arr = Application.Transpose(Application.Transpose(Worksheets("Sheet1").Range("A1:A10"))) 

能工作吗?

现在,在你回答之前,请让我给你更多的事实。

 Dim arr() As Variant arr = Worksheets(1).Range("A1:A10") 

不起作用

并使用Sheets代替Worksheets也都给出了相同的错误。

我已经通过使用Range("A1:A10").Worksheet.Name确保它与活动引用表单相同Range("A1:A10").Worksheet.Name在工作代码之后,它确实在输出中表示Sheet1

没有其他工作簿是开放的,所以它不能引用另一个工作簿。

现在,这最后一点的代码只会增加我的困惑,因为它完全有效!

 Dim arr() As Variant Dim SampleRange As Range Set SampleRange = Worksheets("Sheet1").Range("A1:A10") arr = SampleRange 

因此,使用SAME RANGE在同一张纸上定义相同的方式,现在将其分配给一个范围variables。 并使用它! 而且正如所料,这与WorkSheetsSheets函数一起工作,无论我如何定义工作表(我可以使用索引或工作表的名称,一切工作正常)

如果它帮助任何人,我在Windows XP机器上使用Excel 2007进行testing。 我还没有在任何其他机器上testing过,但我计划在Windows 7和Windows 8上testing2003和2010,但还没有机会。

更新:不是100%确定,如果这是数组相同的确切问题,但从浅层的看来,似乎是:

  Range("B1:B3") = Range("A1:A3") 

上面的代码将不起作用,即使A1:A3被填充,date,数值,string,公式任何东西,它都会将空格写入B1:B3

 Range("B1:B3").Value = Range("A1:A3").Value 

 Range("B1") = Range("A1") 

工作!

另外工作是:

 Range("B1:B3") = Application.Transpose(Application.Transpose(Range("A1:A3"))) 

不,这不是一个错误。

重点是Value是Range对象的默认属性,为什么它不被隐式使用? 你看看我链接的问题吗? (从聊天 )

以前答复的专家已经详细解释了。 我会保持最小的解释,因此让我知道如果你还有任何问题。

让我们先了解我们的对象。 我创build了这个小桌子,清楚地显示我们正在处理什么,以免混淆。

在这里输入图像描述

您也可以添加一个Watch来查看特定对象的Type ,如下图所示。

在这里输入图像描述

所以当你说

 arr = Range("A1:A10") 

Excel知道默认属性是.Value 。 然而,在其他情况下,它并不知道,因为Excel不是一个读心术,或者让我们说足够聪明,以了解是否要使用Worksheets("Sheet1").Range("A1:A10")作为RangeVariant

一旦你明确地指定了你的对象作为Range然后Excel知道你想要什么。 例如这个工程。

 Dim arr() As Variant Dim Rng As Range Set Rng = Worksheets("Sheet1").Range("A1:A10") arr = Rng 

让我澄清我的评论。
它不适合发表评论,我只是回答,至less清楚我的观点。

 Dim arr As Variant '~~> you declare arr as Variant as what Tim said 

这是什么意思?
这意味着arr可以采取任何forms(例如,整数,string,数组,对象和所有其他Variable Type

 Dim arr() as Variant '~~> you declare arr() as array which may contain Varying `Data Type` 

这是什么意思?
这意味着arr()数组variables可以存储不同的Datatypes。
这不包括ObjectsObjects Collection of Objects

现在,为什么以下工作:

 1. Dim arr() As Variant: arr = Range("A1:A10") 2. Dim arr() As Variant: arr = Sheet1.Range("A1:A10") 3. Dim arr() As Variant: arr = Sheets("Sheet1").Range("A1:A10").Value 

这也适用:

 4. Dim arr() as Variant Dim rng as Range Set rng = Sheets("Sheet1").Range("A1:A10") arr = rng 

以上的作品,因为你不是试图将Collections of Objects分配到一个数组。
相反,您正在分配一个特定的实体或值。
Range是一个对象,但不是对象的Collection of Objects
No.1示例是直接访问Sheets Collection Object
同样如此
No.2因为您使用Sheet1而不是Collection of Sheet Objects Sheet1
No.3是自解释的,你赋值.Value数组。
No.4的工作原理是因为rng已经是一个Range对象,而Set又不是一个Collection of Objects

所以这:

 Dim arr() As Variant arr = Sheets("Sheet1").Range("A1:A10") 

不起作用,因为Excel会将其读为试图从Sheets Collection of Objects分配Sheets Collection of Objects ,从而发生错误。
我希望这是有道理的。

我会说一个东西的数组不是一样东西,因为这个东西可以是一些其他东西的数组 。 如果你将某些东西定义为一个数组,那么你赋予的东西必须是一个数组,它可以是数组,数组,数组,数组,数组,数组,数组,数组等等。

当我们不期望的事情发生时,我相信这是内置的数据types转换,大部分时间我们都能轻松实现。 此转换可能必须是直接对象,而不是对象的属性。

例如,行和列是Longtypes的,但是你可以在其中inputByte / Doubletypes:

Cells(1,1.5)给出Cells(1,2)

您不必将1.5转换为Long; Excel在后台为你做这一切。

当您定义一些东西的数组并将其分配给它时,Excel会在场景后面进行types匹配,并在可能的情况下设置值。

在即时窗口中查看这些信息:

?typename(Range("A1:A10").Value)给你Variant() < – 这就是为什么它在Dim arr() As Variant没有任何问题

?typename(Range("A1:A10"))给你的Range 。 但是,当您将其分配给arr ,其中Dim arr() As Variant ,Excel会使用该Range的值将Range转换为Array。

但是,如果Excel没有直接访问对象,Excel似乎无法转换,除非您为其创build了内存。 例如:

 Dim arr() As Variant, oRng As Range Set oRng = Range("A1:A10") arr = oRng Set oRng = Worksheets("Sheet1").Range("A1:A10") arr = oRng 

上面的代码是完全正确的,但是它不能一次性转换和分配arr = ThisWorkbook.Worksheets("Sheet1").Range("A1:A10") ,除非你抛出一个数组( ThisWorkbook.Worksheets("Sheet1").Range("A1:A10").Value的types是Variant() )。