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:

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:
- From the Build menu, select Build...

- 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) * 8) / 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) * 8) / 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) * 8) / 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) * 8) / 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