„Objektvariable oder mit Blockvariablen nicht gesetzt“ Laufzeitfehler in VB6
-
05-07-2019 - |
Frage
Ich habe ein Problem mit VB6 bekommt. Ich habe ein Formular mit mehreren ComboBox-Objekten auf. Ich wünsche den Comboboxen über eine Funktion zu füllen, die eine SQL-Abfrage als Parameter übernimmt. So ist der Code wie folgt aussieht
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
Ich nenne die Funktion wie folgt.
Private Function Test()
' Fill the combobox
frmMyForm.cmbMyCombo = FillComboBoxFromMDB("Database.mdb", _
"SELECT MyTable.MyText FROM MyTable")
End Function
Also im Grunde verstehe ich, dass dies kommt auf Instanziierung, aber ich habe nichts Nützliches über sie online gefunden. Das neue Schlüsselwort funktioniert nicht wie es in VB.Net funktioniert. Wie instanziieren ich die FillComboBoxFromMDB Combobox, so dass die Funktion funktioniert? Ist es überhaupt möglich?
Vielen Dank im Voraus!
Lösung
Sie Code drückt die Überzeugung, dass die Kennung FillComboBoxFromMDB
einen Verweis auf die Combobox auf der linken Seite der Zuweisung im Testverfahren erworben hat.
Dies ist nicht der Fall, die Funktion zuerst mit FillCombBoxFromMDB ist nichts ausgeführt wird, sobald es es versuchen würde (und gescheitert) das Ergebnis der linken Seite zugewiesen werden.
Sie müssen die Combobox als Parameter zu übergeben.
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
Nennen Sie es wie folgt aus: -
Private Function Test()
' Fill the combobox
Call FillComboBoxFromMDB("Database.mdb", _
"SELECT MyTable.MyText FROM MyTable", _
frmMyForm.cmbMyCombo )
End Function
Andere Tipps
Das ist das Problem mit der Arbeit mit VB6-Formular-Steuerelemente, können sie nur in einer Form instanziert werden. Was freakin Scheiß! Oh yeah können Sie die DLL registrieren, die die Kontrollen in residieren. Viel Spaß damit! Ich lief in dem mit dem TCP / IP-Socket.
Meine Lösung war, um eine SocketDriver Schnittstelle zu erstellen. Erstellen Sie ein Formular, und legen Sie die Buchse auf dem Formular. Machen Sie das Formular unsichtbar. Implementieren Sie die SocketDriver Schnittstelle auf dem Formular. Jetzt können Sie die SocketDriver passieren um.
Ich mag Anthony Antwort, mit der Ausnahme, dass ich eine Schnittstelle mit dem Namen ‚DataFiller‘ mit einem Verfahren geführt hätte.
Public Sub AddItem(item As String)
End Sub
Dann auf dem Formular implementieren.
Public Sub AddItem(item As String)
cmbMyCombo.AddItem(item)
End Sub
Jetzt verwenden Signatur
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
die Schnittstelle Durch die Verwendung können Sie einige Trennung von Bedenken haben. Ihr Datenzugriff weiß nichts über Formulare oder Steuerelemente und Ihre froms und Kontrollen nicht wissen, wo die Daten kamen aus, weil die Abhängigkeit ist auf einer Schnittstelle
F: Was ist FillComboBoxFromMDB auf, bevor Sie anrufen AddItem
A: Nichts, das ist, warum Sie den Fehler
Versuchen Sie, eine Variable wie
definierenDim Value as ComboBox
Dann die AddItem auf diesem Aufruf
Value.AddItem(...)
dann am Ende der Funktion
FillComboBoxFromMDB = Value
Oder wie die andere Antwort, wenn Sie nicht wollen, einen Rückgabetyp verwenden, wie Sie verwenden wollten.
Sie haben eine Funktion, die behauptet, dass sein Rückgabetyp ComboBox
ist, aber ich kann nicht überall sehen, wo man tatsächlich jemals den Rückgabewert gesetzt. Da der Rückgabewert nicht gesetzt ist, wird es Nothing
, damit Ihr Fehler, wenn Sie darauf zugreifen.
Von der Verwendung Fall, dass Sie liefern, glaube ich, was Sie wollen, ist ein Helfer-Unterprogramm, das auf einer vorhandene Combobox funktioniert. Also würde man es so nennen:
' Fill the combobox
FillComboBoxFromMDB(frmMyForm.cmbMyCombo, _
"Database.mdb", _
"SELECT MyTable.MyText FROM MyTable")
und das Unterprogramm selbst würde eine Signatur wie folgt aussehen:
Private Sub FillComboBoxFromMDB (ByVal cbo Als ComboBox-, _ ByVal sDBName As String, _ ByVal sSQL As String)
(beachten Sie, dass es sich um eine Sub
ist kein Function
). Innerhalb des Körpers des Unterprogramms, in dem Sie haben
Call FillComboBoxFromMDB.AddItem(DBRecordset.Fields(0).Value)
stattdessen haben
cbo.AddItem(DBRecordset.Fields(0).Value)
auf dem ComboBox
zu handeln, die in das Unterprogramm übergeben wurden.
ich konfrontierte gleiches Problem in VB6 und fand auch eine Lösung.
Der Grund für die Frage war,
meine gespeicherten Prozedur hatte mehrere Select-Anweisungen.
. Lösung: Früher habe ich SET NOCOUNT ON
im Start der gespeicherten Prozedur und SET NOCOUNT OFF
kurz vor der endgültigen Auswahl (Ausgang) Anweisung