I'm currently doing a Point of Sales System but I encountered a problem, the quantity and cost of item add up just fine in the DataGridView but not in the Subtotal, Tax, and Total. I don't know what I did wrong.
Here's my code:
Private Function Cost() As Double
Dim sum As Double = 0
Dim i As Integer = 0
For i = 0 To DataGridView1.Rows.Count - 1
sum = sum + Convert.ToDouble(DataGridView1.Rows(i).Cells(2).Value)
Next i
Return Sum
End Function
Sub AddCost()
Dim vat, q As Double
vat = 3.9
If DataGridView1.Rows.Count > 0 Then
TxtSub.Text = FormatCurrency(Cost().ToString("0.00"))
TxtVAT.Text = FormatCurrency(((Cost() * vat) / 100).ToString("0.00"))
q = ((Cost() * vat) / 100)
TxtTotal.Text = FormatCurrency(q + Cost().ToString("0.00"))
End If
End Sub
Private Sub BtnTapsi_Click(sender As Object, e As EventArgs) Handles BtnTapsi.Click
Dim CostOfItem As Double = 60.0
For Each row As DataGridViewRow In DataGridView1.Rows
If row.Cells(0).Value = "Tapsilog" Then
row.Cells(1).Value = Double.Parse(row.Cells(1).Value) + 1
row.Cells(2).Value = Double.Parse(row.Cells(1).Value) * CostOfItem
Exit Sub
End If
Next
DataGridView1.Rows.Add("Tapsilog", "1", CostOfItem)
AddCost()
End Sub
And here's a sample image of what the problem looks like:
Related
Const TaxRate As Decimal = 0.08, cappuccino As Decimal = 2.0, expresso As Decimal = 2.5, latte As Decimal = 1.75
Private Sub btncalculate_Click(sender As Object, e As EventArgs) Handles btncalculate.Click
Dim price As Decimal, total As Decimal, cantidad As Integer
cantidad = txtquantity.Text
If cappuccinoRadiobtn.Checked Then
price = cappuccino
lblContenido.Text += "Cappuccino $2.00" + Environment.NewLine
Else
If ExpressoRadiobtn.Checked Then
price = expresso
lblContenido.Text += "Expresso $2.50" + Environment.NewLine
ElseIf LatteRadiobtn.Checked Then
price = latte
lblContenido.Text += "Latte $1.75" + Environment.NewLine
End If
End If
total = price * cantidad
txtAmount.Text = total.ToString("C")
lblRecibo.Text += txtAmount.Text + Environment.NewLine
End Sub
The question is: how can I sum the results that shows on Label called lblRecibo and show it as a subtotal on a subtotal TextBox?
Are you using VB.net?
Why not use arrays?
Anyway, you just need to know the quantity or cantidad of each product.
'Label the index of elements in array (good practice)
Private Enum Product
Cappuccino = 0
Expresso = 1
Latte = 2
End Enum
'Enter your maximum items here
Private Const PRODUCT_ITEMS As Integer = 3
Private Const PRODUCT_ITEMS_ARR As Integer = (PRODUCT_ITEMS - 1)
'Declare array for each product quantity
Private Dim productQuantity_ARRAY(PRODUCT_ITEMS_ARR) As Integer
'Declare array for each product subtotal (actually without this you still can get each subtotal)
Private Dim productSubtotal_ARRAY(PRODUCT_ITEMS_ARR) As Decimal
'Initialize the arrays somewhere
Private Sub InitializeArrays()
Dim i As Integer = 0
For i = 0 To PRODUCT_ITEMS_ARR
productQuantity_ARRAY(i) = 0
productSubtotal_ARRAY(i) = 0.0
Next
End Sub
Private Sub btncalculate_Click(sender As Object, e As EventArgs) Handles btncalculate.Click
Dim price As Decimal, total As Decimal, cantidad As Integer
cantidad = txtquantity.Text
If cappuccinoRadiobtn.Checked Then
price = cappuccino
productQuantity_ARRAY(Product.Cappuccino) += cantidad
'This line just updates the productSubtotal_ARRAY every click event
productSubtotal_ARRAY(Product.Cappuccino) = cappuccino* productQuantity_ARRAY(Product.Cappuccino)
lblContenido.Text += "Cappuccino $2.00" + Environment.NewLine
Else
If ExpressoRadiobtn.Checked Then
price = expresso
productQuantity_ARRAY(Product.Expresso) += cantidad
productSubtotal_ARRAY(Product.Expresso) = expresso* productQuantity_ARRAY(Product.Expresso)
lblContenido.Text += "Expresso $2.50" + Environment.NewLine
ElseIf LatteRadiobtn.Checked Then
price = latte
productQuantity_ARRAY(Product.Latte) += cantidad
productSubtotal_ARRAY(Product.Latte) = latte * productQuantity_ARRAY(Product.Latte)
lblContenido.Text += "Latte $1.75" + Environment.NewLine
End If
End If
total = price * cantidad
txtAmount.Text = total.ToString("C")
And then multiply each product quantity with their corresponding prices or you can use the arrays for subtotal
Dim i As Integer
For i=0 To PRODUCT_ITEMS_ARR
If(productSubtotal_ARRAY(i)>0.0)
lblRecibo.Text += productSubtotal_ARRAY(i).ToString("C") + Environment.NewLine
End If
Next
lblRecibo.Text += txtAmount.Text + Environment.NewLine
I don't know what really you are asking for. But you can try to tweak this thing out.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnAdd.Click
If txtCode.Text = "" Or txtName.Text = "" Or txtUnit.Text = "" Or txtPrice.Text = "" Then
MsgBox("Please fill in all fields")
Else
Dim str(3) As String
Dim itm As ListViewItem
str(0) = LSet(txtName.Text, 8)
str(1) = LSet(txtCode.Text, 3)
str(2) = LSet(txtUnit.Text, 6)
str(3) = LSet(txtPrice.Text, 20)
itm = New ListViewItem(str)
ListView1.Items.Add(itm)
lblTotalItems.Text = ListView1.Items.Count
txtCode.Text = ""
txtName.Text = ""
txtUnit.Text = ""
txtPrice.Text = ""
End If
End Sub
I currently have this code for my list view, with more code in my global variables, I'm wanting to add up one column and place them in the Total text box, I know you have to loop through it and add them but i'm not sure how.
Here is the image for the form
Here is an example of the type of loop you could use.
Const col As Integer = 3 'this adds the price column
Dim total As Integer = 0
Dim lvsi As ListViewSubItem
For i As Integer = 0 To ListView1.Items.Count - 1
lvsi = ListView1.Items(i).SubItems(col)
total += Integer.Parse(lvsi.Text)
Next
A lot simple than a ListView use a DataGridView
Just initialize it on Form.Load() with:
DataGridView1.Columns.Add("Name", "Name")
DataGridView1.Columns.Add("Code", "Code")
DataGridView1.Columns.Add("Unit", "Unit")
DataGridView1.Columns.Add("Price", "Price")
DataGridView1.AllowUserToAddRows = False
Then on Add button:
If txtCode.Text = "" Or txtName.Text = "" Or txtUnit.Text = "" Or txtPrice.Text = "" Then
MsgBox("Please fill in all fields")
Else
DataGridView1.Rows.Add(txtName.Text, txtCode.Text, txtUnit.Value, Decimal.Parse(txtPrice.Text, System.Globalization.CultureInfo.InvariantCulture) * txtUnit.Value)
DataGridView1.Refresh()
End If
Here I did the Price column = the Unit times the price you entered.
I also handled decimals partly but you would need to check that price is 2.00 and not 2
Then for total button:
Dim MyTotal As Decimal = 0.00
'For each row in the gridd
For Each row As DataGridViewRow In DataGridView1.Rows
'invcrement total with column 3 equal to the price (index start = 0)
MyTotal = MyTotal + Decimal.Parse(row.Cells(3).Value, System.Globalization.CultureInfo.InvariantCulture)
Next
txtTotal.Text = MyTotal
I'll let you figure out the rest
I have a code to color the cells in a datagridview based on defined criteria for several different pollutants, and it works well. However, there will often be occurrences of the character '<' in cases like "<0.005", meaning "below detection limit", and that crashes the routine with the message "Operator '<' is not defined for type 'DBNull' and type 'Double'."
Edit: This is the latest code as supplied by JohnG. I still get error messages when the subs encounter empty cells or invalid characters
Imports System.Data.SqlClient
Imports System.IO
Imports Microsoft.Office.Interop.Excel
Imports Microsoft.Office.Interop
Imports System.Runtime.InteropServices
Imports System.Text.RegularExpressions
Public Class Form1
Public Property gridResults As Object
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
OpenFileDialog2.Title = "Velg fil ..."
OpenFileDialog2.InitialDirectory = "C:users\<currentuser>\Documents"
OpenFileDialog2.Filter = "Alle filer|*.*|Excel 2003|*.xls|Excel|*.xlsx"
OpenFileDialog2.FilterIndex = 2
OpenFileDialog2.ShowDialog()
End Sub
Private Sub OpenFileDialog2_FileOk(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog2.FileOk
Dim strm As System.IO.Stream
strm = OpenFileDialog2.OpenFile()
TextBox2.Text = OpenFileDialog2.FileName.ToString()
If Not (strm Is Nothing) Then
strm.Close()
End If
Me.Button5_Click(sender, e)
End Sub
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
If String.IsNullOrEmpty(TextBox2.Text) Then
MessageBox.Show("Klikk ""Bla gjennom"" for å velge en fil", "Ingen inndatafil")
Exit Sub
End If
Dim FilePath As String = OpenFileDialog2.FileName
Dim MyConnection As System.Data.OleDb.OleDbConnection
Dim DtSet As System.Data.DataSet
Dim MyCommand As System.Data.OleDb.OleDbDataAdapter
MyConnection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FilePath & ";Extended Properties=Excel 8.0;")
MyCommand = New System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", MyConnection)
MyCommand.TableMappings.Add("Table", "Net-informations.com")
DtSet = New System.Data.DataSet
MyCommand.Fill(DtSet)
DataGridView2.DataSource = DtSet.Tables(0)
MyConnection.Close()
End Sub
Public Function GetElementColorsValues(elementName As String) As Decimal()
Dim ULArray(4) As Decimal
Select Case elementName
Case "As (Arsen)"
ULArray(0) = 8
ULArray(1) = 20
ULArray(2) = 50
ULArray(3) = 600
ULArray(4) = 1000
Case "Cd (Kadmium)"
ULArray(0) = 1.5
ULArray(1) = 10
ULArray(2) = 15
ULArray(3) = 30
ULArray(4) = 1000
Case "Cu (Kopper)"
ULArray(0) = 100
ULArray(1) = 200
ULArray(2) = 1000
ULArray(3) = 8500
ULArray(4) = 25000
Case "Cr (Krom)"
ULArray(0) = 50
ULArray(1) = 200
ULArray(2) = 500
ULArray(3) = 2800
ULArray(4) = 25000
Case "Hg (Kvikksølv)"
ULArray(0) = 1
ULArray(1) = 2
ULArray(2) = 4
ULArray(3) = 10
ULArray(4) = 1000
Case "Ni (Nikkel)"
ULArray(0) = 60
ULArray(1) = 135
ULArray(2) = 200
ULArray(3) = 1200
ULArray(4) = 2500
Case "Pb (Bly)"
ULArray(0) = 60
ULArray(1) = 100
ULArray(2) = 300
ULArray(3) = 700
ULArray(4) = 2500
Case "Zn (Sink)"
ULArray(0) = 200
ULArray(1) = 500
ULArray(2) = 1000
ULArray(3) = 5000
ULArray(4) = 25000
End Select
Return ULArray
End Function
'Fargeleggingsrutine - gir feilmelding
Private Sub SetDGVColColor()
Dim ULArray As Decimal()
Dim curValue As String
Dim decimalValue As Decimal
Dim colName = ""
For col As Integer = 2 To DataGridView2.ColumnCount - 1
colName = DataGridView2.Columns(col).Name
ULArray = GetElementColorsValues(colName)
For Each row As DataGridViewRow In DataGridView2.Rows
If (Not row.IsNewRow) Then
curValue = row.Cells(colName).Value
If (curValue IsNot Nothing) Then
Decimal.TryParse(curValue, decimalValue)
' the above TryParse line will set decimalValue to 0 if curValue is not a valid decimal i.e `<0.005`
Select Case decimalValue
Case >= ULArray(4)
row.Cells(colName).Style.BackColor = Color.BlueViolet
Case >= ULArray(3)
row.Cells(colName).Style.BackColor = Color.Red
Case >= ULArray(2)
row.Cells(colName).Style.BackColor = Color.Orange
Case >= ULArray(1)
row.Cells(colName).Style.BackColor = Color.Yellow
Case >= ULArray(0)
row.Cells(colName).Style.BackColor = Color.LawnGreen
Case Else
row.Cells(colName).Style.BackColor = Color.DodgerBlue
End Select
End If ' ignore empty cell
End If ' ignore the new row
Next
Next
End Sub
Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
SetDGVColColor()
End Sub
'Første svar fra JohnG
'Fjerde forsøk på eksport
Private Sub ExportToExcel()
Dim excel As Microsoft.Office.Interop.Excel._Application = New Microsoft.Office.Interop.Excel.Application()
Dim workbook As Microsoft.Office.Interop.Excel._Workbook = excel.Workbooks.Add(Type.Missing)
Dim worksheet As Microsoft.Office.Interop.Excel._Worksheet = Nothing
excel.Visible = True
Try
worksheet = workbook.ActiveSheet
worksheet.Name = "ExportedFromDataGrid"
Dim cellRowIndex As Integer = 1
Dim cellColumnIndex As Integer = 1
'gets header rows.
For Each column In DataGridView2.Columns
worksheet.Cells(1, column.Index + 1).Value = column.Name
Next
'gets all other rows
Dim rowIndex = 2
For Each row As DataGridViewRow In DataGridView2.Rows
If Not row.IsNewRow Then
For colIndex As Integer = 0 To DataGridView2.Columns.Count - 1
worksheet.Cells(rowIndex, colIndex + 1).Value = row.Cells(colIndex).Value.ToString
Next
End If
rowIndex += 1
Next
' Substituted code below that loops through each column with data
' then sets the color for each of those columns by calling the SetColColor method
For index As Integer = 2 To DataGridView2.Columns.Count
Dim colName = DataGridView2.Columns(index).Name
SetExcelColColor(worksheet, colName, index + 1)
Next
MessageBox.Show("Closing excel: save if needed!")
'workbook.SaveAs("YourFileName..",)
workbook.Close()
excel.Quit()
Marshal.ReleaseComObject(worksheet)
Marshal.ReleaseComObject(workbook)
Marshal.ReleaseComObject(excel)
Catch
MessageBox.Show("Error")
End Try
End Sub
'andre eksportrutine med fargelegging fra JohnG
Private Sub SetExcelColColor(worksheet As Microsoft.Office.Interop.Excel._Worksheet, colName As String, colIndex As Integer)
Dim rIndex = 2
Dim cIndex = colIndex
Dim ULArray = GetElementColorsValues(colName)
Dim curValue As String
Dim decimalValue As Decimal
For Each row As DataGridViewRow In DataGridView2.Rows
If (Not row.IsNewRow) Then
curValue = row.Cells(colName).Value
If (curValue IsNot Nothing) Then
Decimal.TryParse(curValue, decimalValue)
Select Case decimalValue
Case >= ULArray(4)
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.BlueViolet)
Case >= ULArray(3)
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red)
Case >= ULArray(2)
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Orange)
Case >= ULArray(1)
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow)
Case >= ULArray(0)
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LawnGreen)
Case Else
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.DodgerBlue)
End Select
rIndex += 1
End If ' ignore empty cell
End If ' ignore new row
Next
End Sub
Private Sub btnBrowse_Click(sender As Object, e As EventArgs) Handles btnBrowse.Click
Me.ExportToExcel()
End Sub
Private Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click
System.Windows.Forms.Application.Exit()
End Sub
End Class
I am not completely sure if I follow what you are asking so correct me if I am wrong. I am guessing the value “<0.005” is a value in a DataGridView Cell. If this is the case then you will need to change this “String” value to a “Decimal” The previous code I supplied did not check for empty or invalid numbers before the comparison is made. Since the cell value could be anything, the code needs to check for two things: An empty or null cell value or an invalid number. The error you are getting could be coming from either case.
Your comment
How can I make the routine disregard the < character, replace it with "" or replace the entire string with zero?
In this case when the cell contains the value “<0.005” will throw the error you see because comparing a string to a double won’t work. Since you state above that setting this value to zero (0) is sufficient, then I recommend you use a TryParse method. If the TryParse method is given an invalid number it will return zero (0). You could use this knowledge to implement what you describe.
I would recommend you use the same strategy you used to color the Excel cells. I changed the GetElementColorsValues method to return a Decimal array. This change is necessary if the values in the DataGridView are decimal values.
Public Function GetElementColorsValues(elementName As String) As Decimal()
Dim ULArray(4) As Decimal
Select Case elementName
Case "Arsenic"
ULArray(0) = 8
ULArray(1) = 20
ULArray(2) = 50
ULArray(3) = 600
ULArray(4) = 1000
Case "Cadmium"
ULArray(0) = 1.5
ULArray(1) = 10
………..
Now with this array we can compare the decimal values in the DataGridView. I used a Decimal.TryParse to get the Decimal value from a cells string value like below
Decimal.TryParse(curValue, decimalValue)
Above curValue is a string from the DataGridView cell and decimalValue is the retuned Decimal value from parsing the string to a decimal. The whole line Decimal.TryParse(curValue, decimalValue) will return true if the parse was successful and false if not successful.
The convenient aspect of this is that if the parse is unsuccessful (like with a value of <0.005) the TryParse will set the variable decimalValue to zero (0) as you are asking. Simply using the Decimal.TryParse will set the variable decimalValue to zero when it fails and will set it to a valid decimal number if it succeeds. This can be seen in the code below which checks for null or empty values then, if not null or empty uses the Decimal.TryParse to get the decimal value to be used in the comparison for coloring. It uses the same GetElementColorsValues(colName) method used when coloring the Excel cells... you will have to change the excel coloring code also to accommodate the Decimal array… below this method)
Update Edit to catch BDNULL cells in the data table
I was incorrect and technically, you CAN have a row in a DataTable that contains no column data. So the line: row.Cells(colName).Value will obviously throw the error you are getting. I am not saying this is the problem, but that was the only way I could reproduce your error. So the code below checks for these missing columns of data. I changed the code to use DataBoundItems since you are using this in your code; below that is the change needed without using the data bound item. Both worked, however if feel that may not be the case if the table is sorted or rows deleted etc. My next question would be why you would read these empty rows into the data table if they were well… EMPTY?
Obviously, you will need to make these changes when writing the grid to excel.
Private Sub SetDGVColColor()
Dim ULArray As Decimal()
Dim curValue As String
Dim decimalValue As Decimal
Dim colName = ""
For col As Integer = 2 To dgvElements.ColumnCount - 1
colName = dgvElements.Columns(col).Name
ULArray = GetElementColorsValues(colName)
Dim curDataBoundRow
For Each row As DataGridViewRow In dgvElements.Rows
If (Not row.IsNewRow) Then
curDataBoundRow = row.DataBoundItem ' <-- Added Code
If (Not IsDBNull(curDataBoundRow(colName))) Then ' <-- Added Code
curValue = curDataBoundRow(colName)
If (curValue IsNot Nothing) Then
Decimal.TryParse(curValue, decimalValue)
' the above TryParse line will set decimalValue to 0 if curValue is not a valid decimal i.e `<0.005`
Select Case decimalValue
Case >= ULArray(4)
row.Cells(colName).Style.BackColor = Color.BlueViolet
Case >= ULArray(3)
row.Cells(colName).Style.BackColor = Color.Red
Case >= ULArray(2)
row.Cells(colName).Style.BackColor = Color.Orange
Case >= ULArray(1)
row.Cells(colName).Style.BackColor = Color.Yellow
Case >= ULArray(0)
row.Cells(colName).Style.BackColor = Color.LawnGreen
Case Else
row.Cells(colName).Style.BackColor = Color.DodgerBlue
End Select
End If ' cell is empty
End If ' ignore null cells in data table <-- Added Code
End If ' ignore the new row if present
Next
Next
End Sub
Changes to code without using data bound items.
…….
For Each row As DataGridViewRow In dgvElements.Rows
If (Not row.IsNewRow) Then
If (Not IsDBNull(row.Cells(colName).Value)) Then ' <-- ADDED code
curValue = row.Cells(colName).Value
If (curValue IsNot Nothing) Then
…….
Changes to color excel cells method using Decimal value comparisons.
Private Sub SetExcelColColor(worksheet As Microsoft.Office.Interop.Excel._Worksheet, colName As String, colIndex As Integer)
Dim rIndex = 2
Dim cIndex = colIndex
Dim ULArray = GetElementColorsValues(colName)
Dim curValue As String
Dim decimalValue As Decimal
For Each row As DataGridViewRow In dgvElements.Rows
If (Not row.IsNewRow) Then
curValue = row.Cells(colName).Value
If (curValue IsNot Nothing) Then
Decimal.TryParse(curValue, decimalValue)
Select Case decimalValue
Case >= ULArray(4)
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.BlueViolet)
Case >= ULArray(3)
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red)
Case >= ULArray(2)
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Orange)
Case >= ULArray(1)
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow)
Case >= ULArray(0)
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LawnGreen)
Case Else
worksheet.Cells(rIndex, cIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.DodgerBlue)
End Select
rIndex += 1
End If ' ignore empty cell
End If ' ignore new row
Next
End Sub
The error you report is nothing to do with the presence of "<" in your string. It's because you're trying to an actual less-than comparison on a null value. That's invalid - there's no value to compare. You need to check whether the field is null before you perform the operation, and do something else instead:
If Me.DataGridView2.Rows(i).Cells("Cd (Kadmium)").Value IsNot DBNull.Value Then
'continue with the comparisons
Else
'do something else
End If
However, you're right, the presence of "<" will also cause a problem when trying to cast the value to a Double for the comparison.
For that you can do a simple string replacement, e.g.
Dim val = Me.DataGridView2.Rows(i).Cells("Cd (Kadmium)").Value.ToString().Replace("<", "")
Dim dVal = Convert.ToDouble(val)
If dVal < Ul1Cd Then
'etc
Also check your second loop:
For i As Double = 0 To Me.DataGridView2.Rows.Count - 1
you only need
for i = 0 To Me.DataGridView2.Rows.Count - 1
since you declared it before and as double?
Also make sure to set option strict on and infer to off in project compile options.
im working to show the data in my datagrid,and show the total of items brought in textbox2,but this error "Operator '+' is not defined for type 'Decimal' and type 'DBNull'." what is the problem? please help me i need to finish this so badly. :(
Private Sub dailySales_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
con.Connect()
DataGridView1.DataSource = dtb
dtb.Columns.Add("Transaction Code")
dtb.Columns.Add("Transaction Date ")
dtb.Columns.Add("Item Code")
dtb.Columns.Add("Item")
dtb.Columns.Add("Description")
dtb.Columns.Add("Quantity")
dtb.Columns.Add("Price")
dtb.Columns.Add("Total")
display()
con.Close()
total()
TextBox1.Text = DataGridView1.RowCount()
Me.DataGridView1.DefaultCellStyle.Font = New Font("Cambria", 10)
Me.DataGridView1.ColumnHeadersDefaultCellStyle.Font = New Font("Cambria", 12)
Me.DataGridView1.DefaultCellStyle.SelectionBackColor = Color.FromArgb(129, 207, 224)
Dim i As Integer
For i = 0 To DataGridView1.Columns.Count - 1
DataGridView1.Columns.Item(i).SortMode = DataGridViewColumnSortMode.Programmatic
Next
End Sub
Sub total()
Dim sum As Decimal = 0
For x = 0 To DataGridView1.Rows.Count - 1
sum =sum + DataGridView1.Rows(x).Cells(7).Value
Next
TextBox2.Text = sum
End Sub
Sub display()
con.Connect()
Label6.Text = Date.Now.ToString("dd MMMM yyyy")
Dim da = Label6.Text
Dim sc = " where lower(tns_date) like lower('%" & da & "%') "
Dim sql = "select * from tns " & sc & " order by tns_code desc"
odr = con.Retrieve(sql)
dtb.Clear()
While (odr.Read)
Dim ic = odr.GetOracleValue(0)
Dim itn = odr.GetOracleValue(1)
Dim de = odr.GetOracleValue(2)
Dim ca = odr.GetOracleValue(3)
Dim pr = odr.GetOracleValue(4)
Dim st = odr.GetOracleValue(5)
Dim sst = odr.GetOracleValue(6)
dtb.Rows.Add(ic, itn, de, ca, pr, st, sst)
End While
con.Close()
End Sub
Test like this.
Sub total()
Dim sum As Decimal = 0
For x = 0 To DataGridView1.Rows.Count - 1
If Not isDBNull(DataGridView1.Rows(x).Cells(7).Value) then sum =sum + DataGridView1.Rows(x).Cells(7).Value
Next
TextBox2.Text = sum
End Sub
First I set up the DataTable as shown below. Added 3 columns with Desc, Price and The full string to display.
checkBoxDT = New DataTable
checkBoxDT.Columns.Add(New DataColumn With
{.ColumnName = "Desc", .DataType = GetType(String)})
checkBoxDT.Columns.Add(New DataColumn With
{.ColumnName = "Price", .DataType = GetType(Decimal)})
checkBoxDT.Columns.Add(New DataColumn With
{.ColumnName = "DisplayText", .DataType = GetType(String),
.Expression = "Desc + ' - RM ' + Price"})
Then, I create a new dataview and bind the CheckedListBox1 to the DataTable.
checkListView = New DataView(checkBoxDT)
checkListView.Sort = "Desc ASC, Price ASC"
CheckedListBox1.DataSource = checkListView
CheckedListBox1.DisplayMember = "DisplayText"
Here I add new items to the CheckedListBox1 with the code below
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim quan As Integer = 0
Dim currentPrice As Decimal = 0.0
If ComboBox2.SelectedIndex > 0 Then
quan = Convert.ToInt32(ComboBox2.Text.Trim())
currentPrice = Convert.ToDecimal(TextBox3.Text.Trim())
For i As Integer = 1 To quan
checkBoxDT.Rows.Add({ComboBox1.Text, Convert.ToDecimal(TextBox3.Text)})
totalItems = totalItems + 1
totalPrice = totalPrice + currentPrice
Next
Else
currentPrice = Convert.ToDecimal(TextBox3.Text.Trim())
checkBoxDT.Rows.Add({ComboBox1.Text, Convert.ToDecimal(TextBox3.Text)})
totalItems = totalItems + 1
totalPrice = totalPrice + currentPrice
End If
TextBox5.Text = totalItems.ToString()
TextBox4.Text = totalPrice.ToString()
End Sub
But I am having problem in deleting the CheckedListBox1 items. Here is what I have tried.
This is the delete button. I am trying to delete the items in CheckedListBox1 for all the selected items. Then show the right price in TextBox4. When I select only 1 item to be deleted, it works fine. But multiple item selected does not work properly. It deletes other item which is not selected as well.
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim currentPrice As Decimal = 0.0
While CheckedListBox1.CheckedItems.Count > 0
currentPrice = Convert.ToDecimal(CType(CheckedListBox1.SelectedItems(0), DataRowView).Item("Price").ToString())
totalPrice = totalPrice - currentPrice
totalItems = totalItems - 1
checkListView.Delete(CheckedListBox1.SelectedIndex())
End While
TextBox4.Text = totalPrice.ToString()
TextBox5.Text = totalItems.ToString()
End Sub
Here is an example where the DataSource is a DataTable. Any checked items are removed at the DataTable.Rows level.
Dim dtSource As DataTable = CType(CheckedListBox1.DataSource, DataTable)
Dim theItems As CheckedItemCollection = CheckedListBox1.CheckedItems
Dim rows As New List(Of DataRow)
For Each cItem In theItems
Dim row = CType(cItem, DataRowView).Row
rows.Add(row)
Next
For Each r As DataRow In rows
dtSource.Rows.Remove(r)
Next
Second version with count and sum
Dim dtSource As DataTable = CType(clbCheckedListBox.DataSource, DataView).Table
Dim theItems As CheckedItemCollection = clbCheckedListBox.CheckedItems
Dim rows As New List(Of DataRow)
For Each cItem In theItems
Dim row = CType(cItem, DataRowView).Row
rows.Add(row)
Next
Dim Total As Decimal = rows.Select(Function(row) row.Field(Of Decimal)("Price")).Sum
Dim Count As Integer = rows.Count
Console.WriteLine($"Total: {Total}")
For Each r As DataRow In rows
dtSource.Rows.Remove(r)
Next