【问题标题】:Excel VBA: Range to String Array in 1 stepExcel VBA:1步中范围到字符串数组
【发布时间】:2011-10-10 00:51:31
【问题描述】:

我知道您可以轻松地将一系列单元格放入 Variant 数组,但我想使用字符串数组(因为它是一维的,并且比 Variant 数组占用更少的内存)。

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

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

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 

更新: 看起来没有办法在将数据转换为一维字符串数组之前先跳过将数据放入变量数组的步骤。如果这是真的很遗憾(即使不需要太多努力,我也喜欢超优化,所以我希望有一种方法可以跳过这一步)。如果没有解决方案,我将在几天后结束这个问题。感谢你们提供帮助的 cmets,伙计们!

更新2: 西蒙付出了巨大的努力(其他人也是如此),并最终指出确实不可能一次从范围到弦阵列。谢谢大家。

【问题讨论】:

  • 您可以在 VBA 中访问直接的内存操作例程,以创建一个非常有效的函数来转换数组。虽然我的主应用程序中确实有一些内存映射代码,但我没有时间和技能来编写一个,所以它就在那里,它将帮助您制作一个非常有效的数组复制程序。
  • 我给出的带有一些记忆功能的答案的链接是here
  • 虽然我无法将您链接中的信息应用到这个特定问题,但它是一本很好的阅读书,很有趣。感谢您的链接。

标签: arrays string excel vba range


【解决方案1】:

您实际上可以使用Split、Join 和文本中没有的分隔符直接从一个范围转到一个数组。

假设您已经将一维值范围指定为 SrcRange

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

【讨论】:

  • 这是完整问题的唯一答案,“范围到字符串数组在 1 步中”。从 Office 2010 开始,转置方法通过 WorksheetFunction 对象访问。 WorksheetFunction.Transpose(SrcRange)
  • 当我尝试在 Excel 2016 中执行此操作时,我收到 Invalid procedure call or argument
【解决方案2】:

怎么样...

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

【讨论】:

  • 我已经有一个函数,它接受一个变体数组并使其成为一个字符串数组(发布有问题)。正在寻找跳过这一步的方法!
  • 啊……我的错。确实没有办法跳过这一步,尽管必须简单地调用一个函数来转换有什么问题?毕竟只有大约 10 个额外字符的代码......
  • @SimonCowen 但你的函数中有数百个字符,但仍然有效
  • 请注意,这对于单个单元格失败,因为 variantValues 将不是一个数组,而是单个 Variant 值。您可以添加一个简单的theRange.Cells.Count = 1 支票来解决这种情况。
【解决方案3】:
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

【讨论】:

    【解决方案4】:

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

    1. 使用 Copy 方法将范围复制到剪贴板:

      MyTargetRange.Copy
      
    2. 将剪贴板中的内容复制到字符串变量中(在此站点或其他地方搜索将字符串传入/传出剪贴板的函数)。

    3. 将字符串拆分为变量数组:

      MyStringArray = Split(MyClipboardText, vbCrLf)
      
    4. 可选:该数组将有一个额外的空白元素,因为在您刚刚复制到剪贴板的文本的末尾总是有一个额外的 Return (vbCrLf)。要删除,只需调整数组的大小:

      Redim Preserve MyStringArray(Ubound(MyStringArray) - 1)
      

    非常简单快捷!!!

    缺点是剪贴板可能会在您最不期望的时候发生变化(在重新计算期间),并且它只生成字符串数组(不是双精度数或其他数值类型)。

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

    【讨论】:

    • 也许有人可以添加到这里关于如何复制到剪贴板并再次检索它而不改变最顶部的剪贴板数据。也许通过 API?
    【解决方案5】:

    VBA 中使用的命名范围已经是数组。所以首先将范围变成命名范围,然后引用它并删除命名范围。 例如:

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

    【讨论】:

      猜你喜欢
      • 2011-10-21
      • 2019-06-04
      • 2019-01-06
      • 2017-01-28
      • 1970-01-01
      • 2010-12-05
      • 1970-01-01
      • 2015-05-26
      • 2013-06-06
      相关资源
      最近更新 更多