2

良い一日:)

参照番号、受取人、オフィス、住所のテキストボックスを備えたプログラムがあります...参照番号が義務テーブルに存在する場合は、自動的に受取人、オフィス、住所が表示されます。存在しない場合は、受取人の名前を入力しますが、 Payeesテーブルに自動的に存在する場合は、OfficeとAddressを配置します。

私の問題は、正しい結果が表示されるのに、「データリーダーに現在のクエリがありません」というメッセージボックスが表示されることです。コードが重なっていると思いますが、解決方法がわかりません。

txtRefNo.Textのコードは次のとおりです。

Private Sub txtRefNo_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtRefNo.TextChanged
    Try
        modGlobalFunctions.Connection.Close()
        modGlobalFunctions.connectDatabase()

        Reader = modGlobalFunctions.executeQuery("SELECT DISTINCT ref_no, payee from bims_obligations " & _
                                                 "WHERE ref_no = '" & txtRefNo.Text & "'")

        If Reader.HasRows Then
            While Reader.Read
                txtPayee.Text = Reader("payee").ToString()
                txtOffice.Text = Reader("office").ToString()
                txtAddress.Text = Reader("address").ToString()

                txtPayee.Enabled = False
                txtOffice.Enabled = False
                txtAddress.Enabled = False

                certALoadGrid()

            End While

        Else

            txtPayee.Clear()
            txtOffice.Clear()
            txtAddress.Clear()

            txtPayee.Enabled = True
            txtOffice.Enabled = True
            txtAddress.Enabled = True

        End If

        Reader.Close()

        modGlobalFunctions.Connection.Close()
    Catch ex As Exception
        MessageBox.Show(ex.Message, "BIMS", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

    modGlobalFunctions.Connection.Close()
End Sub

およびtxtPayee.textの場合:

   Private Sub txtPayee_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtPayee.TextChanged
    Try

        modGlobalFunctions.Connection.Close()
        modGlobalFunctions.connectDatabase()

        Reader = modGlobalFunctions.executeQuery("SELECT * from bims_payee " & _
                                                 "WHERE payee = '" & txtPayee.Text & "'")

        If Reader.HasRows Then
            While Reader.Read
                txtOffice.Text = Reader("office").ToString()
                txtAddress.Text = Reader("address").ToString()

            End While

        Else

            txtOffice.Clear()
            txtAddress.Clear()

        End If

        Reader.Close()

        modGlobalFunctions.Connection.Close()
    Catch ex As Exception
        MessageBox.Show(ex.Message, "BIMS", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

    modGlobalFunctions.Connection.Close()

End Sub

答えを楽しみにしています...またはrefNoが存在する場合、txtPayeeのtextChangeを無視するというifステートメントがありますか?神のご加護を :)

4

1 に答える 1

1

私はこの行を信じています:

txtPayee.Text = Reader("payee").ToString()

txtPayee_TextChanged発火します。次に、次のように呼び出します。

modGlobalFunctions.Connection.Close()
modGlobalFunctions.connectDatabase()

これらの関数のコードは示していませんが、名前は確かに示唆に富んでいます。次に、このグローバル接続オブジェクトを内部txtPayee_TextChangedで使用し、下部で再度閉じます。

最後に、内部のコードtxtRefNo_TextChangedは次の行で再開されます。

txtOffice.Text = Reader("office").ToString()
txtAddress.Text = Reader("address").ToString()

しかし、これReaderは2回閉じられた(または何らかの方法で置き換えられた)接続に関連付けられており、そのコードは表示されていません。エラーが発生します。


これは、グローバルに共有されるオブジェクトを持つことが悪い考えである理由の1つConnectionにすぎません(バックグラウンドワーカー、タスク、またはマルチスレッドを含むその他のものを使い始めたい場合は、それも悪いことです)。

モジュールに接続文字列を含める方がはるかに優れていmodGlobalFunctionsます。次に、各関数内に個別SqlConnectionSqlCommandオブジェクトを作成し、それぞれをUsingステートメント内に配置します。そうすれば、それらは互いに干渉しません。

私はそれを推測しています

modGlobalFunctions.Connection.Close()

同じ問題の以前の症状を治すために、各関数の上部に追加されました


また、私のコメントに示されているように、キャッチせずEx as Exceptionに表示するだけEx.Messageです。どの例外スローされるかわからず、多くの有用な情報(スタックトレースや内部例外など)を破棄しています。


たとえば、これは私があなたの最初のサブを書く方法です:

Private Sub txtRefNo_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtRefNo.TextChanged
    Using conn As New SqlConnection(ConnectionString) 'Our own private connection, no one else can interfere
        Using cmd As New SqlCommand("SELECT DISTINCT ref_no, payee from bims_obligations WHERE ref_no = @RefNo", conn) 'Using parameters, safer SQL
            cmd.Parameters.AddWithValue("@RefNo", txtRefNo.Text)
            conn.Open() 'Open the connection
            Dim Reader = cmd.ExecuteReader()
            If Reader.HasRows Then
                While Reader.Read
                    txtPayee.Text = Reader("payee").ToString()
                    txtOffice.Text = Reader("office").ToString()
                    txtAddress.Text = Reader("address").ToString()

                    txtPayee.Enabled = False
                    txtOffice.Enabled = False
                    txtAddress.Enabled = False

                    certALoadGrid()

                End While

            Else

                txtPayee.Clear()
                txtOffice.Clear()
                txtAddress.Clear()

                txtPayee.Enabled = True
                txtOffice.Enabled = True
                txtAddress.Enabled = True

            End If
            Reader.Close() 'Not really necessary, but anyway
        End Using
    End Using 'These have cleaned up our connection and command objects
        'If an exception has occurred, we don't know what it is, or how to recover
        'So we don't try and catch it.
End Sub
于 2012-10-02T06:17:03.597 に答える