Excel VBA: Range to String Array in 1 step
我知道您可以轻松地获取一系列单元格并将它们拍打成Variant数组,但是我想使用字符串数组(因为它是一维的,并且比Variant数组占用的内存少)。
有什么方法可以自动将范围转换为字符串数组?
现在,我正在使用一个函数,它将取范围并将值保存在变量数组中,然后将变量数组转换为字符串数组。它很好用,但是我正在寻找一种直接从范围到字符串数组的方法。任何帮助将不胜感激。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Function RangeToArray(ByVal my_range As Range) As String() Dim vArray As Variant Dim sArray() As String Dim i As Long vArray = my_range.Value ReDim sArray(1 To UBound(vArray)) For i = 1 To UBound(vArray) sArray(i) = vArray(i, 1) Next RangeToArray = sArray() End Function |
更新:
看起来没有办法在将数据转换为一维字符串数组之前先跳过将数据扔到变量数组中的步骤。如果确实如此,那真是太可惜了(即使不花很多功夫,我也喜欢超优化,所以我希望有办法跳过这一步)。如果没有解决办法,我将在几天后解决这个问题。谢谢大家的有用评论!
UPDATE2:
答案是西蒙(Simon)付出了很大的努力(其他所有人也都做了),并明确指出,实际上不可能一枪而行地从范围到弦阵。感谢大家。
怎么样...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Public Function RangeToStringArray(theRange As Excel.Range) As String() ' Get values into a variant array Dim variantValues As Variant variantValues = theRange.Value ' Set up a string array for them Dim stringValues() As String ReDim stringValues(1 To UBound(variantValues, 1), 1 To UBound(variantValues, 2)) ' Put them in there! Dim columnCounter As Long, rowCounter As Long For rowCounter = UBound(variantValues, 1) To 1 Step -1 For columnCounter = UBound(variantValues, 2) To 1 Step -1 stringValues(rowCounter, columnCounter) = CStr(variantValues(rowCounter, columnCounter)) Next columnCounter Next rowCounter ' Return the string array RangeToStringArray = stringValues End Function |
实际上,您可以使用文本中未包含的分割,连接和定界符功能直接从范围转到数组。
Assuming you have already assigned a 1D range of values as SrcRange
1 | Dim Array() As String: Array = Split(Join(Application.Transpose(SrcRange),"#"),"#") |
1 2 3 4 5 6 7 8 9 10 11 12 | Function RangeToStringArray(myRange as range) as String() ReDim strArray(myRange.Cells.Count - 1) As String Dim idx As Long Dim c As Range For Each c In myRange strArray(idx) = c.Text idx = idx + 1 Next c RangeToStringArray = strArray End Function |
如果您不介意更改剪贴板的内容,则:
使用Copy方法将范围复制到剪贴板:
1 | MyTargetRange.Copy |
将内容从剪贴板复制到字符串变量(在此站点或其他位置搜索用于向/从剪贴板传输字符串的函数)。
将字符串拆分为一个变量数组:
1 | MyStringArray = Split(MyClipboardText, vbCrLf) |
可选:数组将有一个附加的空白元素,因为在刚复制到剪贴板的文本的末尾总会有一个附加的Return(vbCrLf)。要删除,只需调整数组大小:
1 | Redim Preserve MyStringArray(Ubound(MyStringArray) - 1) |
非常简单快捷!
缺点是剪贴板可能会在您最不期望的时候发生变化(在重新计算过程中),并且只会产生字符串数组(而不是Doubles或其他数值类型)。
如果您正在使用大量使用相同数据(数千个数据点)的重复函数(数千个),这将非常有用。第一次调用函数时,对所需数据范围进行所有中间计算,但将结果保存在静态变量中。还可以通过剪贴板保存输入范围的字符串副本。以后每次调用函数时,再次通过剪贴板将输入范围转换为文本,然后与保存的副本进行比较。如果它们相同,则可以绕过初步计算的分配。
VBA中使用的命名范围已经是数组。因此,首先将范围设为命名范围,然后引用它并删除命名范围。
例如:
1 2 3 | ThisWorkbook.Names.Add Name:="test_array", RefersTo:=Sheet1.Range("A4:B10") a = Sheet1.Range("test_array") ThisWorkbook.Names("test_array").Delete |