“オブジェクト変数またはWithブロック変数が設定されていません” VB6のランタイムエラー
-
05-07-2019 - |
質問
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コンボボックスをインスタンス化するにはどうすればよいですか?可能ですか?
事前に感謝します!
解決
コードは、 FillComboBoxFromMDB
という識別子が、Testプロシージャの割り当ての左側にあるコンボボックスへの参照を取得したという信念を表しています。
関数が最初に実行されるのは、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
他のヒント
vb6フォームコントロールの操作に関する問題は、フォームでのみインスタンス化できることです。なんて馬鹿げた!そうそう、コントロールが存在するDLLを登録できます。楽しんでください! tcp / ipソケットでこれに遭遇しました。
私の解決策は、SocketDriverインターフェースを作成することでした。フォームを作成し、フォームにソケットを配置します。フォームを非表示にします。フォームにSocketDriverインターフェイスを実装します。これでSocketDriverを渡すことができます。
Anthonyの回答が好きですが、1つのメソッドで「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
インターフェースを使用することで、懸念事項を分離できます。データアクセスはフォームやコントロールについては何も知りません。また、依存関係がインターフェイスにあるため、データがどこから来たのかをfromやコントロールは知りません
Q:AddItemを呼び出す前にFillComboBoxFromMDBは何に設定されますか?
A:何もありません。だからエラーが発生します
次のような変数を定義してみてください
Dim Value as ComboBox
そして、この上でAddItemを呼び出す
Value.AddItem(...)
関数の最後にある
FillComboBoxFromMDB = Value
または、使用しようとしているような戻り値の型を使用したくない場合の別の回答として。
戻り値の型が 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
であることに注意してください)。サブルーチンの本文内で、
Call FillComboBoxFromMDB.AddItem(DBRecordset.Fields(0).Value)
代わりに持っている
cbo.AddItem(DBRecordset.Fields(0).Value)
サブルーチンに渡された ComboBox
に作用します。
vb6で同じ問題に直面し、解決策も見つかりました。
問題の背後にある理由は、
私のストアドプロシージャには複数の選択ステートメントがありました。
解決策:ストアドプロシージャの開始時に SET NOCOUNT ON
を使用し、最終選択(出力)ステートメントの直前に SET NOCOUNT OFF
を使用しました。