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

发布于 2024-07-29 20:57:27 字数 1634 浏览 2 评论 0原文

我在使用 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 组合框以便该函数正常工作? 有可能吗?

提前致谢!

I've got a problem with VB6. I have a form with several ComboBox objects on it. I wish to populate the ComboBoxes via a function that takes a SQL query as a parameter. So the code looks like this

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

I call the function like this.

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

So basically I understand that this comes down to instantiation, but I haven't found anything useful about it online. The New keyword doesn't work like it works in VB.Net. How do I instantiate the FillComboBoxFromMDB combobox so that the function will work? Is it even possible?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

赤濁 2024-08-05 20:57:28

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

问题背后的原因是,

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

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

I faced same problem in vb6 and found a solution too.

The reason behind the issue was,

my stored procedure had multiple select statements.

Solution : I used SET NOCOUNT ON in the starting of stored procedure and SET NOCOUNT OFF just before the final selection (output) statement.

静待花开 2024-08-05 20:57:27

您的代码表达了这样的信念:标识符 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

You code expresses the belief that the identifier FillComboBoxFromMDB has acquired a reference to the combobox on the left hand side of the assignment in the Test procedure.

This is not the case the function will execute first with FillCombBoxFromMDB being Nothing once it it would attempt (and fail) to assign the result to the left hand side.

You need to pass the combobox as a parameter.

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

Call it like this:-

 Private Function Test()
 ' Fill the combobox
 Call FillComboBoxFromMDB("Database.mdb", _
                          "SELECT MyTable.MyText FROM MyTable", _
                          frmMyForm.cmbMyCombo ) 
 End Function
傾旎 2024-08-05 20:57:27

使用 vb6 表单控件的问题是,它们只能在表单中实例化。 什么该死的马屁! 哦,是的,您可以注册控件所在的 DLL。祝您玩得开心! 我在 tcp/ip 套接字上遇到了这个问题。

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

我喜欢安东尼的回答,除了我会用一种方法创建一个名为“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

通过使用界面,您可以进行一些关注点分离。 您的数据访问对表单或控件一无所知,并且您的表单和控件不知道数据来自哪里,因为依赖于接口

That the problem with working with vb6 form controls, they can only be instantiated in a form. What freakin' horseshit! Oh yeah you can register the DLL that the controls reside in. Have fun with that! I ran into this with the tcp/ip socket.

My solution was to create a SocketDriver interface. Create a form and put the socket on the form. Make the form invisible. Implement the SocketDriver interface on the form. Now you can pass the SocketDriver around.

I like Anthony's answer, except that I would have created an interface named 'DataFiller' with one method.

Public Sub AddItem(item As String)
End Sub

Then implement on your form.

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

Now use 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

By using the interface you can have some separation of concerns. Your data access knows nothing about forms or controls and your froms and controls does not know where that data came from because the dependency is on an interface

如歌彻婉言 2024-08-05 20:57:27

问:在调用 AddItem 之前,FillComboBoxFromMDB 设置为多少?
答:什么都没有,这就是为什么你收到错误

尝试定义一个变量,例如

Dim Value as ComboBox

调用 AddItem ,

Value.AddItem(...)

然后在函数末尾

FillComboBoxFromMDB = Value

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

Q: What's FillComboBoxFromMDB set to before you call AddItem?
A: Nothing, that is why you get the error

Try defining a variable like

Dim Value as ComboBox

Then calling the AddItem on this

Value.AddItem(...)

then at the end of the function have

FillComboBoxFromMDB = Value

Or as the other answer if you don't want to use a return type like you were trying to use.

风吹短裙飘 2024-08-05 20:57:27

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

从您提供的用例来看,我认为您想要的是一个适用于现有组合框的辅助子例程。 因此,您可以这样调用它:

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

并且子例程本身将具有如下签名:

Private Sub FillComboBoxFromMDB(ByVal cbo As ComboBox, _
ByVal sDBName 作为字符串,_
ByVal sSQL As String)

(请注意,它是 Sub 而不是 Function)。 在子例程的主体中,您必须

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

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

传递到子例程的 ComboBox 进行操作。

You have a function which claims that its return type is ComboBox, but I can't see anywhere where you ever actually set the return value. Since the return value is never set, it will be Nothing, hence your error when you access it.

From the use case you supply, I think what you want is a helper subroutine that works on an existing combobox. So you would call it like this:

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

and the subroutine itself would have a signature like this:

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

(note that it is a Sub not a Function). Within the body of the subroutine, where you have

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

instead have

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

to act on the ComboBox that was passed into the subroutine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文