Excel 将二维范围转换为一维范围以在函数中使用

Excel convert 2d range to 1d range for use in functions

令人惊讶的是,在 Google 中搜索答案 以及此站点都没有找到此问题的明显答案,所以我想 post它。

我正在尝试创建一个宏(可能是 UDF),它将二维单元格范围(如 A1:C3)转换为一维范围(a列或行,如 A1:A10)。当需要二维数组时,这将用于 MATCH() 等函数,例如在 A1:C3 中查找特定值。但我希望该函数具有通用性,以便我可以将它拍打在任何二维数组周围,使其成为一维数组。喜欢 =INDEX(ARRAYDIMENSION(A1:C1),4)=MATCH("hello",ARRAYDIMENSION(A1:C1),0)

我已经想到了一个讨厌的方法;我将数组的每一列(对于 A1:C3,即 A1:A3B1:B3C1:C3)在新的 sheet 中相互重叠(因此 A2 被复制到 A2新的 sheet,C3 复制到 A9,B1 复制到 A4 等)

然后我 return 我的新数组的引用 (Sheet2!A1:A9) 所以 MATCH()INDEX() 或现在看起来在那里的任何东西。

它有效,但有一些明显的缺陷;添加一个新的 sheet 对宏来说既费时又丑陋,将各个列堆叠在一起并不是最有效的方法。但特别是,宏编辑 sheet 所以不能是 UDF(我不认为)意味着我必须将它用作 Worksheet_Calculate Sub,它比仅仅放置它更不自包含在任何需要它的公式中。


我认为这比较清楚,请帮助/建议最好的方法,我才使用 VBA 几周,所以我还不是很熟练。

这将帮助您入门:

Function ArrayDim(rn As Range, dir As Integer)
Dim test() As Variant
Dim rng() As Variant
Dim cell As Range
Dim i As Long
rng = rn.Value
ReDim test(1 To UBound(rng, 1) * UBound(rng, 2))
i = 1

If dir = 0 Then
    For r = 1 To UBound(rng, 1)
        For c = 1 To UBound(rng, 2)
            test(i) = rng(r, c)
            i = i + 1
        Next c
    Next r
Else
    For c = 1 To UBound(rng, 2)
        For r = 1 To UBound(rng, 1)
            test(i) = rng(r, c)
            i = i + 1
        Next r
    Next c
End If

ArrayDim = test
End Function

第二个标准是排序的方法:

0 = 逐行 1 = 逐列

也许是这样的?

Function OneDimArray(rng As Excel.Range) As Variant()

Dim v() As Variant
Dim b As Boolean
Dim a() As Variant
Dim irow As Integer
Dim icol As Integer
Dim r As Range

Set r = Range("a1:c2")
v = r.Value

ReDim a(0)

For icol = 1 To r.Columns.Count
    For irow = 1 To UBound(v)
        a(UBound(a)) = v(irow, icol)
        ReDim Preserve a(UBound(a) + 1)
    Next irow
Next icol

OneDimArray = a

End Function