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:A3
、B1:B3
、C1: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
令人惊讶的是,在 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:A3
、B1:B3
、C1: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