cancel
Showing results for 
Search instead for 
Did you mean: 
Create Post

Visual Basic 101 (part 4)

Level 15

If you've read Part 1, Part 2, and Part 3 of this series, then this is the one you've been waiting for. The code! Before you get too excited, let me clarify a few things, for the record:

  • The only way to get this calculator is to build it following the steps in this series. It will not be available for download nor will SolarWinds offer support for this tool. The code for this tool is made available for educational purposes only.
  • When built, the calculator will only provide recommendations based on a small amount of testing. Your environment will be different and you may want to modify the code to suit your needs. (Comments in the code are given on what to modify, if you so desire.)
  • This calculator has not been tested for accuracy and will not be supported in any way, shape, or form, by SolarWinds, or by the author of this article.
  • SolarWinds is not responsible for any errors or non-working code. Sorry, you'll have to troubleshoot yourselves. (Be sure to review all four of these posts.)
  • This is only one of an infinite number of ways to code this calculator. I'm sure there are more elegant designs. The bottom line is, it works.
  • If and when you get this to work where others cannot, please help them if you can.
  • Wireshark is a free tool that you can use to measure and filter your bandwidth traffic. Wireshark was used in getting bandwidth averages for the four protocols in this calculator. You can use Wireshark to get your own averages and modify the figures in this code, which is commented.


Lesson 5 - Compiling the code

Below is the code you will need to add to your calculator project in Visual Basic. In your calculator project, go to the Code view and delete everything. Next, copy and paste the code below. When done, you should have something that looks like this:

ide4.png

If all is well, hit the Play button, highlighted above. The calculator should appear before you working as planned. If everything works, compile your code into an executable.

Compiling your code into an executable:

  1. From the Build menu, select Build...
    build.png
  2. If successful, your executable should reside in a path similar to this:
    C:\VS2010\Calculator\BWCalc\BWCalc\bin\Release

Copy and Paste Me

Imports System.Data.OleDb

Imports System.Drawing.Drawing2D

Public Class frmMain

Dim WMIMonitorNumbers, WMINeededBW, WMIStat, WMIConvert, WMITotal, FinalTotal, WMIConvert2 As Double

Dim SNMPMonitorNumbers, SNMPNeededBW, SNMPStat, SNMPConvert, SNMPTotal, SNMPConvert2 As Double

Dim RPCMonitorNumbers, RPCNeededBW, RPCStat, RPCConvert, RPCTotal, RPCConvert2 As Double

Dim ICMPMonitorNumbers, ICMPNeededBW, ICMPStat, ICMPConvert, ICMPTotal, Monitortotal, ICMPConvert2 As Double

Dim WMIsuffix, RPCsuffix, SNMPsuffix, ICMPsuffix, suffixtotal As String

Dim All$

Private Sub txtWMI_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtWMI.LostFocus

        On Error Resume Next

        If IsNumeric(txtWMI.Text) = False Or Val(txtWMI.Text) > 10000 Then

            txtWMI.Text = "0"

            WMIMonitorNumbers = txtWMI.Text

            TBWMI.Value = 0

            WMICalc()

            Exit Sub

        End If

        WMIMonitorNumbers = txtWMI.Text

        txtWMI.Text = Format(WMIMonitorNumbers, "###,###")

        WMICalc()

        If txtWMI.Text <= 10000 Then

            TBWMI.Value = txtWMI.Text

        Else

            TBWMI.Value = 10000

        End If

        If WMIMonitorNumbers < 1 Then txtWMI.Text = "0" : WMICalc()

End Sub

Private Sub txtRPC_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtRPC.LostFocus

        On Error Resume Next

        If IsNumeric(txtRPC.Text) = False Or txtRPC.Text > 10000 Then

            txtRPC.Text = "0"

            RPCMonitorNumbers = txtRPC.Text

            TBRPC.Value = 0

            RPCCalc()

            Exit Sub

        End If

        RPCMonitorNumbers = txtRPC.Text

        txtRPC.Text = Format(RPCMonitorNumbers, "###,###")

        RPCCalc()

        If txtRPC.Text <= 10000 Then

            TBRPC.Value = txtRPC.Text

        Else

            TBRPC.Value = 10000

        End If

        If RPCMonitorNumbers < 1 Then txtRPC.Text = "0" : RPCCalc()

End Sub

Private Sub txtSNMP_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtSNMP.LostFocus

        On Error Resume Next

        If IsNumeric(txtSNMP.Text) = False Or txtSNMP.Text > 10000 Then

            txtSNMP.Text = "0"

            SNMPMonitorNumbers = txtSNMP.Text

            TBSNMP.Value = 0

            SNMPCalc()

            Exit Sub

        End If

        SNMPMonitorNumbers = txtSNMP.Text

        txtSNMP.Text = Format(SNMPMonitorNumbers, "###,###")

        SNMPCalc()

        If txtSNMP.Text <= 10000 Then

            TBSNMP.Value = txtSNMP.Text

        Else

            TBSNMP.Value = 10000

        End If

        If SNMPMonitorNumbers < 1 Then txtSNMP.Text = "0" : SNMPCalc()

End Sub

Private Sub txtICMP_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtICMP.LostFocus

        On Error Resume Next

        If IsNumeric(txtICMP.Text) = False Or txtICMP.Text > 10000 Then

            txtICMP.Text = "0"

            ICMPMonitorNumbers = txtICMP.Text

            TBICMP.Value = 0

            ICMPCalc()

            Exit Sub

        End If

        ICMPMonitorNumbers = txtICMP.Text

        txtICMP.Text = Format(ICMPMonitorNumbers, "###,###")

        ICMPCalc()

        If txtICMP.Text <= 10000 Then

            TBICMP.Value = txtICMP.Text

        Else

            TBICMP.Value = 10000

        End If

        If ICMPMonitorNumbers < 1 Then txtICMP.Text = "0" : ICMPCalc()

End Sub

Private Sub txtWMI_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtWMI.KeyDown

        On Error Resume Next

        If e.KeyCode = Keys.Return Then

            If IsNumeric(txtWMI.Text) = False Or txtWMI.Text > 10000 Then

                txtWMI.Text = "0" : Exit Sub

            End If

            WMIMonitorNumbers = txtWMI.Text

            txtWMI.Text = Format(WMIMonitorNumbers, "###,###")

            WMICalc()

            If txtWMI.Text <= 10000 Then

                TBWMI.Value = txtWMI.Text

            Else

                TBWMI.Value = 10000

            End If

        End If

End Sub

    Private Sub WMICalc()

        On Error Resume Next

        WMIStat = 315 'This is the key figure. This number represents multiple tests and averages using Wireshark, filtering out data that is not pertinent. Changing this number will allow you to fine tune the amount of bandwidth used by this protocol.

        WMINeededBW = WMIStat * WMIMonitorNumbers

        WMIConvert = ((WMINeededBW / 1024) * 😎 / 1024

        If WMIConvert = 0 Then lblWMI.Text = "00.00 Kbps" : DoTotal() : Exit Sub

        If WMIConvert < 1 Then

            DoTotal()

            WMIsuffix = " Kbps"

            WMIConvert2 = WMIConvert * 1024

            lblWMI.Text = Format(WMIConvert2, "###,###") & WMIsuffix

            Exit Sub

        Else

            DoTotal()

            WMIsuffix = " Mbps"

            lblWMI.Text = Format(WMIConvert, "standard") & WMIsuffix

            Exit Sub

        End If

  End Sub

Private Sub TBWMI_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TBWMI.ValueChanged

        On Error Resume Next

        WMIMonitorNumbers = TBWMI.Value

        If txtWMI.Text <= 10000 Then

            txtWMI.Text = Format(TBWMI.Value, "###,###")

        End If

        If WMIMonitorNumbers < 1 Then txtWMI.Text = "0"

        WMICalc()

End Sub

Private Sub txtSNMP_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtSNMP.KeyDown

        On Error Resume Next

        If e.KeyCode = Keys.Return Then

            If IsNumeric(txtSNMP.Text) = False Or txtSNMP.Text > 10000 Then

                txtSNMP.Text = "0" : Exit Sub

            End If

            SNMPMonitorNumbers = txtSNMP.Text

            txtSNMP.Text = Format(SNMPMonitorNumbers, "###,###")

            SNMPCalc()

            If txtSNMP.Text <= 10000 Then

                TBSNMP.Value = txtSNMP.Text

            Else

                TBSNMP.Value = 10000

            End If

        End If

End Sub

Private Sub SNMPCalc()

        On Error Resume Next

        SNMPStat = 0.66 'This is the key figure. This number represents multiple tests and averages using Wireshark, filtering out data that is not pertinent. Changing this number will allow you to fine tune the amount of bandwidth used by this protocol.

        SNMPNeededBW = SNMPStat * SNMPMonitorNumbers

        SNMPConvert = ((SNMPNeededBW / 1024) * 😎 / 1024

        If SNMPConvert = 0 Then lblSNMP.Text = "00.00 Kbps" : DoTotal() : Exit Sub

        If SNMPConvert < 1 Then

            DoTotal()

            SNMPsuffix = " Kbps"

            SNMPConvert2 = SNMPConvert * 1024

            If SNMPConvert2 < 1 Then SNMPConvert2 = 1

            lblSNMP.Text = Format(SNMPConvert2, "###,###") & SNMPsuffix

            Exit Sub

        Else

            DoTotal()

            SNMPsuffix = " Mbps"

            lblSNMP.Text = Format(SNMPConvert, "standard") & SNMPsuffix

            Exit Sub

        End If

End Sub

Private Sub TBSNMP_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TBSNMP.ValueChanged

        On Error Resume Next

        SNMPMonitorNumbers = TBSNMP.Value

        If txtSNMP.Text <= 10000 Then

            txtSNMP.Text = Format(TBSNMP.Value, "###,###")

        End If

        If SNMPMonitorNumbers < 1 Then txtSNMP.Text = "0"

        SNMPCalc()

End Sub

Private Sub txtRPC_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtRPC.KeyDown

        On Error Resume Next

        If e.KeyCode = Keys.Return Then

            If IsNumeric(txtRPC.Text) = False Or txtRPC.Text > 10000 Then

                txtRPC.Text = "0" : Exit Sub

            End If

            RPCMonitorNumbers = txtRPC.Text

            txtRPC.Text = Format(RPCMonitorNumbers, "###,###")

            RPCCalc()

            If txtRPC.Text <= 10000 Then

                TBRPC.Value = txtRPC.Text

            Else

                TBRPC.Value = 10000

            End If

        End If

End Sub

Private Sub RPCCalc()

        On Error Resume Next

        Dim Exponent As Double

        RPCStat = 2392 'This is the key figure. This number represents multiple tests and averages using Wireshark, filtering out data that is not pertinent. Changing this number will allow you to fine tune the amount of bandwidth used by this protocol.

        Exponent = 1

        RPCStat = RPCStat ^ Exponent

        RPCNeededBW = RPCStat * RPCMonitorNumbers

        RPCConvert = ((RPCNeededBW / 1024) * 😎 / 1024

        If RPCConvert = 0 Then lblRPC.Text = "00.00 Kbps" : DoTotal() : Exit Sub

        If RPCConvert < 1 Then

            DoTotal()

            RPCsuffix = " Kbps"

            RPCConvert2 = RPCConvert * 1024

            lblRPC.Text = Format(RPCConvert2, "###,###") & RPCsuffix

            Exit Sub

        Else

            DoTotal()

            RPCsuffix = " Mbps"

            lblRPC.Text = Format(RPCConvert, "standard") & RPCsuffix

            Exit Sub

        End If

End Sub

Private Sub TBRPC_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TBRPC.ValueChanged

        On Error Resume Next

        RPCMonitorNumbers = TBRPC.Value

        If txtRPC.Text <= 10000 Then

            txtRPC.Text = Format(TBRPC.Value, "###,###")

        End If

        If RPCMonitorNumbers < 1 Then txtRPC.Text = "0"

        RPCCalc()

End Sub

Private Sub txtICMP_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtICMP.KeyDown

        On Error Resume Next

        If e.KeyCode = Keys.Return Then

            If IsNumeric(txtICMP.Text) = False Then

                txtICMP.Text = "0" : Exit Sub

            End If

            ICMPMonitorNumbers = txtICMP.Text

            txtICMP.Text = Format(ICMPMonitorNumbers, "###,###")

            ICMPCalc()

            If txtICMP.Text <= 10000 Then

                TBICMP.Value = txtICMP.Text

            Else

                TBICMP.Value = 10000

            End If

        End If

End Sub

Private Sub ICMPCalc()

        On Error Resume Next

        ICMPStat = 1.15 'This is the key figure. This number represents multiple tests and averages using Wireshark, filtering out data that is not pertinent. Changing this number will allow you to fine tune the amount of bandwidth used by this protocol.

        ICMPNeededBW = ICMPStat * ICMPMonitorNumbers

        ICMPConvert = ((ICMPNeededBW / 1024) * 😎 / 1024

        If ICMPConvert = 0 Then lblICMP.Text = "00.00 Kbps" : DoTotal() : Exit Sub

        If ICMPConvert < 1 Then

            DoTotal()

            ICMPsuffix = " Kbps"

            ICMPConvert2 = ICMPConvert * 1024

            If ICMPConvert2 < 1 Then ICMPConvert2 = 1

            lblICMP.Text = Format(ICMPConvert2, "###,###") & ICMPsuffix

            Exit Sub

        Else

            DoTotal()

            ICMPsuffix = " Mbps"

            lblICMP.Text = Format(ICMPConvert, "standard") & ICMPsuffix

            Exit Sub

        End If

End Sub

Private Sub TBICMP_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TBICMP.ValueChanged

        On Error Resume Next

        ICMPMonitorNumbers = TBICMP.Value

        If txtICMP.Text <= 10000 Then

            txtICMP.Text = Format(TBICMP.Value, "###,###")

        End If

        If ICMPMonitorNumbers < 1 Then txtICMP.Text = "0"

        ICMPCalc()

End Sub

Private Sub DoTotal()

        On Error Resume Next

        suffixtotal = " Mbps"

        FinalTotal = WMIConvert + SNMPConvert + RPCConvert + ICMPConvert

        If FinalTotal >= 1024 Then

            suffixtotal = " Gbps"

            FinalTotal = FinalTotal / 1024

        End If

        If FinalTotal < 1 Then

            suffixtotal = " Kbps"

            FinalTotal = FinalTotal * 1024

        End If

        Monitortotal = WMIMonitorNumbers + RPCMonitorNumbers + SNMPMonitorNumbers + ICMPMonitorNumbers

        lblMonitors.Text = Format(Monitortotal, "###,###")

        lblTotal.Text = Format(FinalTotal, "Standard") & suffixtotal

        If Monitortotal < 1 Then lblMonitors.Text = "0"

        FinalTotal = 0

        Piecalc()

End Sub

Private Sub cmdReset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdReset.Click

        txtWMI.Text = "0"

        txtRPC.Text = "0"

        txtSNMP.Text = "0"

        txtICMP.Text = "0"

        TBWMI.Value = 0

        TBRPC.Value = 0

        TBSNMP.Value = 0

        TBICMP.Value = 0

        DoTotal()

        txtWMI.Text = "0"

        txtRPC.Text = "0"

        txtSNMP.Text = "0"

        txtICMP.Text = "0"

        TBWMI.Value = 0

        TBRPC.Value = 0

        TBSNMP.Value = 0

        TBICMP.Value = 0

        lblMonitors.Text = "0"

        PieReset()

End Sub

Private Sub PieCalc()

        Chart1.Series.Clear()

        Dim ser1 As Windows.Forms.DataVisualization.Charting.Series

        ser1 = Chart1.Series.Add("Pie Chart")

        ser1.ChartType = DataVisualization.Charting.SeriesChartType.Pie

        ser1.Points(ser1.Points.AddY(WMIConvert)).AxisLabel = "WMI"

        ser1.Points(ser1.Points.AddY(SNMPConvert)).AxisLabel = "SNMP"

        ser1.Points(ser1.Points.AddY(RPCConvert)).AxisLabel = "RPC"

        ser1.Points(ser1.Points.AddY(ICMPConvert)).AxisLabel = "ICMP"

        If WMIConvert + SNMPConvert + RPCConvert + ICMPConvert = 0 Then PieReset()

End Sub

Private Sub PieReset()

        Chart1.Series.Clear()

        Dim ser1 As Windows.Forms.DataVisualization.Charting.Series

        ser1 = Chart1.Series.Add("Pie Chart")

        ser1.ChartType = DataVisualization.Charting.SeriesChartType.Pie

        ser1.Points(ser1.Points.AddY(100)).AxisLabel = "WMI"

ser1.Points(ser1.Points.AddY(100)).AxisLabel = "SNMP"

ser1.Points(ser1.Points.AddY(100)).AxisLabel = "RPC"

ser1.Points(ser1.Points.AddY(100)).AxisLabel = "ICMP"

End Sub

Private Sub frmMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        PieReset()

End Sub

Private Sub speak()

        Dim SAPI

        Dim prefix$

        Dim length As Integer

        Dim CNumber As Double

        SAPI = CreateObject("SAPI.spvoice")

        length = Len(lblTotal.Text)

        If Mid(lblTotal.Text, length - 3, 4) = "Mbps" Then

            prefix$ = "mega bits per second"

        Else

            prefix$ = "kilabits per second"

        End If

        CNumber = Val(lblTotal.Text)

        If Val(lblTotal.Text) = 0 Then

            All$ = "I need numbers to do a calculation. Zero is not an option."

            SAPI.Speak(All$)

            Exit Sub

        Else

            All$ = "The total recommended bandwidth for your" & Monitortotal & "monitors is" & CNumber & prefix$

            SAPI.Speak(All$)

            Exit Sub

        End If

End Sub

Private Sub picSpeak_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles picSpeak.Click

        speak()

End Sub

End Class

2 Comments
Level 7

Thank You for posting this getting-started tutorial. This was my first foray into .NET programming, having come with an extensive background in using MS Access with VBA. For the most part, I was able to follow this tutorial okay, but there was one set of instructions that caused me some confusion in Part 2, Lesson 3: "Adding a Picturebox". Instruction #2 directs us to "Place it and size it in the GroupBox as illustrated above."  I think it would be helpful to add text "...as illustrated above, to the left of the Reset button", as I initially thought the picture box was the pie chart area. It wasn't until I got to the pie chart section that I realized I had made a mistake. Not a big deal, but it did cause some confusion.

The rest of my comments relate to Part 4, with the code. I guess this type of declaration is okay in VB.net:I
Dim WMIMonitorNumbers, WMINeededBW, WMIStat, WMIConvert, WMITotal, FinalTotal, WMIConvert2 As Double

In VBA, only the last variable, WMIConvert2 would be initially dimensioned as a double. All other variables would initially be empty variants, that could then be typecast at run-time. Is VB.Net different from VBA in this regards?

I see a lot of On Error Resume Next statements. This just seems like a crutch to me, to intentionally blow through any errors...

There are LostFocus and Keydown event procedures for the four text boxes, txtWMI, txtSNMP, txtRPC and txtICMP. However, making changes in these text boxes does not provide immediate updates to the results, until one moves focus to a different control. For example, if one starts the application and manually keys in 100 into txtWMI, then immediately clicks on the picture box icon, to have the result spoken, we here "I need numbers to do a calculation; zero is not an option". Similarly, once you have a result, manual updates to the values in the text boxes are not reflected in the result. The slider controls work as expected, with updates always included in the calculated result. It is only the manual entries into the text boxes that are not resulting in updated values for me.

In the RPCCalc subroutine, what purpose is the variable "Exponent" serving? As far as I can tell, it is declared as a double, initialized to a value of 1, and then used in this calculation:

        Exponent = 1
        RPCStat = RPCStat ^ Exponent

I haven't seen where the value of the variable Exponent is reset to any other value, than just one...

Level 15

thanks for the comments and im glad you got it working. as far as the exponent

variable...you may be right, it may be useless. id need to go through the code again. fact of the

matter is i wrote this on the fly with no care for "being neat." just wrote it in a few hours to get the tool, never

intended for it, or the code, to go public. i may have changed my thinking and forgotten to clean that up.

that said, the way i dimensioned the variables is okay. i could have set them at runtime, but my way was just quicker.

as far as the on error resume next...yup, crutch to just plow through. if this were a formal piece of code

i would have done things differently, same with the events, but the beauty of it is

you can tweak it now.

About the Author
Who am I? • I met Robert Frost at the end of the road less traveled, and then pointed him in the right direction. • Einstein asked me to define "Up," and I did. • I cliff dive from airplanes. • On Christmas, Santa comes to me for gifts. • I play three-cushion billiards with one hand. • Lions ask for my protection (I speak Lion). • Bobby Fischer and I came to a stalemate while playing chess. • I have literally given a woman the shirt off of my back. • I have also helped an old lady cross the street. • I know what a dangling participle is. • Mozart bequeathed his Requiem to me, and I corrected it. • I was thrown out of an Eric Clapton concert twice in the same night for drawing too much attention to myself. • I am a verbose minimalist. • I am Bronx. Who are you?