【问题标题】:Excel VBA Copying range values to an Array,Excel VBA将范围值复制到数组,
【发布时间】:2016-02-14 23:47:25
【问题描述】:

我有以下代码摘录,我试图将一系列值复制到声明的数组中,但它不断给我“无法分配给数组”错误,

Dim permittedCurve(0 To 7000) As Variant

permittedCurve = activeWorkbook.Worksheets("Origin").Range("AB6:AB7006").value

我也试过这个,但给了我同样的错误..

Dim permittedCurve(7000) As Variant

permittedCurve = application.transpose(activeWorkbook.Worksheets("Origin").Range("AB6:AB7006").value)

有人可以帮忙吗?我真的没有看到这两种方法有什么问题。 :-(

==============================

更新

我已经尝试了以下,

Dim permittedCurve(4) As Variant
Dim indicationCurve(4) As Variant

indicationCurve(0) = 1
indicationCurve(1) = 10
indicationCurve(2) = 100
indicationCurve(3) = 1000
indicationCurve(4) = 10000

'Copying the curves
permittedCurve = indicationCurve

这仍然会产生相同的“无法分配给数组”错误...为什么?

【问题讨论】:

  • excel是什么版本的?它有 7000 列吗?另外,您的范围没有 7001 值吗?试试 allowedCurve(7001)
  • 当您声明一个数组(0 到 7000)时,数组中的总元素为 7001,与我定义的范围相匹配。 (行数组),我使用的是 Excel 2016 64 位版本。无论如何,我确实尝试过(7001)并且不起作用..
  • @lukieleetronic 我在网上看到的使用转置执行此操作的唯一示例是他们声明没有最小和最大范围的变体(permittedCurve),然后为其分配一个数组 - 但显然你可以完成通过重新调整变体来实现同样的事情 - 我对我的回复进行了编辑

标签: arrays excel vba


【解决方案1】:

当您从工作表的单元格中批量加载时,您总是会得到一个二维数组。第一等级可以被认为是“行”,第二等级可以被认为是“列”。

dim permittedCurve As Variant
'the following is the same as redim permittedCurve(1 to 3, 1 to 6)
permittedCurve = Range("A1:F3").Value2
debug.print lbound(permittedCurve, 1) & ":" & ubound(permittedCurve, 1)
debug.print lbound(permittedCurve, 2) & ":" & ubound(permittedCurve, 2)
'results from the Immediate window:
1:3
1:6

考虑到使用原生 TRANSPOSE function 的问题(和开销),如果您打算从工作表中来回挖掘值,请坚持使用二维数组en masse

可以通过更改变量声明来解决更新后的问题。

Dim permittedCurve As Variant  '<~~ just a variant, not specifically a variant array with 5 elements
Dim indicationCurve(4) As Variant

indicationCurve(0) = 1
indicationCurve(1) = 10
indicationCurve(2) = 100
indicationCurve(3) = 1000
indicationCurve(4) = 10000

'Copying the curves
permittedCurve = indicationCurve
'now it's a variant array with 5 elements

【讨论】:

  • 哦.. 它有效。它将值作为字符串保存为二维数组格式。将其转换为具有 double 类型的直单数组是否相当复杂?
  • 辅助函数可以快速完成;您完全在内存中工作,因此循环不会减慢。该函数必须识别某物是 1×6 还是 6×1,但 LBoundUBound 函数可以通过比较等级来确定。 tbh,我对这种方法进行了一些尝试,但由于我通常在数组中工作,主要目的是快速处理以将值返回到工作表,因此我最终只使用二维数组。
【解决方案2】:

您可以一次一个单元格完成 - 这似乎是一种缓慢的方法,但只有 7000 个单元格,它应该在几分之一秒内运行

Dim rngTarget As Range
Set rngTarget = ActiveWorkbook.Worksheets("Origin").Range("AB6:AB7006")

Dim permittedCurve(0 To 7000) As Variant

Dim i As Long
For i = 0 To UBound(permittedCurve)
    permittedCurve(i) = rngTarget.Cells(i + 1, 1)
Next i

编辑 1:学到新东西 - 尝试:

Dim permittedCurve() As Variant
ReDim permittedCurve(1 To 7001)
permittedCurve = Application.Transpose(Range("AB6:AB7006"))

For i = 1 To UBound(permittedCurve)
    Debug.Print permittedCurve(i)
Next

【讨论】:

  • 我知道这种方法效果很好,但我确实需要使用上述方法,因为我正在最大限度地优化。
  • 它对你有用吗?它给了我“下标超出范围”错误。
【解决方案3】:

我今天在 Excel 365 中遇到了类似的错误(这就是我发现这个线程的原因),看起来这是由于 VBA 对象的某种怪异。似乎只要您的工作表对象与范围分开定义,并且工作表处于活动状态,就可以接受范围到变体的转换。

Dim wkb As Workbook:    Set wkb = Workbooks("WorkbookName.xls")
Dim wks As Worksheet:   Set wks = wkb.Worksheets("WorksheetName")
Dim strRange As String: strRange = "A1:Z1"

' Setting a range for a worksheet that's not active gives an error
' Don't know why. Just need to do it.
wks.Activate
Dim rng As Range:       Set rng = wks.Range(strRange)

Dim varRange() As Variant
varRange = rng                                             ' Works
varRange = rng.Value                                       ' Works
varRange = wks.Range(strRange)                             ' Works
varRange = wkb.Worksheets("WorksheetName").Range(strRange) ' Does not work

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多