【问题标题】:In VBA, how do I access the subject of a With statement from within that statement?在 VBA 中,如何从该语句中访问 With 语句的主题?
【发布时间】:2026-02-09 22:35:01
【问题描述】:

我正在研究一种更快的方法,以在以前编写的代码中循环遍历表中的列。我遇到的问题是,在某些时候我需要将 With 语句的主题(单个单元格范围)分配给范围数组,具体取决于范围和附近单元格的值。

我已经对代码进行了修整,只取了解决问题所必需的那些部分。见下文:

Dim wb As Workbook
Dim wsFit As Worksheet
Dim fittingsTable As ListObject
ReDim fittings(0) As Range
Dim x As Integer
Dim y As Integer

Set wb = ActiveWorkbook
Set wsFit = wb.Worksheets("Fittings")
Set fittingsTable = wsFit.ListObjects("FittingsTable")

For x = 1 To fittingsTable.DataBodyRange.Rows.Count
  With fittingsTable.DataBodyRange(x, 15)
    If .Value <> vbNullString And .Value <> "0" Then
      If .Offset(0, -2).Value <> "TBC" Then
        'Do some stuff
        Set fittings(y) = 'PROBLEM HERE
      Else
        'Do other stuff here
      End If
    End If
  End With
Next

我想将fittingsTable.DataBodyRange(x, 15) 分配给fits(y),但我不知道如何访问作为With 语句主题的范围。

我知道我可以在 With 语句开始之前将所需范围分配给另一个变量,然后将该变量分配给配件(y),但我觉得必须有一种简单的方法来访问初始主题With 声明,这样我就不会用更多的变量来阻塞我的代码。我也可以使用 .Address 属性来使用工作表分配范围,但此时我真的很想找到更直接的方法。

【问题讨论】:

  • 看看你是否被允许做Set fittings(y) = .Cells
  • 配件在哪里定义?像大多数人在使用 VBA 时遇到问题一样,您可以省略 Option Explicit 将该行添加到模块的顶部,编译器会告诉您出了什么问题。
  • Set fittings(y) = fittingsTable.DataBodyRange(x, 15) 有效吗?您尝试过的方法发生了什么变化。
  • 您使用的是单个单元格,因此.Item(1) 将为您提供捕获的范围。我不知道你为什么考虑一个额外的变量“混乱” - 这表明 real 解决方案可能只是提取一些方法。
  • 确实fittingsTable.DataBodyRange.cells(x,15) 工作,看起来像fittingsTable.DataBodyRange 是一个excel.range。

标签: excel vba


【解决方案1】:

您的With 块持有Range 对象引用。

您可以使用.Cells(无参数)属性来检索对该Range 对象的引用:

Set fittings(y) = .Cells

或者,更明确地说,它是一个单单元格范围:

Set fittings(y) = .Cells(1, 1)

这会产生一个隐含的默认成员调用,最终等同于:

Set fittings(y) = .Item(1, 1)

这适用于Range。对于许多其他类,没有返回对象引用的属性。例如,Collection:

With New Collection
    .Add 42
    Set foo = ???? ' can't get a reference to the Collection object!
End With

一般的解决方案是将With块变量提取到一个局部变量中,现在该变量可以像任何其他局部变量一样访问:

Dim c As Collection
Set c = New Collection
With c
    .Add 42
    Set foo = c
End With

对于您控制的自定义类,您可以拥有一个返回 Me 的属性 getter:

Public Property Get Self() As Class1
    Set Self = Me
End Property

现在可以通过该属性访问 With 块变量:

With New Class1
    .Something = 42
    Set foo = .Self
End With

【讨论】: