Excel 为什么条件在Do循环外工作,但在Do循环内提供类型不匹配

Excel 为什么条件在Do循环外工作,但在Do循环内提供类型不匹配,excel,vbscript,vba,Excel,Vbscript,Vba,我在一些vbscript代码中有一个Do循环,当我上次使用它时(一两个月前),它肯定能工作。今天,它无法工作,出现运行时错误: Microsfot VBScript运行时错误:第{行上有Do的行}处的类型不匹配 以下是原始代码: counter = 0 Do until objSheet.range(startCell).offset(counter) = "" counter = counter + 1 Loop 我已经通过添加if语句测试了条件语句是

我在一些vbscript代码中有一个Do循环,当我上次使用它时(一两个月前),它肯定能工作。今天,它无法工作,出现运行时错误:

Microsfot VBScript运行时错误:第{行上有Do的行}处的类型不匹配

以下是原始代码:

counter = 0 
Do until objSheet.range(startCell).offset(counter) = ""     
    counter = counter + 1
Loop
我已经通过添加if语句测试了条件语句是否应该工作:

counter = 0 
call writeLine(objSheet.range(startCell).offset(counter))    
if not objSheet.range(startCell).offset(counter) = "" then call writeLine("not blank")
Do until objSheet.range(startCell).offset(counter) = ""     
    counter = counter + 1
Loop
if语句执行良好,在我的输出窗口中,我得到:

10100

不空白

但是,在第一次尝试时,它仍然会在Do行上获得类型不匹配

然后我尝试了另一个Do循环:

counter = 0
call writeLine(objSheet.range(startCell).offset(counter))   
if not objSheet.range(startCell).offset(counter) = "" then call writeLine("not blank")
    
Do 
    if objSheet.range(startCell).offset(counter) = "" then
        Exit Do
    else
        counter = counter + 1
    end if
Loop
它仍然输出“10100,非空”,也就是说,它执行第一个if语句时绝对没有问题,但随后它在Do循环中的if语句上得到了类型不匹配

为什么会出现类型不匹配?


编写相同问题的可能更相关的方式:为什么If语句在Do循环内时类型不匹配,而在Do循环外时类型不匹配?

工作表的单元格内可能存在错误值

试一试


要明确的是: 如果代码试图将Excel单元格错误值与字符串
进行比较,则会引发运行时错误。当然,您可以通过错误处理捕获运行时错误。但是,在包含单元格错误值的单元格之后读取单元格会有很多困难。因此,在我看来,更好的方法是检查是否存在单元格错误值,如果存在,则将其转换为字符串。因此不会抛出运行时错误

如果需要确切地知道它是哪个Excel单元格错误值,则可以执行以下操作:

...
    if VarType(val) = vbError then val = objSheet.range(startCell).offset(counter).text
    MsgBox val
...

刚要发帖,但已经发了

但我认为问题在于(
计数器
在你的
Do
循环中循环的速度太快,以至于你到达了一个
Offset()
,工作表不喜欢它,它返回一个

Microsoft VBScript运行时错误:类型不匹配

您可以使用
On Error Resume Next
来测试这一点,以确定
Err.Source
的值是多少,以查看Excel COM是否引发了错误

counter = 0
Call writeLine(objSheet.range(startCell).offset(counter))   
If Not objSheet.range(startCell).offset(counter) = "" Then Call writeLine("not blank")

Do
    'Capture errors
    On Error Resume Next
    'If the "If" statement errors will jump over and execute the next
    'statement which will be the error check.
    If objSheet.range(startCell).offset(counter) = "" Then
        Exit Do
    Else
        counter = counter + 1
    End If
    If Err.Number <> 0 Then
        Call writeLine("Error: " & Err.Source & " (" & Err.Number & ") - " & Err.Description)
    End If
    'Stop capturing errors.
    On Error Goto 0
Loop
#
MAX_ROW
从相关链接中的信息中获取的值

然后在循环检查中,您没有超过此值

If counter <= MAX_ROWS Then
    ...
End If

相关链接

startCell的定义在哪里?看起来像是将整数与字符串进行比较,这将导致类型不匹配的错误。使用
Len(objSheet.range(startCell).offset(counter)=”
作为条件,而不是
objSheet.range(startCell).offset(counter)&“<1
。在什么迭代中失败。当它出错时,点击“调试”,查看
计数器的值是多少。我的猜测是,在它失败之前,你经历了很多迭代。计数器定义为整数。也许它的最大值是65535(VBA中整数的上限)。相反,把它定义为长循环。当你写“notblank”时,你就在循环之外了。循环的迭代只影响内部的代码。当它失败时,请仔细检查计数器的值。如果循环中的If语句结果为false,则只需迭代计数器。您不做任何其他操作,因此它可能迭代得非常快。在
counter=counter+1
行之前,粘贴一个
debug.print计数器
,然后您可以在VBA的即时窗口中观察迭代的发生。循环的第一行不是仍然会出错吗?它不会返回
vbError
它只是触发一个运行时错误。@Lankymart-Nope,它可以工作。阿克塞尔一针见血:我在表格中的一些单元格中有错误值。Axel的代码处理错误,防止类型不匹配。@AndyT啊,没错,这很有意义。就像我说的,不要再做很多Excel COM的东西了。因此,我猜实际单元格中包含
#ERROR
。@Lankymart-#REF在本例中,但我假设#N/A和任何其他excel错误类型也会出现同样的问题。
Const MAX_ROWS = 65536
If counter <= MAX_ROWS Then
    ...
End If
Dim value
...
Do
    'Capture errors
    On Error Resume Next
    value = objSheet.range(startCell).offset(counter)
    If value = "" Or Err.Number <> 0 Then
        Exit Do
    Else
        counter = counter + 1
    End If
    On Error Goto 0
Loop