VB6:运行时错误“13”:设置和 int 时类型不匹配 int

Posted

技术标签:

【中文标题】VB6:运行时错误“13”:设置和 int 时类型不匹配 int【英文标题】:VB6: Runtime Error '13': Type Mismatch when setting and int with an int 【发布时间】:2009-05-08 16:00:50 【问题描述】:

我对 VB6 编程并不陌生,但我也不是它的大师。希望有人能帮我解决一个关于类型不匹配错误的问题,我尝试使用从函数返回的 int 设置 int 变量。

我试图设置的整数定义为:

Global AICROSSDOCKStatus As Integer

现在,当我尝试进行此调用时,我得到了运行时错误 13

AICROSSDOCKStatus = ProcessQuery(iocode, pb, AICROSSDOCBOLFN, "")

我已经逐行调试了程序。 ProcessQuery 函数获取并返回预期的整数,但是当分配给 AICROSSDOCKStatus 时它失败了。

顺便说一句,我还尝试对 ProcessQuery 执行 CInt(),结果相同。

有人对我可以尝试的方法有什么建议吗?

编辑: 这是ProcessQuery的定义

Function ProcessQuery(icode As Integer, pb As ADODB.Recordset, TableName As String, sql$) As Integer

编辑 2:我无法告诉你为什么以这种方式完成。我继承了代码库。哎呀...


Function ProcessQuery(icode As Integer, pb As ADODB.Recordset, TableName As String, sql$) As Integer
    ProcessQuery = ProcessQuery1(icode, pb, TableName, sql$)
End Function

Function ProcessQuery1(icode As Integer, pb As ADODB.Recordset, TableName As String, sql$) As Integer
''THIS IS THE ORIGINAL SQL CALL ROUTINE!
Dim STATUS As Integer
On Error GoTo ProcessSQLError

STATUS = 0
Select Case icode
   Case BCLOSE
        If pb.State  0 Then
            pb.Close
        End If
        Set pb = Nothing
        STATUS = 3
    Case BOPEN
        STATUS = 9
        Set pb = New ADODB.Recordset
    Case BOPENRO
        STATUS = 9
        Set pb = New ADODB.Recordset
    Case BGETEQUAL, BGETEQUAL + S_NOWAIT_LOCK, BGETGREATEROREQUAL, BGETGREATEROREQUAL + S_NOWAIT_LOCK
        If pb.State  0 Then
            pb.Close
            ''Set pb = Nothing
            ''Set pb = New ADODB.Recordset
        End If
        pb.Open sql$, MISCO_SQL_DB, adOpenDynamic, adLockOptimistic
        If Not pb.EOF Then
            pb.MoveFirst
        Else
            STATUS = 9
        End If
    Case BGET_LE, BGET_LE + S_NOWAIT_LOCK
        If pb.State  0 Then
            pb.Close
        End If
        pb.Open sql$, MISCO_SQL_DB, adOpenDynamic, adLockOptimistic
        If Not pb.BOF Then
            pb.MoveLast

        Else
            STATUS = 9
        End If
    Case BGETFIRST, BGETFIRST + S_NOWAIT_LOCK
        If pb.State  0 Then pb.Close
        sql = "select * from " + TableName
        If InStr(1, gblOrderBy, "ORDER BY") > 0 Then
            sql = sql + gblOrderBy
        Else
            sql = sql + " ORDER BY " + gblOrderBy
        End If

        gblOrderBy = ""
        pb.Open sql$, MISCO_SQL_DB, adOpenDynamic, adLockOptimistic
        If Not pb.EOF Then
                                                        pb.MoveFirst
        End If
    Case BGETLAST, BGETLAST + S_NOWAIT_LOCK
        If pb.State  0 Then
            pb.Close
        End If
        sql = "select * from " + TableName
        If InStr(1, gblOrderBy, "ORDER BY") > 0 Then
            sql = sql + gblOrderBy
        Else
            sql = sql + " ORDER BY " + gblOrderBy
        End If
        gblOrderBy = ""
        pb.Open sql$, MISCO_SQL_DB, adOpenDynamic, adLockOptimistic
        If Not pb.EOF Then
            pb.MoveFirst
            pb.MoveLast
        End If
    Case BGETNEXT, BGETNEXT + S_NOWAIT_LOCK:            pb.MoveNext
    Case BGETPREVIOUS, BGETPREVIOUS + S_NOWAIT_LOCK:    pb.MovePrevious
    Case B_UNLOCK
        ''need to add code here
    Case BINSERT
        If pb.State = 0 Then
            pb.Open TableName, MISCO_SQL_DB, adOpenDynamic, adLockOptimistic
        End If
    Case BDELETE
        STATUS = 8
        pb.Delete
    Case Else
        STATUS = 1
        MsgBox "STOP: UNDEFINDED PROCEDURE" + Str$(icode)
End Select
If STATUS = 0 Then
    If pb.EOF Or pb.BOF Then STATUS = 9
End If

ProcessQuery1 = STATUS
Exit Function

ProcessSQLError:
    MsgBox TableName + ": " + Error(Err), vbCritical, "Error "
    ProcessQuery1 = 9

End Function

【问题讨论】:

你能发布ProcessQuery的定义吗? 您能否发布 ProcessQuery 的完整代码而不仅仅是签名? 哇。有些人编码好像维护程序员是一个知道自己住在哪里的暴力精神病患者。其他人编写的代码会将任何维护者变成暴力精神病患者。 ProcessQuery1是二流派的产物。 介绍 Msgbox:以简单的方式处理错误!毕竟,Err.Raise 和错误处理程序只是......太复杂了。你现在需要你的错误并且需要它们在你的脸上!! BAM! vbCritical 你今天采用了这个新的错误处理“最佳实践”!! (注意:实际结果可能会有所不同。使用 MsgBox 作为错误处理策略实际上可能会导致调试时间增加、更多挫败感、更高的胆固醇和脱发。在极少数情况下,由于刨削导致失明勺子等餐具的眼睛也可能发生)。 【参考方案1】:

好吧,我不能说我知道出了什么问题,但这里有一个可能的调试步骤:首先分配一个本地定义的整数,然后将 AICROSSDOCKStatus 分配给本地 int。如果运行时 err 13 发生在第一次分配时,那么确实会发生一些奇怪的事情 - 如果它发生在第二次,那么您可能想查看是否有任何全局变量是您可能超出界限的数组。

祝你好运!

【讨论】:

【参考方案2】:

尝试使用一个中间变体,它应该从你的函数中获取任何类型的类型。它至少应该允许您调查返回值的真实类型。

【讨论】:

【参考方案3】:

这将告诉您函数实际返回的类型的名称:

MsgBox TypeName(ProcessQuery(...)) 

将 ProcessQuery() 函数限制为 int 在任何情况下都可能有助于从一开始就防止此类错误:

Function ProcessQuery(whatever arguments) As Integer
  ''// ...
End Function

【讨论】:

当我在 ProcessQuery1 上的 ProcessQuery 中尝试这个时,我得到了预期的“整数”。当我尝试 TypeName(ProcessQuery(...)) 时出现错误。 那我猜错误发生在within ProcessQuery1()。取消注释“On Error Goto”语句以查看它的位置。顺便说一句,函数 ProcessQuery1() 是......相当混乱,委婉地说。类型不匹配根本不是它唯一的问题。 你不是在开玩笑说它有问题。它通过ProcessQuery1,当在ProcessQuery中达到'End Function'时出现错误。 由于 ProcessQuery() 和 ProcessQuery1() 似乎具有完全相同的签名...您可以直接在代码中调用 ProcessQuery1() 来获得乐趣吗? 所以错误确实实际上发生在 ProcessQuery1() 函数中。您是否注释掉了“On Error”声明?字符串连接是用 VB 中的“&”运算符完成的,而不是用“+”。也许就是这样(“sql =”select * from “+ etc. etc.”)。【参考方案4】:

API 返回一个 16 位的 VB6 整数有点不寻常。很多时候,翻译 C 函数原型的人会将 c“int”与 VB6 Integer 混淆,而在 VB6 中等价物实际上是 Long。

【讨论】:

【参考方案5】:

问题不在于函数的返回有问题,而是通过引用传递的参数有问题。我需要一个 Recordset(pb) 以通过引用传递,但我已将 (pb) 声明为 Record。

【讨论】:

【参考方案6】:

试试下面的,看看值是不是int,

msgbox ProcessQuery(iocode, pb, AICROSSDOCBOLFN, "")

我确信它不会是 int 并且这是它失败的结果。我的猜测是,它会带有字符,使其成为非数字值。

你可以尝试IsNumeric()函数对结果进行检查,是否为数值。

【讨论】:

以上是关于VB6:运行时错误“13”:设置和 int 时类型不匹配 int的主要内容,如果未能解决你的问题,请参考以下文章

在 vb6 中填充组合框时出现运行时错误 0

是啥导致此运行时错误 13“类型不匹配”?

将数据类型 int 转换为 nvarchar 时出错

vb6.0中所有字符输入之间的距离

vb6上的错误“运行时错误-2147319779自动化错误对象库未注册”

运行时错误:有符号整数溢出:2147483647 + 1 不能以“int”类型表示