You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB编译错误:End If无对应Block If(含嵌套Do While)

VBA编译错误“End If without block If”的解决办法

你的代码核心问题出在Do循环的语法错误,导致编译器解析混乱,才触发了End If相关的错误提示。

问题点拆解

你写的Do循环结构不符合VBA语法规范:

Do
    ' 循环内容
While Not error_rng Is Nothing

正确的Do...While循环必须加上Loop关键字,结构应为Do...Loop While。因为循环结构不完整,编译器无法正确识别代码块边界,才会误判End If的匹配关系。

另外代码还有两个容易踩坑的细节:

  1. 变量声明不规范:原代码Dim search_rng, error_range, result_range, result As range里,只有最后一个result是Range类型,前面三个变量默认是Variant类型,需要逐个声明类型。
  2. Find循环死循环风险:原代码里没有更新error_rng的逻辑,找到第一个匹配项后会一直循环,需要添加FindNext来查找下一个匹配值,同时记录第一个匹配地址避免重复循环。

修正后的完整代码

Function GetBOMEntriesWithoutRM() As Variant
    Dim tbl As ListObject
    Dim search_rng As Range, error_rng As Range, result_rng As Range, result As Range
    Dim dict As New Dictionary
    Dim sht As Worksheet ' 补充声明sht变量

    On Error GoTo Fail
    For Each sht In ThisWorkbook.Worksheets
        ' 先判断工作表是否存在表对象,避免报错
        If sht.ListObjects.Count > 0 Then
            Set tbl = sht.ListObjects(1)
            
            If tbl.Name Like "tbBOM*" Then
                Set result_rng = tbl.ListColumns("Item").DataBodyRange
                Set search_rng = tbl.ListColumns("RMIndex").DataBodyRange
                Set error_rng = search_rng.Find(What:=CVErr(xlErrNA), LookIn:=xlValues)
                
                If Not error_rng Is Nothing Then
                    Dim firstAddr As String
                    firstAddr = error_rng.Address ' 记录第一个匹配地址,避免循环重复
                    Do
                        Set result = Intersect(error_rng.EntireRow, result_rng)
                        ' 建议存单元格值而非单元格对象,避免后续引用问题
                        If Not dict.Exists(result.Cells(1).Value) Then
                            dict.Add result.Cells(1).Value, result.Cells(1).Value
                        End If
                        Set error_rng = search_rng.FindNext(error_rng)
                    Loop While Not error_rng Is Nothing And error_rng.Address <> firstAddr
                End If
            End If
        End If
    Next sht
    
    GetBOMEntriesWithoutRM = dict.Items()
    Exit Function
    
Fail:
    GetBOMEntriesWithoutRM = 0
    
End Function

额外说明

  • 使用字典前,需要在VBA编辑器的「工具」→「引用」里勾选Microsoft Scripting Runtime,否则会报错。
  • 原代码中字典存的是单元格对象,改为存单元格值能避免后续引用失效的问题。

内容的提问来源于stack exchange,提问作者ebrahim alfardan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 20:23:27