TnTinMN 418 Practically a Master Poster

Just a guess, but I think Zick may be a user of google translate or something similar. Hence the odd wording.

Based on this:

Dim query As String
For Each item As ListViewItem In ListView1.Items
query = "Select * from [Calls and Visits$] where AM like '" & item.SubItems(1).Text & "%'"
'execute the query and do something with the results
Next

and this

after finding all the AM in the listview1 to listview2 i will sum all their calls and visits by Month (January to December)

I believe that he wants to search ListView2 for each "AM" entry in ListView1 and compute a yearly "Call" and "Visits" total per "AM" entry.

Perhaps Something Like this:

Private Sub Test()
   ' make some data
   Dim LV1Source As New DataTable
   Dim r As DataRow
   With LV1Source
      .Columns.Add("AM", GetType(String))
      .Columns.Add("Code Name", GetType(String))
      .Columns.Add("Department", GetType(String))
      .Columns.Add("Status", GetType(String))
      r = .NewRow : r(0) = "fred" : r(1) = "Something" : .Rows.Add(r)
      r = .NewRow : r(0) = "barney" : r(1) = "Something" : .Rows.Add(r)
   End With
   Dim LV2Source As New DataTable
   With LV2Source
      .Columns.Add("AM", GetType(String))
      .Columns.Add("Total Calls", GetType(Int32))
      .Columns.Add("Total Visits", GetType(Int32))
      .Columns.Add("Month", GetType(String))
      .Columns.Add("Year", GetType(Int32))
      r = .NewRow : r(0) = "fred" : r(1) = 10 : r(2) = 5 : r(3) = "January" : r(4) = 2011 : .Rows.Add(r)
      r = .NewRow : r(0) = "fred" : r(1) = 10 : r(2) = 5 : r(3) = "February" : r(4) = 2011 : .Rows.Add(r)
      r = …
TnTinMN 418 Practically a Master Poster

that's what I get from free handing it; complaints about 2 transposed leters that you then turn into a whole different method. :-/

If dp.YValues(0) > DateTime.FromOADate(Chart1.ChartAreas("Fred").AxisY.Minimum).Add(New TimeSpan(0, 3, 0)).ToOADate Then

TnTinMN 418 Practically a Master Poster

Perhaps a quick refresher read will help you gel your thought process. It has pretty pictures (I like pictures). :)

http://www.c-sharpcorner.com/UploadFile/eecabral/OOPSand.NET211102005075520AM/OOPSand.NET2.aspx

TnTinMN 418 Practically a Master Poster

The DataPoints primarily Type Double or something that can be converted to double. Think it logically, it needs plots floating pont values.

In this application, the Y-Axis values are AODate values that in turn are Type Double. The YAxis.Minimum value is your relative zero point. To get a TimeSpan value 3 minutes greater than that:

if dp.YValues(0) > DataTime.FromOADate(Chart1.ChartArea(0).AxisY.Minimum).Add(New TimeSpan(0,3,0)).ToAODate then
TnTinMN 418 Practically a Master Poster
TnTinMN 418 Practically a Master Poster

I'm getting old and sloppy in my coding; it is a datatype precision mistake.

change
Dim targetY As Single = CSng(area.AxisY.Minimum + ((targetTS.Ticks / deltaTSticks) * (area.AxisY.Maximum - area.AxisY.Minimum)))

to

Dim targetY As Double = (area.AxisY.Minimum + ((targetTS.Ticks / deltaTSticks) * (area.AxisY.Maximum - area.AxisY.Minimum)))

TnTinMN 418 Practically a Master Poster

What is the error message?
Linq is not the fastest in the world. How many data points do you have (approximately)?

For drawing the line, you need to scale the position to the axis as the labels are not the axis values. We had to fake it into using the timespan values with the custom labels.

     Private Sub Chart1_PostPaint(ByVal sender As Object, ByVal e As System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs) Handles Chart1.PostPaint
          If TypeOf e.ChartElement Is ChartArea Then

              Dim area As ChartArea = CType(e.ChartElement, ChartArea)

              Dim x1 As Single = CSng(area.AxisX.ValueToPixelPosition(area.AxisX.Minimum))
              Dim x2 As Single = CSng(area.AxisX.ValueToPixelPosition(area.AxisX.Maximum))

              ' need to scale the targetY value to the y-Axis values

              Dim targetTS As New TimeSpan(0, 3, 0) 'your 00:03:00

              ' when we originally setup the Y-Axis we used OADates to create a numeric value
              ' now convert these back to .Net datetime and get the range in Ticks
              Dim deltaTSticks As Int64 = DateTime.FromOADate(area.AxisY.Maximum).Ticks - DateTime.FromOADate(area.AxisY.Minimum).Ticks

              ' It is a linear scale:  y = y(0) + slope * X
              ' where X is targetTS.tick
              '       slope = (area.AxisY.Maximum - area.AxisY.Minimum) / deltaTsticks
              '       y(0) = area.AxisY.Minimum 
              '       y = targetY
              Dim targetY As Single = CSng(area.AxisY.Minimum + ((targetTS.Ticks / deltaTSticks) * (area.AxisY.Maximum - area.AxisY.Minimum)))

              ' now convert to pixel position
              Dim y As Single = CSng(area.AxisY.ValueToPixelPosition(targetY))

              e.ChartGraphics.Graphics.DrawLine(New Pen(Color.Blue, Width:=5), x1, y, x2, y)

          End If
     End Sub
TnTinMN 418 Practically a Master Poster

Curious is not the word I use when that happens!

LOL. And just what may the word you use be?

TnTinMN 418 Practically a Master Poster

The code I posted showed you a way to retrieve the available instances of SQL Server within the local network [System.Data.Sql.SqlDataSourceEnumerator.Instance.GetDataSources()].

Where you place the code is up to you to decide.

Personally, I would make the user select a server on the first time execution of the program and then store that server info as a user setting. For subsequent runs, do a check on load to verify that the server is still available. If not, prompt the user for a new selection. It would also be advisable to verify that the database file exists where you expect it to be before attempting to make a connection. Users do get curious at times and can delete your files.

TnTinMN 418 Practically a Master Poster

how will i change that connection/datasource as what the user wants?

I thought you did not want them to be able to change the DataSource.

If you need to allow them to select a server, maybe this will work for you?

    Dim csb As New SqlClient.SqlConnectionStringBuilder

    csb.IntegratedSecurity = True
    csb.UserInstance = True

    ' Full File Path Works with both these DataSource constructs
    'csb.AttachDBFilename = "F:\SQLServer2008\AttachedDBTest.mdf"
        ' DataSource = ".\" & InstanceName
        ' DataSource = ServerName & "\" & InstanceName


    ' |DataDirectory| only works with DataSource = ".\" & InstanceName
    csb.AttachDBFilename = "|DataDirectory|\AttachedDBTest.mdf"

    ' Try to retrieve the available servers
    Dim dtSQLServers As DataTable = System.Data.Sql.SqlDataSourceEnumerator.Instance.GetDataSources()
    If dtSQLServers.Rows.Count > 0 Then
        Try
            Dim ServerName As String = dtSQLServers.Rows.Item(0).Field(Of String)("ServerName")
            Dim InstanceName As String = dtSQLServers.Rows.Item(0).Field(Of String)("InstanceName")

            csb.DataSource = ".\" & InstanceName
            'csb.DataSource = ServerName & "\" & InstanceName

        Catch ex As Exception
            MsgBox(ex.Message)
            Exit Sub
        End Try

    End If

    Dim conn As New SqlClient.SqlConnection(csb.ConnectionString)

    conn.Open()
    conn.Close()
john.knapp commented: <snippet>nice!</snippet> +3
TnTinMN 418 Practically a Master Poster

Well here's one las t update. I added a few for comments to help you uderstand whats in there and cleaned up the code.

As far as things to help you learn.

  1. First and of high important. Set Option Strict On, Option Explicit Off, and Option Infer Off as defaults in your settings. You may hate that you have to do some extra typing, but it will save you much more time in debugging. It will also make you think about why VS is now saying that you should not do some code in a certain way.

  2. Your search engine is your friend. If you are looking for help on a certain keyword or method, try searching for "msdn what you are looking for". This used to mainly take you directly to the documentation page, but I noticed that lately, it pulls more from the microsoft forums. Both can be useful and bad at the same time. If you are looking at the documentation, scroll to the end of the page; that is where the community feedback is and there is often corrections and sometime sample code placed there.

  3. Let VS help you zero in on possible things to investigate further. Right click on methods and click "Go to definition" This helps see more information about the method and can help think about what to go looking for.

  4. Sample code is always good, but you will most likely for the source code as C#. This is OK, because in reality …

Reverend Jim commented: Good advice +12
TnTinMN 418 Practically a Master Poster

Can you take a look on the code again?

Good thing I did. Found some serious logic errors. Good example of that just because it worked, doesn't mean its right.

Now has color setting capabilty and rounded corners. Yes, I had to tweak it. ;)
I really want to use a pointed crystal shape, but writing a custom shape is will take some time. I also add some stuff to make it nicer to use a control. Feel free to ask if you have questions.

Please close this thread if your happy with it.

TnTinMN 418 Practically a Master Poster

I have one question though. Is is possible to integrate the control in the Global Assembly Cache so I won't have to include the file in every project anew?

Sure, just start a new Control Library project and copy the usercontrol code to it. Here is a link to how to add an assembly to the GAC.

http://msdn.microsoft.com/en-us/library/dkkx7f79%28v=vs.90%29.aspx

TnTinMN 418 Practically a Master Poster

First off, COOL project.

I think what you want is to define this as a user control so that you can place multiple instances on a form. I apolgize for totally rewriting your code, but it looked like to much fun to play with for me not to turn it into a control I will use.

Here is the modified project. I did not impliment your track bar, but I think you can deal with that.

Edit: I forgot to mention, just rebuild the project. The Digit control should showup on your toolbar.

Reverend Jim commented: Excellent post. +12
TnTinMN 418 Practically a Master Poster

Hi Lulu,

You are sure beating that example code to death! :-)

You should really post more of the code when you are asking for help. People are not going to know what DTRow is for example.

Oh well, so much fo my pedantic streak. Here is one way you could do it.

      Dim group As IEnumerable(Of DataRow) = _
         From sortrow As DataRow In ( _
         From row In DS.Tables(0).AsEnumerable() _
         Group row By LINENAME = row.Field(Of String)("LINENAME") Into grp = Group _
         Order By LINENAME _
         Select DTRow(grpDT, _
                      New Object() {LINENAME, _
                                    myToday.Add( _
                                                New TimeSpan(CType( _
                                                                     grp.Average(Function(r2 As DataRow) TimeSpan.Parse(r2.Field(Of String)("EVENTTM")).Ticks),  _
                                                                     Int64 _
                                                                   ) _
                                                            ) _
                                               ) _
                                   } _
                     ) _
         ) Order By sortrow.Item("EVENTTM")

Or you could just do it on your datatable.

      'Add the query results to the new Table
      For Each row As DataRow In group
         grpDT.Rows.Add(row)
      Next

      grpDT.DefaultView.Sort = "[EVENTTM] Asc" ' for ascending


      'grpDT.DefaultView.Sort = "[EVENTTM] Desc" ' for descending 


      'Assign new Table as DataSource of DGV
      GridView1.DataSource = grpDT.DefaultView

Select one way or the other. Not Both.

TnTinMN 418 Practically a Master Poster

Did some playing around and found putting the search into a separate function increased the speed by a factor of approximately 4(i.e. on my machine original code was 1200-1300, the new code
300-400)
You also switched to using a char for the seek parameter versus char which is the the reason for the speed increase not the fact that it hidden under another function.

If the OP would change: str.IndexOf(",", 0) to str.IndexOf(',', 0) the factor of 4 performance boost would also be observed.

So there is a lesson in this; when seeking for one char use the char overload not the string overload.

TnTinMN 418 Practically a Master Poster

I suspect your problem is that the splitcontainer only captures the mouse when you move over the splitterbar. Try wiring up the mouse move event for each panel in the container like this:

  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
     AddHandler SplitContainer1.Panel1.MouseMove, AddressOf SplitContainer1_MouseMove
     AddHandler SplitContainer1.Panel2.MouseMove, AddressOf SplitContainer1_MouseMove
  End Sub

  Private Sub SplitContainer1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles SplitContainer1.MouseMove
     Debug.WriteLine(MousePosition.ToString)
  End Sub
TnTinMN 418 Practically a Master Poster

Assuming that you are using VB's "application framework" you have a couple of options. To ensure that the framework is enabled, go to the "Solution Explorer" and either double-left click on "My Project" or right-click on it and select open.
Open_Props

This will open the project's property setting page.

props_page

Make sure that the "Enable application framework is checked". No notice the "Shutdown mode" combobox. In this case it is set to "When startup form closes". This means exactly as is implied, the application shutsdown when the startup form is closed.

Now assuming that you are using the "Application.Exit" method (not the "End" statement) to exit the application either via clicking your close program button or in the "FormClosing" event handler, you can put your logout code in just the "Startup Form's closing event handler. No need to put this logic in all of the forms. By using "Application.Exit" versus "End", you allow all message loops to complete first. The "End" statement does very little cleanup and like slamming the door closed on the application.

Another option would be to using the application's "Shutdown" event handler. You access the code page for this event by clicking on the "View Application Events" button shown in the above picture.

app_events_1

shutdown_event

coded_shutdown
Now you add you logout code under the shutdown event. The "My" namespace is meant to be your extentable …

Reverend Jim commented: Excellent advice +12
john.knapp commented: excellent, should be a tutorial +3
TnTinMN 418 Practically a Master Poster
TnTinMN 418 Practically a Master Poster

I am not aware of any issues in setting this property. I suspect that any issues you had in Excel VBA may have involved a registry value getting changed when you set a property, but that's just a guess. I normally enable script error suppression at the design level.

As these are errors are typically generated by bad java script code, thus supressing them should not be an issue. However, this little tidbit from MS makes me wonder.

When ScriptErrorsSuppressed is set to true, the WebBrowser control hides all its dialog boxes that originate from the underlying ActiveX control, not just script errors. Occasionally you might need to suppress script errors while displaying dialog boxes such as those used for browser security settings and user login. In this case, set ScriptErrorsSuppressed to false and suppress script errors in a handler for the HtmlWindow.Error event. For more information, see the code example in this topic.

See this for more info.

I also get browser errors regarding javascript and I don’t know how to handle that within the confines of VB.NET’s WebBrowser. As it is, I have to manually stop it from running or don’t, it doesn’t matter with regards to the query but it does stop my code at the DocumentCompleted event.

I don't know if you are aware of this or not, but when navigating to a given Url, you will likely get multiple "DocumentCompleted" events fired. The way to handle this is:

  Private …
Stuugie commented: Thank you very much +2
TnTinMN 418 Practically a Master Poster

I do not use WPF much, but I believe the "IsHitTestVisible" property is the one that you want to set to false and not the "IsEnabled" property.

TnTinMN 418 Practically a Master Poster
   Sub SetVisibility()
      Dim i As Int32 = 1
      CType(Me.FindName("Button_" & i.ToString), Control).Visibility = Windows.Visibility.Hidden
   End Sub
TnTinMN 418 Practically a Master Poster

This may help with the script errors issue. Set the "ScriptErrorsSuppressed" property on the WebBrowser control to True. That will prevent the error dialog from opening.

TnTinMN 418 Practically a Master Poster

Try changing: MainForm.WebBrowser1.DataBindings.Add("Url", ds.Tables("item"), "link")

To: MainForm.WebBrowser1.DataBindings.Add("Url", ds.Tables("item"), "link", True)

This enables formatting of the value which invokes the property's TypeConverter.

TnTinMN 418 Practically a Master Poster
Public Class ControlDirtyTrackerCollection
Implements List(Of ControlDirtyTracker)


End Class
TnTinMN 418 Practically a Master Poster

Set the Series2.YAxisType to Secondary

            With .Series("Series2")
                .ChartArea = "Fred"
                .ChartType = SeriesChartType.Point
                .XValueType = ChartValueType.String
                .XValueMember = "Linename"
                .YValueType = ChartValueType.DateTime
                .YValueMembers = "Count"
                .YAxisType = System.Windows.Forms.DataVisualization.Charting.AxisType.Secondary
                End With
TnTinMN 418 Practically a Master Poster

I'm freehanding these modifications to add the count field, but I sure that you will let me know if it throws an error. ;)

  Select DTRow(grpDT, _
           New Object() {LINENAME, _
                         New TimeSpan(CType( _
                                            grp.Average(Function(r2 As DataRow) TimeSpan.Parse(r2.Field(Of String)("EVENTTM")).Ticks),  _
                                             Int64 _
                                             ) _
                                       ), _
                          grp.Count() _
                        } _
          )

Now you need to make room for the count in the datatable.

        Dim grpDT As DataTable = Ds.Tables(0).Clone 'Copy structure of original Table
        'Make the changes you indicated to the Table structure.  You can do this as long as the table is empty.
        grpDT.Columns("EVENTTM").DataType = GetType(TimeSpan)
        grpDT.Columns("EVENTTM").ColumnName = "DURATION"

' ********  Column to hold Count        
        grpDT.Columns.Add("Count", gettype(Int32))

As far as examples of LINQ go, there are a lot of them out there.

Just search:

  • MSDN LINQ VB 101 Examples
  • MSDN IEnumerable LINQ extensions
  • MSDN IEnumerable

Unfortunately, MS created an abomination called the anonymous type in some perverted effort to make writing LINQ queries simpler. If you read some of their BS, they will claim that you have to use the Anonymous type to hold the result. This is total misinformation and they can not even keep their own ranks in line as many of them write LINQ examples, as I have shown you, using a strongly typed target variable. This is a somewhat of a style preference, but to use the anonymous type you have to have Option Infer On, and this goes against my personal philosphy. I believe code should explicitly …

TnTinMN 418 Practically a Master Poster

I had merged the Date.Add into the LINQ. This should work.

  Select DTRow(grpDT, _
               New Object() {LINENAME, _
                                         New TimeSpan(CType( _
                                                              grp.Average(Function(r2 As DataRow) TimeSpan.Parse(r2.Field(Of String)("EVENTTM")).Ticks),  _
                                                              Int64 _
                                                            ) _
                                                     ) _
                            } _
              )
TnTinMN 418 Practically a Master Poster

Another alternative is to use a common handler for all the checkboxes.checkchanged event and construct the string on each event.

  Private Sub CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
     Handles CheckBox1.CheckedChanged, _
             CheckBox2.CheckedChanged, _
             CheckBox3.CheckedChanged
     Static Problems As New List(Of CheckBox)
     Dim cb As CheckBox = CType(sender, CheckBox)
     If cb.Checked Then
        Problems.Add(cb)
     Else
        Problems.Remove(cb)
     End If
     Dim sb As New System.Text.StringBuilder(100)
     For i As Int32 = 0 To Problems.Count - 1
        sb.Append(Problems.Item(i).Text)
        If i < Problems.Count - 1 Then sb.Append(", ")
     Next
     TextBox1.Text = sb.ToString
  End Sub
TnTinMN 418 Practically a Master Poster

So what you want is the the arithetic mean (average) of the timespan values? This can be done using the "Average" function instead of the "Sum" function. However the "Average" function will return a value of type "Double" and the TimeSpan constructor takes a "Int64" type, so a type conversion is needed as well.

Change:

  Select DTRow(grpDT, _
               New Object() {LINENAME, _
                             myToday.Add( _
                                         New TimeSpan( _
                                                      grp.Sum(Function(r2 As DataRow) TimeSpan.Parse(r2.Field(Of String)("EVENTTM")).Ticks) _
                                                     ) _
                                        ) _
                            } _
              )

to:

  Select DTRow(grpDT, _
               New Object() {LINENAME, _
                             myToday.Add( _
                                         New TimeSpan(CType( _
                                                              grp.Average(Function(r2 As DataRow) TimeSpan.Parse(r2.Field(Of String)("EVENTTM")).Ticks),  _
                                                              Int64 _
                                                            ) _
                                                     ) _
                                        ) _
                            } _
              )
TnTinMN 418 Practically a Master Poster

Why did you not state that you are attempting to create a Yamazumi chart when you first posted?

Creating the functionality you have described can be accomplished using the chart control with some thought put into structuring the source data and a willingness to write some code. Two criteria that you have indicated that you are unwilling to accept.

Good luck.

TnTinMN 418 Practically a Master Poster

You will probably need to go one level lower in the event order; that is why I suggested the KeyDown event. You may need to use the PreviewKeyDown event and set the IsInputKey property.

Majestics commented: Solved the problem. Thanx +8
TnTinMN 418 Practically a Master Poster

I am a bit confused about which control you want to monitor (DGV vs EditControl).

If it is for the DGV and the arrow-up and arrow-down keys, then try using the DGV.KeyDown event.

TnTinMN 418 Practically a Master Poster

So you seem to understand how the chart control plots the points. Instead of relying on the so-called DataBinding supported by this control, create each series in code. You will have one series for each column in the datatable. Add a datapoint for each row in the column.

To get each chart column to be the same color, define an aray of colors. The size of the array would be the number of rows in the datatable. Then while adding each datapoint, set the DataPoint.Color property from this array based on the data source row.

TnTinMN 418 Practically a Master Poster

Take a look at your own post!

If you plot 3 series each with 5 points, you get 5 columns with 3 points in each column.

Notice the relation detween the number of points and the number of columns as well as the relation between number of series and number of points per column.

What you wanted was 3 columns with 5 points each.

So make 5 series each with 3 points.

TnTinMN 418 Practically a Master Poster

Do you have the C# Code? If so, you could reconfigure it as class library and call the download method.

If not, there are two options: 1) Process.WaitForExit and 2) The Process.Exit event.

http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.exited.aspx

TnTinMN 418 Practically a Master Poster

I glad that you have it working. :))

First, regarding the timespan. From the result that i get, total sum that is more than 24 hours will be converted to 1 day, for example: 1.03:04:49.
How can I change the day to 24 hours like 1.03:04:49 will become 27:04:49. Is it possible to do like that?

Yes. There are two ways that I know of to do this. Here is the simplest one.

   Private Sub Chart1_FormatNumber(ByVal sender As Object, ByVal e As System.Windows.Forms.DataVisualization.Charting.FormatNumberEventArgs) Handles Chart1.FormatNumber

      If sender Is Chart1.ChartAreas("Fred").AxisY OrElse TypeOf sender Is System.Windows.Forms.DataVisualization.Charting.DataPoint _
         AndAlso e.ValueType = ChartValueType.DateTime Then
         ' recreate original TimeSpan
         ' Remember that the Chart control uses OADates
         Dim ts As TimeSpan = DateTime.FromOADate(e.Value).Subtract(myToday)
         e.LocalizedValue = Trim(String.Format("{0,4:##00}:{1,2:00}:{2,2:00}", _
                                          (ts.Days * 24) + ts.Hours, _
                                          ts.Minutes, _
                                          ts.Seconds) _
                                 )

      End If

   End Sub

Second, how can i set the Y-Axis to become larger so that the total hour can see clearly

First off, you could make the size of the control taller. There are several values you can set regarding the interval to display less info if that is what you mean. Here is an extend section of what I showed earlier. Its best to play with these and see if you like the results. Normally, I would recommend looking at the documentation, but is this case that is an almost useless activity.

   ' Setup the chart

   With Chart1
      '.Dock = DockStyle.Fill
      .DataSource = dt
      .Legends.Clear() …
TnTinMN 418 Practically a Master Poster

Hi lulu:

The following example is for a WinForm, but I believe the charting control works the same for the a Web app.

You need to first convert the Timespan to a datetime value to chart it, but I guess you already discovered that. ;)

The problem then becomes one of formatting the Y-axis. Not too hard, but it can be confusing. Give this a try on a new WinForm project to which you have added a single chart control to the form.

Imports System.Windows.Forms.DataVisualization.Charting
Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

   ' Make some data
   Dim dt As New DataTable
   Dim r As DataRow
   With dt
      .Columns.Add("Label", GetType(String))
      .Columns.Add("TS", GetType(TimeSpan))
      r = .NewRow : r(0) = "A1" : r(1) = TimeSpan.Parse("0.00:45:00") : .Rows.Add(r)
      r = .NewRow : r(0) = "A2" : r(1) = TimeSpan.Parse("1.01:00:00") : .Rows.Add(r)
      r = .NewRow : r(0) = "A3" : r(1) = TimeSpan.Parse("0.06:00:00") : .Rows.Add(r)
      r = .NewRow : r(0) = "A4" : r(1) = TimeSpan.Parse("0.12:45:00") : .Rows.Add(r)

   End With

   ' Add a DateTime Column
   dt.Columns.Add("ChartTime", GetType(DateTime))


   ' Now for the real work!

   ' I use "Today" as the base date.  In a perfect world we could do:
      'For Each r In dt.Rows
      '   r("ChartTIME") = New DateTime(CType(r("TS"), TimeSpan).Ticks)
      'Next
   ' but the chart control uses OLE Automation dates and they use a 
   ' different time basis than .Net Dates.

   ' set a temp Today to prevent the unlikely case the the day changes while executing …
TnTinMN 418 Practically a Master Poster

Logic Error

If PathRead() = 0 Then
            MsgBox("Error Reading Path Info: One or more Paths do not exist.", MsgBoxStyle.Critical, "Path Read Error")
            MsgBox("Would you like to create these files?", MsgBoxStyle.YesNo, "Create?")
            If MsgBoxResult.Yes Then
                MkDir("/Paths/")
                System.IO.File.Create("/Paths/aPath.txt")
                System.IO.File.Create("/Paths/mPath.txt")
                System.IO.File.Create("/Paths/lPath.txt")
                System.IO.File.Create("/Paths/wPath.txt")
            End If
End If

Should be:

If PathRead() = 0 Then
            MsgBox("Error Reading Path Info: One or more Paths do not exist.", MsgBoxStyle.Critical, "Path Read Error")

            If MsgBox("Error Reading Path Info: One or more Paths do not exist." & vbcrlf & _
                      "Would you like to create these files?", MsgBoxStyle.YesNo, "Create?") = MsgBoxResult.Yes Then
                MkDir("/Paths/")
                System.IO.File.Create("/Paths/aPath.txt")
                System.IO.File.Create("/Paths/mPath.txt")
                System.IO.File.Create("/Paths/lPath.txt")
                System.IO.File.Create("/Paths/wPath.txt")
            End If
End If
TnTinMN 418 Practically a Master Poster

Ok, let's walk this through.

If RadioButton0 is clicked, it's "Checked" property will be True. Every time this happens you run the "clear" method. You also want the to execute the "clear" method by clicking ButClr that is parented by the "Calculator" class. It appears that your reference to the "CourseTab" class is named "courseTab". "clear" is defined as a Public method which means it can be called in ButClr_Clicked by adding the following statement to the "ButClr_Clicked" method:

`courseTab.clear`

The only thing that calling the method like this will not accomplish is setting RadioButton0's "Checked" state to True. Since you have not shown that you are handling the RadioButton0.CheckChanged event, there appears to be no reason that setting this in the "clear" method would be a problem. So you could add the follow statement to the "clear" method.

RadioButton0.Checked = True

With that stated, I will not try anymore to steer you way from the programming practice of programmatically clicking buttons.

InvokeOnClick is a protected method, meaning that sans using Reflection, you can only invoke it in the inherited class in which the statement resides. You are trying call it as a public method. It won't work.

You could do something like this though:

Me.InvokeOnClick(courseTab.RadioButton0, New EventArgs)

Take note that this will only work if RadioButton0 is declared Public or if it is delcared Friend and the declaration resides in the same assembly from which it is being accessed.

TnTinMN 418 Practically a Master Poster

So you are maintaining two lists; one for the words and the second to to strore the number of occurence of that word.

Why not use the dictionary class as was previously suggested by ddanbe?
It has all the functionallity you require already built-in.

private Dictionary<string, Int32> words = new Dictionary<string, Int32>();

Then you could do something like this:

      string subjectword = "fred";  // the current word you are working with

      if (words.ContainsKey(subjectword))
      {
         words[subjectword] += 1;
      }
      else
      {
         words.Add(subjectword, 1);
      }
TnTinMN 418 Practically a Master Poster

So that is what they teach! Augh!!!!!!!!!!!!!!

If you have a block of code that needs to be called by multiple event handlers, it is best to define that code block as a separate method (subroutine) and call it as needed.

Something like this pattern.

Private Sub RadioButton1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton1.CheckedChanged
   If RadioButton1.Checked Then DoSomething()
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
   DoSomething()
End Sub

Sub DoSomething()
   'well, I would do something if I knew what to do.
End Sub

To programmaticallly click a button, you could do this:

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
   Button1.PerformClick()
   RadioButton1.PerformClick()
End Sub

But if you really want to use Control.InvokeOnClick:

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
   Me.InvokeOnClick(Button2, New EventArgs)
End Sub

This assumes that "Me" is a class that has the Control class somewhere in it's inheritance tree.

TnTinMN 418 Practically a Master Poster

It would help if you showed your code. Also would help if you identified the line of code that throws the error.

TnTinMN 418 Practically a Master Poster

Performing computions on TimeSpan and DateTime types are two areas that the DataTable class does not support very well.

That said, you are left to process the rows yourself in code.

Here are two options, both of which entail creating an array of resultant rows that can then be added to a new DataTable

  1. You could iterate through the table and create a list of unique LINENAME's and then do a DT.Rows.Select to pull those rows. You would then need to iterate through the returned rows and perform the summation. Then this result would be converted into a new DataRow and stored in an Array of DataRows.

    Not difficult to do and it is easy to follow the code logic.

  2. The second option essentially does the above, but uses a LINQ query on the DataTable to group and compute. These can be compact statements, but are confusing to those who do not use them very often. This will return an IENumerable(Of DataRow) that can then be iterated through and added to a DataTable.

I am going to show the LINQ method.

For your particular problem, we need to deal with the TimeSpan structure. To get a value that can be summed, I use the "Ticks" property and sum that value.

The method shown below handles the conversion the string TimeSpan value directly. No need for the TimeSpan conversion sterp that you showed.

As I do not do webpages, I have written and tested this in a WinForm project. You …

TnTinMN 418 Practically a Master Poster

You are adding parameters that may not exist in the command string.

INSERT INTO [Customer] (Company, Business_Phone, Home_Phone, Mobile_Phone, Fax) VALUES (@CMPNY, @BUSPH, @HOMPH, @MBLPH, @FAXNM)
In this case you will have parameters for Last_Name and First_Name that are empty. I believe that the parameters must be in the order requested as it doe not do a look-up of the provided parameters.

I have restructured your code and eliminated some unnecessary functional but confusing code.

   Dim custstr As String = "INSERT INTO [Customer] ("
   Dim valuestr As String = ") VALUES ("

   Dim custcmd As New OleDbCommand()
   Dim txt As String
   txt = txt_company.Text

   If Not String.IsNullOrEmpty(txt) AndAlso txt.Trim.Length <> 0 Then
       custstr &= "Company"
       valuestr &= "@CMPNY"
       custcmd.Parameters.AddWithValue("@CMPNY", txt_company.Text)
   End If

   txt = txt_lastname.Text
   If Not String.IsNullOrEmpty(txt) AndAlso txt.Trim.Length <> 0 Then
       custstr &= ", Last_Name"
       valuestr &= ", @LSTNM"
       custcmd.Parameters.AddWithValue("@LSTNM", txt_lastname.Text)
   End If

   txt = txt_firstname.Text
   If Not String.IsNullOrEmpty(txt) AndAlso txt.Trim.Length <> 0 Then
       custstr &= ", First_Name"
       valuestr &= ", @FSTNM"
       custcmd.Parameters.AddWithValue("@FSTNM", txt_firstname.Text)
   End If

   txt = txt_busphone.Text
   If Not String.IsNullOrEmpty(txt) AndAlso txt.Trim.Length <> 0 Then
       custstr &= ", Business_Phone"
       valuestr &= ", @BUSPH"
       custcmd.Parameters.AddWithValue("@BUSPH", txt_busphone.Text)
   End If

   txt = txt_homephone.Text
   If Not String.IsNullOrEmpty(txt) AndAlso txt.Trim.Length <> 0 Then
       custstr &= ", Home_Phone"
       valuestr &= ", @HOMPH"
       custcmd.Parameters.AddWithValue("@HOMPH", txt_homephone.Text)
   End If

   txt = txt_mobilephone.Text
   If Not String.IsNullOrEmpty(txt) AndAlso txt.Trim.Length <> 0 Then
       custstr &= ", Mobile_Phone"
       valuestr &= ", @MBLPH"
       custcmd.Parameters.AddWithValue("@MBLPH", txt_mobilephone.Text)
   End If

   txt = txt_fax.Text
   If Not String.IsNullOrEmpty(txt) AndAlso txt.Trim.Length …
TnTinMN 418 Practically a Master Poster

the time format is 00:00:00 0 is time(7), i will try TnTinMN method , and i will see what will be going.

The SQL Time datatype will through a wrench in the machinery for using the datatable expression. This datatype gets converted to a .Net TimeSpan and there is no way that I know of to achieve the data manipulations necessary to get this to a decimal value need to compute "Cost" in a datacolumn expression. You can follow the example I provided up to the point of adding the expression statement with this minor change to the Select statement in the query.

SELECT Empl_Name, Hours_Worked, Rate, CAST(CAST(Hours_Worked AS DateTime) AS Float) * 24.0 * CAST(Rate AS Float) AS Cost FROM Labor

In the case where you would be using the DGV for entry/editting, it will be necessary to handle the CellValueChanged event. Here is an example for that.

   Private Sub LaborDataGridView_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles LaborDataGridView.CellValueChanged
      If Not LaborDataGridView.IsHandleCreated Then Exit Sub 'handles initialization

      If LaborDataGridView.Columns(e.ColumnIndex).DataPropertyName = "Hours_Worked" OrElse _
         LaborDataGridView.Columns(e.ColumnIndex).DataPropertyName = "Rate" Then
         'get the underlying datatable row
         Dim dr As DataRow = CType(LaborDataGridView.Rows(e.RowIndex).DataBoundItem, DataRowView).Row
         'set cost to reflect changes
         dr("Cost") = CType(dr("Hours_Worked"), TimeSpan).TotalHours * CType(dr("Rate"), Decimal)
         LaborDataGridView.InvalidateRow(e.RowIndex) 'refresh the row with new value
      End If

   End Sub
TnTinMN 418 Practically a Master Poster
TnTinMN 418 Practically a Master Poster

Hiba,

No offense intended, but the DataGridView control is really intended as a viewer for data in a tabular format and not as a spreadsheet. It would be better to handle these calculations in the backing data storage. Even if the data is not pulled from a database, it is much easier to create a datatable with a computed column and set the DGV's datasource to your created table.

Let's assume you are using a database for that you have created a dataset for through the designer. We will edit the datasource. This is just a simple Access DB that I created, but the type of database is irrelevant.

0

148
Now we are going to add a new column to hold the result of multiplying "Hours_Worked" by "Rate". We will name this column "Cost".
229
Go to the properties for "Cost" and set its DataType to decimal.

313
Ok, now we have cost column in the dataset, however it does not exist in the database. We will create it in our fill query.
45
Click the "Next" button until you reach the Sql screen.
52
We will edit the "Select" statement to add the "Cost" column
Hours_Worked * Rate As Cost
65

Click "Next" and give a name for the two methods.
71

Reverend Jim commented: Great post. Should be a tutorial. +11
TnTinMN 418 Practically a Master Poster

The richtextbox uses chr(10) (VBLf) to designate a new line. So if that is working, then check for VBLf (this is a VB character constant).

On non-Unix systems, the System.Environment.NewLine is a two character string equivalent to chr(13) & chr(10). You could also use the VB constant VBCrLf for this.

What is it that you are trying to accomplish? There are most likely other methods that could be suggested.

TnTinMN 418 Practically a Master Poster

The ommision of ByVal is a non-optional "feature" MS added in VB2010 SP1. ByVal is the default parameter passage mechanism in .Net. Supposedly MS originally used the placement of ByVal as a reminder for those migrating from VB6 where ByRef is default.