DataGridView does not show decimals - vb.net

I hope somebody can help me since i am unable to find a solution for it on the net.
I am working on a form where a datagridview is filled automatically using a tableadapter with data from a access database. In the database i have a column with doubles containing small decimal numbers. The datagridview is filled correctly except for this one, which does not show the decimals. e.g. "0,00400364688627264" only shows "0" or "0.000000" depending on how i format the column. Even scientific formatting only shows"0.000000E+000" in the dgv. I suspect it has something to do with the separator "," in access and have tried setting the regional location before calling the fill:
System.Globalization.CultureInfo.DefaultThreadCurrentCulture = New Globalization.CultureInfo("da-DK")
But that does not work either. Thought this would be a fairly simple problem, but cannot figure out why it is not working.

Ok, i could not find a solution. I guess it has something to do with the tableadapter fill method and the local setting. Anyway, I made a work around and instead filled the datagridview from a adodb recordset. I will probably hear some complains about this solution but it works :-) Thanks Jimi and Fabio for taking your time.
Dim StamRS As New ADODB.Recordset
Dim dt As New DataTable
Dim StamAD As New OleDb.OleDbDataAdapter
Try
Connection.connect()
StamRS.Open(sqlstr, conn, 1, 3)
If StamRS.RecordCount > 0 Then
StamAD.Fill(dt, StamRS)
Stamopl_DGV.DataSource = dt
End If
Catch ex As Exception
MsgBox("Fejl i åbning af Stamopløsnings databasen.")
Finally
StamRS.Close()
StamRS = Nothing
Connection.closeconn()
End Try

Related

vb.net Bind a combobox to a datasource

Over the past few days, I've read about a thousand forum posts, and looked at many code samples, but I still can't figure this out.
My goal is to populate a combobox with values from an Access 2007 query. I can do this by using the DataSource, DisplayMember and ValueMember properties, but regardless of the data in the query, the comboboxes all just default to the to first item in the items collection and don't change when the main BindingSource is moved. I am binding the controls with this line of code:
ComboBox1.DataSource = DataSet1.qryItemSourceTest
ComboBox1.DisplayMember = "SourceTestDisplayField"
ComboBox1.ValueMember = "SourceTestIDField"
Combobox1.DataBindings.Add(New Binding("SelectedValue", qryTestBindingSource, "TestField", True))
I have also tried using a BindingSource as a DataSource.
I have also tried using an array as a DataSource.
If I drag the control on from the Data Source tab in the IDE, it will scroll through records properly, but it will only display the value and not the query 'look-up' value that I want the combobox to display. I have tried changing the DisplayMember and ValueMember properties of the combobox after dragging it on from the Data Sources tab and that seems to break the functionality as well.
I'm looking for some best practices here. I know I'm missing something easy here and I apologize for post an issue that has already been covered so many times, but I could use some individual help here.
Edit: I eventually was able to accomplish my goal using the Visual Studio IDE Properties window. The second property on a control is a Data Bindings property which expands into exactly what I needed. I just never saw this before because it was not in alphabetically order like everything else.
Hi you can do this code to populate data into combo
Try
Dim cn As New OleDbConnection
cn.ConnectionString = conString
cn.Open()
cmd.Connection = cn
cmd.CommandText = "your query"
'Execte reader function is used to hold more than one value from the table
dr = cmd.ExecuteReader()
' Fill a combo box with the datareader
Do While dr.Read = True
ComboBox1 = dr.Item(0)
Loop
cn.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
If you have any more problems don't hesitate to ask.

Refreshing Datagridview From Dataset Issue

I seem to be pulling my hair out over something that seems pretty straight forward in my eyes. I cannot get a datagridview control to update correctly after altering a dataset.
I initially populate a datagridview from a dataset and auto generate the columns no problem. However, if I regenerate my dataset with new data, the datagridview will display the new data correctly, but won't remove the old column headers.
For example, I have a query that gives me Store Name and Manager and auto populates my datagridview. Then if I change my query to just give me Store Name and Supervisor, it gives me Store Name, Manager (with blank column) and Supervisor.
I have tried datagridview.refresh() and datagridview.update() but nothing seems to work.
Here is my code:
MySQLConn.Open()
Dim ExQry As New MySqlCommand(QryStr, MySQLConn)
ExQry.CommandType = CommandType.Text
Dim da As New MySqlDataAdapter(ExQry)
dasCustomQryData.Clear() 'my dataset is called dasCustomQryData
da.Fill(dasCustomQryData, "QryData")
da.Update(dasCustomQryData, "QryData")
With dgvCustomQuery
.DataSource = Nothing
.Dock = DockStyle.Fill
.AutoGenerateColumns = True
.DataSource = dasCustomQryData
.DataMember = "QryData"
.Refresh()
.Visible = True
End With
MySQLConn.Close()
da.Dispose()
dasCustomQryData.Dispose()
So, when I want to update my datagridview, I plugin a new QryStr to the above code and it rebuilds my dataset. The dataset is getting updated, because the datagridview contains the correct data, however, my problem is that the datagridview isn't clearing the old columns that aren't populated anymore.
All help appreciated. Thanks
I would recommend you create a connection and a dataset straight from VB and the in the dataset it shows the tables. At the bottom of the tables is a standard query but u can create your own...with variables as parameters and then you can call the query through the table adapter and assign this straight to the datagridview.
That always seems to work for my programs. What sort of database are u using? Might be obvious but just to make sure, the datagridview is not bound right? Sample from one of my projects dgData.DataSource = TblEventsTableAdapter.ViewEvent(cmbEvents.SelectedItem.ToString) where dgdata is obviously datagridview. ViewEvent is a custom query created in the dataset and takes in 1argument. Hope this is of use to you
Ok, after a bit of troubleshooting and playing around with code, I found that the simple solution to this was that the datatable itself was not releasing the column headers. So even though the datagridview and the dataset was getting cleared, the datatable was still populated.
The following command solved my issue:
dt.Columns.Clear()

Autocomplete list does not show all possible completions with BindingSource.Item

I've got a BindingSource for a DataSet. I'm fairly new to this whole binding business and databases, and it took me hours to figure out how to use BindingSource to get to an item, because the Row method was not included in the autocomplete. Not to confuse anyone, here's some sample code:
Dim somePreperty As String
Dim dataSet As New MyDataSet
Dim table As New MyDataSetTableAdapters.MyTableAdapter
Dim source As New BindingSource
source.DataSource = dataSet
source.DataMember = "SomeMember"
table.Fill(dataSet.SomeMember)
lablCabinet.DataBindings.Add("Text", source(0), "MemberID") '<This works fine>'
someProperty = source.Item(0).Row("ProductModel") '<So does this>'
The code runs perfectly and does exactly what I want. My problem is the following: When I've typed in source.Item(0)., autocomplete does not display Row in the list. Is this perhaps not the best way to do what I'm doing? Is there a reason it's hidden? Is this a good coding practice to do so? The fact that is wasn't there took me lots of time Googling, so I'm trying to figure out whether it's a Visual Studio glitch or my own.
Thanks in advance! = )
source.item(0) returns an object, so intellisense has no idea what is is.
You know what it should be, the compiler does not.
If you cast it first to a table or assing it to a table, intellisense will kick in.
So either:
ctype(source.item(0),datatable)
Or
dim tbl as datatable=source.item(0).

VB.NET - Visual Foxpro OLE DB Problem with Numeric Decimal Column

In Short:
I'm using VB.NET 2008 to connect to a Visual Foxpro 6 Database using the vfpoledb.1 driver. When I attempt to fill an OleDbDataAdapter with a dataset table that contains one of the numeric columns, I get the following error message:
The provider could not determine the Decimal value. For example, the row was just created, the default for the Decimal column was not
available, and the consumer had not yet set a new Decimal value.
I'd like to retrieve this column from VB.NET 2008 and keep it in a numeric format.
The Long Version:
I'm using VB.NET to connect to a Visual Foxpro 6 database. Several of the columns in the table are intended for numeric data type of up to 8 digits. I'm not sure how Visual Foxpro data types work but it appears that this field allows someone to enter any of the following example values:
99999999
99999.99
9.99
9.00
{nothing}
From Visual Foxpro: I have access to small program called Foxwin that allows me to browse the VFP tables in a native VFP environment. This is what I'm using to access the data to obtain my examples for what I posted above. From here I can see that some rows contain no values at all in this field although they appear to be filled with spaces when there is no data. I've tried to run update queries to fill in every row with valid data but my update queries finish without updating any rows. I've tried ISNULL(bal_qty) and bal_qty IS NULL and neither one works.
From MS Access 2007: Using the same driver that I'm using in VB.NET and I can load the ADO recordset and bind it to a form without a problem. The decimal values appear to be stripped off, probably because all of them are ".00". I prefer to build this small program in VB.NET so I'm using MS Access only for testing.
From VB.NET: My SQL statement works if I convert bal_qty to String but this causes sort problems. I've tried VAL(STR(bal_qty)) and it fails with the same error message I've posted above. Here's the code I'm using:
Imports System.Data.OleDb
Public Class Form1
Dim sConString As String = "Provider=vfpoledb.1;Data Source=C:\MyDatabase.dbc;Mode=3;"
Dim con As OleDbConnection = New OleDbConnection(sConString)
Private Function FetchData()
con.Open()
Dim ds As DataSet = New DataSet()
Dim sSQL As String
'This SQL statement works but the data doesn't sort properly.
'sSQL = "SELECT item_cd, item_desc, STR(bal_qty) FROM invent;"
sSQL = "SELECT item_cd, item_desc, bal_qty FROM invent;"
Dim cmd As OleDbCommand = New OleDbCommand(sSQL, con)
Dim daInv As OleDbDataAdapter = New OleDbDataAdapter(cmd)
Dim iRecCount As Integer
iRecCount = daInv.Fill(ds, "invent") 'The error occurs here.
Me.DataGridView1.DataSource = ds.Tables("invent").DefaultView
End Function
Private Sub btnFetchData_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnFetchData.Click
Call FetchData()
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
con.Close()
con = Nothing
End Sub
End Class
We have this problem with a .NET app that reads foxpro dbf's. Our solution was to use the following in the select statement:
SELECT PropertyID, VAL(STR(SaleAmt)) as SaleAmt FROM MyTable
This converts the decimal column (SaleAmt) to a string and then back to a numeric value. Additionally, if an integer is desired, you can use INT(SaleAmt) in your SELECT statement.
I've found the problem that was causing this. In the bal_qty column/field there was numeric data entered that didn't conform to the column's data type definition.
My field bal_qty has a Visual Foxpro data definition of:
Type: Numeric
Width: 8
Decimal: 2
The Visual Foxpro software apparently allowed the user to enter a value of 1000987 in this field which, as near as I can tell, doesn't cause an issue in Visual Foxpro. However, it does cause problems when accessing the data using anything other than Visual Foxpro because it violates the settings for this field.
Further testing revealed that MS Access 2007 also has a problem with this value. After loading the recordset into my Datasheet view form I get the error: "Data provider or other service returned an E_FAIL status." If I include the following WHERE clause I do not get the error: WHERE bal_qty < 9999
I've now resolved the problem by running an SQL UPDATE statement to change the value of bal_qty in the offending record.
I also found bad data in a column called markup. Hundreds of records are showing only asterisks where they should be showing numeric data. Including this markup column in my recordset queries causes my queries to fail with errors also.
See this SO Post concerning Asterisks in Numeric Columns and how to deal with it from .NET:
How do I read asterisk (***) fields from .DBF data base?
If you're trying to resolve this problem you can view and edit VFP data natively using Visual RunFox 6 which is free on Ed Leafe's website: http://leafe.com/dls/vfp You can also edit the table structure from here. This tool is far from intuitive unless you are an experienced VFP programmer. You have to enter VFP commands from the command window for most everything you want to do.
I've worked with VFP through C# and VB with many tables with/without decimals without problems. As for the ordering of data, you could add the "order by" clause to the select so its default coming DOWN from VFP into VB in a presorted mode.
Additionally, in the version's I've built, I don't query into a dataset, and don't know if that might be a problem somewhere somehow...
dim dt as DataTable
dim sSQL as String
sSQL = "Select item_cd, item_desc, bal_qty from invent order by bal_qty"
then, your data adapter...
daInv.Fill( dt )
then you would still be able to bind directly to your grid...
Me.DataGridView1.DataSource = dt
As for the numeric content, from your DBF Viewer utility, the input mask of the table structure should default to its expecting values... browse to any record, get into th field and start typing "9.99999", so "9." will force you to ITs known decimal location, then keep typing 9's after the decimal see how many actual places ARE available. I could see how it might nag you if you try to put in a value with greater decimal precision than it allows.

ComboBox DataBinding DisplayMember and LINQ queries

Update
I decided to iterate through the Data.DataTable and trimmed the values there.
Utilizing SirDemon's post, I have updated the code a little bit:
Sub test(ByVal path As String)
Dim oData As GSDataObject = GetDataObj(path)
EmptyComboBoxes()
Dim oDT As New Data.DataTable
Try
Dim t = From r In oData.GetTable(String.Format("SELECT * FROM {0}gsobj\paths ORDER BY keyid", AddBS(path))) Select r
If t.Count > 0 Then
oDT = t.CopyToDataTable
For Each dr As Data.DataRow In oDT.Rows
dr.Item("key_code") = dr.Item("key_code").ToString.Trim
dr.Item("descript") = dr.Item("descript").ToString.Trim
Next
dataPathComboBox.DataSource = oDT
dataPathComboBox.DisplayMember = "descript"
dataPathComboBox.ValueMember = "key_code"
dataPathComboBox.SelectedIndex = 0
dataPathComboBox.Enabled = True
End If
Catch ex As Exception
End Try
End Sub
This works almost as I need it to, the data is originally from a foxpro table, so the strings it returns are <value> plus (<Field>.maxlength-<value>.length) of trailing whitespace characters. For example, a field with a 12 character length has a value of bob. When I query the database, I get "bob_________", where _ is a space.
I have tried a couple of different things to get rid of the whitespace such as:
dataPathComboBox.DisplayMember.Trim()
dataPathComboBox.DisplayMember = "descript".Trim.
But nothing has worked yet. Other than iterating through the Data.DataTable or creating a custom CopyToDataTable method, is there any way I can trim the values? Perhaps it can be done in-line with the LINQ query?
Here is the code I have so far, I have no problem querying the database and getting the information, but I cannot figure out how to display the proper text in the ComboBox list. I always get System.Data.DataRow :
Try
Dim t = From r In oData.GetTable("SELECT * FROM ../gsobj/paths ORDER BY keyid") _
Select r
dataPathComboBox.DataSource = t.ToList
dataPathComboBox.SelectedIndex = 0
'dataPathComboBox.DisplayMember = t.ToList.First.Item("descript")
dataPathComboBox.Enabled = True
Catch ex As Exception
Stop
End Try
I know that on the DisplayMember line the .First.Item() part is wrong, I just wanted to show what row I am trying to designate as the DisplayMember.
I'm pretty sure your code tries to set an entire DataRow to a property that is simply the name of the Field (in a strongly type class) or a Column (in a DataTable).
dataPathComboBox.DisplayMember = "descript"
Should work if the DataTable contains a retrieved column of that name.
Also, I'd suggest setting your SelectedIndex only AFTER you've done the DataBinding and you know you actually have items, otherwise SelectedIndex = 0 may throw an exception.
EDIT: Trimming the name of the bound column will trim just that, not the actual bound value string. You either have to go through all the items after they've been bound and do something like:
dataPathComboBox.Item[i].Text = dataPathComboBox.Item[i].Text.Trim()
For each one of the items. Not sure what ComboBox control you're using, so the item collection name might be something else.
Another solution is doing that for each item when it is bound if the ComboBox control exposes an onItemDataBound event of some kind.
There are plenty of other ways to do this, depending on what the control itself offers and what you choose to do.
DisplayMember is intended to indicate the name of the property holding the value to be displayed.
In your case, I'm not sure what the syntax will by since you seem to be using a DataSet, but that should be
... DisplayMember="Item['descript']" ...
in Xaml, unless you need to switch that at runtime in which case you can do it in code with
dataPathComboBox.DisplayMember = "Item['descript']"
Again, not 100% sure on the syntax. If you are using a strongly typed DataSet it's even easier since you should have a "descript" property on your row, but given hat your error indicates "System.DataRow" and not a custom type, I guess you are not.
Because I can't figure out the underlying type of the datasource you are using I suggest you to change commented string to
dataPathComboBox.DisplayMember = t.ElementType.GetProperties.GetValue(0).Name
and try to determine correct index (initially it is zero) in practice.