Click here to Skip to main content
15,884,176 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I am developing a project employee management system. I have a form Attendance which will be used to take attendance. I want to insert those employee records into the database which a checked . But I am getting error. Also suggest an alternative way to take the attendance.

Code:
-----------------------------------------------------------------
VB
Private Sub btnmark_Click(sender As Object, e As EventArgs) Handles btnmark.Click
        Try
            con.Open()
            com = New SqlCommand()
            com.Connection = con
            com.CommandText = "mark_attendance"
            com.CommandType = CommandType.StoredProcedure
         
            For Each employee In CheckedListBox1.CheckedItems
                getDetails()
                com.Parameters.AddWithValue("@empid", CheckedListBox1.GetItemText(employee))
                com.Parameters.AddWithValue("@empname", empname)
                com.Parameters.AddWithValue("@dept", dept)
                com.Parameters.AddWithValue("@date", System.DateTime.Today)
            Next
            com.ExecuteNonQuery()
            MsgBox("Attendance Marked...!", MsgBoxStyle.Information)
        Catch ex As Exception
            MsgBox(ex.Message)
        Finally
            con.Close()
        End Try
    End Sub

    Private Sub btnexit_Click(sender As Object, e As EventArgs) Handles btnexit.Click
        Me.Close()
    End Sub
    Private Sub getDetails()
        Try
            con.Open()
            com = New SqlCommand("SELECT empname,dept from emp_master where empid=@empid", con)
            com.Parameters.AddWithValue("@empid", CheckedListBox1.SelectedItem)
            dr = com.ExecuteReader
            If dr.HasRows Then
                While dr.Read
                    dept = dr("dept")
                    empname = dr("empname")
                End While
            End If
        Catch ex As Exception
            MsgBox(ex.Message)
        Finally
            dr.Close()
            con.Close()
        End Try
    End Sub
End Class

-----------------------------------------------------------
Error:
-----------------------------------------------------------
1). The connection was not closed. The connection's current state is open.
2). ExecuteNonQuery requires an open and available Connection. The connection's current state is closed.
Posted
Comments
Thanks7872 9-Apr-15 13:19pm    
Refer ADO.NET documentation. You need to have look at some of it's basics.
Herman<T>.Instance 9-Apr-15 13:36pm    
Where/What line does the exception occur?

1 solution

You're sharing the same connection object across multiple methods, which is a bad idea.

When you call the getDetails method, the shared connection object is already open, so the con.Open call throws an exception. The Finally block then closes the connection, so your ExecuteNonQuery call fails as well.

The best solution would be to update your mark_attendance stored procedure to read the name and department for the passed-in employee ID.

Otherwise, you'll need to execute two queries for each checked item:
VB.NET
Private Sub btnmark_Click(sender As Object, e As EventArgs) Handles btnmark.Click
   Using connection As New SqlConnection("YOUR CONNECTION STRING HERE")
      Using markCommand As New SqlCommand("mark_attendance", connection)
         Using getDetailsCommand As New SqlCommand("SELECT empname,dept from emp_master where empid = @empid", connection)
            
            markCommand.CommandType = CommandType.StoredProcedure
            connection.Open()
            
            For Each employee In CheckedListBox1.CheckedItems
               Dim empid As String = CheckedListBox1.GetItemText(employee)
               Dim empname, dept As String
               
               getDetailsCommand.Parameters.Clear()
               getDetailsCommand.Parameters.AddWithValue("@empid", empid)
               Using dr As SqlDataReader = getDetailsCommand.ExecuteReader()
                  If dr.Read() Then
                     empname = CStr(dr("empname"))
                     dept = CStr(dr("dept"))
                  End If
               End Using
               
               markCommand.Parameters.Clear()
               markCommand.Parameters.AddWithValue("@empid", empid)
               markCommand.Parameters.AddWithValue("@empname", empname)
               markCommand.Parameters.AddWithValue("@dept", dept)
               markCommand.Parameters.AddWithValue("@date", DateTime.Today)
               markCommand.ExecuteNonQuery()
            Next
            
            MsgBox("Attendance Marked...!", MsgBoxStyle.Information)
         End Using
      End Using
   End Using
End Sub
 
Share this answer
 
Comments
A94 10-Apr-15 12:15pm    
Thank You. But how to update "mark_attendance" procedure as it is used to insert data of the attendance.Is there any other alternative.Please suggest
Richard Deeming 10-Apr-15 12:18pm    
Remove the @empname and @dept parameters; declare local variables called @empname and @dept; and add the SELECT statement at the top of the procedure:

SELECT @empname = empname, @dept = dept FROM emp_master WHERE empid = @empid;
A94 10-Apr-15 22:37pm    
But where to add. In procedure or in code that you have suggested above.
Richard Deeming 13-Apr-15 7:15am    
To update the mark_attendance procedure, you would need to make those changes to the procedure. You would then remove the getDetailsCommand, empname and dept from the code in my answer.
A94 11-Apr-15 8:56am    
I tried the above code (i.e doing it by executing 2 queries). But it inserts only the last checked employee. for example , suppose I check empid 1 and 2 then I will store the record of 2nd id(i.e, 2) and not the first one. I want both...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900