2009-07-30 21 views
2

VB6に問題があります。私はそれにいくつかのComboBoxオブジェクトを持つフォームを持っています。私は、パラメータとしてSQLクエリを取る関数を介してComboBoxesを設定したいと思う。コードは次のようになります"オブジェクト変数またはWithブロック変数が設定されていません" VB6のランタイムエラー

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コンボボックスをインスタンス化するにはどうすればよいですか?それも可能ですか?

ありがとうございます!

+3

おめでとうございます! VB6の2つのエラーメッセージの1つに遭遇しました! (他の唯一のものは「メソッド '〜'はオブジェクト '〜'にありません」) –

+2

「ActiveXエラー429」を忘れないでください:) – AakashM

+0

これは、最も楽しいものの1つです。私はちょうど2000年からその機能を追加するためにそれらの遺産のプロジェクトを得るのが大好き... – Gert

答えて

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 
+0

OKですが、これは基本的に機能を持つという考え方を打ち消します。それをSubに変換して、コンボボックスByRefを渡してください。 – Gert

+1

戻り値で何もできない場合、関数を持つ点はありません。 VB6のコンボボックスは、他の値と同様に作成して割り当てることはできません。あなたが見ることができるように、私は既にそれをSubに変換しました – AnthonyWJones

+0

ええ、ちょうど何かがあるかどうか知りたかっただけです。私はこれがうまくいかないことに気をつけました。それをクリアしていただきありがとうございます。 – Gert

1

Q:FillComboBoxFromMDBはあなたがAddItemメソッドを呼び出す前に設定は何ですか?
A:何も、それはあなたがエラーを取得する理由

は次に、関数の最後で、この

Value.AddItem(...) 

にAddItemメソッドを持って呼び出す

Dim Value as ComboBox 

のような変数を定義してみています

FillComboBoxFromMDB = Value 

また、yあなたが使用しようとしていたような戻り値の型を使いたくない。

+0

残念ながらそれは動作しません。 – Gert

+1

これは 'Dim Value As ComboBox'が新しい' ComboBox'をインスタンス化しないので動作しません。 –

+0

そうですね、それは私が意味したことです。 – Gert

1

戻り値の型がComboBoxであると主張する関数がありますが、実際に戻り値を設定する場所はどこにもありません。戻り値は決して設定されないので、それはNothingになります。したがって、アクセス時のエラーです。

あなたが提供するユースケースからは、の既存のコンボボックスで動作するヘルパーサブルーチンが必要だと思います。だから、このようにそれを呼び出します。

' Fill the combobox 
FillComboBoxFromMDB(frmMyForm.cmbMyCombo, _ 
        "Database.mdb", _ 
        "SELECT MyTable.MyText FROM MyTable") 

とサブルーチン自体はこのような署名しています:文字列、_ ByValのSSQLとして

プライベートサブFillComboBoxFromMDB(コンボボックスとしてByVal CBO、_ ByValのsDBNameをAs String)

Subではなく、Functionであることに注意してください)。あなたは

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

を持つサブルーチン、体内の代わりに

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

はサブルーチンに渡されたComboBoxに行動しなければなりません。

2

vb6フォームコントロールを操作する際の問題は、フォームでのみインスタンス化できます。何が馬鹿だ!ああ、コントロールが存在するDLLを登録することができます。楽しんでください!私はtcp/ipソケットでこれに遭遇しました。

私の解決策は、SocketDriverインターフェイスを作成することでした。フォームを作成し、フォームにソケットを配置します。フォームを非表示にします。フォームにSocketDriverインターフェイスを実装します。これでSocketDriverを渡すことができます。

私はアンソニーの答えが好きですが、私は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やコントロールはその依存関係がインターフェイス上にあるため、そのデータの出所を知らない。

1

vb6で同じ問題が発生した。

問題の原因は、

私のストアドプロシージャには複数のselect文があります。

解決方法:ストアドプロシージャの開始時にSET NOCOUNT ONを使用し、最後の選択(出力)ステートメントの直前にSET NOCOUNT OFFを使用しました。

関連する問題