【问题标题】:One-dimensional array from Excel RangeExcel Range 中的一维数组
【发布时间】:2011-10-04 13:57:22
【问题描述】:

我目前正在使用以下代码填充我的数组 Securities:

Option Base 1
Securities = Array(Worksheets(3).Range("A8:A" & SymbolCount).Value)

这会产生一个二维数组,其中每个地址都是 (1...1,1...N)。我想要一个一维数组 (1...N)。

我怎样才能 (a) 将 Securities 填充为一维数组,或者 (b) 有效地将 Securities 剥离为一维数组(我在每个循环中都遇到了问题)。

【问题讨论】:

    标签: excel vba


    【解决方案1】:

    我知道您已经接受了答案,但这里有更简单的代码:

    如果您要抓取单行(多列),请使用:

    Securities = application.transpose(application.transpose _
                 (Worksheets(3).Range("A8:A" & SymbolCount).Value))
    

    如果您要获取单列(多行),请使用:

    Securities = application.transpose(Worksheets(3).Range("A8:A" & SymbolCount).Value)
    

    所以,基本上你只需为行转置两次,为列转置一次。

    更新:

    大表可能不适用于此解决方案(如下评论中所述):

    我在一个大表中使用了这个方案,发现这个技巧有一个限制:Application.Transpose(Range("D6:D65541").Value)'runs without error,但是Application.Transpose(Range("D6:D65542").Value)'run-time error 13 Type mismatch

    更新 2:

    您可能在 cmets 中提到的另一个问题:

    如果超过 255 个字符,则函数失败。

    我已经很久没有使用 Excel VBA 了,但这可能是以这种方式访问​​数据的一般限制?

    【讨论】:

    • 同意这是迄今为止将一行数据转换为一维数组的最简单方法
    • @Emma,我不记得我是从哪里弄到这个把戏的。但我所做的只是将一个 1xn 矩阵更改为 nx1,它只是一个由 n 个单元组成的数组。不知道为什么该行为内置于 Excel 中以这种方式工作。 Excel 中的很多东西都没有很好地记录,这是一个很大的程序!
    • 我在一个大表中使用了这个方案,发现这个技巧有一个限制:Application.Transpose(Range("D6:D65541").Value)'运行没有错误,但是Application.Transpose(Range("D6:D65542").Value)'运行时错误13类型不匹配
    • Transpose() 对于 Excel 2007 及更高版本的 Excel,只能处理最多 65,536 个元素的一维数组。
    • 我知道这篇文章有点老了,但你的回答对我有帮助。仍然是我见过的实现这一目标的最佳解决方案!
    【解决方案2】:
    Sub test2()
        Dim arTmp
        Dim securities()
        Dim counter As Long, i As Long
        arTmp = Range("a1").CurrentRegion
        counter = UBound(arTmp, 1)
        ReDim securities(1 To counter)
        For i = 1 To counter
            securities(i) = arTmp(i, 1)
        Next i
        MsgBox "done"
    End Sub
    

    【讨论】:

    • 选项 (a) 根本不起作用。无论如何,建议的代码应该很快。
    • 抱歉,VBA 新手,你能解释一下第 5 行吗?
    • 作为一般规则:在 VBE 中,单击关键字并按 F1 以获得帮助。 Ubound(arTmp, 2) 返回 arTemp 在 2d 维度中的上界,即列维度。现在我明白了你的问题:我可能在那里犯了一个错误......:-/
    • UBound 行出现“下标超出范围”错误。第 5 行参考查询 CurrentRegion 行 - 为什么有必要?
    • 啊,好的。不,这是没有必要的。你也可以使用arTmp = Range("A8:A" & SymbolCount)
    【解决方案3】:

    这将反映 iDevlop 给出的答案,但我想为您提供一些关于它的作用的更多信息。

    Dim tmpArray As Variant
    Dim Securities As Variant
    
    'Dump the range into a 2D array
    tmpArray = Sheets(3).Range("A8:A" & symbolcount).Value
    
    'Resize the 1D array
    ReDim Securities(1 To UBound(tmpArray, 1))
    
    'Convert 2D to 1D
    For i = 1 To UBound(Securities, 1)
        Securities(i) = tmpArray(i, 1)
    Next
    

    从范围中获取一维数组的最快方法可能是将范围转储到二维数组中并将其转换为一维数组。这是通过声明第二个变体并在将范围转储到第一个变体后使用ReDim 将其重新调整为适当的大小来完成的(请注意,您不需要使用 Array(),您可以像我一样执行此操作上面有,比较清楚)。

    您只需遍历 2D 数组,将每个元素放入 1D 数组中。

    我希望这会有所帮助。

    【讨论】:

    • 我喜欢将其批量转储到二维数组的想法。循环真的需要得到一维数组吗?不是可以ReDim Preserve原来的二维矩阵吗?
    • 您确定 (1) 我们需要两个变量数组,一个用于 1D,第二个用于 2D,(2) 循环遍历所有变量是最快的方式?我们不能只切片或以某种方式重新调整原始数组,从中切掉一个维度吗?
    【解决方案4】:

    如果您将单个列中的值按原样读取到数组中,那么我认为您最终会得到一个需要使用 array(1, n) 语法访问的数组。

    或者,您可以遍历数据中的所有单元格并将它们添加到数组中:

    Sub ReadIntoArray()
        Dim myArray(), myData As Range, cl As Range, cnt As Integer, i As Integer
        Set myData = Worksheets(3).Range("A8:A" & SymbolCount) //Not sure how you get SymbolCount
    
        ReDim myArray(myData.Count)
    
        cnt = 0
        For Each cl In myData
            myArray(cnt) = cl
            cnt = cnt + 1
        Next cl
    
        For i = 0 To UBound(myArray) //Print out the values in the array as check...
            Debug.Print myArray(i)
        Next i
    End Sub
    

    【讨论】:

    • 循环遍历单元格比先将它们转储到二维数组中更慢且效率更低。
    • @Issun - 我同意你的看法。根据我的理解,如果您将单个列范围作为数组读取,则必须使用 array(1, n) 表示法访问它,而 OP 希望能够使用 array(n) 符号。
    • 是的,没错。最快的方法是将整个范围转储到 2D 数组中,然后将其转换为 1D 数组(我还发布了有关如何执行此操作的解决方案)。我已经测试了很多次,它比循环单元格(我也经常这样做)要快得多,尽管循环似乎更直接。 :)
    • @Issun - 您有将二维数组转换为一维数组的解决方案的链接吗?这对我来说是一个很好的学习机会......
    • 我在这个问题上发布了它!
    猜你喜欢
    • 1970-01-01
    • 2016-09-04
    • 1970-01-01
    • 2018-04-10
    • 2017-12-25
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 2022-06-15
    相关资源
    最近更新 更多