首页 > 解决方案 > Excel VBA - 仅在 with 语句之后结束的 while 语句

问题描述

如果仅在“end with”之后放置“wend”,我似乎无法在 with 语句中放置 while 语句。

Sub Testing()

Dim i As Integer
i = 1

With ThisWorkbook.Worksheets("Data")

While i <= 4

.Cells(i, 20).Value = "5"

End With  'get error, as the wend for the while is not yet found

i = i + 1

Wend

End Sub

这是否意味着如果它包含仅在 with 语句之后结束的 while 语句,我不能使用 with 语句?

标签: excelvbawhile-loop

解决方案


在进入 while 语句之前,我需要对工作表做一些事情,但我还需要在 while 完成之前结束

你不能拥有它,它不是合法的语法。块有一个开始和一个结束标记,它们不能交织在一起——无论我们正在查看什么样的块。

非法的:

If condition Then
    '...
    With something
        '...
End If
        '...
    End With

这并不意味着块不能根据需要嵌套!

合法的:

If condition Then
    With something
        '...
    End With
End If

编译器从上到下“读取”代码。当它遇到块语句(例如With)时,它希望下一条End {Block}语句关闭该块 - 如果不是这种情况,则会引发语法错误并且代码无法编译。

所以你根本不能End WithWend令牌之前拥有(注意:Do While...Loop将是首选;还考虑到迭代次数在编译时是已知的,For...Next应该使用循环而不是手动增加循环体​​中的计数器)。

With块有时是实用的,但它从来都不是真正需要的。

在这种特殊情况下,With ThisWorkbook.Worksheets("Data")取消引用存在于ThisWorkbook;中的工作表。如果该工作表ThisWorkbook在编译时存在,那么您可以改用它的 CodeName,从而避免取消引用已经可以从项目中的任何位置全局访问的工作表 -(Name)将该模块的属性设置为 eg DataSheet,然后您可以直接引用,像这样:

DataSheet.Cells(i, 20).Value = "5"

除非您的真实代码是嵌套With语句(为了理智,不应该这样做!),否则将End With令牌移到循环之外以合法地嵌套两个块就足够了。如果循环外的代码也可以使用With块,那么它也可以拥有它:

For i = 1 To 4
    With DataSheet
        .Cells(i, 20).Value = "5"
    End With
Next

With DataSheet
    'other code
End With

推荐阅读