|
I have been working on this code for quite awhile and cant seem to get it right. Its supposed to worked like
1. Click button to load csv(appended to datagrid1)
2. Click another button to export the edited csv.(not working at all, not sure where to start)
currently my datagrid codes are
<br />
button load_csv click<br />
Dim strConnection As System.Data.OleDb.OleDbConnection<br />
Dim myPath As String = "c:\testing.csv"<br />
<br />
Try<br />
<br />
'Dim objDataSet As System.Data.DataSet<br />
Dim objAdapter As System.Data.OleDb.OleDbDataAdapter<br />
<br />
strConnection = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source='" & myPath & " '; " & "Extended Properties=Excel 8.0;")<br />
objAdapter = New System.Data.OleDb.OleDbDataAdapter("select * from [sheet1$]", strConnection)<br />
objDataSet = New System.Data.DataSet<br />
objAdapter.Fill(objDataSet)<br />
DataGrid1.DataSource = objDataSet.Tables(0).DefaultView<br />
strConnection.Close()<br />
<br />
Catch ex As Exception<br />
<br />
Dim er As String<br />
<br />
strConnection.Close()<br />
<br />
End Try
i believe i do have to declare a global variable for datagrid1 as the export function needs it.
modified on Monday, July 28, 2008 2:03 PM
|
|
|
|
|
zzsoulzz wrote: Click another button to export the edited csv.(not working at all, not sure where to start)
Provide your code for this part, the other code you provided looks right. Is it populating the datagrid?
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
|
|
|
|
|
yes it is populating for my datagrid1
here is the code for export to csv
Dim dataSource As DataTable = DirectCast(DataGrid1.DataSource, DataTable)<br />
<br />
Dim currentRow As New System.Text.StringBuilder<br />
Dim entireFile As New System.Text.StringBuilder<br />
<br />
'Write the column names as headers for the file<br />
For Each column As DataColumn In dataSource.Columns<br />
currentRow.Append(""""c & column.ColumnName & """"c & ",")<br />
Next<br />
<br />
'Add the current line to the entire file StringBuilder<br />
entireFile.Append(currentRow.ToString)<br />
<br />
'Write each data row to the file StringBuilder<br />
For rowIndex As Int32 = 0 To dataSource.Rows.Count - 1<br />
currentRow = New System.Text.StringBuilder<br />
For Each column As DataColumn In dataSource.Columns<br />
currentRow.Append(""""c & dataSource.Rows(rowIndex)(column.ColumnName).ToString & """"c & ",")<br />
Next<br />
entireFile.Append(currentRow.ToString)<br />
Next<br />
<br />
'Write the contents of the entireFile StringBuilder to a file.<br />
Dim sw As New System.IO.StreamWriter("C:\Temp\DataGrid.csv")<br />
<br />
sw.Write(entireFile.ToString)
|
|
|
|
|
Why not open the file in the beginning and just write the lines one at a time? Is the StreamBuilder creating the csv data correctly?
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
|
|
|
|
|
having that code allows others to input their own csv instead of specifying one.
the current export isnt exporting at all.
it returns
<br />
An unhandled exception of type 'System.InvalidCastException' occurred in BScanner.exe<br />
<br />
Additional information: Specified cast is not valid.<br />
for this line
Dim dataSource As DataTable = DirectCast(DataGrid1.DataSource, DataTable)
|
|
|
|
|
Hi,
I'm not a VB 2005 coder. I'm forced to use VB because the SDK that came with a device only supports VB.
I have to send 65536 floating values to this device. I store these values in a double array and when I need to send them to the device I use stringbuilder in a thread to build the string, as following.
For i = 0 To 65535
System.Threading.Thread.Sleep(1)
ArbString.Append(", ")
ArbString.Append(ArbData(i).ToString("0.0000"))
worker.ReportProgress(i)
Next
Despite using stringbuilder the whole takes around 40 seconds to complete. Am I doing something wrong here or is there something I can do to speed the whole thing up?
TIA
|
|
|
|
|
shortest time you can sleep is 13 ms if i recall correctly.
so 65536 * 13 = 851 sec if Im not too tired after my vacation :P
|
|
|
|
|
Hi,
1.
you can't get an accurate delay like that. Sleep causes a thread switch, and it could take any
number of milliseconds before your thread is allowed back in.
for more accurate timing stuff, you may want to read my timers article.
2.
if you want to measure StringBuilder.Append performance, make a loop that contains just that;
no threading stuff, no backgrounders, no GUI access. Loop it many many times and use a StopWatch
to measure it. (BTW my article does not mention StopWatch, it was based on NET 1.x and StopWatch
got introduced with 2.0; I am working on an update).
3.
If you want maximum StringBuilder performance, make sure it has sufficient capacity right from
the start. If you don't, it will outrun its capacity, allocate a new and larger buffer
(typ. twice as large) and copy what it had so far. Your example needed around 500K characters, so
about two megabytes of unnecessary data copying have occured. Of course, using string instead of
StringBuilder would have been much much worse.
|
|
|
|
|
Hi Luc,
Thanks for your effort.
1. The sleep(1) is there todo just that, to give other threads a chance to get some execution time in the scheduler.
2. I didn't measure it using any timers, just the watch on my wrist. The thing is I did build a nice little GUI around this whole process with a nice animation and a progressbar but it still seems weird to me that this whole process would take so much time to complete.
3. You might be onto something there, how do I preallocate the size of a stringbuilder?
|
|
|
|
|
I'm wondering why the sleep command is there? If you are just building a string, then do you need the sleep?
Also, reporting progress - I would try cut that down a lot! Perhaps using:
if (i mod 255)=0 then
worker.ReportProgress(i)
end if
This will report progress a lot less often, so fewer thread switches etc.
|
|
|
|
|
Hi Jasey9,
I have a few other threads running and the sleep(1) is just there to force the scheduler to switch threads so this one doesn't hog up all the execution time. Give other threads a chance so to speak.
Thanks I'll try your suggestion.
|
|
|
|
|
frylord wrote: System.Threading.Thread.Sleep(1)
Might be the culprit. I understand you may need a delay to the device, but during each iteration?
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
|
|
|
|
|
Hi Paul,
It's not the sleep(1). The reason I know this is at first I expected this process to complete within a "reasonable" (not letting the user think the GUI got stuck) amount of time so I did this process under a button. Then when I noticed it's taking a lot of time to complete I put it in a thread with a nice GUI and such.
The sleep(1) is just there to force the scheduler to switch threads to give other threads some execution time as well.
Thanks for the effort.
|
|
|
|
|
frylord wrote: sleep(1) is just there to force the scheduler to switch threads to give other threads some execution time as well.
Looking at what Luc said, it makes sense, and the other poster's idea of using the mod might help.
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
|
|
|
|
|
frylord wrote: The sleep(1) is just there to force the scheduler to switch threads to give other threads some execution time as well.
That does not make sense to me. Either the code is running in the GUI thread, and Sleep is a no-no;
or it runs in another thread, and you should put Sleep calls when they are necessary. You don't need
to help Windows, Windows will reschedule threads when it feels like it, even when
they don't cooperate. You don't expect a single while(1){} to hog the CPU for 100% and
forever, do you? (I am not implying you should do such things, just saying Windows does not care
about the meaning of your code).
Just pointing out Windows will switch away from any thread, in favor of another thread:
- with higher priority
- with same priority, out of fairness concerns
- and even occasionally with lower priority, to maybe escape from an accidental deadlock situation.
BTW: the last paragraph applies more to desktop versions, and less to server versions of Windows.
|
|
|
|
|
Well to be honest I don't know. Somehow my college teachers indoctrinated the idea that you should block your current thread so other threads can get some execution time aswel. The same idea continued into my university years and has sticked with me ever since and I've also seen the same in alot of online tutorials and examples. I think this idea of blocking one thread to give others a chance could be left over from the days when schedulers weren't as complex.
|
|
|
|
|
Hi,
if you have a lot of work that needs to be done but is not urgent, then you should organize things
in such a way that other, possibly more urgent things, can be done first. This is accomplished
either by using a thread with lower priority (recommended when available, it is on Windows),
or by "throttling" yourself, i.e. forcing the OS to try and do something else from time to time.
Now giving away the CPU after copying 8 characters is not a good idea, since a thread switch would
cost anywhere between 10 and 1000 times as much as the work you are doing. So the reduction by
255 as suggested by one reply is appropriate.
But as I said before, it only takes some 40 msec althogether, so don't bother; just don't do it
in your own GUI thread!
BTW: GUI threads have a slightly higher priority than other threads at "normal priority" anyway.
And yes, it would be different on simpler operating systems, as well as on real-time environments,
as could be found in embedded systems.
|
|
|
|
|
Hi,
I have read your message again, and feel a need to add some:
- I am not sure the elapsed time is caused by the code you have shown, it merely loads a StringBuilder,
it does not send anything to your external device;
- if your connection is say a serial port (you did not specify) then it is operating at some baud rate;
when we assume 115200 Bd then that means a maximum of some 13K characters per second; so your
500K characters would require 35 seconds at least. So the transmission itself could be the bottleneck.
- if your (serial?) port uses some kind of handshaking (you did not specify), then maybe
it is the device itself that can't run any faster, and is telling the PC to slow down. In this case
the target device is the bottleneck.
If any of the above applies, it becomes unclear why you feel the need to first build a huge
string. You might consider outputting the numbers one by one, or a few KB at a time.
Finally, are you sure you need the comma-space combination? If one of those characters is redundant,
it takes one-eight of the bandwidth (that is 5 seconds in your case). And if you see a chance to
turn the assumed serial port to 7-bit instead of 8-bit that would shave of another 5 seconds or so
(this requires both sides to agree on it). Also, maybe the device does not need the 0.0000 format;
if it does not care about trailing zeroes, why send them?
|
|
|
|
|
Hi Luc,
Once again thank you.
The device is connected through a TCP/IP connection.
The thing is that the SDK doesn't allow for sending the data one by one, you need to send it in one line. So what I do is build the string I need to send using string builder and then afterwards send it using the SDK function and the stringbuilder ToString function.
I think I'll have to explain a bit more about the device, atleast I owe you that much I guess. The so called "device" is a arbitrary waveform generator. here's an excerpt from the manual.
You can download from 1 point (a dc signal) to 65,536 (64K) points per
waveform. You can download the points as floating-point values. Use the SendArbData function to
download floating-point values from -1.0 to +1.0.
And here's the bit on how the data should be.
The following statement shows how to use the SendArbData function to
download seven points to volatile memory.
SendArbData("1, .67, .33, 0, -.33, -.67, -1")
So basically it wants me to format a huge string of 65536 data points in CSV format and then use the SendArbData function to send it to the device.
|
|
|
|
|
OK,
so for N float numbers:
- use StringBuilder, give it initial capacity of 7*N
- fill it with your floats and try to keep it as short as possible, hence:
- try if it works without the space
- do some formatting (to avoid stupid decimals as in 0.3333333333333333(
- don't provide unnecessary resolution (if 0.00 is sufficient, don't use 0.0000)
- chop off trailing zeroes
- don't put sleeps, GUI stuff, etc in the fill loop
- update something on the GUI when the StringBuilder is filled
- give it to SendArbDate
- update something on the GUI when that method returns
- don't worry about some extra code in the fill loop, as long as it is not sleep, thread related
or GUI related.
I ran a simple filler for a megabyte stringbuilder; it took less than 50 msec, so that is
definitely not where the problem is.
You still haven't told much about the interface though; TCP/IP may or may not indicate Ethernet;
you can run it on a serial port too!
Warning: the device or its library may dislike a terminating ", " so strip it off before turning
StringBuilder into string.
Final remark: if either the library or the target device does a long computation (such as a
Fast Fourier Transform, which isn't always fast!) SendArbData might not return for a long time.
|
|
|
|
|
The manual isn't really clear on this but by trying I figured out that the device needs 4 decimals after the comma to get an accurate output.
For example when I set the Vmax to 9 volts and I want it to output 3 volts (1/3) then I need to set the data point to 0.3333333333333333333 if I had infinite accuracy. But just by trying I found out that by setting the data point to 0.33 i gives me 2.7 volts and when I set it to 0.3333 it gives me 3.01 volts.
I think you might be onto something with the GUI thing.
To be honest my first version wasn't with stringbuilder I think. When I first wrote the code I put it under a button using normal string. Then when I found that was too slow I built the thread thing then later on I put stringbuilder in there.
Okay after some trying I found that the culprit in this case was the progressbar which was being updated every loop. When I just use the stringbuilder it's quite fast.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click<br />
Dim Rnd As Random = New Random()<br />
Dim Dbl_RndData(65535) As Double<br />
Dim Str_RndData As StringBuilder<br />
Dim i As Integer = 0<br />
<br />
Str_RndData = New StringBuilder()<br />
<br />
' Fill the Double array with random data<br />
For i = 0 To 65535<br />
Dbl_RndData(i) = Rnd.NextDouble<br />
Next<br />
<br />
' Convert the data to a string using stringbuilder<br />
For i = 0 To 65535<br />
Str_RndData.Append(Dbl_RndData(i).ToString("0.0000"))<br />
Str_RndData.Append(", ") ' Append a comma to get CSV format<br />
Next<br />
End Sub
Thanks for the help.
|
|
|
|
|
You're welcome.
Just out of curiosity, how fast is it now?
|
|
|
|
|
Using this code:
Dim Rnd As Random = New Random()<br />
Dim Dbl_RndData(65535) As Double<br />
Dim Str_RndData As StringBuilder<br />
Dim i As Integer = 0<br />
Dim StpWtch As Stopwatch = New Stopwatch<br />
<br />
<br />
Str_RndData = New StringBuilder()<br />
<br />
' Fill the Double array with random data<br />
For i = 0 To 65535<br />
Dbl_RndData(i) = Rnd.NextDouble<br />
Next<br />
<br />
StpWtch.Start()<br />
' Convert the data to a string using stringbuilder<br />
For i = 0 To 65535<br />
Str_RndData.Append(Dbl_RndData(i).ToString("0.0000"))<br />
Str_RndData.Append(", ") ' Append a comma to get CSV format<br />
Next<br />
StpWtch.Done()<br />
<br />
TextBox1.Text = StpWtch.ElapsedTime.ToString
And this Stopwatch counter:
http://www.codeproject.com/KB/vb/vbnetstopwatch.aspx[^]
I get 0.196240863014713 seconds
|
|
|
|
|
I am retrieving data from database with list Box control. I like to show different items are different color depending upon condition. For example if I presenting student name in list box, when populating all student name, the student name who passed show in green color and who failed in red color. Please provide help in vb.bet.
|
|
|
|
|
Hi,
This article[^] demonstrates the nice things a ListBox can do. It is C# code, but the same applies to VB.NET
In essence, the listed items don't have to be strings, they could be any kind of object;
and a ListBox supports user-drawing, so you decide how things look.
|
|
|
|