从VBA中的范围创建数组

bas*_*lia 27 arrays excel vba range

我有一个看似基本的问题,但无法找到解决它的任何资源.

简单地说,我只想将一系列单元格(所有一列)的内容加载到一个数组中.

我能够通过以下方式实现这一目标

DirArray = Array(Range("A1"), Range("A2"))
Run Code Online (Sandbox Code Playgroud)

但由于某种原因,我不能以这种方式表达时创建数组:

DirArray = Array(Range("A1:A2"))
Run Code Online (Sandbox Code Playgroud)

我的真实范围要长得多(并且长度可能不同),所以我不想以这种方式单独枚举单元格.谁能告诉我如何将整个范围正确加载到数组中?

后面的代码:

MsgBox UBound(DirArray, 1)
Run Code Online (Sandbox Code Playgroud)

MsgBox UBound(DirArray)
Run Code Online (Sandbox Code Playgroud)

返回0,而前者返回1.

vac*_*cip 41

只需将变量定义为变量,并使它们相等:

Dim DirArray As Variant
DirArray = Range("a1:a5").Value
Run Code Online (Sandbox Code Playgroud)

不需要Array命令.

  • 哇,这太明显了。我曾尝试过,但我认为没有与 DirArray(1, 1) 结合使用,而 DirArray(1, 1) 是需要的,而不仅仅是 DirArray(1)。非常感谢! (2认同)
  • 这实际上创建了一个长度为 5 的数组,其中长度为变体之一。 (2认同)
  • 几乎。建议将数组显示为`Variants` 数组。改为声明`Dim DirArray() As Variant`。 (2认同)
  • @ja也许你的观点没有实际意义......这就是为什么我提请你注意它。然而,我的观点毫无意义。保存数组的变体比声明的变体数组灵活得多! (2认同)

Vit*_*ata 20

如果我们这样做:

Dim myArr as Variant
myArr = Range("A1:A10")
Run Code Online (Sandbox Code Playgroud)

新数组将具有两个维度.这并不总是让人感觉舒服:

在此输入图像描述

为了避免这两个维度,当将单个列添加到数组时,我们可以使用内置的Excel函数"Transpose".有了它,数据就变成了一个维度:

在此输入图像描述

如果我们连续存在数据,则单个转置将无法完成工作.我们需要两次使用Transpose函数:

在此输入图像描述

  • 另外,`myArr = [transpose(A1:A10)]` (4认同)
  • 上帝一直以来我都做了多余的步骤。+1 (2认同)
  • 为了节省其他人的时间,较新版本的 Excel 现在具有 Application.WorksheetFunctions.Transpose() 函数 (2认同)

bre*_*tdj 17

使用Value2可带来性能优势.根据Charles Williams的博客

Range.Value2的工作方式与Range.Value相同,只是它不检查单元格格式并转换为Date或Currency.这可能就是为什么它在检索数字时比.Value更快.

所以

DirArray = [a1:a5].Value2
Run Code Online (Sandbox Code Playgroud)


Pao*_*olo 6

除了提出的解决方案之外,如果您有一维范围到一维数组,我更喜欢通过如下函数来处理它。原因很简单:如果出于任何原因您的范围减少到 1 个元素范围,据我所知,命令 Range().Value 将不会返回变体数组,而只是返回变体,并且您将无法分配变体变量到变体数组(先前声明)。

我必须将可变大小范围转换为双精度数组,并且当范围为 1 个单元格大小时,我无法使用像 range().value 这样的构造,因此我继续执行如下所示的函数。

Public Function Rng2Array(inputRange As Range) As Double()

    Dim out() As Double    
    ReDim out(inputRange.Columns.Count - 1)

    Dim cell As Range
    Dim i As Long
    For i = 0 To inputRange.Columns.Count - 1
        out(i) = inputRange(1, i + 1) 'loop over a range "row"
    Next

    Rng2Array = out  
End Function
Run Code Online (Sandbox Code Playgroud)


Dar*_*s99 6

无论范围大小如何,该函数都会返回一个数组。

范围将返回一个数组,除非范围只有 1 个单元格,然后返回单个值。该函数会将单个值转换为数组(从 1 开始,与 range 返回的数组相同)

这个答案改进了以前的答案,因为它会从一个范围返回一个数组,无论大小如何。它也比其他答案更有效,因为如果可能的话,它会返回由范围生成的数组。适用于单维和多维数组

该函数的工作原理是尝试找到数组的上限。如果失败,那么它必须是单个值,因此我们将创建一个数组并将值分配给它。

Public Function RangeToArray(inputRange As Range) As Variant()
Dim size As Integer
Dim inputValue As Variant, outputArray() As Variant

    ' inputValue will either be an variant array for ranges with more than 1 cell
    ' or a single variant value for range will only 1 cell
    inputValue = inputRange

    On Error Resume Next
    size = UBound(inputValue)

    If Err.Number = 0 Then
        RangeToArray = inputValue
    Else
        On Error GoTo 0
        ReDim outputArray(1 To 1, 1 to 1)
        outputArray(1,1) = inputValue
        RangeToArray = outputArray
    End If

    On Error GoTo 0

End Function
Run Code Online (Sandbox Code Playgroud)


小智 5

我再次投票支持迭代范围内的单元格。除非有人找到解决方法,否则我尝试将范围直接分配给 Variant 的经验是,它工作得很好(尽管当我实际上只需要 1D 时返回二维数组),除非我的范围有多个区域,例如,当我只想要筛选表的列中的可见单元格时,或者如果我在工作表上按住 Ctrl 键选择了不同的单元格块时。

使用 for..each 循环迭代该范围内的所有单元格总是会产生我期望的结果。

Public Function RangeToArray(ByRef myRange As Range)
    Dim i As Long
    Dim individualCell As Range
    
    ReDim myArray(myRange.Count - 1)

    For Each individualCell In myRange
        myArray(i) = individualCell.Text         ' or maybe .Value
        i = i + 1
    Next
    RangeToArray = myArray
    
End Function
Run Code Online (Sandbox Code Playgroud)

我想将此添加为对 Paolo 答案的评论,因为它非常相似,但我是新手并且没有足够的声誉,所以这里是另一个略有不同的答案。