【问题标题】:Array from Range in Excel VBAExcel VBA中的范围数组
【发布时间】:2010-12-05 16:08:02
【问题描述】:

好吧,我一直在为一点点代码苦苦挣扎,似乎无法绕过它...... 我正在尝试从一系列单元格中获取一个数组,但是该数组显示为 1 个元素宽。
好吧,代码如下:

Dim item As Variant
MsgBox Range("D19:H19").Count    
item = Range("D19:H19").Value
MsgBox LBound(item) & " " & UBound(item)   

根据我的理解项目应该包含一个二维数组......但是我得到以下结果 第一个 MsgBox 打印 5 第二个 MsgBox 打印 1 1

怎么了?

【问题讨论】:

  • 我不是 vba 专家,但取一个范围(或数组)的值似乎很奇怪。它是否返回范围的第一个值?
  • 通常 VBA 会返回一个二维数组,其中行值为第 1 维,列值为第 2 维,但是在这里我正在寻找一个在一行中包含 5 个单元格的范围,所以我不太确定是返回一维数组还是二维数组...
  • @dave:是的,它只返回范围的第一个值......有什么想法为什么会这样做吗?!
  • 它实际上并不返回范围的第一个值。选择一个 2D 范围的单元格,然后按几次 Tab。您将看到一个选定的单元格突出显示。那就是单元格Value返回的内容。

标签: vba excel office-2007


【解决方案1】:

这是正确的。即使您选择了一个单元格数组,您仍然可以选择从数组中选择一个单元格(例如,使用制表符逐步浏览该数组的项目)

.Value

只获取当前单选单元格的内容。

如果要枚举数组,可以调用Range-object的.Cells()-方法

假设 D19 到 H19 分别包含“a”到“e”,调用

Range("D19:H19").Cells(2)

返回您"b"。请注意,这是一个基于 1 的数组,可以是二维的。 Cells() 最多使用 2 个参数来指定与选择原点的内部偏移量。

希望澄清...问候

【讨论】:

  • “从工作表中获取值并填充数组”部分中的代码 sn-p support.microsoft.com/kb/213798 显示了类似的代码,所以我想知道为什么我的代码不起作用!
  • 好吧,我在 Excel 2k3 上对此进行了测试。这可能是因为 Value 可能是二维的……lbound 采用第二个参数,它表示为我们所说的维度。我不再确定哪个参数对应哪个值。 VarType(Range("D19:H19").Value) 返回什么?应该是vbArray...你可以试试Ubound(item,1)而不是Ubound(1)
  • 好吧,我尝试了 Ubound(item, 1) 但无济于事。我仍然从第二个 MsgBox 输出中得到 1 1 。关于什么 (Range("D19:H19").Value ) 应该返回...我想我不太确定..我只是在处理代码示例..
  • 嗯,很奇怪……好吧,这篇文章指的是 2007 年之前的所有版本,但不是 2007 年本身。因此,它现在的工作方式可能有所不同。 .Cells(number) 的解决方案怎么样? ...还有一点:尝试使用 item() 而不是 item 声明项目
  • 使用 .Cells(number) 我将不得不在 for-next 循环中遍历范围内的所有单元格,对吧?...好吧,如果没有其他选择,我不会介意寻求这个解决方案......只要它始终如一地工作......
【解决方案2】:

您的项目应包含预期的二维数组。如果您在代码中设置断点并查看 VBA 编辑器中的小“Locals”窗口,您应该会看到。您对 LBound 和 UBound 的调用正在获得第一维的界限。如果你调用 Lbound(item,2) 和 UBound(item,2),你应该得到 1 和 5 如你所愿。

编辑: 也就是说,一旦你完成了分配,item 看起来就像你可以这样声明的东西:

暗淡项目(1 到 1、1 到 5)

VBA 编程的一大弊端是数组可以有任意的下限。所以你所有的代码都需要意识到这一点。

【讨论】:

    【解决方案3】:

    问题出在 LBound 和 UBound 上

    jtolle 关于 LBound 和 UBound 是正确的。

    LBound(item, 2)
    
    UBound(item, 2)
    

    但是,项目不能作为一个数组变暗(你会得到一个错误)。

    我想这就是你想要的

    Dim item As Variant
    MsgBox Range("D19:H19").Count
    item = Range("D19:H19").Value
    
    MsgBox LBound(item, 2) & " " & UBound(item, 2)
    
    For i = LBound(item, 2) To UBound(item, 2)
      MsgBox item(1, i)
    Next
    

    【讨论】:

    • 没错。我的编辑是为了描述通过获取 Range 对象的 Value 属性并将其放入 item 中返回的数组的形式。我并不打算建议将 item 声明为数组,只是一旦分配,它看起来与已声明为数组的变量相同。
    • @imfrancisd:工作就像一个魅力!我仍然不明白我做错了什么,我似乎不明白 VBA 中的数组概念..
    【解决方案4】:

    如果你想要一个一维数组,例如,为了一个 IN 子句加入它,你应该转置你的范围。 我发现你必须为一行转置两次,一次为一列数据,如下所示:

    Dim rngRow As Range, rngColumn As Range
    
    Set rngRow = Sheets(1).Range("A1", "Z1")
    Set rngColumn = Sheets(1).Range("A1", "A20")
    
    Dim arrRowValues, arrColValues
    arrRowValues = WorksheetFunction.Transpose(WorksheetFunction.Transpose(rngRow))
    arrColValues = WorksheetFunction.Transpose(rngColumn)
    
    Dim numList As String, stringList As String
    numList = Join(arrRowValues, ",")
    stringList = "'" & Join(arrColValues, "','") & "'"
    

    值得一玩。

    【讨论】:

      【解决方案5】:

      试试这个:

      Dim item As Variant
      MsgBox Range("D19:H19").Count
      item = Application.Transpose(Range("D19:H19").Value)
      MsgBox LBound(item) & " " & UBound(item)
      

      【讨论】:

      • 我认为“转置”是用于列的...不过无论如何都会检查一下...
      • 仅供参考,转置在 Excel 2003 中不可用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-07
      • 1970-01-01
      • 1970-01-01
      • 2016-06-28
      • 2014-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多