سؤال

I have made a form that is supposed to get the attendance details for a specific session. The used elements are:

1- CheckedListBox

2- Combobox :CB_Students

3- Button : Update

My table is Student, which contains Code| First Name| Last Name| Day1| Day2| Day3| Day4| Day5, where the Days are of the type tinyint, referring to Presence or Absence.

I want the user to check the students' names from the CheckedListBox, so I populated the CheckedListBox with the concatenation of First Names and Last Names, each item showing the full name.

Since the CheckedListBox is indirectly created by the database records, I suppose I cannot connect it to the database directly, so I have created a hidden ComboBox with values of Code corresponding to each student shown in the CheckedListBox.

For example, my student table is as below:

Code | F_Name | L_Name

1 | F1 | L1

2 | F2 | L2

The CheckedListBox contains: F1 L1 and F2 L2, and the ComboBox contains 1 and 2.

The day number also is found during the form load and saved as the Public variable Inquiry.

Below is my code for the Update Button:

Dim j, S As Integer
    sqlstr = "UPDATE Student SET Day'" & Inquiry & "'=@field1 WHERE Code='" & CB_Students.Items.Item(j) & "'"
    DBCmd = New MySql.Data.MySqlClient.MySqlCommand(sqlstr, DBConn)
    With DBCmd
        For j = 0 To CheckedListBox1.Items.Count - 1
            S = CheckedListBox1.GetItemCheckState(j)
            If S = 1 Then
                .Parameters.AddWithValue("@field1", 1)
            ElseIf S = 0 Then
                .Parameters.AddWithValue("@field1", 0)
            End If
        Next j
    End With
    DBCmd.ExecuteNonQuery()
    DBCmd.Dispose()

However, during the execution, I get the error: "Parameter '@field1' has already been defined."

How should I deal with this problem? Also, is the statement CB_Students.Items.Item(j) used correctly to give my sql string the student code in the ComboBox?

Update 1:

Inquiry is an integer. I also tried the following code:

 For j = 0 To CheckedListBox1.Items.Count - 1
        S = CheckedListBox1.GetItemCheckState(j)
        If S = 1 Then
            With DBCmd
                .Parameters.AddWithValue("@field1", 1)
                .ExecuteNonQuery()
                .Dispose()
            End With
        ElseIf S = 0 Then
            With DBCmd
                .Parameters.AddWithValue("@field1", 0)
                .ExecuteNonQuery()
                .Dispose()
            End With
        End If
    Next j

But again, as in my response to Never_Mind, I get the following error at the first DBCmd.ExecuteNonQuery() line: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''4' =1 WHERE Code='6'' at line 1".

The values seem to be correct. Day number is 4, Field1 is 1 and Code is 6. I don't see what the problem is.

Update 2:

Below is the code for populating the CheckedListBox and the ComboBox, which is in the form load. C_Code is the Class Code, another field in the student table. ClassID is a public integer variable saved in the previous form. This form appears using the .ShowDialog method.

sqlstr = "SELECT * FROM Student WHERE C_Code = '" & ClassID & "'"
DBCmd = New MySql.Data.MySqlClient.MySqlCommand(sqlstr, DBConn)
DBDR = DBCmd.ExecuteReader
    While (DBDR.Read())
        Std_Name = DBDR("F_Name") & " " & DBDR("L_Name")
        CheckedListBox1.Items.Add(Std_Name)
        CB_Students.Items.Add(DBDR("Code"))
    End While
    DBCmd.Dispose()
    DBDR.Close()

Also, Code is integer.

Update 3:

I have changed Inquiry's datatype into String and removed the single quotes.

Anyhow, I was thinking maybe I could make different field numbers. Something like this:

Dim j, S, k As Integer
    sqlstr = "UPDATE Student SET D" & Inquiry & " =@field" & k & " WHERE Code='" & CB_Students.Items.Item(j) & "' "
DBCmd = New MySql.Data.MySqlClient.MySqlCommand(sqlstr, DBConn)
For j = 0 To CheckedListBox1.Items.Count - 1
        For k = 1 To CheckedListBox1.Items.Count
            S = CheckedListBox1.GetItemCheckState(j)
            If S = 1 Then
                With DBCmd
                    .Parameters.AddWithValue("@field" & k, 1)
                    .ExecuteNonQuery()
                    .Dispose()
                End With
            ElseIf S = 0 Then
                With DBCmd
                    .Parameters.AddWithValue("@field" & k, 0)
                    .ExecuteNonQuery()
                    .Dispose()
                End With
            End If
        Next k
    Next j

But this doesn't work. I think there should be something wrong with the way I've concatenated @field and k while adding through the command. How can I get it to work?

I would really appreciate the help!

هل كانت مفيدة؟

المحلول 2

Just figured the answer. Since we cannot recreate @field1, we recreate the sql string (the whole thing) by putting it in a loop.

For j = 0 To CheckedListBox1.Items.Count - 1
        S = CheckedListBox1.GetItemCheckState(j)
        sqlstr = "UPDATE Student SET D" & Inquiry & " =@field1 WHERE Code='" & CB_Students.Items.Item(j) & "' "
        DBCmd = New MySql.Data.MySqlClient.MySqlCommand(sqlstr, DBConn)
            If S = 1 Then
                With DBCmd
                .Parameters.AddWithValue("@field1", 1)
                    .ExecuteNonQuery()
                    .Dispose()
                End With
            ElseIf S = 0 Then
                With DBCmd
                .Parameters.AddWithValue("@field1", 0)
                    .ExecuteNonQuery()
                    .Dispose()
                End With
            End If
    Next j

This one was quite tough! But heck, it gets easy when it's solved, eh?

نصائح أخرى

Try this

 With DBCmd
        For j = 0 To CheckedListBox1.Items.Count - 1
            S = CheckedListBox1.GetItemCheckState(j)
            If S = 1 Then
                .Parameters.AddWithValue("@field1", 1)
 .ExecuteNonQuery()
            ElseIf S = 0 Then
                .Parameters.AddWithValue("@field1", 0)
 .ExecuteNonQuery()
            End If
        Next

    End With

First remove the single quote from the string Inquiry to concatenate the progressive of the field to the word day. BEWARE. I suppose that you have full control over the value of the Inquiry variable and check if it is a valid number before concatenating to the Day word

Second Define your parameter just once outside the loop with a dummy value, then, inside the loop set the value to the state of the current item and execute the query

Third Use a parameter also for the code value

j = 0 ' you should initialize this variable to a valid index inside the items collection of the combo'
sqlstr = "UPDATE Student SET Day" & Inquiry & "=@field1 WHERE Code=@code"
DBCmd = New MySql.Data.MySqlClient.MySqlCommand(sqlstr, DBConn)
With DBCmd
    .Parameters.AddWithValue("@field1", 0)
    .Parameters.AddWithValue("@code", Convert.ToInt32(CB_Students.Items(j)))
    For j = 0 To CheckedListBox1.Items.Count - 1
        S = if(CheckedListBox1.GetItemCheckState(j) = CheckState.Checked, 1, 0)
       .Parameters("@field1").Value = S
       .ExecuteNonQuery()
    Next j
End With

This approach is not very efficient because an update command is executed for each day item (checked or not), but to remove this inefficiency will require a full rewrite of this code.

As for the usage of the combobox items, I think you should use the SelectedValue property, but it depends on how you have filled the combo and which value is assigned to the ValueMember property and which datatype is the code database field

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top