我有一个函数,该函数传递了一系列和两个范围作为参数:
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语句内的行上收到错误,抱怨“对象'Point'的方法'DataLabel'失败”。
尝试查找错误,我尝试打印出循环中使用的每个对象的值,发现与在
yverdier
偏移一个偏移c
的范围内的每个单元格不同,foreach
引用了第一列的整个列直通。通常情况并非如此,为什么在这种情况下
for i = 1 to c.rows.count...
-loop的行为有所不同?解决问题的最简单方法是什么? 显然我可以做ojit_code,但是我对VBA的奇怪行为感到困惑。
最佳答案
我认为这是预期的行为。
您将yverdier
定义为langsone.Columns(2)
,这意味着yverdier
是Range
类型的集合,集合中有一个(多个单元格)单列。我认为您的解释是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