2

我遇到了VB6的问题。我有一个表格,上面有几个 ComboBox 对象。我希望通过一个将 SQL 查询作为参数的函数来填充 ComboBoxes。所以代码看起来像这样

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 组合框以使该函数起作用?甚至可能吗?

提前致谢!

4

5 回答 5

7

您的代码表达了这样一种信念,即标识符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
于 2009-07-30T13:22:42.833 回答
2

使用 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

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

于 2009-07-31T05:07:45.137 回答
1

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

尝试定义一个变量,如

Dim Value as ComboBox

然后在此调用 AddItem

Value.AddItem(...)

然后在函数的末尾有

FillComboBoxFromMDB = Value

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

于 2009-07-30T13:23:54.067 回答
1

您有一个声称其返回类型为的函数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不是 a Function)。在子例程的主体内,你有

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

而是有

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

ComboBox对传递给子例程的那个采取行动。

于 2009-07-30T13:27:05.093 回答
1

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

问题背后的原因是,

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

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

于 2011-11-10T08:54:46.747 回答