Run two events simultaneously - vb.net

The code for my animated text already stored in my Table1 works very well without any error in my MDIParent1.But when I execute another code for exemple an print code when i click on Button_Print The animated text will stop Temporary and the animation of the text will be very heavy.Please How to run other code without effect on my animated text ?
My code in Module1
Public Sub Text_Panel_Animation()
Try
Dim da As New OleDbDataAdapter("Select * from Table1 order by Id", Con)
Dim dt As New DataTable
da.Fill(dt)
MDIParent1.Label1.Left = 0 - MDIParent1.Label1.Width
If dt.Rows.Count > 0 Then
For r As Integer = 1 To dt.Columns.Count - 1
MDIParent1.Label1.Text &= " " & (dt(0)(r).ToString)
Next
MDIParent1.Timer1.Start()
End If
Con.Close()
Catch ex As Exception
MsgBox(ex.Message(), MsgBoxStyle.Critical, "Error")
End Try
End Sub
In MDIParent1 Load .. I put this code :
Call Text_Panel_Animation()
And In MDIParent1 .. i have also :
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
If Label1.Left >= Me.Panel1.Width Then Label1.Left = 0 - Label1.Width
Label1.Left += 1
End Sub
I tried with this code but i have a same problem :
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Task.Run(Sub()
Try
Dim Dt As New DataTable
Dim SQLstr As String = "Select * from Table1"
SQLstr = "Select * from Table1 order BY Id"
Dim Da As New OleDbDataAdapter(SQLstr, Con)
Da.Fill(Dt)
Dim Rpt As New Crystal1
Rpt.SetDataSource(Dt)
Dim frm As New Form1
Me.Dispose()
frm.Show()
Form1.CrystalReportViewer1.Zoom(100%)
Catch
End Try
End Sub)
End Sub

You can start the printing in a new task
Private Sub Button_Print_Click (sender As Object, e As EventArgs) Handles Button_Print.Click)
Task.Run(Sub()
'TODO: Do the printing here...
End Sub)
End Sub
Note that you have to take precautions to be able to access the UI from this other task. See: VB.NET: Invoke Method to update UI from secondary threads
I would not do any UI stuff in the other task, since this can lead to problems. Instead, I would only query the DB and render the report in another task and then await this task before doing UI-related things. I'm not using Crystal Reports myself, but it would probably be something like this
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Rpt As Crystal1
Await Task.Run(
Sub()
Try
Dim Dt As New DataTable
Dim SQLstr As String
SQLstr = "Select * from Table1 order BY Id"
Dim Da As New OleDbDataAdapter(SQLstr, Con)
Da.Fill(Dt)
Rpt = New Crystal1
Rpt.SetDataSource(Dt)
Catch
End Try
End Sub)
Dim frm As New Form1
Me.Dispose()
frm.Show()
Form1.CrystalReportViewer1.Zoom(100%)
Form1.CrystalReportViewer1.ReportSource = Rpt
End Sub
Do not forget the Async keyword in the method header.
Note: If Me is the main form, then Me.Dispose() will terminate the application.

Related

How can I make a datagridview live connected to an access database stored locally in VB.NET?

I would like it so when I delete/edit a record from the datagridview, it will automatically delete/edit the access database file. Here is a snippet of my code which loads the database into the datagridview.
Public Function dbConnect() As Boolean
Try
cn = New OleDbConnection(DataBasePath)
cn.Open()
'MessageBox.Show("is work ")
Return True
Catch ex As Exception
MessageBox.Show("Unable to open the database: " & ex.Message)
Return False
End Try
End Function
Private Function GetOrders() As DataTable
Dim dtOrders As New DataTable
dbConnect()
Dim SQLCMD As New OleDbCommand
SQLCMD.Connection = cn
SQLCMD.CommandText = "Select * From [OrdersTbl]"
dtOrders.Load(SQLCMD.ExecuteReader())
Return dtOrders
End Function
Private Sub EditOrdersForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
OrdersDataGrid.DataSource = GetOrders()
End Sub
How can I make it so that changes are saved to the local file.
I have a datagridview and a button on the form. Here's the code you can refer to:
Private dt As DataTable = New DataTable
Private da As OleDbDataAdapter
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim connection As OleDbConnection = New OleDbConnection("your connection string")
connection.Open()
Dim cmdTxt As String = "SELECT * FROM yourTable"
da = New OleDbDataAdapter(New OleDbCommand(cmdTxt, connection))
Dim builder As OleDbCommandBuilder = New OleDbCommandBuilder(da)
da.Fill(dt)
Dim source As BindingSource = New BindingSource With {
.DataSource = dt
}
DataGridView1.DataSource = source
connection.Close()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
DataGridView1.EndEdit()
da.Update(dt)
End Sub
Every time you want to update database from your datagridview, just click the button.

show patients that had a certain type of diagnose

I have a patient database. In that database i have a table "diagnosetypes" and a table with dossiers with a patient that received a certain diagnose.
In my diagnose form i have a list of diagnoses and now i want to add a listbox with a filter on all patients/dossiers that had this certain diagnose when that diagnose is selected in the combobox.
this is my current code
Public Class Diagnoses
Private Sub Diagnoses_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Tbl_DossiersTableAdapter.Fill(Me.PatientenDatabaseDataSetX.tbl_Dossiers)
Me.Tbl_DiagnosesTableAdapter.Fill(Me.PatientenDatabaseDataSetX.tbl_Diagnoses)
Dim dt = Tbl_DiagnosesBindingSource
cboxDiagnose.DataSource = dt
cboxDiagnose.DisplayMember = "Diag_Type"
txtDiagnoseBeschrijving.Text = dt(0)("Diag_Type").ToString
cboxDiagnose.Focus()
End Sub
Private Sub CboxDiagnose_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles cboxDiagnose.SelectionChangeCommitted
txtDiagnoseBeschrijving.Text = DirectCast(cboxDiagnose.SelectedItem, DataRowView)("Diag_Beschrijving").ToString
End Sub
Private Sub CboxDiagnose_Click(sender As Object, e As EventArgs) Handles cboxDiagnose.Click
RefreshData()
End Sub
Private Sub BtnAddDiagnose_Click(sender As Object, e As EventArgs) Handles btnAddDiagnose.Click
FormMakeDiagnoseType.Show()
End Sub
Private Sub RefreshData()
Try
Me.Tbl_DiagnosesBindingSource.Filter = Nothing
Me.Tbl_DiagnosesTableAdapter.Fill(Me.PatientenDatabaseDataSetX.tbl_Diagnoses)
Catch ex As Exception
MsgBox("Refresh Data Error: " & ex.Message.ToString(),
MsgBoxStyle.OkOnly Or MsgBoxStyle.Information, "Add New Record Failed!")
End Try
End Sub
End Class
edit: I changed my code to look like this as a way of trying to accomplish it myself , but i won't work.
Private Sub Diagnoses_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim cn As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=F:\GoogleDrive\EINDWERK VBNET\PatientenDatabase.accdb")
cn.Open()
Dim cmmd As New OleDb.OleDbCommand("SELECT * FROM tbl_Dossiers WHERE OZ_ID.value = cboxDiagnose.text", cn)
Dim dr As OleDb.OleDbDataReader
dr = cmmd.ExecuteReader
Do While dr.Read
lboxPat_Diagcombo.Items.Add(dr("Rel_naam"))
Loop
cn.Close()
found something that works!
defined a binding source in code
then linked the listbox datasource to the binding source
then added following code :
Private Sub Onderzoeken_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Tbl_DossiersTableAdapter.Fill(Me.PatientenDatabaseDataSetX.tbl_Dossiers)
Me.Tbl_OnderzoeksTypesTableAdapter.Fill(Me.PatientenDatabaseDataSetX.tbl_OnderzoeksTypes)
Dim dt = Tbl_OnderzoeksTypesBindingSource
cboxOnderzoek.DataSource = dt
cboxOnderzoek.DisplayMember = "OZ_TypeOnderzoek"
cboxOnderzoek.ValueMember = "OZ_ID"
rtbBeschrijvingOnderzoek.Text = dt(0)("OZ_TypeOnderzoek").ToString
cboxOnderzoek.Focus()
Private Sub CboxDiagnose_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles cboxOnderzoek.SelectionChangeCommitted
rtbBeschrijvingOnderzoek.Text = DirectCast(cboxOnderzoek.SelectedItem, DataRowView)("OZ_Onderzoeksbeschrijving").ToString
Dim cn As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=F:\GoogleDrive\EINDWERK VBNET\PatientenDatabase.accdb")
cn.Open()
Dim ssql As String = "Select Rel_ID, tbl_Relaties.Rel_Naam &' ' & Rel_Voornaam as totaleNaam " &
"From tbl_Relaties INNER Join (tbl_Dossiers INNER Join tbl_DossRelatie On " &
"tbl_Dossiers.Dos_ID = tbl_DossRelatie.DR_DossID) ON tbl_Relaties.Rel_ID = tbl_DossRelatie.DR_RelID WHERE OZ_ID = " & cboxOnderzoek.SelectedValue
Dim cmmd As New OleDb.OleDbCommand(ssql, cn)
Dim dr As OleDb.OleDbDataReader
dr = cmmd.ExecuteReader
If dr.HasRows Then
Application.DoEvents()
bs_Relaties.DataSource = dr
lboxOZpatientcombo.DisplayMember = "totaleNaam"
lboxOZpatientcombo.ValueMember = "Rel_ID"
End If
cn.Close()
End Sub
since i added a binding source, the rest was easier to do:
Private Sub lboxOZpatientcombo_DoubleClick(sender As Object, e As EventArgs) Handles lboxOZpatientcombo.DoubleClick
Try
Dim MPF As New MainPatientform
MPF.display(Me, bs_Relaties.Current("rel_id"))
Catch ex As Exception
End Try
End Sub
thanks to all for new insights in this matter.

Delete selected row from DataGridView and MS-Access Database

I am trying to delete the selected row from DataGridView and MS-Access database..
Private Sub ButtonEditDelete_Click(sender As Object, e As EventArgs) Handles ButtonEditDelete.Click
If Not Connection.State = ConnectionState.Open Then
Connection.Close()
End If
Try
If Me.DataGridViewEdit.Rows.Count > 0 Then
If Me.DataGridViewEdit.SelectedRows.Count > 0 Then
Dim intStdID As Integer = Me.DataGridViewEdit.SelectedRows(0).Cells("Username").Value
Connection.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Johnster\documents\visual studio 2015\Projects\Cash register\Cash register\Database11.accdb;Jet OLEDB:Database Password="
Connection.Open()
Command.Connection = Connection
Command.CommandText = "DELETE From MasterUser WHERE ID=? And Username=? And UserFullname=? AND Password=?"
Dim res As DialogResult
res = MsgBox("Are you sure you want to DELETE the selected Row?", MessageBoxButtons.YesNo)
If res = DialogResult.Yes Then
Command.ExecuteNonQuery()
Else : Exit Sub
End If
Connection.Close()
End If
End If
Catch ex As Exception
End Try
End Sub
Replace your (Try) Part with this code:
Using cn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Johnster\documents\visual studio 2015\Projects\Cash register\Cash register\Database11.accdb;Jet OLEDB:Database Password=")
cn.Open()
Try
For Each row As DataGridViewRow In DataGridViewEdit.SelectedRows
Using cm As New OleDbCommand
cm.Connection = cn
cm.CommandText = "DELETE * FROM CheckDJ WHERE [Username]= #myuser"
cm.CommandType = CommandType.Text
cm.Parameters.AddWithValue("#myuser", CType(row.DataBoundItem, DataRowView).Row("Username"))
cm.ExecuteNonQuery()
End Using
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
cn.Close()
End Using
then clear your datasource of datagridview by this line:
DataGridViewEdit.Datasource = nothing
then repeat the code part that is responsible of filling the datagridview from the database
You are going about this in very much the wrong way. The proper way to do it would be to use an OleDbDataAdapter to populate a DataTable, bind that to a BindingSource and bind that to your DataDridView. You can then call RemoveCurrent on the BindingSource to set the RowState of the DataRow bound to the selected DataGridViewRow to Deleted. You then use the same OleDbDataAdapter to save the changes from the DataTable back to the database. The Fill method of the data adapter retrieves data and the Update method saves changes. You can call Update every time there's a change to save or you can let the user make all there changes locally first and then save them all in a single batch. Here's a code example:
Private connection As New OleDbConnection("connection string here")
Private adapter As New OleDbDataAdapter("SELECT ID, Name, Quantity, Unit FROM StockItem",
connection)
Private builder As New OleDbCommandBuilder(adapter)
Private table As New DataTable
Private Sub InitialiseDataAdapter()
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey
End Sub
Private Sub GetData()
'Retrieve the data.
adapter.Fill(table)
'Bind the data to the UI.
BindingSource1.DataSource = table
DataGridView1.DataSource = BindingSource1
End Sub
Private Sub SaveData()
'Save the changes.
adapter.Update(table)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
InitialiseDataAdapter()
GetData()
End Sub
Private Sub deleteButton_Click(sender As Object, e As EventArgs) Handles deleteButton.Click
BindingSource1.RemoveCurrent()
End Sub
Private Sub saveButton_Click(sender As Object, e As EventArgs) Handles saveButton.Click
SaveData()
End Sub
In certain circumstances, you may not be able to use an OleDbCommandBuilder and would have to create the InsertCommand, UpdateCommand and DeleteCommand yourself.

How to display data in DataGridView like flight information display

I have a program that displays data from MS Access in DataGridView by Timers
I put 2 dgvs in my Form and each one should display different data from different tables.
my dgv displays 14 rows (that's the full size of monitor!).
here is what i tried:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Timer1.Start()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
getDATA(dgv1, dgv2, Timer1, Timer2, "tab1")
End Sub
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
getDATA(dgv2, dgv1, Timer2, Timer1, "tab2")
End Sub
Private Sub getDATA(dgv As DataGridView, vdgv As DataGridView, tm1 As Timer, tm2 As Timer, tbl As String)
Try
dgv.Visible = True
vdgv.Visible = False
If conn.State = ConnectionState.Open Then conn.Close()
Dim sqlstr As String = ""
sqlstr = "Select f1,f2,f3,f4 from " + tbl
Dim ds As New DataTable
Dim da As New OleDbDataAdapter(sqlstr, conn)
ds.Reset()
da = New OleDbDataAdapter(sqlstr, conn)
da.Fill(ds)
conn.Open()
If ds.Rows.Count = 0 Then
dgv.Rows.Clear()
Else
dgv.Rows.Clear()
dgv.Rows.Add(ds.Rows.Count)
For s = 0 To ds.Rows.Count - 1
dgv.Rows(s).Cells(0).Value = ds.Rows(s).Item("f1")
dgv.Rows(s).Cells(1).Value = ds.Rows(s).Item("f2")
dgv.Rows(s).Cells(2).Value = ds.Rows(s).Item("f3")
dgv.Rows(s).Cells(3).Value = ds.Rows(s).Item("f4")
Next s
End If
dgv.ClearSelection()
conn.Close()
tm1.Stop()
tm2.Start()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
This code is work fine, but sometimes one of the tables contains more than 14 rows!
how can i display the rest of rows in specific DGV?
should i use another Timer?

DataGridView and BindingSource timer issue

I have a DataGridview that displays the data and a TextBox that allows me to filter the BindingSource with an SQL query to display the data based on the input string. This is all working fine apart from once I have filtered the DataGridView the timer function I have is resetting it back so all the data is being displayed again. The timer is set on a 1000ms basis, so it will show the filtered result for a second, then revert back.
Heres my code:
Imports System.Data.OleDb
Public Class Form1
Dim duraGadgetDB As String = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source = C:\Users\Dave\Documents\duraGadget.mdb;"
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim sql As String = "SELECT * FROM duragadget"
Dim connection As New OleDbConnection(duraGadgetDB)
Dim dataadapter As New OleDbDataAdapter(sql, connection)
Dim ds As New DataSet()
connection.Open()
dataadapter.Fill(ds, "dura")
connection.Close()
DataGridView1.DataSource = ds
DataGridView1.DataMember = "dura"
DataGridView1.Columns(5).Width = 300
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
insert.Show()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim currentRowID As Integer
Dim scrollPosition As Integer = DataGridView1.FirstDisplayedScrollingRowIndex
Try
If DataGridView1.CurrentRow IsNot Nothing Then
currentRowID = DataGridView1.CurrentRow.Index
Dim sql As String = "SELECT * FROM duragadget"
Dim connection As New OleDbConnection(duraGadgetDB)
Dim dataadapter As New OleDbDataAdapter(sql, connection)
Dim ds As New DataSet()
connection.Open()
dataadapter.Fill(ds, "dura")
connection.Close()
DataGridView1.DataSource = ds
DataGridView1.DataMember = "dura"
DataGridView1.CurrentCell = DataGridView1.Item(1, currentRowID)
End If
Catch ex As Exception
End Try
DataGridView1.FirstDisplayedScrollingRowIndex = scrollPosition
End Sub
Private Sub txtSearchOnSku_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtSearchOnSku.TextChanged
Dim currentRowID As Integer
Dim scrollPosition As Integer = DataGridView1.FirstDisplayedScrollingRowIndex
Try
If DataGridView1.CurrentRow IsNot Nothing Then
currentRowID = DataGridView1.CurrentRow.Index
Dim sql As String = "SELECT * FROM duragadget"
Dim connection As New OleDbConnection(duraGadgetDB)
Dim dataadapter As New OleDbDataAdapter(sql, connection)
Dim ds As New DataSet()
Dim dsView As New DataView
Dim bs As New BindingSource()
connection.Open()
dataadapter.Fill(ds, "dura")
connection.Close()
dsView = ds.Tables(0).DefaultView
bs.DataSource = dsView
bs.Filter = "skuNo LIKE'" & txtSearchOnSku.Text & "*'"
DataGridView1.DataSource = bs
DataGridView1.CurrentCell = DataGridView1.Item(1, currentRowID)
End If
Catch ex As Exception
End Try
DataGridView1.FirstDisplayedScrollingRowIndex = scrollPosition
End Sub
End Class
Can anyone tell me how to stop this happening?
Assuming you mean that, if you have entered a value in your text box to filter your results, that you then don't want you timer to fire and unfilter them...
You can either, check the contents of the TextBox in the Timer1_Tick routine;
If txtSearchOnSku.Text <> "" Then Exit Sub
Or you can disable your timer in the txtSearchOnSku_TextChanged routine;
If txtSearchOnSku.Text <> "" Then
Timer1.Stop
Else
Timer1.Start
End If
Or, if you want to update your results once a second, based on you search, you can include the Filtering code in your Timer1_Tick routine.
As a quick point, you have alot of repeated code there. It may be worthwhile refactoring the repeated code out into another sub.