&引用;对象变量或未设置块变量";VB6中的运行时错误

&引用;对象变量或未设置块变量";VB6中的运行时错误,vb6,runtime,instantiation,Vb6,Runtime,Instantiation,我对VB6有问题。我有一个表单,上面有几个ComboBox对象。我希望通过一个将SQL查询作为参数的函数来填充组合框。代码如下所示 Private Function FillComboBoxFromMDB(ByVal sDBName As String, _ ByVal sSQL As String) As ComboBox '/* ' * Execute SQL in MDB and fill the C

我对VB6有问题。我有一个表单,上面有几个ComboBox对象。我希望通过一个将SQL查询作为参数的函数来填充组合框。代码如下所示

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
所以基本上我理解这归结为实例化,但我还没有在网上找到任何有用的东西。新关键字的工作方式与VB.Net中的工作方式不同。如何实例化FillComboBoxFromMDB combobox,以便该函数能够工作?有可能吗


提前谢谢

代码表示标识符
FillComboBoxFromMDB
在测试过程中获取了对赋值左侧的combobox的引用

如果函数尝试(并且失败)将结果分配到左侧,则函数将首先执行,FillComboxFromMDB为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

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

尝试定义一个变量,如

Dim Value as ComboBox
然后调用此附加项

Value.AddItem(...)
然后在函数的末尾有

FillComboBoxFromMDB = Value

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

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

从您提供的用例来看,我认为您需要的是一个在现有组合框上工作的助手子例程。你可以这样称呼它:

' Fill the combobox
FillComboBoxFromMDB(frmMyForm.cmbMyCombo, _
                    "Database.mdb", _
                    "SELECT MyTable.MyText FROM MyTable")
子例程本身会有这样的签名:

' Fill the combobox
FillComboBoxFromMDB(frmMyForm.cmbMyCombo, _
                    "Database.mdb", _
                    "SELECT MyTable.MyText FROM MyTable")
私有子FillComboBoxFromMDB(ByVal cbo作为组合框_ ByVal sDBName作为字符串_ ByVal sSQL(作为字符串)

(请注意,它是
子功能
而不是
功能
)。在子例程的主体中,在

 Call FillComboBoxFromMDB.AddItem(DBRecordset.Fields(0).Value)
取而代之的是

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

要对传递到子例程的组合框执行操作。

使用vb6表单控件时出现的问题,只能在表单中实例化它们。真他妈的胡说八道!哦,是的,你可以注册控件所在的DLL。玩得开心!我在使用tcp/ip套接字时遇到了这个问题

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

我喜欢Anthony的答案,只是我会用一个方法创建一个名为“DataFiller”的接口

Public Sub AddItem(item As String)
End Sub
然后在表单上实现

Public Sub AddItem(item As String)
   cmbMyCombo.AddItem(item)
End Sub
现在使用签名

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

通过使用该接口,您可以实现一些关注点分离。您的数据访问对窗体或控件一无所知,而您的from和控件也不知道数据来自何处,因为依赖关系在接口上

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

这个问题背后的原因是,

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


解决方案:我在存储过程开始时使用了
setnocounton
,在最终选择(output)语句之前使用了
setnocountoff

OK,但这基本上违背了函数的概念。也可以将其转换为Sub并将combobox ByRef传递。如果不能对其返回值执行任何操作,则函数没有意义。VB6中的组合框不像其他值那样可以创建和指定。正如你所看到的,我已经把它转换成了潜艇是的,我只是想知道是否有办法。我有一种预感,这不会发生。谢谢你的澄清。虽然我同意你不能像创建普通对象那样创建组合框(使用新语句),但为什么你不能传递它们?@Ant:你没有理由不能传递它们,我在上面的代码中传递了一个。祝贺你!您遇到了VB6的两条错误消息之一!(唯一的另一个是“对象“~”上没有方法“~”)别忘了“ActiveX错误429”:)嗯,这是最有趣的一个,是的。我只是喜欢让那些2000年遗留项目为……添加功能……我们都经历过,格特,我们感受到了你的痛苦。:)由于ComboBox没有实例化新的
ComboBox
,因此这将无法作为
暗值。是的,对于该示例,很抱歉,它并不意味着是一个工作示例,而是指向正确的方向,因为我在回答时没有VB。感谢其他评论者注意到这一点,希望能有所帮助!