vb.net - How can I change the type of values that the DataTable can store? - vb.net

I want to add characters (like % and pp) in values stored in a DataTable, but I'm getting an error message:
Input string was not in a correct format.Couldn't store <97.0%> in Actual Column. Expected type is Decimal.
How can I change the type of values that the DataTable can store?
Dim dv As New System.Data.DataView
Dim dt As New System.Data.DataTable
dv = SQL_Customer.Select(DataSourceSelectArguments.Empty)
dt = dv.ToTable()
dt.Rows(1)(1) = CStr(dt.Rows(1)(1)) & "%"
dt.Rows(1)(2) = CStr(dt.Rows(1)(2)) & "%"
dt.Rows(1)(3) = CStr(dt.Rows(1)(3)) & "%"
dt.Rows(1)(4) = CStr(dt.Rows(1)(4)) & "pp"

You can't change the type of a data table column once it's filled.
One work around is to add a new column of type string and then populate that column with the string values you need and then delete the column that is of the type you don't need.

If this helps someone, this is how I resolved the problem:
Dim dv As New System.Data.DataView
Dim dt As New System.Data.DataTable
Dim dt2 As New System.Data.DataTable
Dim SelectedIndex As Object
If datagrid.SelectedIndex = "-1" Then SelectedIndex = 0 Else SelectedIndex = GV_Cust.SelectedIndex
'Populate Dataview with data in SQL Query for Customer KPIs
dv = SQL_Customer.Select(DataSourceSelectArguments.Empty)
'Populate table with data from dataview. Note that the data is formated as per data loaded. So if number is loaded, then format for the cell is number. This creates a problem when adding percentages
dt = dv.ToTable()
'New colums are added as string format in the dataTable so that % and pp can be added
Dim column As DataColumn
For i = 1 To 6
' Create second column.
column = New DataColumn()
column.DataType = System.Type.GetType("System.String")
column.ColumnName = i
column.AutoIncrement = False
column.Caption = i
column.ReadOnly = False
column.Unique = False
' Add the Column to the DataColumnCollection.
dt.Columns.Add(column)
Next
'New columns are populated and calculations for variances are calculated
For j = 0 To 2
For i = 0 To 4
dt.Rows(i)(7 + j) = dt.Rows(i)(1 + j) & "%"
dt.Rows(i)(10) = (dt.Rows(i)(1) - dt.Rows(i)(2)) & "pp"
dt.Rows(i)(11) = (dt.Rows(i)(1) - dt.Rows(i)(3)) & "pp"
dt.Rows(i)(12) = (dt.Rows(i)(2) - dt.Rows(i)(3)) & "pp"
Next
For i = 5 To 6
dt.Rows(i)(7 + j) = dt.Rows(i)(1 + j)
If dt.Rows(i)(2) = 0 Then dt.Rows(i)(10) = 0 & "%" Else dt.Rows(i)(10) = Math.Round((((dt.Rows(i)(1) / dt.Rows(i)(2))) - 1) * 100, 1) & "%"
If dt.Rows(i)(3) = 0 Then dt.Rows(i)(11) = 0 & "%" Else dt.Rows(i)(11) = Math.Round((((dt.Rows(i)(1) / dt.Rows(i)(3))) - 1) * 100, 1) & "%"
If dt.Rows(i)(3) = 0 Then dt.Rows(i)(12) = 0 & "%" Else dt.Rows(i)(12) = Math.Round((((dt.Rows(i)(2) / dt.Rows(i)(2))) - 1) * 100, 1) & "%"
Next
Next
'Old columns are deleted and new wones are renamed
dt.Columns.Remove("A")
dt.Columns("1").ColumnName = "A"
dt.Columns.Remove("B")
dt.Columns("2").ColumnName = "B
dt.Columns.Remove("C")
dt.Columns("3").ColumnName = "C"
dt.Columns.Remove("D")
dt.Columns("4").ColumnName = "D"
dt.Columns.Remove("D")
dt.Columns("5").ColumnName = "E"
dt.Columns.Remove("F")
dt.Columns("6").ColumnName = "F"
'Customer grid is populated, a selection button is added and the first row is selected
datagrid.DataSource = dt
datagrid.AutoGenerateSelectButton = True
datagrid.DataBind()
datagrid.SelectedIndex = SelectedIndex

Related

vb.net chart: How to get AxisX.CustomLabels in sync with AxisX.MajorTickMark

As shown in the code, I get CustomLabels displayed, but they are not on the MajorTickMarks defined in the ChartArea. How do I get this in sync?
vb.net
Dim from_X, to_X As Date
from_X = myClass.get_DateOfWeek(CInt(yearkNo), CInt(weekNo), DayOfWeek.Monday)
'Last week from mainTable
weekNo = mainTable.Columns(mainTable.Columns.Count - 1).ColumnName.Split(CChar("/"))(0).Substring(2, 2)
yearkNo = mainTable.Columns(mainTable.Columns.Count - 1).ColumnName.Split(CChar("/"))(1).Substring(0, 4)
to_X = myClass.get_DateOfWeek(CInt(yearkNo), CInt(weekNo), DayOfWeek.Saturday)
Dim ints as integer = CInt(DateDiff(DateInterval.WeekOfYear, from_X, to_X, FirstDayOfWeek.Monday, FirstWeekOfYear.FirstFullWeek))
Dim xdate(ints) As Date 'is looped through and the date of the respective week is added.
newchart(chart1) 'create new chart
Dim chartArea1 As New ChartArea("Default")
chart1.ChartAreas.Add(chartArea1)
chart1.ChartAreas("Default").AxisX.IntervalType = DateTimeIntervalType.Weeks
chart1.ChartAreas("Default").AxisX.Interval = 1
chart1.ChartAreas("Default").AxisX.LabelAutoFitStyle = LabelAutoFitStyles.DecreaseFont
chart1.ChartAreas("Default").AxisX.LabelAutoFitMinFontSize = 7
chart1.ChartAreas("Default").AxisX.LabelStyle.Font = My.Settings.fontbold8
chart1.ChartAreas("Default").AxisX.LabelStyle.Angle = 90
chart1.ChartAreas("Default").AxisX.MajorTickMark.Enabled = True
chart1.ChartAreas("Default").AxisX.MinorTickMark.Enabled = False
chart1.ChartAreas("Default").AxisX.Minimum = from_X.ToOADate()'44443
chart1.ChartAreas("Default").AxisX.Maximum = to_X.ToOADate()'44828
chart1.ChartAreas("Default").AxisX.IsMarginVisible = False
chart1.Series.Add("K").Color = ColorTranslator.FromHtml("#297AB7") 'MattBlau colorx(0)
chart1.Series("K").Points.DataBindXY(xdate, yValues)
chart1.ChartAreas("Default").AxisX.CustomLabels.Clear()
For intVal As Integer = 0 To ints - 1
Debug.Print(intVal & " - " & Format(xdate(intVal), "yyyy-MM-dd"))
Select Case intVal
Case 0, 5, 10, 15, 20, ints - 2
chart1.ChartAreas("Default").AxisX.CustomLabels.Add(xdate(intVal).ToOADate(), xdate(ints - 1).ToOADate(), myClass.get_WeekNumber(xdate(intVal)) & "/" & xdate(intVal).Year)
End Select
Next
It looks now like here in the picture:
https://www.spearhead-home.com/Downloads/20220517_XAchseKWs.jpg
Found now a solution for me:
AxisX.IntervalType, AxisX.Minimum, AxisX.Maximum must match the series DataBindXY(xValues, yValues)
Dim ints as integer = CInt(DateDiff(DateInterval.WeekOfYear, von_X, bis_X, _
FirstDayOfWeek.Monday, FirstWeekOfYear.FirstFullWeek))
Dim xdate(ints) As Date 'is looped through and the date of the respective week is added.
Dim xInt(ints) As Integer 'is looped through and the numbers of the interval-count added.
chart1.ChartAreas("Default").AxisX.IntervalType = DateTimeIntervalType.NotSet
chart1.ChartAreas("Default").AxisX.Interval = 1
chart1.ChartAreas("Default").AxisX.Minimum = 0
chart1.ChartAreas("Default").AxisX.Maximum = ints - 1
chart1.ChartAreas("Default").AxisX.CustomLabels.Clear()
For intVal As Integer = 0 To ints - 1
Dim kw_run As String = ""
kw_run = myClass.set_WeekFormat(myClass.get_WeekNumber(xdate(intVal)), xdate( _
intVal), True)
'result looks like: 2022/20
chart1.ChartAreas("Default").AxisX.CustomLabels.Add(intVal, intVal + 1, kw_run, _
0, LabelMarkStyle.None)
Next
'Series
chart1.Series("mySeries").Points.DataBindXY(xInt, yValues)
'...

Update previous row

I have an Excel file that contains some datas that I want to export into an Access db. In the C column I've got a field called 'Description'. Usually this field occupy just one cell, but it can happens that is more long.
In this case, for example, AP.01 has got 5 rows of description. How can update the first row with the next rows?
Public Sub updateDB(ByVal PathDB As String, str As String, id As Integer)
Dim db As New cDB
Dim v As New cVoce
Dim rs As ADODB.Recordset = db.RecordSet
v.Description = str
db.connetti_DB(PathDB)
db.get_rs("UPDATE Voice SET Description = '" + v.Description + "' WHERE id= '"+id+"'")
End Sub
Public Function get_rs(ByVal query As String) As ADODB.Recordset
If db Is Nothing Then rs = Nothing : Return rs
rs = New ADODB.Recordset
rs.CursorType = ADODB.CursorTypeEnum.adOpenStatic
rs.LockType = ADODB.LockTypeEnum.adLockOptimistic
rs.Open(query, db)
Return rs
End Function
This code doesn't work because I update my current row, for this reason is useless the UPDATE instruction. How can I fix my code?
EDIT I post here the For loop
For r = 2 To grid.RowCount - 1
vett = Split(grid(r, 1).Text)
total = UBound(Split(grid(r, 1).Text, "."))
If grid(r, 1).Text <> "" Then
Select Case total
Case 0
Dim chapter As New cChapter
flag = 1
id = id + 1
chapter.Cod = grid(r, 1).Text.Substring(0, 1)
chapter.Description = grid(r, 3).Text
If Left(vett(0), 1) >= Chr(65) And Left(vett(0), 1) <= Chr(90) Then
chapter.Cod = Left(vett(0), 1)
oldChap = chap.Cod
If chapter.Cod <> oldCap Then
chapters.Add(chapter)
End If
End If
chapters.Add(chapter)
stringChap = chap.Description
Dim par As New cParagraph
If Left(vett(0), 2) >= Chr(65) And Left(vett(0), 2) <= Chr(90) Then
par.Cod = Left(vett(0), 2)
par.Cod_Chapter = Left(vett(0), 1)
oldPar = par.Cod
If par.Cod <> oldPar Then
paragraphs.Add(par)
End If
End If
If grid(r, 3).Text.Length > 255 Then
par.Description = grid(r, 3).Text.ToString.Substring(0, 252) + "..."
Else
par.Description = grid(r, 3).Text.ToString
End If
paragraphs.Add(par)
stringPar = par.Description
Case 1
flag = 2
id = id + 1
c_Voc = voc.Cod_Chapter
p_Voc = voc.Cod_Paragraph
voc.Cod_Chapter = grid(r, 1).Text.Substring(0, 1)
voc.Cod_Paragraph = grid(r, 1).Text.Split(".")(0)
voc.Cod_Voice = Right(vett(0), 2)
If grid(r, 3).Text.Length > 255 Then
voc.Description = grid(r, 3).Text.ToString.Substring(0, 252) + "..."
Else
voc.Description = grid(r, 3).Text.ToString
If voc.Description.EndsWith("-") Then
a = Replace(voc.Description, "-", "")
voc.Description = a
End If
End If
stringVoice = voc.Description
voices.Add(voc)
voices.Save_DB(dbDest)
Case 2
flag = 3
id = id + 1
sVoice = New cVoice
oldSvoice = voice.Cod_SVoice
sVoice.Cod_SVoice = Left(vett(0), 2)
If sVoice.Cod_SVoce <> oldSvoice Then
voices.Add(sVoice)
voices.Save_DB(dbDest)
End If
If grid(r, 3).Text.Length > 255 Then
sVoice.Description = grid(r, 3).Text.ToString.Substring(0, 252) + "..."
Else
sVoice.Description = grid(r, 3).Text
End If
stringSvoice = sVoice.Description
sVoice.Cod_Voce = Left(vett(0), 5)
sVoice.Price1 = grid(r, 12).Text
sVoice.Price2 = sVoice.Price1
sVoice.UniMi = grid(r, 11).Text
sVoce.Sep = "."
voices.Add(sVoce)
voices.Save_DB(dbDest)
End Select
Else
If flag = 1 Then
stringChap = grid(r, 3).Text
chap.Description = stringChap & grid(r, 3).Text
stringPar = grid(r, 3).Text
paragraph.Description = stringPar & grid(r, 3).Text
End If
If flag = 2 Then
stringVoice = grid(r, 3).Text
voc.Description = voc.Description & stringVoice
voices.updateDB(dbDest, stringVoice, id)
voices.Add(voc)
End If
If flag = 3 Then
stringSvoice = grid(r, 3).Text
sVoice.Description = stringSvoice & grid(r, 3).Text
voices.Add(sVoice)
End If
chapter.Save_DB(dbDest)
paragraph.Save_DB(dbDest)
voice.Save_DB(dbDest)
End If
Next
EDIT2 I declared id As Integer and when Code column has a value then id=id+1. In this way I always know which row I have to modify. I modified also updateDB (now I'm using 3 parameters) and I added a WHERE condition into my query. Despite the update, nothing has changed
In database you cannot store records without PrimaryKey (actually you can, but it is bad idea). Since in your solution id is in fact Excel row number (sorry if I'm not correct but it looks like from code) it could be very hard to maintain it in future (in case someone add or remove description row). It would be better to change id column to text and use code as PK.
Storing description then could be solved in 2 ways:
1) Concatenate all rows containing description into 1 variable adding vbNewLine in between and store it in description field.
2) More relational but also more complex - create 2nd table for description with PK as i.e. autonumber, ForeignKey Code referring to main table. Maintenance will be here very complex. Not really worth effort.
Amount of changes in code is quite big, so sorry I'll not provide fixed code but I hope idea is clear.
BTW: The reason why description is not updated is described in your post. You are increasing id only when code is present, so every description field from first group have id = 1. The most simple fix in your code would be to create 2 update statements - One for rows with code
UPDATE Voice SET Description = '" + v.Description + "' WHERE id= '"+id+"'
Second one for rows without code:
UPDATE Voice SET Description = Description + CHAR(13) + CHAR(10) + '" + v.Description + "' WHERE id= '"+id+"'

Strange issue with Datagridview-Rows not displayed

I have a Datagridview connected to a dataset.The problem is that occasionally,when the data is refreshed,it is not displayed in the DGV.The code is:
Private Sub DisplayInDGV()
Dim SQLSet As String
Dim DASet As New OleDb.OleDbDataAdapter
Dim DSSet As New DataSet
SQLSet = "Select * From SetDisplayTable"
DASet = New OleDb.OleDbDataAdapter(SQLSet, Con)
DSSet.Clear()
DASet.Fill(DSSet, "DSSetHere")
With DGVSetView
.Refresh()
.AutoGenerateColumns = False
.DataSource = Nothing
.DataSource = DSSet.Tables(0)
.Update()
DGVSetView.Columns(i).DataPropertyName = DSSet.Tables(0).Columns(i).ToString
.Columns(0).DataPropertyName = DSSet.Tables(0).Columns(0).ToString
.Columns(2).DataPropertyName = DSSet.Tables(0).Columns(1).ToString
.Columns(3).DataPropertyName = DSSet.Tables(0).Columns(2).ToString
.Columns(4).DataPropertyName = DSSet.Tables(0).Columns(3).ToString
.Columns(5).DataPropertyName = DSSet.Tables(0).Columns(4).ToString
.Columns(6).DataPropertyName = DSSet.Tables(0).Columns(5).ToString
.Columns(7).DataPropertyName = DSSet.Tables(0).Columns(6).ToString
.Columns(8).DataPropertyName = DSSet.Tables(0).Columns(7).ToString
.Columns(9).DataPropertyName = DSSet.Tables(0).Columns(8).ToString
.Columns(10).DataPropertyName = DSSet.Tables(0).Columns(9).ToString
.Columns(11).DataPropertyName = DSSet.Tables(0).Columns(10).ToString 'Item Unique Code for Hot Edit
.Columns(14).DataPropertyName = DSSet.Tables(0).Columns(12).ToString
End With
'Updating Totals/::
For ItemRow As Integer = 0 To DGVSetView.Rows.Count - 1
If DGVSetView.Rows(ItemRow).Cells(14).Value = True Then
DGVSetView.Rows(ItemRow).Cells(12).Value = DGVSetView.Rows(ItemRow).Cells(10).Value
ElseIf DGVSetView.Rows(ItemRow).Cells(14).Value = False Then
DGVSetView.Rows(ItemRow).Cells(13).Value = DGVSetView.Rows(ItemRow).Cells(10).Value
End If
Next
'Updating School and general totals in DGV//:
Dim SchoolTotal, GeneralTotal As Decimal
For ColumnTotal As Integer = 0 To DGVSetView.Rows.Count - 1
SchoolTotal += DGVSetView.Rows(ColumnTotal).Cells(12).Value
GeneralTotal += DGVSetView.Rows(ColumnTotal).Cells(13).Value
Next
txtSchoolAmtFinal.Text = SchoolTotal
txtGeneralAmtFinal.Text = GeneralTotal
DGVSetView.Update()
'Get gross total of the DGV amount column//:
If DGVSetView.RowCount <> 0 Then
Dim GrossAmt As Decimal = 0
For Index As Integer = 0 To DGVSetView.RowCount - 1
' GrossAmt += Convert.ToDecimal(DataGridView1.Rows(Index).Cells(11).Value)
If Str(DGVSetView.Rows(Index).Cells(10).Value) = "Null" Or (DGVSetView.Rows(Index).Cells(10).Value) <= 0 Then
MsgBox("Item Number " & (DGVSetView.Rows(Index).Cells(10).Value) & " is either blank or 0", MsgBoxStyle.Exclamation, "Item Error")
Else
GrossAmt += Convert.ToDecimal(DGVSetView.Rows(Index).Cells(10).Value)
End If
Next
txtInsertGrossAmt.Text = GrossAmt ' - Val(DGVSetView.Text)
Call SetNetAmount()
End If
'Generate Serial//:
Dim X As Integer
Do While X < DGVSetView.Rows.Count
DGVSetView.Item(0, X).Value = X + 1
X = X + 1
Loop
'Disbaling editing in all columns except pending//:
With DGVSetView
.Columns(0).ReadOnly = True
.Columns(2).ReadOnly = True
.Columns(3).ReadOnly = True
.Columns(4).ReadOnly = True
.Columns(5).ReadOnly = True
.Columns(6).ReadOnly = True
.Columns(7).ReadOnly = True
.Columns(8).ReadOnly = True
.Columns(9).ReadOnly = True
.Columns(10).ReadOnly = True
End With
txtTotalItems.Text = DGVSetView.Rows.Count
For Each r As DataGridViewRow In DGVSetView.Rows
r.Cells(1).Value = True
Next r
End Sub
The problem is that occasionally,the DGV will not show any rows and displays a blank frame.At such instances.if I check in DGV.Rows.count
the result is 0 despite there being underlying data in the table.
Note that this happens randomly.At other times the DGV refreshed properly and also displays data correctly.
Also note that this DGV resides within a TabControl.
Further,when the DGV fails to display the data,the totals which I have calculated in the above sub procedure return zero value.As such the problem appears to lie somewhere in the rows not being inserted in the DGV.
Thank you.
Khalid.
//Edit;Code Updated:
#jmcilhinney I have updated my code as follows.However,the earlier problem of the DGV going blank occasionally persists.Also the update process has slowed down slightly.It seems I may be making a mistake in the location of placing the Suspend and ResumeBinding statements:
Private Sub SetPreview()
Dim SQLSet As String
Dim DASet As New OleDb.OleDbDataAdapter
Dim DSSet As New DataSet
SQLSet = "Select * From SetDisplayTable"
Dim DTDGV As New DataTable
Dim DGVBindingSource As New BindingSource
DASet = New OleDb.OleDbDataAdapter(SQLSet, Con)
DASet.Fill(DTDGV)
DGVBindingSource.DataSource = DTDGV
DGVBindingSource.ResumeBinding()
With DGVSetView
.AutoGenerateColumns = False
.DataSource = DGVBindingSource
.Columns(0).DataPropertyName = DTDGV.Columns(0).ToString
.Columns(2).DataPropertyName = DTDGV.Columns(1).ToString
.Columns(3).DataPropertyName = DTDGV.Columns(2).ToString
.Columns(4).DataPropertyName = DTDGV.Columns(3).ToString
.Columns(5).DataPropertyName = DTDGV.Columns(4).ToString
.Columns(6).DataPropertyName = DTDGV.Columns(5).ToString
.Columns(7).DataPropertyName = DTDGV.Columns(6).ToString
.Columns(8).DataPropertyName = DTDGV.Columns(7).ToString
.Columns(9).DataPropertyName = DTDGV.Columns(8).ToString
.Columns(10).DataPropertyName = DTDGV.Columns(9).ToString
.Columns(11).DataPropertyName = DTDGV.Columns(10).ToString 'Item Unique Code for Hot Edit
.Columns(14).DataPropertyName = DTDGV.Columns(12).ToString
End With
DGVBindingSource.SuspendBinding()
'Updating Totals/::
For ItemRow As Integer = 0 To DGVSetView.Rows.Count - 1
If DGVSetView.Rows(ItemRow).Cells(14).Value = True Then
DGVSetView.Rows(ItemRow).Cells(12).Value = DGVSetView.Rows(ItemRow).Cells(10).Value
ElseIf DGVSetView.Rows(ItemRow).Cells(14).Value = False Then
DGVSetView.Rows(ItemRow).Cells(13).Value = DGVSetView.Rows(ItemRow).Cells(10).Value
End If
Next
'Updating School and general totals in DGV//:
Dim SchoolTotal, GeneralTotal As Decimal
For ColumnTotal As Integer = 0 To DGVSetView.Rows.Count - 1
SchoolTotal += DGVSetView.Rows(ColumnTotal).Cells(12).Value
GeneralTotal += DGVSetView.Rows(ColumnTotal).Cells(13).Value
Next
txtSchoolAmtFinal.Text = SchoolTotal
txtGeneralAmtFinal.Text = GeneralTotal
DGVSetView.Update()
'Get gross total of the DGV amount column//:
If DGVSetView.RowCount <> 0 Then
Dim GrossAmt As Decimal = 0
For Index As Integer = 0 To DGVSetView.RowCount - 1
' GrossAmt += Convert.ToDecimal(DataGridView1.Rows(Index).Cells(11).Value)
If Str(DGVSetView.Rows(Index).Cells(10).Value) = "Null" Or (DGVSetView.Rows(Index).Cells(10).Value) <= 0 Then
MsgBox("Item Number " & (DGVSetView.Rows(Index).Cells(10).Value) & " is either blank or 0", MsgBoxStyle.Exclamation, "Item Error")
Else
GrossAmt += Convert.ToDecimal(DGVSetView.Rows(Index).Cells(10).Value)
End If
Next
txtInsertGrossAmt.Text = GrossAmt ' - Val(DGVSetView.Text)
Call SetNetAmount()
End If
'Disabling editing in all columns except pending//:
With DGVSetView
.Columns(0).ReadOnly = True
.Columns(2).ReadOnly = True
.Columns(3).ReadOnly = True
.Columns(4).ReadOnly = True
.Columns(5).ReadOnly = True
.Columns(6).ReadOnly = True
.Columns(7).ReadOnly = True
.Columns(8).ReadOnly = True
.Columns(9).ReadOnly = True
.Columns(10).ReadOnly = True
End With
txtTotalItems.Text = DGVSetView.Rows.Count
For Each r As DataGridViewRow In DGVSetView.Rows
r.Cells(1).Value = True
Next r
End Sub

How to merge cells and remove blank spaces in my DataGrid using proper loop

My title is still broad so i'll explain here further.
This is my current output using my code:
.
But I want to make it look like this..
As you can see on the pictures, i want to remove the blank spaces. Because if I selected MORE data, let's say I selected 7 more days, it will go DIAGONALLY not horizontally.
I think I have a problem regarding my loops. Hope you can help me trace because I've been stuck here for a week debugging. (nevermind my long query, i just want to post all my code. I've also added comments for easier debugging.)
Here's my code:
Private Sub LoadDateAndUser()
Dim SqlStr As String = ""
Dim sqlConn As New SqlConnection(DataSource.ConnectionString)
Dim sqlComm As New SqlCommand(SqlStr, sqlConn)
Dim sqlAdapter As New SqlDataAdapter(sqlComm)
Dim o_Dataset As New DataSet()
SqlStr = " SELECT convert(varchar(10), A.TransDate, 101) as TransDate,ADMMED.TransNum, ADMMED.AdministeredDate, D.Dosage [Dosage], ISNULL(C.GenericName, ' ') + ' (' + IsNull(B.ItemName,'') + ' ' + IsNull(B.ItemDesc,'') + ')' [Medication], ADMMED.UserID" & _
" FROM INVENTORY..tbInvStockCard as A" & _
" LEFT OUTER JOIN INVENTORY..tbInvMaster as B On A.ItemID = B.ItemID " & _
" LEFT OUTER JOIN Inventory.dbo.tbForGeneric as C On B.GenericID = C.GenericID" & _
" LEFT OUTER JOIN Station..tbNurse_AdministeredMedicines ADMMED on a.idnum= ADMMED.idnum " & _
" LEFT OUTER JOIN build_file.dbo.tbCoDosage as D on A.DosageID = D.DosageID" & _
" LEFT OUTER JOIN Station.dbo.tbNurseCommunicationFile as E on A.IdNum = E.IDnum and E.ReferenceNum = A.RefNum" & _
" WHERE A.IdNum = '" & Session.Item("IDNum") & "' and ( A.RevenueID = 'PH' or A.RevenueID = 'PC' ) " & _
" AND A.LocationID = '20' and Not IsNull(ADMMED.AdministeredDate, '') = ''" & _
" AND A.RefNum = ADMMED.ReferenceNum and ADMMED.ItemID = A.itemid" & _
" AND (B.ItemClassificationID = '1' or B.ItemClassificationID = '10' or B.ItemClassificationID = '11' or B.ItemClassificationID = '16' or B.ItemClassificationID = '2' or B.ItemClassificationID = '9')" & _
" order by TransDate desc,ADMMED.AdministeredDate desc"
sqlComm.CommandText = SqlStr
sqlAdapter.Fill(o_Dataset, "Table")
Dim o_Row As DataRow
Dim o_AdmDates As New Collection()
Dim s_FormattedLastAdmDate As String = ""
Dim s_FormattedAdmDate As String = ""
Dim o_DerivedTable As New DataTable()
With o_DerivedTable
.Columns.Add("TransDate")
.Columns.Add("Medication")
.Columns.Add("Dosage")
.Columns.Add("TransNum")
End With
'Select all unformatted administered dates from the query
Dim o_UnformattedAdmDates As DataRow() = o_Dataset.Tables(0).Select("", "AdministeredDate Desc")
'Extract distinct administered dates and change its format
For Each o_Row In o_UnformattedAdmDates
s_FormattedAdmDate = Format(CDate(o_Row.Item("AdministeredDate")), KC_Date_Format) 'eg. Jan 01 15
If s_FormattedLastAdmDate <> s_FormattedAdmDate Then
s_FormattedLastAdmDate = s_FormattedAdmDate
o_AdmDates.Add(s_FormattedLastAdmDate) 'add all formatted dates in o_AdmDates
End If
Next
'Add formatted administred dates to derived table
Dim o_Item As String
For Each o_Item In o_AdmDates
o_DerivedTable.Columns.Add(o_Item)
Next
'Loop through the administred date
Dim o_NewRow As DataRow
Dim o_NextRow As DataRow
Dim i_Ctr As Integer
Dim x_isNewRow As Boolean = True
Dim i_MaxRec As Integer
i_MaxRec = o_Dataset.Tables(0).Rows.Count - 1
For i_Ctr = 0 To i_MaxRec
o_Row = o_Dataset.Tables(0).Rows(i_Ctr)
If i_Ctr <> i_MaxRec Then
o_NextRow = o_Dataset.Tables(0).Rows(i_Ctr + 1)
End If
If x_isNewRow Then
o_NewRow = o_DerivedTable.NewRow()
End If
o_NewRow("TransDate") = o_Row("TransDate")
o_NewRow("Medication") = o_Row("Medication")
o_NewRow("Dosage") = o_Row("Dosage")
o_NewRow("TransNum") = o_Row("TransNum")
'Fill approriate result date column based on query
For Each o_Item In o_AdmDates
s_FormattedAdmDate = Format(CDate(o_Row.Item("AdministeredDate")), KC_Date_Format)
Dim AdmTim As DateTime = DateTime.Parse(o_Row("AdministeredDate"))
If s_FormattedAdmDate = o_Item Then
o_NewRow(s_FormattedAdmDate) = AdmTim.ToString("hh:mm tt") + " - " + o_Row("UserID")
End If
Next
If i_Ctr < i_MaxRec _
And Not o_NextRow Is Nothing _
And o_Row("TransDate") = o_NextRow("TransDate") _
And o_Row("Medication") = o_NextRow("Medication") _
And o_Row("Dosage") = o_NextRow("Dosage") _
And o_Row("AdministeredDate") = o_NextRow("AdministeredDate") Then
x_isNewRow = False
Else
o_DerivedTable.Rows.Add(o_NewRow)
x_isNewRow = True
End If
Next
'Bind derived table
dgSheet.DataSource = o_DerivedTable
dgSheet.DataBind()
If o_Dataset.Tables(0).Rows.Count > 0 Then
GroupGridView(dgSheet.Items, 0, 3)
Else
End If
End Sub
I think you must review your programming logic:
After that huge ugly SqlStr : you will have a DataSet, with a Table with all rows mixed !?
Let's try a pseudo-code:
I think is better to create in that DataSet, 2 Tables:<br>
**first** table with: id, DateOrder, Medication, Dosage <br>
and **second** table with: idDate, FirstTable.id, AdministeredDate
after that you know how many ADMMED.AdministeredDate.Count are, because you must know how manny columns you need to add
create a 3-rd table from iteration of first table, nested with second by ID.
Set as Datasource for DataGridView the Third DataTable.
So you have 2 datasets, and generate this one .. one to many ..
.. I have no time now, if you don't get the ideea .. forget it !

Automatic chart update with new data entry

My chart loads data from a DataGridView.
I want to automatically update my chart with new data if new values are inserted into the DataGridView.
My chart is bound to table1 and table2 in my DataGridView which gets values from a DataTable. Here is a small portion of the code:
Dim myData As New DataTable
wcAdapter.SelectCommand = wcCommand
wcAdapter.Fill(myData)
-
Chart1.DataSource = myData
Chart1.Series("Series1").ValueMemberX = "table1"
Chart1.Series("Series1").ValueMembersY = "table2"
Here is the complete code:
Try
wcconn.Open()
Dim wcCommand As New MySqlCommand()
''telesales name
' Dim wcQuery = "SELECT ID, Telesales, SUBSTRING(lastupdatedate, 1, 10) as 'Day', SUBSTRING(lastupdatetime FROM -9 FOR 6) as 'Time' FROM ratingout where Telesales='" & cbTelesales.Text & "' and lastupdatedate= '" & newDate & "' and lastupdatedate is not null and lastupdatetime is not null ORDER BY lastupdatetime ;"
' wcCommand.Connection = wcconn
' wcCommand.CommandText = wcQuery
Dim newDate As String
newDate = dateWorkCheck.Text
newDate = newDate.Replace("/", "-")
Dim y, m, d As String
y = newDate.Substring(6, 4)
m = newDate.Substring(3, 2)
d = newDate.Substring(0, 2)
newDate = y & "-" & m & "-" & d
Dim wcQuery = "SELECT ID, Telesales, lastupdatedate as 'Day', SUBSTRING(lastupdatetime FROM -8 FOR 2) as 'Time' FROM ratingout where Telesales='" & cbTelesales.Text & "' and lastupdatedate= '" & newDate & "' and lastupdatedate is not null and lastupdatetime is not null ORDER BY lastupdatetime ;"
wcCommand.Connection = wcconn
wcCommand.CommandText = wcQuery
Dim wcData As New DataTable
wcAdapter.SelectCommand = wcCommand
wcAdapter.Fill(wcData)
Dim i = 0
If wcData.Rows.Count = 0 Then
wcAdapter.Dispose()
Try
Dim wQuery = "SELECT ID, Telesales, lastupdatedate as 'Day', SUBSTRING(lastupdatetime FROM -8 FOR 2) as 'Time' FROM ratingout where Telesales='" & cbTelesales.Text & "' and lastupdatedate= '" & dateWorkCheck.Text & "' and lastupdatedate is not null and lastupdatetime is not null ORDER BY lastupdatetime ;"
wcCommand.Connection = wcconn
wcCommand.CommandText = wQuery
Dim wData As New DataTable
wcAdapter.SelectCommand = wcCommand
wcAdapter.Fill(wData)
wData.Columns.Add("tt")
wData.Columns.Add("num")
wcData.Columns.Add("tt")
wcData.Columns.Add("num")
'dgvWorkCheck.AutoSizeRowsMode = DataGridViewAutoSizeRowMode.AllCells
Dim dr As DataRow
For Each dr In wData.Rows
If lastV Is Nothing OrElse Not ColumnEqual(lastV, dr("Time")) Then
''check if first value is nothing
If lastV = Nothing Then
lastV = "00"
l = "0"
Else
dr("tt") = lastV
dr("num") = l
'wcData.Tables("ratingout").Rows(I)("ID") = dr("ID")
End If
ListBox1.Items.Add(lastV & " <--> " & l)
lastV = dr("Time")
l = 1
ElseIf lastV Is Nothing OrElse ColumnEqual(lastV, dr("Time")) Then
l += 1
'Dim series1 As New Series()
'series1.Points.Add(l)
End If
For I = I To wData.Rows.Count
If I <> wData.Rows.Count Then
I += 1
If i = wData.Rows.Count Then
dr("tt") = lastV
dr("num") = l
ListBox1.BeginUpdate()
ListBox1.Items.Add(dr("Telesales") & " between[" & lastV & " and 17:00, ] <--> " & l & "[ records ]")
ListBox1.EndUpdate()
End If
GoTo n
Else
MsgBox("last data")
End If
Next
n:
Next
txtRec.Text = wData.Rows.Count
dgvWorkCheck.DataSource = wData
''chart
Dim ChartArea2 As ChartArea = New ChartArea()
Dim Legend2 As Legend = New Legend()
Dim Series2 As Series = New Series()
Dim Chart2 = New Chart()
Me.Controls.Add(Chart2)
ChartArea2.AxisX.LabelStyle.Angle = -90
ChartArea2.AxisX.LabelStyle.Interval = 1
ChartArea2.AxisY.LabelStyle.Angle = -90
ChartArea2.AxisY.LabelStyle.Interval = 5
ChartArea2.Name = "ChartArea2"
Chart2.ChartAreas.Add(ChartArea2)
Legend2.Name = "Legend2"
Chart2.Legends.Add(Legend2)
Chart2.Location = New System.Drawing.Point(12, 113)
Chart2.Name = "Chart2"
Series2.ChartArea = "ChartArea2"
Series2.Legend = "Legend2"
Series2.Name = "Series2"
Chart2.Series.Add(Series2)
Chart2.Size = New System.Drawing.Size(1145, 604)
Chart2.TabIndex = 0
Chart2.Text = "Chart2"
Chart2.Series("Series2").XValueMember = "tt"
Chart2.Series("Series2").YValueMembers = "num"
Chart2.DataSource = dgvWorkCheck.DataSource
Chart2.DataBind()
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Exit Try
since the new data is inserted into a database, you will only need to rebind the gridview to it's source in order to display the new incoming data.
You should isolate the code that binds data to your chart in a function and have it called every time a new field gets inserted:
Function FillChartWithData()
Dim myData As New DataTable
wcAdapter.SelectCommand = wcCommand
wcAdapter.Fill(myData)
...
Chart1.Series("Series1").ValueMemberX = "table1"
Chart1.Series("Series1").ValueMembersY = "table2"
End Function
EDIT
I looked at your coded and it seems you're missing the part responsible for inserting new data inside the 'ratingout' table. You should create a function that allows you to insert new data, something along the line of:
Dim insertRating = "INSERT INTO ratingout VALUES (#NewTeleSalesName, #NewDate);"
Dim insertCmd As New MySqlCommand(insertRating, wcconn)
insertCmd.Parameters.Add("#NewTeleSalesName", MySqlDbType.VarChar, 255, "teleSalesName")
insertCmd.Parameters.Add("#NewDate", MySqlDbType.Datetime, 8, New DateTime(2010, 8, 5))
insertCmd.ExecuteNonQuery()
In order to update my chart bargraph named CashChart (which was databound to a BindingSource) I had to do the following:
To clear the chart information,
Clear the bounding source information
And then re-assign the bounding source information: for example:
CashChart.Series(0).Points.Clear()
CashChart.DataSource = ""
CashChart.DataSource = ESTADOINSTANTANEOBindingSource
Before, only my DataTable was updating, but after these commands, I was able to get the bargraph to update with new values in the table.