VB6中的“对象变量或块变量未设置”运行时错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VB6中的“对象变量或块变量未设置”运行时错误相关的知识,希望对你有一定的参考价值。

我有VB6的问题。我有一个包含几个ComboBox对象的表单。我希望通过一个以SQL查询作为参数的函数来填充ComboBox。所以代码看起来像这样

Private Function FillComboBoxFromMDB(ByVal sDBName As String, _
                                     ByVal sSQL As String) As ComboBox
    '/*
    ' * Execute SQL in MDB and fill the ComboBox with the results
    ' * Returns filled ComboBox
    ' */
    Dim DB As Database
    Dim DBRecordset As Recordset

    On Error GoTo FillComboBoxFromMDB_ErrHandler

    Set DB = OpenDatabase(sDBName, False, False)

    If Not DB Is Nothing Then
        Set DBRecordset = DB.OpenRecordset(sSQL)
        If Not DBRecordset Is Nothing Then
            If DBRecordset.RecordCount > 0 Then
                Call FillComboBoxFromMDB.AddItem(DBRecordset.Fields(0).Value)
                ' ^^ This row gives the "Object variable or With block variable not set"
            End If
        Else
            Call WriteLog("Unable to execute " & sSQL)
        End If
        DB.Close
    Else
        Call WriteLog("Unable to open " & sDBName)
    End If

    Exit Function
FillComboBoxFromMDB_ErrHandler:
    Call WriteLog("FillComboBoxFromMDB() error: " & Err.Number & " " & Err.Description)
End Function

我把这个函数称为这样。

Private Function Test()
    ' Fill the combobox
    frmMyForm.cmbMyCombo = FillComboBoxFromMDB("Database.mdb", _
                                               "SELECT MyTable.MyText FROM MyTable")
End Function

基本上我理解这归结为实例化,但我没有在网上找到任何有用的东西。 New关键字不能像在VB.Net中那样工作。如何实例化FillComboBoxFromMDB组合框以使该函数有效?它甚至可能吗?

提前致谢!

答案

您的代码表示相信标识符FillComboBoxFromMDB已获取对测试过程中赋值左侧的组合框的引用。

这不是函数首先执行,FillCombBoxFromMDB为Nothing,它会尝试(并且失败)将结果分配给左侧。

您需要将组合框作为参数传递。

Private Sub FillComboBoxFromMDB(ByVal sDBName As String, _
                                     ByVal sSQL As String, ByVal cbo As ComboBox)
    '/*
    ' * Execute SQL in MDB and fill the ComboBox with the results
    ' * Returns filled ComboBox
    ' */
    Dim DB As Database
    Dim DBRecordset As Recordset

    On Error GoTo FillComboBoxFromMDB_ErrHandler

    Set DB = OpenDatabase(sDBName, False, False)

    If Not DB Is Nothing Then
        Set DBRecordset = DB.OpenRecordset(sSQL)
        If Not DBRecordset Is Nothing Then
            If DBRecordset.RecordCount > 0 Then
                Call cbo.AddItem(DBRecordset.Fields(0).Value)
                ' ^^ This row gives the "Object variable or With block variable not set"
            End If
        Else
            Call WriteLog("Unable to execute " & sSQL)
        End If
        DB.Close
    Else
        Call WriteLog("Unable to open " & sDBName)
    End If

    Exit Sub
FillComboBoxFromMDB_ErrHandler:
    Call WriteLog("FillComboBoxFromMDB() error: " & Err.Number & " " & Err.Description)
End Sub

这样称呼: -

 Private Function Test()
 ' Fill the combobox
 Call FillComboBoxFromMDB("Database.mdb", _
                          "SELECT MyTable.MyText FROM MyTable", _
                          frmMyForm.cmbMyCombo ) 
 End Function
另一答案

使用vb6表单控件的问题,它们只能在表单中实例化。什么怪胎'马蹄铁!哦,是的,你可以注册控件所在的DLL。玩得开心!我用tcp / ip socket遇到了这个问题。

我的解决方案是创建一个SocketDriver接口。创建一个表单并将套接字放在窗体上。使表单不可见。在表单上实现SocketDriver接口。现在你可以传递SocketDriver了。

我喜欢Anthony的答案,除了我用一种方法创建了一个名为'DataFiller'的界面。

Public Sub AddItem(item As String)
End Sub

然后在表单上实现。

Public Sub AddItem(item As String)
   cmbMyCombo.AddItem(item)
End Sub

现在使用Signature

Private Sub FillComboBoxFromMDB(ByVal sDBName As String, _
                                 ByVal sSQL As String, ByVal injectWith As DataFiller)
   'yada yada code

   injectWith.AddItem(DBRecordset.Fields(0).Value)

   'yada yada code

End Sub

Private Function Test()
   ' Fill the combobox
   FillComboBoxFromMDB("Database.mdb", _
                                           "SELECT MyTable.MyText FROM MyTable", frmMyForm)
End Function

通过使用界面,您可以分离一些问题。您的数据访问对表单或控件一无所知,并且您的froms和控件不知道该数据来自何处,因为依赖项位于接口上

另一答案

问:在调用AddItem之前,FillComboBoxFromMDB设置为什么? 答:没什么,这就是你得到错误的原因

尝试定义一个变量

Dim Value as ComboBox

然后在此调用AddItem

Value.AddItem(...)

然后在功能结束时有

FillComboBoxFromMDB = Value

或者作为另一个答案,如果你不想使用像你试图使用的返回类型。

另一答案

你有一个函数,声称它的返回类型是ComboBox,但我看不到你实际设置返回值的任何地方。由于永远不会设置返回值,因此它将是Nothing,因此当您访问它时会出现错误。

从你提供的用例中,我认为你想要的是一个适用于现有组合框的辅助子程序。所以你会这样称呼它:

' Fill the combobox
FillComboBoxFromMDB(frmMyForm.cmbMyCombo, _
                    "Database.mdb", _
                    "SELECT MyTable.MyText FROM MyTable")

子程序本身会有这样的签名:

Private Sub FillComboBoxFromMDB(ByVal cbo As ComboBox,_ ByVal sDBName As String,_ ByVal sSQL As String)

(请注意,这是一个Sub而不是Function)。在子程序的主体内,你所拥有的

 Call FillComboBoxFromMDB.AddItem(DBRecordset.Fields(0).Value)

相反

 cbo.AddItem(DBRecordset.Fields(0).Value)

对传递到子程序的ComboBox采取行动。

另一答案

我在vb6中遇到了同样的问题并且也找到了解决方案。

问题背后的原因是,

我的存储过程有多个select语句。

解决方案:我在存储过程的启动时使用了SET NOCOUNT ON,在最终选择(输出)语句之前使用了SET NOCOUNT OFF

以上是关于VB6中的“对象变量或块变量未设置”运行时错误的主要内容,如果未能解决你的问题,请参考以下文章

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

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

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

尝试从C#调试到VB6会产生TYPE_E_CANTLOADLIBRARY?

UPDATE 查询中的错误 - VB6 DAO 访问

在制作exe时,VB6权限被拒绝错误。编译器在创建实例的行停止