For Each循环不查看Range.Columns的单个单元格

时间:2016-08-11 12:45:34

标签: excel vba excel-vba

我有一个函数,它传递一系列和两个范围作为参数:

Call settInnISerie(.SeriesCollection("Toppsuging"), r, langsone.Columns(2))
Sub settInnISerie(srs As Series, xverdier As Range, yverdier As Range)
  Dim c As Range
  Dim i As Long

  srs.XValues = xverdier
  srs.Values = yverdier
  i = 1
  srs.ApplyDataLabels
  For Each c In yverdier.Offset(0, -1)
    If Not IsError(c) And i <= srs.Points.Count Then
      srs.Points(i).DataLabel.Text = "=" & Replace(c.Address(external:=True), "[" & ThisWorkbook.Name & "]", "", 1, -1, vbTextCompare)
    End If
    i = i + 1
  Next c
End Sub

然而,我在if语句中的行上出现错误,抱怨&#34; Method&#39; DataLabel&#39;对象&#39;点&#39;失败&#34;

尝试追踪错误,我尝试打印出循环中使用的每个对象的值,并发现不是像我预期的那样在yverdier范围内偏移一个范围内的每个单元格而不是{ {1}}引用第一个直通的整个列。

通常当我使用类似的构造时情况并非如此,为什么c - 循环在这种情况下表现不同?解决问题的最简单方法是什么?

显然我可以做foreach,但我很困惑,对我来说,VBA是一种奇怪的行为。

1 个答案:

答案 0 :(得分:3)

我认为这是预期的行为。

您将yverdier定义为langsone.Columns(2),这意味着yverdierRange类型的集合,集合中包含一列(多个单元格)。我认为你的解释是yverdier是由langsone.Columns(2)内的单元组成的单一范围,但两者之间存在细微差别。

因此,For...Each上的Range循环将迭代集合中的每一列(单个列),而不是Cells。如果编码,我想你会得到你的欲望行为:

For Each c In yverdier.Offset(0, -1).Cells

此示例代码和调试输出显示了我在实践中的含义 - 只需创建一个空白工作簿并将此代码放在Module中:

Option Explicit

Sub Test()

    Dim rngSource As Range
    Dim rng As Range

    Set rngSource = Sheet1.Range("A1:D3")

    Debug.Print "Columns:"
    For Each rng In rngSource.Columns
        Debug.Print rng.Address
    Next rng

    Debug.Print "Rows:"
    For Each rng In rngSource.Rows
        Debug.Print rng.Address
    Next rng

    Debug.Print "Cells:"
    For Each rng In rngSource.Cells
        Debug.Print rng.Address
    Next rng

    Debug.Print "No property:"
    For Each rng In rngSource
        Debug.Print rng.Address
    Next rng

End Sub

将输出:

Columns:
$A$1:$A$3
$B$1:$B$3
$C$1:$C$3
$D$1:$D$3
Rows:
$A$1:$D$1
$A$2:$D$2
$A$3:$D$3
Cells:
$A$1
$B$1
$C$1
$D$1
$A$2
$B$2
$C$2
$D$2
$A$3
$B$3
$C$3
$D$3
No property:
$A$1
$B$1
$C$1
$D$1
$A$2
$B$2
$C$2
$D$2
$A$3
$B$3
$C$3
$D$3