I want To generate all category button - vb.net

I have this pos system i want to generate All category button and display All product list in the FlowLayoutPanel
Private Sub FrmPos_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Connection()
LoadCategory()
LoadMenu()
Me.KeyPreview = True
End Sub
this code for LoadCategory()
Sub LoadCategory()
cn.Open()
cm = New SqlCommand("Select * From TblCategory", cn)
dr = cm.ExecuteReader
While dr.Read
BtnCategory = New Button
BtnCategory.Width = 100
BtnCategory.Height = 35
BtnCategory.Text = dr.Item("Category").ToString
BtnCategory.FlatStyle = FlatStyle.Flat
BtnCategory.BackColor = Color.FromArgb(55, 176, 213)
BtnCategory.ForeColor = Color.White
BtnCategory.Cursor = Cursors.Hand
BtnCategory.TextAlign = ContentAlignment.MiddleLeft
FlowLayoutPanel1.Controls.Add(BtnCategory)
AddHandler BtnCategory.Click, AddressOf filter_click
End While
dr.Close()
cn.Close()
End Sub
this code for filter_click
Public Sub filter_click(sender As Object, e As EventArgs)
If LblTransNo.Text = String.Empty Then
MsgBox("Click New Order first!", vbCritical)
Return
End If
_filter = sender.text.ToString
LoadMenu()
End Sub

You have 2 different things going on in the LoadCategory method. I moved the database code to a separate method.
Connections, Commands, and DataReaders all need to be disposed. These objects need to be declared locally in Using blocks. They provide a Dispose method where they release unmanaged resources. Using...End Using blocks will call Dispose for you and close the object even if there is an error.
You don't want to hold a connection open while you build your buttons and interact with the user interface. It appears that you are only using a single field called Category. Don't pull down all the fields with Select *. Just return the data you need to use.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
LoadFlowPanel()
LoadMenu()
Me.KeyPreview = True
End Sub
Private OPConStr As String = "Your connection string."
Private Function GetCategoryData() As DataTable
Dim dt As New DataTable
Using cn As New SqlConnection(ConStr),
cmd As New SqlCommand("Select Category From TblCategory;", cn)
cn.Open()
Using dr = cmd.ExecuteReader
dt.Load(dr)
End Using
End Using
Return dt
End Function
Private Sub LoadFlowPanel()
Dim dt = GetCategoryData()
Dim BtnAll As New Button
With BtnAll
.Width = 100
.Height = 35
.Text = "All"
.FlatStyle = FlatStyle.Flat
.BackColor = Color.FromArgb(55, 176, 213)
.ForeColor = Color.White
.Cursor = Cursors.Hand
.TextAlign = ContentAlignment.MiddleLeft
End With
FlowLayoutPanel1.Controls.Add(BtnAll)
AddHandler BtnAll.Click, AddressOf filter_click
For Each row As DataRow In dt.Rows
Dim BtnCategory = New Button
With BtnCategory
.Width = 100
.Height = 35
.Text = row("Category").ToString
.FlatStyle = FlatStyle.Flat
.BackColor = Color.FromArgb(55, 176, 213)
.ForeColor = Color.White
.Cursor = Cursors.Hand
.TextAlign = ContentAlignment.MiddleLeft
End With
FlowLayoutPanel1.Controls.Add(BtnCategory)
AddHandler BtnCategory.Click, AddressOf filter_click
Next
End Sub

Related

show groupboxes depending on selection in listbox access database vb.net

I have an access databasetable with addresses and a table with addresstypes.
When i add a new relation there's different groupboxes with additional information that should be displayed according to the addresstype.
For example: a patient has only basic address info.
A doctor needs a reference number too, so if i click on relation type "doctor" the address groupbox should appear but also the groupbox with doctor reference textbox.
An instance should also get the instance groupbox + address groupbox etc etc.
Addresses can also be "multiple types" so if an address is A: a doctor, and B an instance, both boxes should appear.
My current code looks like this:
Public Class NewRelationForm
'groupboxen disablen on load
Me.grpKiesUwRelatietype.Visible = True
Me.grpBasisData.Visible = False
Me.grpDataBI.Visible = False
Me.grpFoto_Nota.Visible = False
Me.grpHuisartsData.Visible = False
Me.grpPartijData.Visible = False
Me.grpVerwijzerdata.Visible = False
End Sub
'KNOPPEN en Functies!
Private Sub NewRelationForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Tbl_TypeTableAdapter1.Fill(Me.PatientenDatabaseDataSetX1.tbl_Type)
Me.Tbl_OnderzoeksTypesTableAdapter.Fill(Me.PatientenDatabaseDataSetX1.tbl_OnderzoeksTypes)
Me.Tbl_RelatiesTableAdapter.Fill(Me.PatientenDatabaseDataSetX.tbl_Relaties)
End Sub
Private Sub btnAddRelation_Click(sender As Object, e As EventArgs) Handles btnAddRelation.Click
FormMakeRelationType.Show()
End Sub
Private Sub lboxRelatieTypes_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lboxRelatieTypes.SelectedIndexChanged
End Sub
'Private Sub lboxRelatieTypes_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lboxRelatieTypes.SelectedIndexChanged
''If ComboBox1.SelectedIndex = 1 Then
'' grpBasisData.Visible = True
'' grpFoto_Nota.Visible = True
'' grpFoto_Nota.Location = New Point(720, 120)
''End If
'End Sub
End Class
I could really use a pointer in how to do this, i've tried if else, i've tried select case, but i can't find "the right way".
I'm a beginner
edit1: This is a pic from the winform: https://imgur.com/a/80pKnjR
and this is the access db (names in the db are changed for privacy purposes
https://www.dropbox.com/sh/4gudk8lwxtjahiq/AACz69ocFWIlU7hiTlQxbviLa?dl=0
I found it...
based on an article in stackoverflow: How to show hidden text boxes when items are selected in a combo box
If someone knows how to make this piece of code "easier to handle" or "more compact" i'm very open to ideas.
Also: i can only select one , the rest of the groupboxes dissappear , so it needs some finetuning but i'm 90% there!
Private Sub lboxRelatieTypes_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lboxRelatieTypes.SelectedIndexChanged
If lboxRelatieTypes.Text.Trim.Contains("Patiënt") = True Then
Me.grpBasisData.Visible = True
Me.grpDataBI.Visible = False
Me.grpFoto_Nota.Visible = True
Me.grpHuisartsData.Visible = False
Me.grpPartijData.Visible = False
Me.grpVerwijzerdata.Visible = False
ElseIf lboxRelatieTypes.Text.Trim.Contains("Verwijzer") = True Then
Me.grpBasisData.Visible = True
Me.grpDataBI.Visible = False
Me.grpFoto_Nota.Visible = True
Me.grpHuisartsData.Visible = False
Me.grpPartijData.Visible = False
Me.grpVerwijzerdata.Visible = True
ElseIf lboxRelatieTypes.Text.Trim.Contains("Betalende Instantie") = True Then
Me.grpBasisData.Visible = True
Me.grpDataBI.Visible = True
Me.grpFoto_Nota.Visible = True
Me.grpHuisartsData.Visible = False
Me.grpPartijData.Visible = True
Me.grpVerwijzerdata.Visible = False
ElseIf lboxRelatieTypes.Text.Trim.Contains("Huisarts") = True Then
Me.grpBasisData.Visible = True
Me.grpDataBI.Visible = False
Me.grpFoto_Nota.Visible = True
Me.grpHuisartsData.Visible = True
Me.grpPartijData.Visible = False
Me.grpVerwijzerdata.Visible = False
ElseIf lboxRelatieTypes.Text.Trim.Contains("Huisarts" & "Betalende Instantie") = True Then
Me.grpBasisData.Visible = True
Me.grpDataBI.Visible = True
Me.grpFoto_Nota.Visible = True
Me.grpHuisartsData.Visible = True
Me.grpPartijData.Visible = False
Me.grpVerwijzerdata.Visible = False
End If
'Dim curitem As String = lboxRelatieTypes.SelectedItems.ToString()
'Dim con As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=F:\GoogleDrive\EINDWERK VBNET\PatientenDatabase.accdb")
'con.Open()
'Dim sql As String = String.Format("select * from tbl_Relaties where Rel_Type='{0}'", curitem)
'Dim command As New OleDbCommand(sql, con)
'Dim reader As OleDbDataReader = command.ExecuteReader()
'If curitem.Contains "Huisarts" Then
' End If
'con.Close()
I make a code example, which show the textbox in the groupbox based on the listbox.
Form_Load event:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim con As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\PatientenDatabase.mdb")
con.Open()
Dim sql As String = "select Type_Naam from tbl_type"
Dim command As New OleDbCommand(sql, con)
Dim reader As OleDbDataReader = command.ExecuteReader()
While reader.Read()
ListBox1.Items.Add(reader.GetString(0))
End While
con.Close()
End Sub
Listboxindexchanged event:
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
Dim curItem As String = ListBox1.SelectedItem.ToString()
Dim con As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\PatientenDatabase.mdb")
con.Open()
Dim sql As String = String.Format("select * from tbl_Relaties where Rel_Type='{0}'", curItem)
Dim command As New OleDbCommand(sql, con)
Dim reader As OleDbDataReader = command.ExecuteReader()
If reader.HasRows Then
While reader.Read()
txtID.Text = reader.GetValue(0).ToString()
txtType.Text = reader.GetValue(1).ToString()
txtName.Text = reader.GetValue(2).ToString()
txtVoo.Text = reader.GetValue(3).ToString()
txtAdress.Text = reader.GetValue(4).ToString()
End While
Else
txtID.Text = String.Empty
txtType.Text = String.Empty
txtName.Text = String.Empty
txtVoo.Text = String.Empty
txtAdress.Text = String.Empty
End If
con.Close()
End Sub
Final result:
Besides, I only make a few column code and you can follow the above code to complete the rest of the code.

Insert data from auto generated textbox to SQL Server database

I have created a code for generating a text box in vb.net using button click and function
Public Function AddNewTextBox() As System.Windows.Forms.TextBox
Dim txt As New System.Windows.Forms.TextBox()
Me.Controls.Add(txt)
txt.Top = cLeft * 30
txt.Left = 100
'txt.Text = "TextBox " & Me.cLeft.ToString
cLeft = cLeft + 1
txt.ForeColor = Color.DarkGreen
txt.BackColor = Color.Gray
txt.Font = New Font("Arial", 14.0, FontStyle.Regular)
txt.Size = New Size(237, 31)
txt.Location = New Point(156, 130 + top1)
Return txt
End Function
In the button
Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'call the function
AddNewTextBox()
End Sub
I have tried this
cmd.CommandText = "INSERT INTO userlog ([username],[userlastname]) Values ( #username) "
cmd.Parameters.AddWithValue("#username", txt.Text(i).Text)
cmd.Parameters.AddWithValue("#userlastname", txt.Text(i).Text)
but getting an error in
txt.Text(i)
since txt is declared only in AddNewTextBox function.
I have made 3 auto generated text boxs
How do I save this data inside the text box to the database?
Add a FlowlayoutPanel to your form and set the FlowDirection to TopDown. (as commented by #jmcilhinney) This saves calculating the position of the text boxes.
It doesn't make sense to have a function returning a text box when you never use the return value.
The data access code uses the .Add method suggested by #SMor. See
http://www.dbdelta.com/addwithvalue-is-evil/
and
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
and another one:
https://dba.stackexchange.com/questions/195937/addwithvalue-performance-and-plan-cache-implications
I had to guess at the datatypes. Check your database for correct types.
The values come from the controls collection of the FlowLayoutPanel where the controls were added.
Using blocks ensure that you database objects are closed and disposed even if there is an error. Pass the connection string directly to the constructor of the connection and the command text and connection directly to the constructor of the command.
Public Sub AddNewTextBox()
Dim txt As New System.Windows.Forms.TextBox()
txt.Name = "user" & nameTextBox.ToString
txt.ForeColor = Color.DarkGreen
txt.BackColor = Color.Gray
txt.Font = New Font("Arial", 14.0, FontStyle.Regular)
txt.Size = New Size(120, 30)
FlowLayoutPanel1.Controls.Add(txt)
End Sub
Private Sub UpdateUsers()
Using cn As New SqlConnection("Your connection string")
Using cmd As New SqlCommand("INSERT INTO userlog ([username],[userlastname]) Values ( #username, #userlastname);", cn)
cmd.Parameters.Add("#username", SqlDbType.VarChar).Value = FlowLayoutPanel1.Controls(0).Text
cmd.Parameters.AddWithValue("#userlastname", SqlDbType.VarChar).Value = FlowLayoutPanel1.Controls(1).Text
cn.Open()
cmd.ExecuteNonQuery()
End Using
End Using
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AddNewTextBox()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
UpdateUsers()
End Sub
EDIT
For Each tb As TextBox In FlowLayoutPanel1.Controls
If tb.Text = "" Then
MessageBox.Show("Please fill all text boxes before Updating")
Return
End If
Next
Since the TextBox is being added to the control collection of the Form, you can use the OfType enumerable method to get all TextBox controls. What's more I would probably assign the Tag of the generated TextBox to the desired field name so that you can query the control collection for the first instance of the TextBox who's tag equals the desired field.
Also its worth mentioning that you can use the With keyword to get rid of some unnecessary code.
With all that being said, your AddNewTextBox method would look like this:
Public Function AddNewTextBox(ByVal fieldName As String) As System.Windows.Forms.TextBox
Dim txt As New System.Windows.Forms.TextBox()
Me.Controls.Add(txt)
With
.Top = cLeft * 30
.Left = 100
'.Text = "TextBox " & Me.cLeft.ToString
cLeft = cLeft + 1
.ForeColor = Color.DarkGreen
.BackColor = Color.Gray
.Font = New Font("Arial", 14.0, FontStyle.Regular)
.Size = New Size(237, 31)
.Location = New Point(156, 130 + top1)
.Tag = fieldName
End With
Return txt
End Function
Your Button's click event would look like this:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'call the function
Dim txt As TextBox = AddNewTextBox("username")
End Sub
And your parameterized query would look like this:
Dim usernameTextBox As TextBox = Me.Controls.OfType(Of TextBox).FirstOrDefault(Function(txt) txt.Tag IsNot Nothing AndAlso txt.Tag = "username")
If usernameTextBox IsNot Nothing Then
cmd.Parameters.AddWithValue("#username", usernameTextBox.Text)
End If

Update a chart automatically with a timer

So, I am developing an application and I got stuck probably on a basic thing that I can't solve. I have a chart which is connected to a database and it will be running a query. I was able to do it, but the issue there I am facing is that it won't update unless I close and open the application.
I will show you the code that I am using and then explain it:
Public Sub UpdateChart()
Try
SQLCon = New SqlConnection
SQLCon.ConnectionString = "......................"
Timer1.Interval = 3000
Timer1.Start()
Dim sqlStatis As String = "SELECT Top 5 Filename, Filesize FROM infofile"
Dim da As New SqlDataAdapter(sqlStatis, SQLCon)
Dim ds As New DataSet()
da.Fill(ds, "infofile")
Chart1.DataSource = ds.Tables("infofile")
Catch ex As Exception
MessageBox.Show(ex.ToString())
Finally
SQLCon.Dispose()
End Try
End Sub
Public Sub BuildChart()
Dim Chart1 = New Chart()
Dim ChartArea1 As ChartArea = New ChartArea()
Dim Legend1 As Legend = New Legend()
Dim Series1 As Series = New Series()
Me.Controls.Add(Chart1)
ChartArea1.Name = "ChartArea1"
Chart1.ChartAreas.Add(ChartArea1)
Legend1.Name = "Legend1"
Chart1.Legends.Add(Legend1)
Chart1.Location = New System.Drawing.Point(12, 12)
Chart1.Name = "Chart1"
Series1.ChartArea = "ChartArea1"
Series1.Legend = "Legend1"
Series1.Name = "Tamanho do ficheiro"
Chart1.Series.Add(Series1)
Chart1.Size = New System.Drawing.Size(600, 300)
Chart1.TabIndex = 0
Chart1.Text = "Chart1"
Chart1.Series("Tamanho do ficheiro").XValueMember = "Filename"
Chart1.Series("Tamanho do ficheiro").YValueMembers = "Filesize"
End Sub
This method will be called on the form and the data will be shown as I want. As you can see on the method I have a Timer and it will update the chart every 3 seconds or 3000 milliseconds.
Inside of the Timer I have this:
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
UpdateChart()
End Sub
And inside of the form I have this:
Public Sub Gráfico_Load(sender As Object, e As EventArgs) Handles MyBase.Load
BuildChart()
UpdateChart()
End Sub
It doesn't gives me any error but it doesn't update even if I create a button called "Update Chart" and put the method already created inside of the button.
So do you have any ideia I could I solve my problem?
I would move
Timer1.Interval = 3000
Timer1.Start()
to the end of the Form Load
and Dim Chart1 as a form level variable and new it up in the Load as well

How to update a Chart

I've just finished developing a piece of code where I am able to create a Chart and query from my database. Here I insert values from the database and it will show to the user.
I will post here the code that I've done to create a chart:
Public Sub BuildChart()
Try
SQLCon = New SqlConnection
SQLCon.ConnectionString = "........."
Dim sqlStatis As String = "SELECT Top 5 Filename, Filesize FROM infofile"
Dim Chart1 As New Chart()
Dim da As New SqlDataAdapter(sqlStatis, SQLCon)
Dim ds As New DataSet()
da.Fill(ds, "infofile")
Dim ChartArea1 As ChartArea = New ChartArea()
Dim Legend1 As Legend = New Legend()
Dim Series1 As Series = New Series()
Me.Controls.Add(Chart1)
ChartArea1.Name = "ChartArea1"
Chart1.ChartAreas.Add(ChartArea1)
Legend1.Name = "Legend1"
Chart1.Legends.Add(Legend1)
Chart1.Location = New System.Drawing.Point(12, 12)
Chart1.Name = "Chart1"
Series1.ChartArea = "ChartArea1"
Series1.Legend = "Legend1"
Series1.Name = "Tamanho do ficheiro"
Chart1.Series.Add(Series1)
Chart1.Size = New System.Drawing.Size(600, 300)
Chart1.TabIndex = 0
Chart1.Text = "Chart1"
Chart1.Series("Tamanho do ficheiro").XValueMember = "Filename"
Chart1.Series("Tamanho do ficheiro").YValueMembers = "Filesize"
Chart1.DataSource = ds.Tables("infofile")
Catch ex As Exception
MessageBox.Show(ex.ToString())
Finally
SQLCon.Dispose()
End Try
End Sub
As you can see I've created a method which will be called in the form and the info will be shown there. Outside of everything I declared a variable Dim Chart1 As New Chart(). Now I want to create a method which allows me with a timer to update automatically the chart. So I should create another method called UpdateChart where I could insert there this:
Timer1.Interval = 3000
Timer1.Start()
But now I have no idea what should I use to update it every 3 secs or 3000 milliseconds.
On Load you want to call the BuildChart method and start the timer:
Private Sub frmTest_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
BuildChart()
With Timer1
.Enabled = True
.Interval = 3000
.Start()
End With
End Sub
For BuildChart you only need to create the chart itself and not bind the data.
Public Sub BuildChart()
Try
Dim Chart1 As New Chart()
Dim ChartArea1 As ChartArea = New ChartArea()
Dim Legend1 As Legend = New Legend()
Dim Series1 As Series = New Series()
Me.Controls.Add(Chart1)
ChartArea1.Name = "ChartArea1"
Chart1.ChartAreas.Add(ChartArea1)
Legend1.Name = "Legend1"
Chart1.Legends.Add(Legend1)
Chart1.Location = New System.Drawing.Point(12, 12)
Chart1.Name = "Chart1"
Series1.ChartArea = "ChartArea1"
Series1.Legend = "Legend1"
Series1.Name = "Tamanho do ficheiro"
Chart1.Series.Add(Series1)
Chart1.Size = New System.Drawing.Size(600, 300)
Chart1.TabIndex = 0
Chart1.Text = "Chart1"
Chart1.Series("Tamanho do ficheiro").XValueMember = "Filename"
Chart1.Series("Tamanho do ficheiro").YValueMembers = "Filesize"
Catch ex As Exception
MessageBox.Show(ex.ToString())
Finally
SQLCon.Dispose()
End Try
End Sub
We then want UpdateChart to be called from the Timer.Tick event.
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
UpdateChart()
End Sub
Private Sub UpdateChart()
Chart1.Series(0).Points.Clear()
Chart1.DataSource = ""
SQLCon = New SqlConnection
SQLCon.ConnectionString = "............."
Dim sqlStatis As String = "SELECT Top 5 Filename, Filesize FROM infofile"
Dim da As New SqlDataAdapter(sqlStatis, SQLCon)
Dim ds As New DataSet()
da.Fill(ds, "infofile")
Chart1.DataSource = ds.Tables("infofile")
End Sub
Be aware though that this will create a lot of hits to your database.

How do you pre-load a form in VB.Net?

I have a form that contains lots of stuff, including textboxes, images, panels, and a database. The problem is that when I started running it, the window shows up, but the contents display a few seconds after the window is displayed.
I tried removing this important code in the form's shown event. It is a bit useful, but the program doesn't work properly:
Private Sub Inventory_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
Label1.Parent = PictureBox1
Label2.Parent = PictureBox1
OpenConnection()
Dim da As SqlDataAdapter = New SqlDataAdapter("Select * from inventory order by [Item No] asc", conn)
Dim ds As New DataSet
da.Fill(ds, "inventory")
DataGridView1.DataSource = ds.Tables("inventory")
DataGridView1.ClearSelection()
conn.Close()
If DataGridView1.RowCount <> 0 Then
PictureBox1.Visible = False
Label1.Visible = False
Label2.Visible = False
End If
TextBox2.Focus()
MG.Visible = True
btnClear.PerformClick()
txtItemNo.ReadOnly = False
txtItemNo.Text = DataGridView1.RowCount + 1
txtItemNo.ReadOnly = True
btnDelete.Enabled = False
clearExpiryDate.Visible = False
End Sub
How can I fix this delay?