2011-07-21 52 views
19

我知道你可以很容易地取一些单元格并将它们放到一个Variant数组中,但我想使用一个字符串数组(因为它是单维的,占用的内存比一个Variant数组)。Excel VBA:范围到1个步骤中的字符串数组

有没有办法自动将范围转换为字符串数组?

现在我正在使用一个函数,它将采用范围并将值保存在变量数组中,然后将变量数组转换为字符串数组。它的工作很好,但我正在寻找一种方法,直接从范围到字符串数组。任何帮助将不胜感激。

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 

UPDATE: 它看起来像没有办法第一它转换为一维字符串数组之前跳过数据掷入变量阵列的步骤。如果这是真的,那真可惜(即使它不需要太多的努力,我喜欢超优化,所以我希望有一种方法可以跳过这一步)。如果没有解决方案出现,我会在几天内解决问题。感谢有用的评论,伙计们!

UPDATE2: 回答西蒙,他付出了很大的努力(所有人都这么做),并且很好地指出,从一个镜头范围到字符串阵列确实是不可能的。感谢大家。

+0

有,你可以在VBA访问创建一个非常有效的作用于数组转换直接内存操作例程。我没有时间和技巧来鞭打一个,尽管我在主应用程序中有一些内存映射代码,所以它就在那里,并且会帮助您制作一个非常高效的阵列复制程序。 –

+1

我给出的一些内存函数的链接是[here](http://superuser.com/questions/196565/how-to-merge-data-from-two-differently-structured-excel -files/196577#196577)。 –

+0

尽管我无法将链接中的信息应用于此特定问题,但它是一个很好的阅读和有趣的内容。感谢您的链接。 – aevanko

回答

10

......怎么

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 
+1

我有一个函数,它需要一个变体数组,并将其设置为一个字符串数组(发布时有问题)。寻找一种跳过这一步的方法! – aevanko

+1

啊......我的不好。真的没有办法跳过这一步,尽管简单地调用一个函数进行转换有什么问题?它只有大约10个额外的代码字符... –

+0

@SimonCowen,但是在你的函数中有数百个字符,尽管没有更少,但仍然可以工作 – iliketocode

2
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 
     Set strArray(idx) = c.Text 
     idx = idx + 1 
    Next c 

    RangeToStringArray = strArray 
End sub 
1

如果你不介意改变剪贴板的内容,那么:

  1. COPY的范围与方法复制到剪贴板:

    MyTargetRange.Copy 
    
  2. 将剪贴板中的内容复制到字符串变量(搜索此站点或其他位置,以便将函数传递到剪贴板或从剪贴板传输字符串)。

  3. 分割字符串成变量数组:

    MyStringArray = Split(MyClipboardText, vbCrLf) 
    
  4. 选购:数组将有一个额外的空白元素,因为总是有文字的末尾额外回报(vbCrLf)你刚才复制到剪贴板。要删除只是调整阵列:

    Redim Preserve MyStringArray(Ubound(MyStringArray) - 1) 
    

非常简单和快捷!

缺点是剪贴板可能会改变,当你至少期望它(在重新计算过程中),它只会产生字符串数组(不是双精度或其他数值类型)。

如果您正在使用大量使用相同数据(数千个数据点)的重复函数(数千个),这将非常有帮助。第一次调用函数时,对所需数据范围进行所有中间计算,但将结果保存在静态变量中。还可以通过剪贴板保存输入范围的字符串副本。在随后每次调用函数时,再次通过剪贴板将输入范围转换为文本,并与保存的副本进行比较。如果他们是相同的,你可能会绕过你的初步计算的分配。

+0

也许有人可以添加到如何复制到剪贴板并再次检索它而不改变最高剪贴板数据。也许通过API? –

3

实际上,您可以使用函数Split,Join和分隔符不在文本中直接从范围转到数组。

假设你已指定的值的范围1D作为SrcRange

Dim Array() As String: Array = Split(Join(Application.Transpose(SrcRange), "#"), "#") 
+1

这是唯一回答完整问题“Range to String Array ** in 1 step **”。从Office 2010开始,转置方法通过WorksheetFunction对象进行访问。 'WorksheetFunction.Transpose(SrcRange)' – lonestorm

+0

当我尝试在Excel 2016中执行此操作时,我得到'无效的过程调用或参数'。 – nhinkle

0

VBA中使用的命名范围已经阵列。因此,首先将范围转换为命名范围,然后引用它并删除命名范围。 例如:

ThisWorkbook.Names.Add Name:="test_array", RefersTo:=Sheet1.Range("A4:B10") 
a = Sheet1.Range("test_array") 
ThisWorkbook.Names("test_array").Delete