So I have instant messaging functionality that I use with a database. Each time a message is sent it prints what's in the message column in the database into a rich text box in my vb.net application
My problem is. I have to click on the "send message" button twice to get the functionality to work, as the first time I click it, nothing happens
Does anyone have any idea where I'm gone wrong? Much appreciated!
Try
'----------------Sends the message-------------------------------------
MysqlConn.Open() ' opening the connection to the DB
Dim query As String
query = "insert into dojodb.chats (Message) values ('" & txtMessage.Text & "')"
command = New MySqlCommand(query, MysqlConn)
reader = command.ExecuteReader 'executes the command and reads data from db
reader.Close()
'-------------------Retreives the message------------------------------------
Dim sqlStr As String = "SELECT * FROM chats"
Dim chatcommand As New MySqlCommand(sqlStr, MysqlConn)
Dim rdr As MySqlDataReader = chatcommand.ExecuteReader()
Dim tbl As New DataTable
tbl.Load(rdr)
'-------For every row, print the message, skip a line, and add 1 so it goes to next msg--------
For i As Integer = 0 To tbl.Rows.Count - 1
rowIndex = i
strOutPut &= CStr(tbl.Rows(rowIndex)("Message")) & vbNewLine
i = i + 1
Next
txtGroupChat.Text = strOutPut
strOutPut = "" 'clearing the string so that it does not print out duplicate info next time
'-------------------------End Retrieve-------------------------------------------
MysqlConn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message) 'printing the exact error to help future testing if needed
Finally
MysqlConn.Dispose()
End Try
End Sub
I think your problem is this section:
'-------For every row, print the message, skip a line, and add 1 so it goes to next msg--------
For i As Integer = 0 To tbl.Rows.Count - 1
rowIndex = i
strOutPut &= CStr(tbl.Rows(rowIndex)("Message")) & vbNewLine
i = i + 1
Next
Why are you skipping a line? This will cause every other message in the table to not be written out, and therefore that's why you have to press it twice so that it shows up. You don't need to manually increment the indexer in a For loop, I suggest you try this:
For i As Integer = 0 To tbl.Rows.Count - 1
rowIndex = i
strOutPut &= CStr(tbl.Rows(rowIndex)("Message")) & vbNewLine
Next
Related
I have a dialog with a combobox listing the years an event was held.
Changing the year, changes the following list boxes
One list box 'called inEvent' shows all golfers the attended said event.
The other list box called 'available' that shows every golfer we have in our database that did not attend that years event
It has two buttons. One removes golfers from 'inEvent' and moves them to 'available'. This button works.
The other button does the opposite. It adds available golfers to the selected event year. But it gives me the error -
"The statement has been terminated. Cannot insert the value NULL into column 'intGolferEventYearID', table 'dbo.TGolferEventYears'; column does not allow nulls. INSERT fails."
Changing any line of code in VB results in a different error. So I think the error has to come from SQL itself which I don't know much about. Only other thing I can think of is the listbox is giving the wrong information.
Private Sub btnAddAuto_Click(sender As Object, e As EventArgs) Handles btnAddAuto.Click
Dim strInsert As String = ""
Dim cmdInsert As OleDb.OleDbCommand ' used for our Select statement
Dim dt As DataTable = New DataTable ' table we will load from our reader
Dim intRowsAffected As Integer
' open the DB
OpenDatabaseConnectionSQLServer()
' Build the select statement
strInsert = "INSERT INTO TGolferEventYears ( intGolferID, intEventYearID) Values (" & lstAvailable.SelectedValue & ", " & cboEvents.SelectedIndex + 1 & ")"
' Retrieve all the records
cmdInsert = New OleDb.OleDbCommand(strInsert, m_conAdministrator)
intRowsAffected = cmdInsert.ExecuteNonQuery()
' close the database connection and reload the form so the changes are shown
CloseDatabaseConnection()
frmEventsGolfers_Load(sender, e)
End Sub
I separated the data access code from the user interface. This will make it easy to remove data access entirely from the Form if you later desire.
Private Sub MoveGolfer(GolfID As Integer, YearID As Integer)
'If you keep your connections local you can be sure they are
'closed and disposed which is what the Using...End Using blocks do.
Using cn As New SqlConnection("Your connection string")
Using cmd As New SqlCommand("INSERT INTO TGolferEventYears ( intGolferID, intEventYearID) Values (#Golf, #Year;")
'Always use parameters to protect against Sql injection
cmd.Parameters.Add("#Golf", SqlDbType.Int).Value = GolfID
cmd.Parameters.Add("#Year", SqlDbType.Int).Value = YearID
cn.Open()
cmd.ExecuteNonQuery()
End Using
End Using
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim GolferID As Integer = CInt(lstAvailable.SelectedValue)
Dim Year As Integer = cboEvents.SelectedIndex + 1
Try
MoveGolfer(GolferID, Year)
Catch ex As Exception
'Catch a more specific exception and handle accordingly
MessageBox.Show(ex.Message)
End Try
End Sub
Since I don't really understand SQL I didn't realize my PK didn't have the IDENTITY tag added in the table. Adding this fixed my issue.
Here is the code I added
Dim strSelect As String
Dim cmdSelect As OleDb.OleDbCommand
Dim drSourceTable As OleDb.OleDbDataReader
Dim intNextHighestRecordID As
strSelect = "SELECT MAX(intDealerAutos) + 1 AS intNextHighestRecordID " &
" FROM TDealerAutos"
'Excute command
cmdSelect = New OleDb.OleDbCommand(strSelect, m_conAdministrator)
drSourceTable = cmdSelect.ExecuteReader
'Read result( highest ID )
drSourceTable.Read()
'Null? (Empty Table)
If drSourceTable.IsDBNull(0) = True Then
'Yes, start numbering at 1
intNextHighestRecordID = 1
Else
'No, get the next highest ID
intNextHighestRecordID = CInt(drSourceTable.Item(0))
End If
'Build the select statement
strInsert = "INSERT INTO TDealerAutos ( intDealerAutos, intDealerID, intAutoID)" &
"Values (" & intNextHighestRecordID & ", " & cboDealers.SelectedValue & ", " & lstAvailable.SelectedValue & ")"
I have a filter so it filters the binding source by the customerID. But what if the customer id doesnt exist? When i enter id = 3 and doesnt exist it messes up my whole binding per say, meaning it nulls everything and when i want to reopen the binding it crashes saying it cant locate the item. So trying not to go into detail with the errors, i want to make it so if it results back to null then present the user with an error saying not located etc and enter again, if correct/present then do its filter job.
My code:
dim filterstring as string
filterstring = CStr(bsorder.Filter = "id = " & custid & "")
If filterstring.Count() = 0 Then
MessageBox.Show("Error! try again!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
bsorder.Filter = "ID = " & custid & ""
End If
I needed to check if the row existed before applying the filter, to do so i used a Try/Catch method to successfully know rather the id existed or not. The code that worked is below:
Try
Using myConnection As OleDbConnection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=.\yous.accdb")
myConnection.Open()
Dim str As String
str = "SELECT * FROM table WHERE whateverID=#ID "
Using cmd As OleDbCommand = New OleDbCommand(str, myConnection)
cmd.Parameters.AddWithValue("#ID", custid)
Using dr As OleDbDataReader = cmd.ExecuteReader
If dr.HasRows Then
dr.Read()
End Using
End Using
End Using
Catch ex As Exception
MsgBox(ex.ToString)
End Try
On my code let's say I have 2 forms
On the main one is the DataGridView, it contains a column called ActivityStatus, which displays if the member is either Stopped/On-going
I have a second form that I open by double clicking on a row, which gives me all the member's details, and at the bottom of the form there's a button that has a password; if written correctly, it should switch his ActivityStatus (if he's stopped; he'll become ongoing, vice versa)
Here's the code I wrote for it
In form 1:
Private Sub DGVData_CellContentDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles DGVData.CellContentDoubleClick
Dim SV As New -- [FORM 2 NAME HERE]
If e.RowIndex >= 0 Then
Dim Row As DataGridViewRow
Row = DGVData.Rows(e.RowIndex)
SV.ActivityChange = Row.Cells("ActivityStatus").Value.ToString
SV.IDVerify = Row.Cells("ID").Value.ToString
ED.Show()
End If
End Sub
In form 2:
Public Class StatusVertificationBox
Public Property ActivityChange As String
Public Property IDVerify As String
Private Sub StatusPassBtn_Click(sender As Object, e As EventArgs) Handles StatusPassBtn.Click
If StatusPassTxt.Text = "password123" Then
If ActivityChange = 1 Then
Dim Ask As MsgBoxResult
Ask = MsgBox("Are you sure?", MsgBoxStyle.YesNo)
If Ask = MsgBoxResult.Yes Then
Dim MakeActiveCmd As String = "UPDATE InitialTable " &
"SET ActivityStatus = 0 " &
"WHERE ID='" & IDVerify & "' "
MsgBox("This member's membership has been stopped")
ElseIf Ask = MsgBoxResult.No Then
MsgBox("No modifications have been made")
End If
ElseIf ActivityChange = 0 Then
Dim Ask As MsgBoxResult
Ask = MsgBox("Are you sure?", MsgBoxStyle.YesNo)
If Ask = MsgBoxResult.Yes Then
Dim MakeInactiveCmd As String = "UPDATE InitialTable " &
"SET ActivityStatus = 1 " &
"WHERE ID='" & IDVerify & "' "
MsgBox("This member's membership has been renewed")
ElseIf Ask = MsgBoxResult.No Then
MsgBox("No modifications have been made")
End If
End If
Me.Close()
Else
MsgBox("Incorrect Password, please try again.")
StatusPassTxt.Clear()
End If
End Sub
I don't understand where the issue is. The IF statement isn't working properly (the text displays on the MsgBox doesn't match the statement, and the value isn't changing at all on the datagridview)
Any help would be highly appreciated, thanks for reading guys
EDIT: fixed things from the code, I improperly copied it, since I edited a few things to make it easier to you guys to understand, which made me miss out a few codes
EDIT2: I noticed that it ALWAYS follows the last IF statement that I put on it.. It's always following If ActivityChange = 0, even if (according to how it shows) it should show as 1.. I still don't know how to solve this
EDIT:
the variable ActivityChange is of type String. Therefore the comparison should be:
If StrComp(ActivityChange, "1") = 0 Then
...
How can I convert a row data into string or text and display it into a label? My problem is when I click on my login button which contains the SQL code that gains a row data into alabel, the result in my label is false. not the text. How can I convert it into string?
Here's my code:
Private Sub cmdLog_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdLog.Click
Dim connection As New SqlClient.SqlConnection
Dim command As New SqlClient.SqlCommand
Dim adaptor As New SqlClient.SqlDataAdapter
Dim dataset As New DataSet
Dim reader As MySqlDataReader = Nothing
Dim sapi
sapi = CreateObject("sapi.spvoice")
connection.ConnectionString = ("Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Calupad\Desktop\HTF feat Yiyet\HTF feat Yiyet\Database1.mdf;Integrated Security=True;User Instance=True")
command.CommandText = "SELECT * FROM [Users] WHERE Username='" & txtUser.Text & "' AND Password ='" & txtPass.Text & "';"
txtWel.Text = "Welcome Back, " + txtUser.Text + "!....."
connection.Open()
command.Connection = connection
adaptor.SelectCommand = command
adaptor.Fill(dataset, "0")
txtStat.text = command.CommandText = "SELECT Status FROM [Users] WHERE Username = '" & txtUser.Text & "' ".ToString
txtStat.Text = stat
Dim count = dataset.Tables(0).Rows.Count
If count > 0 Then
MsgBox("Login Successful!" & vbNewLine & txtStat.Text, MsgBoxStyle.Information, "Access Granted")
sapi.speak(txtWel.Text)
Me.Hide()
Form1.Show()
frmMenu.Show()
txtUser.Clear()
txtPass.Clear()
tries = 3
Else
ctr = tries - 1
tries = ctr
sapi.speak(txtUser.Text + txtNot.Text)
MsgBox("Invalid Account!" + vbNewLine + "Attempts Remaining: " & tries, vbCritical, "Access Denied")
txtUser.Clear()
txtPass.Clear()
If tries = 0 Then
MsgBox("You've reached the maximum attempts!" + vbNewLine + "The program will be terminated.", vbCritical, "Terminated!")
Me.Close()
End If
End If
End Sub
First of all, the way you check for username and password is weak and is most certainly volnurable to SQL injections. You are checking if the 'count' of rows is greater than zero then the user has logged in successfully, where as you should only compare count to 1. and instead of counting the rows, try to compare the row values to what the user has input in the username and passoword fields and what is returned from the database rows.
The "hacker" can simply type this and he will be allowed to log in according to the logic of your code:
You just need to retrieve the data stored into dataset variable that you filled using the adapter.
Assuming your database table contains fields like First_Name and 'Last_Name', here is how you can display them on any label control on your form:
adaptor.Fill(dataset, "0")
myFirstName.Text = dataset.Tables(0).Rows(0).Item("First_Name").ToString()
myLastName.Text = dataset.Tables(0).Rows(0).Item("First_Name").ToString()
You can also retrieve the column without having to know its name like this
myLabel.text = = dataset.Tables(0).Rows(0).Item(3).ToString()
'This will retrieve the 4th column from the table (zero based array)
You can also clean up your code by declaring a variable to hold the retrieved table
adaptor.Fill(dataset, "0")
Dim myTable as DataTable = dataset.Tables(0)
myFirstName.Text = myTable.Rows(0).Item(0).ToString()
Hope this helps
i need to upload and display images to and from database. i have written this code for uploading and it uploads fine. except 1 problem. It crashes when i dont select an image. can someone help me fix it for null value? also how do you display an image in IE?
code for inserting image -
Dim imageInfo As FileInfo = Nothing
Dim data() As Byte = Nothing
imageInfo = New FileInfo(Me.UploadLogo.Value.Trim())
Dim imagestream As FileStream = New FileStream(imageInfo.ToString, FileMode.Open)
if name_id > 0
ReDim data(imagestream.Length - 1)
imagestream.Read(data, 0, imagestream.Length)
imagestream.Close()
Sqlstr = "UPDATE logos WITH(ROWLOCK) " & _
"SET Logo=#Logo,Modified_Date=GETDATE() " & _
"WHERE ID = " + name_id.ToString + ""
Else
Sqlstr = "INSERT logos (Logo,Created_Date) " & _
"VALUES ("#Logo,GETDATE())"
End If
SqlCmd = New SqlCommand(Sqlstr, SqlCnn)
Dim pictureParameter As SqlParameter = Nothing
pictureParameter = New SqlParameter("#Logo", SqlDbType.Image)
pictureParameter.Value = data
SqlCmd.Parameters.Add(pictureParameter)
SqlCmd.ExecuteScalar()
this works fine only if an image is selected, crashes for NULL values.
Also please help me with image display. thanks
To solve your "file not selected problem", you should have an If statement along the lines of:
If Not File.Exists(Me.UploadLogo.Value.Trim())
' Exit out or handle no file selected
End If