How to create different instances of a form - vb.net

The below Code is written inside the Timer Tick event. It works fine as long as the Time and Date are not same. When the Time and Date are same it only displays 1 message. How can I show multiple message for the same date and Time ? I think this can be done If I create different instances for a form. But I don't know how many same time and Date will be there in the database. So I can't do that. Is there any work around ?
Dim frm As New frmMessage
Dim nowDate As String = String.Format("{0:M/d/yyyy}", DateTime.Now)
Dim nowTime As String = String.Format("{0:h:mm tt}", DateTime.Now)
Dim mySelectQuery As String = "SELECT ReminderID, Date, Time, Subject, Reminder FROM Reminder WHERE Date LIKE '" & nowDate & "' AND Time LIKE '" & nowTime & "'"
Dim myConnString As String = "Data Source=" & Application.StartupPath & "\Database\SimpleDB.db3"
Dim sqConnection As New SQLiteConnection(myConnString)
Dim sqCommand As New SQLiteCommand(mySelectQuery, sqConnection)
sqConnection.Open()
Dim sqReader As SQLiteDataReader = sqCommand.ExecuteReader()
Try
If sqReader.HasRows = True Then
While sqReader.Read()
frm.Show()
If (Not sqReader.IsDBNull(0)) Then
frm.txtID.Text = sqReader.GetInt32(0)
End If
If (Not sqReader.IsDBNull(1)) Then
frm.txtDate.Text = sqReader.GetString(1)
End If
If (Not sqReader.IsDBNull(2)) Then
frm.txtTime.Text = sqReader.GetString(2)
End If
If (Not sqReader.IsDBNull(3)) Then
frm.txtSubject.Text = sqReader.GetString(3)
End If
If (Not sqReader.IsDBNull(4)) Then
frm.txtReminderText.Text = sqReader.GetString(4)
End If
End While
End If
sqReader.Close()
sqConnection.Close()
Catch ex As Exception
MsgBox("Error:" & ex.Message, vbExclamation)
End Try

if i understood correctly , you want to show a form for each row retrunring from the database.
i`m not sure this sort of UI practice is best if you have more than a couple of rows ,
but you can instanciate a new form as you said for each row,
instead of using the same instance
all you need to do is replace:
frm.Show()
with
Dim newForm As New frmMessage()
newForm.Show()

Related

How can I check a received string for a specific word?

I am sending the string "end" from my arduino uno to a vb.net application. I want the vb.net app to recognise the word and conduct a specific action. I can see that the word is being received in the console, but it doesn't seem to be recognised by the code.
Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Console.WriteLine(SerialPort1.ReadExisting)
If SerialPort1.ReadExisting IsNot "end" Then
dataRxd = dataRxd & SerialPort1.ReadExisting
Else
txtRx.Text &= dataRxd
Console.WriteLine("###############")
Console.WriteLine(dataRxd)
'Dim result As newData = JsonConvert.DeserializeObject(Of newData)(dataRxd)
'Dim com As result.com
'SerialPort1.Close()
'MySqlConn = New MySqlConnection
'MySqlConn.ConnectionString = "server=localhost;userid=root;password=g4rg45m3ll1;database=tags"
'Try
' Dim SDA As New MySqlDataAdapter
' Dim dbDataSet As New DataTable
' Dim bSource As New BindingSource
' MySqlConn.Open()
' 'Query = "update tags.tags_read set LastRead= now() where TagID='" & dataRxd & "';"
' Query = "insert into tags.tags_read values ('" & dataRxd & "', now());"
' cmd = New MySqlCommand(Query, MySqlConn)
' reader = cmd.ExecuteReader
'Catch ex As MySqlException
' MessageBox.Show(ex.Message)
'End Try
'MySqlConn.Dispose()
'MySqlConn.Close()
'SerialPort1.Open()
End If
End Sub
Here is a sample of the received data to the vb.net app, showing that the word is being received:
0001220000570221001B
end
0001220000570221001B
end
The thread 0x4a70 has exited with code 0 (0x0).
ReadExisting is a method, not a property. If you call it once then you are reading the existing data, so there's no more data. You can't call it again and get the same data. If you expect to use the data that you read more than once then do as should always be the case: assign the method result to a variable and then use that variable as required.
Dim msg = SerialPort1.ReadExisting()
Console.WriteLine(msg)
If msg <> "end" Then
dataRxd = dataRxd & msg
Note that I also used <> rather than IsNot, because it's really value equality and not reference equality that you care about.

Availability using Access Database

I am attempting to make a hotel booking system. However the availability has got me a bit confused. I have about 15 buttons which I am able to save the number to the database but when the form loads/ date changed. I need the button to stay red and be unclickable. For example if I had a room 11 booked from 3/06/17 to 5/06/17 then I'd need the button to remain red from the 3/06/17 to 4/06/17 since the room is able to still be booked on the 5/06/17 after cleaning. I hope this makes sense. Below is the code I am using to try to do this. The code does run however the button does not turn red.
I was thinking does my SQL statement need to be changed but I'm not too sure. I'm pretty new to coding so an explanation would be helpful. Thanks.
Private Sub ReadRecords()
Dim btn As Button = Nothing
Dim BookingFound As Boolean = False
Using MyConn As New OleDbConnection
MyConn.ConnectionString = connString
MyConn.Open()
Dim check As String = "SELECT COUNT(*) FROM [BookingInformation] WHERE [Date In] = '" & dtpDateIn.Value.Date & "' AND [Date Out] = '" & dtpDateOut.Value.Date & "'"
Dim BookingExists As Boolean = False
Dim command As OleDbCommand = New OleDbCommand(check, MyConn)
Using reader As OleDbDataReader = command.ExecuteReader()
While reader.Read()
If reader(0) = 0 Then
BookingExists = False
Else
BookingExists = True
End If
End While
End Using
If BookingExists = True Then
Dim getData As String = "SELECT * FROM [BookingInformation] WHERE [Date Out] = '" & dtpDateOut.Text & "'"
Dim command2 As OleDbCommand = New OleDbCommand(getData, MyConn)
Using reader As OleDbDataReader = command2.ExecuteReader()
While reader.Read()
BookingFound = True
strDateIn = reader("Date In").ToString()
strDateOut = reader("DateOut").ToString
strRoomNumber = reader("Room Number").ToString
End While
If BookingFound = True Then
btn.BackColor = Color.Red
End If
End Using
End If
MyConn.Close()
End Using
End Sub
Private Sub Room_Booking_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ReadRecords()
End Sub
You should make your access database understand your input as date, access database is very sensitive to datatypes, for example if you write
"SELECT * FROM [user_tb] WHERE user_id=1"
Your code will work fine if your user_id data type is autonumber.
so try
Dim getData As String = "SELECT * FROM [BookingInformation] WHERE [Date Out] = #" & dtpDateOut.Text & "#"
Instead of
Dim getData As String = "SELECT * FROM [BookingInformation] WHERE [Date Out] = '" & dtpDateOut.Text & "'"
That is replace ' with #

Slow database query: Using VB.net connecting to Access

I have a program which will only allow a certain amount of concurrent users to use the program at one time. To do this I have a single table in an access database which holds each user that is using the program. Now although this does work the query seems to be running very slowly, I am certain it is something to do with the database functions as it was running fine before I implemented them.
Here are my functions:
Public Function openDB() As Boolean
cnn.Open()
Return True
End Function
Public Function closeDB() As Boolean
cnn.Close()
Return True
End Function
Then there is the function for checking the database. This is where I think it may be tripping up because I have 2 queries running here:
Public Function CheckLicence() As Boolean
Dim result As Boolean = HandleRegistry()
If result = True Then
Dim _table As String = "Users"
Dim query As String = "SELECT * FROM " & _table & " WHERE Machine_ID='" & CpuId() & "'"
Dim sizeQuery As String = "SELECT COUNT(*) FROM " & _table
Dim NoUsers As Integer = 0
Dim ds As New DataSet
Dim dr As OleDbDataReader
Dim cmd As New OleDbCommand(query, cnn)
dr = cmd.ExecuteReader
Dim sizeCdm As New OleDbCommand(sizeQuery, cnn)
NoUsers = sizeCdm.ExecuteScalar()
If dr.Read() Then
Return True
Else
If NoUsers < My.Settings.NoUsers Then
addToDB()
Else
MsgBox("Too many users are currently using this program. Clear a user and try again.")
Return False
End If
End If
Else
MsgBox("Your licence has expired, contact support to purchase a new licence.")
Return False
End If
Return True
End Function
And to add and remove I have to get the cpu id, I found the code for that on here somewhere it does work but maybe that could be the slow part, I dont actually know if this is the correct way of getting it.
Public Sub addToDB()
Dim _table As String = "Users"
Dim query As String = "INSERT INTO " & _table & " ([User], [Machine_ID]) VALUES (?,?)"
Dim ds As New DataSet
Dim cmd As New OleDbCommand(query, cnn)
cmd.Parameters.AddWithValue("?", Environment.UserName)
cmd.Parameters.AddWithValue("?", CpuId())
cmd.ExecuteNonQuery()
End Sub
Public Sub RemoveFromDB()
Dim _table As String = "Users"
Dim query As String = "DELETE * FROM " & _table & " WHERE Machine_ID='" & CpuId() & "'"
Dim ds As New DataSet
Dim cmd As New OleDbCommand(query, cnn)
cmd.ExecuteNonQuery()
End Sub
Private Function CpuId() As String
Dim computer As String = "."
Dim wmi As Object = GetObject("winmgmts:" &
"{impersonationLevel=impersonate}!\\" &
computer & "\root\cimv2")
Dim processors As Object = wmi.ExecQuery("Select * from " &
"Win32_Processor")
Dim cpu_ids As String = ""
For Each cpu As Object In processors
cpu_ids = cpu_ids & ", " & cpu.ProcessorId
Next cpu
If cpu_ids.Length > 0 Then cpu_ids =
cpu_ids.Substring(2)
Return cpu_ids
End Function
How about storing the cpuID globally and fetching only once. Also, use the Using construct on anything that needs to be disposed. Lastly, run a few StopWatches around your methods to see which one is slow or just debug through each one to find the slow method.
Answer:
How about storing the cpuID globally and fetching only once. Also, use the Using >construct on anything that needs to be disposed. Lastly, run a few StopWatches >around your methods to see which one is slow or just debug through each one to >find the slow method. – Andrew Mortimer
Moved the call for getting the cpuID to the program initialisation so that it runs on startup. This made it run much faster than it did before.

How to Trigger Code with ComboBox Change Event

I have a created a database containing historical stock prices. On my form I have two comboboxes, ComboBox_Ticker and ComboBox_Date. When these comboboxes are filled I want to check the database and see if the respective data exists in the database. If it does I want to change the text of a label called Label_If_Present to "In Database".
My problem occurs with the change event. I want all of this to happen once I change the data in the textboxes. I have tried both the .TextChanged and .LostFocus events. The '.TextChanged' triggers the code to early and throws and error in my SQL command statement. The `.LostFocus' event doesn't do trigger my code at all.
Here is my current code:
Public databaseName As String = "G:\Programming\Nordeen Investing 3\NI3 Database.mdb"
Public con As New OleDb.OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source =" & databaseName)
Public tblName As String = "Historical_Stock_Prices"
Private Sub Change_Labels(ByVal sender As Object, ByVal e As EventArgs) Handles ComboBox_Ticker.TextChanged, ComboBox_Date.TextChanged
con.Close()
Dim dr As OleDbDataReader
con.Open()
If (File.Exists(databaseName)) Then
Dim restrictions(3) As String
restrictions(2) = tblName
Dim dbTbl As DataTable = con.GetSchema("Tables", restrictions)
If dbTbl.Rows.Count = 0 Then
Else
Dim cmd2 As New OleDb.OleDbCommand("SELECT * FROM " & tblName & " WHERE Ticker = '" & ComboBox_Ticker.Text & "' " & " AND Date1 = '" & ComboBox_Date.Text & "'", con)
dr = cmd2.ExecuteReader
If dr.Read() = 0 Then
'If record does not exist
Label_If_Present.Text = ""
Else
Label_If_Present.Text = "In Database"
End If
con.Close()
End If
Else
End If
End Sub
I have successfully implemented this concept on other forms within my project. This one is slightly different and I can't figure out why I can't get this one to work.
Handling the TextChanged event should work, however you need to set the DropDownStyle to DropDownList so that the Text property can only be a given value.
Then check to see that both comboboxes have values selected. Something like this should work:
If ComboBox_Ticker.Text <> "" AndAlso DateTime.TryParse(ComboBox_Date.Text, Nothing) Then

Change textbox value dynamically?

I have 7 textboxes named lblSun, lblMon etc and 7 buttons named cmdSun, cmdMon etc. I want to change the Text value of these text boxes and buttons from within the query. I've tried Me.Controls("cmd" & daysOfWeek(i)).Text, but it does not work.
The error is Object reference not set to an instance of an object.
Here is my code:
Public Sub loadSchedule()
' days of week
Dim daysOfWeek(0 To 6) As String
Dim i As Integer
Dim var As String
Dim ctrl As Control
' set up the days of the week
daysOfWeek(0) = "Sun"
daysOfWeek(1) = "Mon"
daysOfWeek(2) = "Tue"
daysOfWeek(3) = "Wed"
daysOfWeek(4) = "Thu"
daysOfWeek(5) = "Fri"
daysOfWeek(6) = "Sat"
' connect to the db
Dim con As OleDb.OleDbConnection = New OleDb.OleDbConnection(Form1.conString)
con.Open()
' query stuff
Dim query As String
Dim cmd As New OleDb.OleDbCommand
Dim rs As OleDb.OleDbDataReader
' loop
For i = LBound(daysOfWeek) To UBound(daysOfWeek)
' set query
query = "SELECT * FROM Schedule WHERE Employee=" & employee & " AND ScheduleDay='" & daysOfWeek(i) & "'"
cmd = New OleDb.OleDbCommand(query, con)
rs = cmd.ExecuteReader()
' var
var = "cmd" & daysOfWeek(i)
' any results?
If rs.HasRows = True Then
' get it
rs.Read()
' show it baby
'Controls("lbl" & daysOfWeek(i)).Text = rs.Item("TimeIn") & " - " & rs.Item("TimeOut")
Me.Controls("cmd" & daysOfWeek(i) & "").Text = "Edit"
Else
' show it baby
Controls("lbl" & daysOfWeek(i)).Text = "RDO"
Controls("cmd" & daysOfWeek(i)).Text = "New"
End If
Next
' close db
con.Close()
End Sub
Can anyone help me? What am I doing wrong?
You are trying to access the controls in Me.Controls which don't exist, because the buttons/textboxes are inside a table.
You should use :
table.Controls("cmd" & daysOfWeek(i)).Text = "Edit"