我遇到了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组合框以使该函数有效?它甚至可能吗?
提前致谢!
答案 0 :(得分:7)
您的代码表示相信标识符FillComboBoxFromMDB
已在测试过程中获取了对分配左侧组合框的引用。
如果FillCombBoxFromMDB一旦尝试(并且失败)将结果分配到左侧,那么函数将首先执行该函数。
您需要将组合框作为参数传递。
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
答案 1 :(得分:2)
使用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
现在使用签名
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和控件不知道数据的来源,因为依赖项在接口上
答案 2 :(得分:1)
问:在调用AddItem之前,FillComboBoxFromMDB设置为什么?
答:没什么,这就是你得到错误的原因
尝试定义像
这样的变量Dim Value as ComboBox
然后在此
上调用AddItemValue.AddItem(...)
然后在函数的末尾有
FillComboBoxFromMDB = Value
如果您不想使用像您尝试使用的返回类型,则作为另一个答案。
答案 3 :(得分: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
而不是Function
)。在子程序的主体内,你有
Call FillComboBoxFromMDB.AddItem(DBRecordset.Fields(0).Value)
而不是
cbo.AddItem(DBRecordset.Fields(0).Value)
对传递给子程序的ComboBox
采取行动。
答案 4 :(得分:1)
我在vb6中遇到了同样的问题并找到了解决方案。
问题背后的原因是,
我的存储过程有多个select语句。
解决方案:我在存储过程的开始使用SET NOCOUNT ON
,在最终选择(输出)语句之前使用SET NOCOUNT OFF
。