为什么条件在Do-Loop之外工作,但在其中给出类型不匹配

时间:2016-08-03 11:59:33

标签: excel-vba vbscript vba excel

我在某些vbscript代码中有一个Do-Loop,当我上次使用它时(一两个月前)它肯定有效。今天它没有工作,运行时错误:

  

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-Loop中的if语句中获得Type Mismatch。

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

编写同一个问题可能更相关:为什么If语句在Do-Loop中有一个类型不匹配,但在它不在它之外时呢?

2 个答案:

答案 0 :(得分:2)

表格的单元格中可能存在错误值。

尝试

Do 

    val = objSheet.range(startCell).offset(counter)
    MsgBox TypeName(val)

    if VarType(val) = vbError then val = "Error"
    MsgBox val

    if val = "" then exit do

    counter = counter + 1
    MsgBox counter

Loop

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

如果需要确切地知道它是哪个Excel单元格错误值,那么可以这样做:

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

答案 1 :(得分:1)

即将发布,但@axel-richter已发布beat me too it

但是我认为(带有@jnevill的一些问题的问题在于counter环绕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

一个简单的解决方法是设置一个恒定的上限值

Const MAX_ROWS = 65536

MAX_ROW取自相关链接

中的信息

然后在循环内检查您是否未超过此值

If counter <= MAX_ROWS Then
    ...
End If

另一种方法是使用On Error Resume Next来触发循环退出。

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 

相关链接