简体   繁体   中英

vb.NET: Textbox TextChange

Good day:)

I have a program with textboxes for Reference Number, Payee, Office and Address... What I want is that if the Reference Number exists in Obligation Table it will automatically put Payee, Office and Address, If not, you will type Payee's name but if exists in Payees table automatically it will put the Office and Address...

my problem is that it displays the correct result BUT a message box saying "No current query in data reader." I think the code are overlapping each other but i don't know how to resolve this.

Here's my code for 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

and for 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

Looking forward for answers... or is there an if statement that if refNo exists then it will disregard textChange of txtPayee??? God bless :)

I believe that this line:

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

Will cause txtPayee_TextChanged to fire. Which then calls:

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

You haven't shown us the code for those functions, but the names are certainly suggestive. You then use this global connection object inside txtPayee_TextChanged , and close it again at the bottom.

Finally, the code inside txtRefNo_TextChanged resumes with these lines:

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

But that Reader is associated with a connection that's been closed twice (or replaced, in some fashion, again, you've not shown that code) - and you'll have an error.


This is but one reason why having a globally shared Connection object is a bad idea (it's also bad if/when you want to start using background workers, Tasks, or anything else that involves multithreading).

It would be far better to just have a connection string in your modGlobalFunctions module. Then, inside each function, create separate SqlConnection and SqlCommand objects - placing each within Using statements. That way they will not interfere with each other.

I'm guessing that the

modGlobalFunctions.Connection.Close()

Were added at the top of each function to cure an earlier symptom of the same issue


Also, as indicated in my comment - don't catch Ex as Exception and just display Ex.Message . You have no idea what exceptions might be thrown, and you're disposing of a lot of useful information (such as the Stack Trace and Inner Exception)


Eg this is how I'd write your first sub:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM