“未设置对象变量或With块变量” 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 组合框以便该函数正常工作? 有可能吗?
提前致谢!
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我在 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 andSET NOCOUNT OFF
just before the final selection (output) statement.您的代码表达了这样的信念:标识符
FillComboBoxFromMDB
已获取对测试过程中赋值左侧的组合框的引用。一旦函数尝试(并失败)将结果分配给左侧,则函数首先执行的情况并非如此,FillCombBoxFromMDB 为 Nothing。
您需要将组合框作为参数传递。
像这样称呼它:-
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.
Call it like this:-
使用 vb6 表单控件的问题是,它们只能在表单中实例化。 什么该死的马屁! 哦,是的,您可以注册控件所在的 DLL。祝您玩得开心! 我在 tcp/ip 套接字上遇到了这个问题。
我的解决方案是创建一个 SocketDriver 接口。 创建一个表单并将套接字放在表单上。 使表格不可见。 在窗体上实现 SocketDriver 接口。 现在您可以传递 SocketDriver 了。
我喜欢安东尼的回答,除了我会用一种方法创建一个名为“DataFiller”的接口。
然后在您的表单上实施。
现在使用签名
通过使用界面,您可以进行一些关注点分离。 您的数据访问对表单或控件一无所知,并且您的表单和控件不知道数据来自哪里,因为依赖于接口
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.
Then implement on your form.
Now use Signature
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
问:在调用 AddItem 之前,FillComboBoxFromMDB 设置为多少?
答:什么都没有,这就是为什么你收到错误
尝试定义一个变量,例如
调用 AddItem ,
然后在函数末尾
或者如果你不想像你尝试那样使用返回类型,则作为另一个答案使用。
Q: What's FillComboBoxFromMDB set to before you call AddItem?
A: Nothing, that is why you get the error
Try defining a variable like
Then calling the AddItem on this
then at the end of the function have
Or as the other answer if you don't want to use a return type like you were trying to use.
您有一个函数声称其返回类型为 ComboBox,但我看不到您实际设置返回值的任何地方。 由于返回值从未设置,因此它将为
Nothing
,因此在访问它时会出现错误。从您提供的用例来看,我认为您想要的是一个适用于现有组合框的辅助子例程。 因此,您可以这样调用它:
并且子例程本身将具有如下签名:
Private Sub FillComboBoxFromMDB(ByVal cbo As ComboBox, _
ByVal sDBName 作为字符串,_
ByVal sSQL As String)
(请注意,它是
Sub
而不是Function
)。 在子例程的主体中,您必须对
传递到子例程的
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 beNothing
, 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:
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 aFunction
). Within the body of the subroutine, where you haveinstead have
to act on the
ComboBox
that was passed into the subroutine.