|
Hello,
I have added a DataGridViewComboBoxColumn to a DataGridView and i'm having a little problem.
For testing I am loading one item in the combobox. The item value source is an xml filename without
path or extension; ie. "Foodlion". The xml file has an entry that defines this filename but has a
different case like "FoodLion". After loading the xml file and passing its' value "FoodLion" to the
combobox, I get this context error in DataGridView1.DataError:
Formatting, Display
I'm not performing any formatting on this field since I expect just text.
I get it that the combobox must be performing a FindExact() type search and does not match.
Before I go through the pain staking effort to try an make sure the names match, is there
something I can do change the combobox processing?
Thanks
|
|
|
|
|
Why not load the combobox using either the .ToLower() or .ToUpper() functions? Or if you want it to "look nice" you could always use the TextInfo.ToTitleCase(String) Method (System.Globalization)[^] method.
In general the ComboBox.FindString Method[^] is not case-sensitive so I suspect this has nothing to do with a "FindExact() type search" but you have neither shared code nor the exact wording of the error so it's a little difficult to help further
|
|
|
|
|
Sorry for the confusion.
The error from my post in more clear terms are:
Private Sub DataGridView1_DataError(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewDataErrorEventArgs) Handles MyBase.DataError
{
' DataGridViewDataErrorContexts.Display
' DataGridViewDataErrorContexts.Formatting
Debug.WriteLine(e.Context.ToString())
}
My ComboBox code would not do you any good because it is full of structure data references which would not make sense to you but here is what causes the problem, hopefully more clear.
When I initialize the DataGridView columns, for the combobox object I load the list value which is the filename of the source xml file which happens to be "Foodlion" (note case).
Dim cmb As New DataGridViewComboBoxColumn()
cmb.Items.Add("Foodlion")
I then create a row with the value for the ComboBox which happens to be "FoodLion" (case difference)
because that's the way it was originally created in the xml file.
Me.Rows.Add(dataArray())
This causes the above error whenever the cell is Formatted by the DataGridView.
Making sure the data and the combobox list item are the same case fixes the problem.
So something in the DataGridView formatting doesn't like the case difference. Therefore
that's why I 'assumed' that the ComboBox or underlying code was doing a case sensitive
search; My Bad.
Your Q. Why not load the combobox using either the .ToLower() or .ToUpper() functions?
When the xml file is created the filename is saved in the xml data (in a particular case).
The 'case' of the filename of the file that is stored on disk can change. When I enumerate
the xml files on disk (Directory.GetFiles(path, "*.xml")), I use that filename to load into
the combobox list as above (cmb.Items.Add("Foodlion"). If its' case is not the same as what is stored in the xml file,
I get the DataError.
I just asked the question in case someone may have encountered this type of issue with DataGridViewComboBoxColumn.
I think I have found a work around 'HACK' by saving the filename in the xml file in a particular
format and then formatting the filename from disk the same way.
I hate to HACK code.
Again, sorry for the confusion.
Hope this is clearer.
Thanks
|
|
|
|
|
Hopefully your hack will work but given that you are apparently doing a
cmb.Items.Add("Foodlion") and
Me.Rows.Add(dataArray()) couldn't you do
cmb.Items.Add(("Foodlion").ToLower) and
Me.Rows.Add(dataArray.Select(c => c.ToLower()).ToArray()) instead?
(Apologies - I'm nowhere near Visual Studio and can't check whether my solution compiles let alone works! Hopefully you get the gist)
|
|
|
|
|
Actually that's basically my hack except that the dataArray comes from my own xml class that loads the xmlfile data into variables (ie an array). The xml class formats the data and my custom DataGridView class loads from the xml class in the way you suggest.
Thanks for you suggestion.
|
|
|
|
|
So I have a Linq statement, that groups product sales by SKU over a period of about 3 years.
The products go up in price from inflation, so I grab the last price sold for.
But sometimes they will give a product away for free after a sales is made for say $1.00
Last Month - $12.00
This month - Free or $0
I'm trying to figure out how to group the items that have a price above 0
Dim gCustomerItemsAll As List(Of MarginItemCustomerProfit) = sTpAll.Where(Function(w) w.FCustomerNo.Equals(cI.FCustomerNumber)).OrderBy(Function(ob) ob.FItemNo).GroupBy(Function(item) item.FItemNo).Select(Function(cl) New MarginItemCustomerProfit() With {
.FCustomerNumber = cl.First().FCustomerNo,
.FItemNumber = cl.First().FItemNo,
.FShipQty = cl.Sum(Function(qty) qty.FShipQty),
.FCost = cl.Last().FCost,
.FPrice = cl.Last().FPrice,
.FAmount = cl.Sum(Function(amount) amount.FAmount)
}).ToList()
I tried this
.Last(Function(price) price > 0)
but it failed
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
It seems to be quite easy:
Dim gCustomerItemsAll As List(Of MarginItemCustomerProfit) = sTpAll _
.Where(Function(w) w.FCustomerNo.Equals(cI.FCustomerNumber) AndAlso w.Price>0) _
.GroupBy(Function(item) item.FItemNo) _
.Select(Function(cl) New MarginItemCustomerProfit() With _
{ _
.FCustomerNumber = cl.First().FCustomerNo,
.FItemNumber = cl.First().FItemNo,
.FShipQty = cl.Sum(Function(qty) qty.FShipQty),
.FCost = cl.Last().FCost,
.FPrice = cl.Last().FPrice,
.FAmount = cl.Sum(Function(amount) amount.FAmount)
}) _
.ToList()
OrderBy() method call is redundant due to later usage of GroupBy() method.
|
|
|
|
|
I thought about that but didn't give it a try.
I'm glad you didn't say use First() since I forgot to mention that.
I'll try it.
Long time since we have communicated. Hope all is well with you.
If it ain't broke don't fix it
Discover my world at jkirkerx.com
modified 29-Aug-19 14:33pm.
|
|
|
|
|
You're using First and Last within the group, but I don't see any order specified for that operation.
If you just want the last price that's not free, try something like:
.FPrice = cl
.OrderByDescending(Function(i) If(i.FPrice = 0, 0, 1))
.ThenByDescending(Function(i) i.YOUR_DATE_FIELD_HERE)
.First().FPrice
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
First and Last was a tough choice so I chose first for customer and part number and last for cost and price.
Maybe not the best decision and I knew inflation or supply and demand was a factor when I first wrote it.
When I think about it, it probably doesn't matter if the part number is always the same.
But I didn't see the free item after the paid item coming and missed the thought of it occurring.
On a side note mentioned by Maciej on the OrderBy, Guess I should of used the ShipDate for that, for a true first or last. What do you think?
The code runs and free items have been removed from the report now, which is what I wanted and tried to do in code elsewhere. Not sure if I need this line .FShipDate = cl.Last().FShipDate,
If I could make this better, I'd be open to suggestions. The FCost and FPrice bothers me because they fluctuate. Thought about using average but I'm not sure how to implement it.
'Use Linq to Group the Items Together
Dim gCustomersAll As List(Of MarginItemCustomerProfit) = sTpAll.GroupBy(Function(item) item.FCustomerNo).Select(Function(cl) New MarginItemCustomerProfit() With {
.FCustomerNumber = cl.First().FCustomerNo,
.FItemNumber = cl.First().FItemNo,
.FShipQty = cl.Sum(Function(qty) qty.FShipQty),
.FShipDate = cl.Last().FShipDate, // Not sure if I need this line
.FCost = cl.Max(Function(cost) cost.FCost),
.FPrice = cl.OrderByDescending(Function(i) If(i.FPrice = 0, 0, 1)).ThenByDescending(Function(i) i.FShipDate).First().FPrice,
.FAmount = cl.Sum(Function(amount) amount.FAmount)
}).ToList()
If it ain't broke don't fix it
Discover my world at jkirkerx.com
modified 29-Aug-19 14:42pm.
|
|
|
|
|
Imports System.Data.SqlClient
Public Class Equipos_de_Computacion
Dim sql As String = ""
Private Sub BtnInsertar_Click(sender As Object, e As EventArgs) Handles btnInsertar.Click
If (Me.txtCodigoInterno.Text = "") Then
MsgBox("El campo idententificacion no puede estar vacio", MsgBoxStyle.Critical, "Atencion")
Me.txtCodigoInterno.Select()
Else
Dim CodigoInterno As Integer
Dim NumerodeSerie As Integer
Dim NumerodeFactura As Integer
Dim FechadeCompra As Date
Dim Precio As Decimal
Dim Acargode As String = ""
Dim Estado As String = ""
Dim Depreciacion As Decimal
Dim Caracteristicas As String = ""
CodigoInterno = CInt(Me.txtCodigoInterno.Text)
NumerodeSerie = CInt(Me.txtNumerodeSerie.Text)
NumerodeFactura = CInt(Me.txtNumerodeFactura.Text)
FechadeCompra = CDate(Me.DateTimePicker1.Value)
Precio = Me.nudPrecio.Value
Acargode = Me.txtACargode.Text
Estado = Me.txtEstado.Text
Depreciacion = Me.NudDepreciacion.Value
Caracteristicas = Me.txtCaracteristicas.Text
cmd.CommandType = CommandType.Text
cmd.Connection = conn
sql = "INSERT INTO [Equipos de Computacion] (CodigoInterno, NumerodeSerie, NumerodeFactura, FechadeCompra, Precio, Acargode, Estado, Caracteristicas, Depreciacion)"
sql += "Values('" & CodigoInterno & "','" & NumerodeSerie & "','" & NumerodeFactura & "','" & FechadeCompra & "', '" & Precio & "' ,'" & Acargode & "','" & Estado & "','" & Caracteristicas & "','" & Depreciacion & "')"
MsgBox(sql)
cmd.CommandText = sql
Try
cmd.ExecuteNonQuery()
MsgBox("Registro insertado correctamente")
Catch ex As Exception
If ex.ToString.Contains("duplicate") Then
MsgBox("El registro ya existe en la base de datos")
Else
MsgBox(ex.ToString)
End If
End Try
End If
End Sub
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvEquiposdeComputacion.CellContentClick
End Sub
Private Sub BtnMostrar_Click(sender As Object, e As EventArgs) Handles btnMostrar.Click
Dim DS As New DataSet
Dim DA As New SqlDataAdapter("Select * from [Equipos de Computacion]", conn)
DA.Fill(DS)
dgvEquiposdeComputacion.DataSource = DS.Tables(0)
End Sub
Private Sub DateTimePicker1_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged
End Sub
Private Sub BtnTotalDepreciacion_Click(sender As Object, e As EventArgs) Handles btnTotalDepreciacion.Click
NudDepreciacion.Value = CDec(FormatNumber(nudPrecio.Value * 0.25, 2))
End Sub
Private Sub TxtPrecio_TextChanged(sender As Object, e As EventArgs)
End Sub
Private Sub txtPrecio_KeyPress(sender As Object, e As KeyPressEventArgs) Handles nudPrecio.KeyPress
nudPrecio.DecimalPlaces = 2
End Sub
Private Sub txtPrecio_LostFocus(sender As Object, e As EventArgs)
Dim VarMonedaDolares As Double
VarMonedaDolares = nudPrecio.Value
nudPrecio.Value = CDec(FormatCurrency(VarMonedaDolares, 2))
End Sub
End Class
|
|
|
|
|
It means you are somewhere comparing numbers to characters and not including the '' around them or you are trying to put a word into a number field.
You first need to switch your code to using Parameters instead of concatenating your sql because you are susceptible to sql injection attacks. And you can't handle single quotes in your data the way you're doing it, which might actually be causing your issue anyway.
Social Media - A platform that makes it easier for the crazies to find each other.
Everyone is born right handed. Only the strongest overcome it.
Fight for left-handed rights and hand equality.
|
|
|
|
|
cmd.CommandText = "INSERT INTO [Equipos de Computacion] (CodigoInterno, NumerodeSerie, NumerodeFactura, FechadeCompra, Precio, Acargode, Estado, Caracteristicas, Depreciacion) VALUES (@CodigoInterno, @NumerodeSerie, @NumerodeFactura, @FechadeCompra, @Precio, @Acargode, @Estado, @Caracteristicas, @Depreciacion)"
cmd.Parameters.AddWithValue("@CodigoInterno", CInt(Me.txtCodigoInterno.Text))
cmd.Parameters.AddWithValue("@NumerodeSerie", CInt(Me.txtNumerodeSerie.Text))
cmd.Parameters.AddWithValue("@NumerodeFactura", CInt(Me.txtNumerodeFactura.Text))
cmd.Parameters.AddWithValue("@FechadeCompra", CDate(Me.DateTimePicker1.Value))
cmd.Parameters.AddWithValue("@Precio", Me.nudPrecio.Value)
cmd.Parameters.AddWithValue("@Acargode", Me.txtACargode.Text)
cmd.Parameters.AddWithValue("@Estado", Me.txtEstado.Text)
cmd.Parameters.AddWithValue("@Caracteristicas", Me.txtCaracteristicas.Text)
cmd.Parameters.AddWithValue("@Depreciacion", Me.NudDepreciacion.Value) Everything you wanted to know about SQL injection (but were afraid to ask) | Troy Hunt[^]
How can I explain SQL injection without technical jargon? | Information Security Stack Exchange[^]
Query Parameterization Cheat Sheet | OWASP[^]
Once you've fixed that critical security vulnerability in your code, you'll need to check that the values you're trying to insert match the data types of the columns in your table.
You should also avoid using CInt and CDate to convert user input. If the user types in something that can't be converted, you'll get an exception. Instead, use Integer.TryParse[^] / Date.TryParse[^] and display a warning to the user if their input is invalid.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thank u!!, now the only problem that i got is the depreciation box, i dont want to register integer depreciation numbers i want to register decimal depreciation numbers in the database im using this formula
nudDepreciacion.Value = FormatNumber(nudPrecio.Value * 0.25, 2)
.
|
|
|
|
|
So you want to multiply the value in the control by 0.25 and round to two decimal places before you store it in the database?
cmd.Parameters.AddWithValue("@Depreciacion", Math.Round(CDbl(Me.NudDepreciacion.Value) * 0.25, 2))
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
thank u again but now the number is registered without a coma.
|
|
|
|
|
If it's a number, then you should be storing it as a number. Don't store numbers as strings!
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
ok thank u. i wrote the code with the correction that u told me.Now, I wanna know how to store the result of depreciation with a coma that separates decimals because is storing the result without a coma.
|
|
|
|
|
DO NOT STORE NUMBERS AS STRINGS!
Numbers do not have "commas" or other formatting information. They are just numbers.
1,234.56 is the same as 1234.56 , which is the same as 1234.5600 . They are all the same number.
If you're trying to store formatted values in your database, then you're doing it wrong.
Store values in the correct data type, and format the values in the user interface.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Listen to what Richard is saying, if not you are in for a world of pain in the future. Apply the same rules to dates, DO NOT STORE DATES AS STRINGS. Store them as date or datetime data type.
Never underestimate the power of human stupidity -
RAH
I'm old. I know stuff - JSOP
|
|
|
|
|
Hello !
I'm using entity framework
Is there any way to count how many database hit were made ?
( The reason why I make this question, is because i'm using a 3d party software that add some commands to Entity Framework. One of these is that several different queries (the software claim) are executed using a single database hit. I want to verify this.)
Thank you !
|
|
|
|
|
If you can't tell the difference, what does it matter?
The Master said, 'Am I indeed possessed of knowledge? I am not knowing. But if a mean person, who appears quite empty-like, ask anything of me, I set it forth from one end to the other, and exhaust it.'
― Confucian Analects
|
|
|
|
|
I want to know if this software is telling the truth or no , if yes I want to use it.
|
|
|
|
|
Everyone lies.
The Master said, 'Am I indeed possessed of knowledge? I am not knowing. But if a mean person, who appears quite empty-like, ask anything of me, I set it forth from one end to the other, and exhaust it.'
― Confucian Analects
|
|
|
|
|
|