VB.NET CreateInstance of structure - arrays

I wrote the following code:
Public Class Form1
Private Structure udtThing
Dim SomeText As String
Dim SomeElements() As String
Public Shared Function CreateInstance() As udtThing
Dim result As New udtThing
result.SomeText = String.Empty
ReDim result.SomeElements(2)
result.SomeElements(0) = String.Empty
result.SomeElements(1) = String.Empty
result.SomeElements(2) = String.Empty
Return result
End Function
End Structure
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim nThings() As udtThing
nThings = Array.CreateInstance(GetType(udtThing), 10)
End Sub
End Class
I partly works, nThings becomes an array of 11 udtThings.
But .SomeElements is not redimmed to 3 strings of String.Empty, but it is "Nothing" instead.
Does anybody see where I went wrong?
Thank you very much!

By design, a Redim is required. Array.CreateInstance() isn't going to perform that operation, it can't guess what size is required. You'll have to help:
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim nThings(10) As udtThing
For ix As Integer = 0 To UBound(nThings)
nThings(ix) = udtThing.CreateInstance()
Next
End Sub

Related

Issue with Array - NullReferenceException was unhandled - VB.NET

I am basically trying to create an array to export checked items onto a word document. But I am getting an error saying
"Object reference not set to an instance of object."
and
"Referenced 'SelectedMutualFunds' has a value of 'Nothing'
Below is my code:
Public Class ExportFunds
Public SelectedMutualFunds() As String
Private Sub ExportFundOkButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExportFundOkButton.Click
Dim i As Integer
Dim array_Counter As Integer
array_Counter = 0
For i = 0 To ExportFundCheckedListBox.Items.Count() - 1
If ExportFundCheckedListBox.GetItemCheckState(i) = CheckState.Checked Then
SelectedMutualFunds(array_Counter) = ExportFundCheckedListBox.Items(i).ToString
array_Counter += 1
End If
Next
Me.Close()
End Sub
Can someone please help me solve this issue?
You need to provide length to your string array
Public SelectedMutualFunds() As String
to the following within ExportFundOkButton_Click before you use, preferably just before the for loop.
Redim SelectedMutualFunds(ExportFundCheckedListBox.Items.Count() - 1)
You can get this down to a one-liner and fix the NullReference exception at the same time:
Private Sub ExportFundOkButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExportFundOkButton.Click
SelectedMutualFunds = ExportFundCheckedListBox.Items.Where(Function(i) i.CheckState = CheckState.Checked).Select(Function(i) i.ToString()).ToArray()
Me.Close()
End Sub
Or, slightly longer but easier to read:
Private Sub ExportFundOkButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExportFundOkButton.Click
SelectedMutualFunds = ExportFundCheckedListBox.Items.
Where(Function(i) i.CheckState = CheckState.Checked).
Select(Function(i) i.ToString()).
ToArray()
Me.Close()
End Sub

Visual Basic 2013 How to Ping all IPs in ListBox

Hello this is my first time posting here. well to the point, I have pieced together
a app that is able to load a text file, add on the fly to a "listbox", now all i need it to Ping all ips in said "listbox" but i get an error and stops working. need help to ping all ips.
Private Sub Go_Click(sender As Object, e As EventArgs) Handles Go.Click
If ListBox1.Items.Count <= 0 Then
MsgBox("Please Add at Least One IP or Website!")
Exit Sub
End If
For l_index As Integer = 0 To ListBox1.Items.Count - 1 'THIS IS WHERE CODE STOPS WORKING, NEED "MAGIC CODE" HERE
Dim lines As String = CStr(ListBox1.Items(l_index))
BackgroundWorker1.RunWorkerAsync(lines)
Next
End Sub
I am using Openfiledialog to load Text File to listbox1 and backgroundworker to do the ping. I am using
Imports System.Net
Imports System.Net.NetworkInformation
Imports System.Threading
Imports System.IO
What i want to do is once that all "IPs" are in the listbox i want to press Go to Ping all Ips. How can i get this to work?
Imports System.Net
Imports System.Net.NetworkInformation
Imports System.Threading
Imports System.IO
Public Class Main
Private Sub AboutUpingToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles AboutUpingToolStripMenuItem.Click
AboutUping.Show()
End Sub
Private Sub MenuStrip1_ItemClicked(sender As Object, e As ToolStripItemClickedEventArgs) Handles MainMenu.ItemClicked
End Sub
Private Sub QuitToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles QuitToolStripMenuItem.Click
Application.Exit()
End Sub
Private Sub OpenFileDialog1_FileOk(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog1.FileOk
Dim lines = File.ReadAllLines(OpenFileDialog1.FileName)
ListBox1.Items.AddRange(lines)
End Sub
Private Sub OpenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OpenToolStripMenuItem.Click
OpenFileDialog1.ShowDialog()
End Sub
Private Sub NewToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles NewToolStripMenuItem.Click
Create.Show()
End Sub
Private Sub ToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles ToolStripMenuItem1.Click
End Sub
Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Go_Click(sender As Object, e As EventArgs) Handles Go.Click
If ListBox1.Items.Count <= 0 Then
MsgBox("Please Add at Least One IP or Website!")
Exit Sub
End If
For l_index As Integer = 0 To ListBox1.Items.Count - 1 'THIS IS WHERE CODE STOPS WORKING, NEED "MAGIC CODE" HERE
Dim lines As String = CStr(ListBox1.Items(l_index))
BackgroundWorker1.RunWorkerAsync(lines)
Next
End Sub
Private Sub CloseFileToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles CloseFileToolStripMenuItem.Click
TextBox1.Clear()
ListBox1.Items.Clear()
End Sub
Private Sub cmdADD_Click(sender As Object, e As EventArgs) Handles cmdADD.Click
Dim myitem
myitem = txtADD.Text()
ListBox1.Items.Add(myitem)
txtADD.Clear()
End Sub
Private Sub cmdRemove_Click(sender As Object, e As EventArgs) Handles cmdRemove.Click
For a As Int32 = ListBox1.SelectedItems.Count - 1 To 0 Step -1
For i As Int32 = ListBox1.Items.Count - 1 To 0 Step -1
'-- compare the value of the select item to any given item in the list.
If ListBox1.SelectedItems(a) = ListBox1.Items(i) Then
'-- remove the item by the index we found
ListBox1.Items.RemoveAt(i)
'-- exit the inner for loop
Exit For
End If
Next
Next
End Sub
Private Sub cmdClear_Click(sender As Object, e As EventArgs) Handles cmdClear.Click
ListBox1.Items.Clear()
End Sub
Private Sub HelpToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles HelpToolStripMenuItem.Click
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim lines = DirectCast(e.Argument, String())
Dim Ping As New Ping
Dim replies As New List(Of PingReply)
For Each ip In lines
Dim reply = Ping.Send(ip)
replies.Add(reply)
Next
e.Result = replies
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Dim sb As New System.Text.StringBuilder
Dim replies = DirectCast(e.Result, List(Of PingReply))
For Each reply In replies
Dim index As Integer
index += 1
sb.Append("Ping ").Append(index).Append(": ").Append(reply.Address).Append(" ").Append(reply.RoundtripTime).Append(" ms")
sb.AppendLine()
Next
TextBox1.Text = sb.ToString
End Sub
End Class
Your error is here
one of your ping fails and results an exception which is returned to the completed event handler and when the handler tries to get the result the TargetInvocationException exception is thrown
solution is to check the error
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
If e.Error Is Nothing Then
Dim sb As New System.Text.StringBuilder
Dim replies = DirectCast(e.Result, List(Of PingReply))
For Each reply In replies
Dim index As Integer
index += 1
sb.Append("Ping ").Append(index).Append(": ").Append(reply.Address).Append(" ").Append(reply.RoundtripTime).Append(" ms")
sb.AppendLine()
Next
TextBox1.Text = sb.ToString
Else
'error handling
End If
End Sub
additionally you may need to handle the actual error to protect rest of the ping replies otherwise because of 1 failure whole batch of result will be lost
For Each ip As String In lines
Try
Dim reply As PingReply = Ping.Send(ip)
replies.Add(reply)
Catch ex as PingException
'error handling
End Try
Next
Update
another point of error,
For l_index As Integer = 0 To ListBox1.Items.Count - 1
Dim lines As String = CStr(ListBox1.Items(l_index))
BackgroundWorker1.RunWorkerAsync(lines)
Next
since you are passing as single string from the method above and in the method below you are attempting to cast as string array so it fails, change it like this
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim ip = DirectCast(e.Argument, String)
Dim Ping As New Ping
Dim replies As New List(Of PingReply)
Try
Dim reply As PingReply = Ping.Send(ip)
replies.Add(reply)
Catch ex as PingException
'error handling
End Try
e.Result = replies
End Sub
also advised to use Option Strict On to reduce some type checking errors
Thanks!Got it to work! Sending "Listbox1" to array
Private Sub Go_Click(sender As Object, e As EventArgs) Handles Go.Click
Dim lines() As String = ListBox1.Items.OfType(Of String)().ToArray()
BackgroundWorker1.RunWorkerAsync(lines)
End Sub
Now it works app does not crash.

Using listbox to access 2D array VB

So I am trying to use a listbox to access variables in my 2D array. I am unsure what is the best way to do this. Right now I am using the selectedindex of the listbox to access it but I am only seeing the second dimension being show in my message box. Any help would be appreciated.
Option Explicit On
Option Strict On
Option Infer Off
Public Class Form1
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
lstInventory.Items.Add("Hand Grenade")
lstInventory.Items.Add("9mm Ammo Box")
lstInventory.Items.Add(".40 Ammo Box")
lstInventory.SelectedIndex = 0
End Sub
Dim dblInventoryItem(,) As Double = {{10.99, 5},
{5.99, 10},
{8.99, 8}}
Private Sub btnCheck_Click(sender As System.Object, e As System.EventArgs) Handles btnCheck.Click
Dim intRow As Integer = lstInventory.SelectedIndex
MessageBox.Show(dblInventoryItem(intRow, 1).ToString)
End Sub
End Class
You don't want to use a multi-dimensional array here.
The OOP way to do this would be to define inventory item as its own class or structure, and use instances to both populate your list box and store the inventory item price and quantity.
Something like:
Public Class Form1
Structure InventoryItem
Public Sub New(ByVal itmName As String, ByVal itmPrice As Double, ByVal itmQty As Integer)
Name = itmName : Price = itmName : Quantity = itmQty
End Sub
Dim Name As String
Dim Price As Double
Dim Quantity As Integer
End Structure
Dim invItems As New List(Of InventoryItem)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
invItems.Add(New InventoryItem("Hand Grenade", 10.99, 5))
'' ... Add your additional items here
For Each i As InventoryItem In invItems
lstInventory.Items.Add(i.Name)
Next
End Sub
Private Sub btnCheck_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCheck.Click
Dim invItem As InventoryItem = invItems(lstInventoryItems.SelectedIndex)
MessageBox.Show(invItem.Name & "," & invItem.Price & "," & invItem.Quantity)
End Sub
End Class

VB2010 Extract a string of numbers from a string or array

I have a filepath that I would like to pull the starting directory job number from the beginning of the filepath. Except I don't know how to just pull the number string out of the filepath string. (i.e.: filepath= Q:\2456_blah_blah\file.txt - or something) I'd like to just pull '2456' as a string,
then put that number string into TextBox2 I've created on my form.
The code I have so far spits out a '0' instead of the number string desired.
Any help would be much appreciated.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.OpenFileDialog1.FileName = Nothing
If Me.OpenFileDialog1.ShowDialog = System.Windows.Forms.DialogResult.OK Then
Me.TextBox1.Text = Me.OpenFileDialog1.FileName
End If
If GetInfo() = True Then
For Each Xitem In ExcelRowList
Dim lvitem As ListViewItem
lvitem = Me.ListView1.Items.Add(Xitem.C1)
Next
End If
'''Here is where I call the GetFilePathOnly function
TextBox2.Text = GetFilePathOnly(TextBox1.Text)
End Sub
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
End Sub
'''Section below is what defines my number string, then I call it above for the Button1.Click operation(towards the end)
Private Function GetFilePathOnly(ByVal Fullpath As String) As String
Dim File As String = Fullpath
Dim number As Double = Val(File)
Dim outcome As String = number.ToString 'File.Substring(0, File.LastIndexOf("\") + 1)
Return outcome
End Function
Thanks
You could also use a regular expression easily.
Dim numRegex As New Regex("\d+")
Dim number As String = numRegex.Match("Q:\2456_blah_blah\file.txt").Value
A lazy way would be to use Split:
TextBox2.Text = path.Split("\")(1).Split("_")(0)

How to modify a value in the array in visual basic

The following is the code which I am using for creating a two dimensional array
Public Class frmGrades
Private Score As Dictionary(Of String, String) = New Dictionary(Of String, String)
Private Sub cmdApply_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdApply.Click
Static intNumber As Integer
ReDim Preserve Score(1, intNumber)
Score(0, intNumber) = txtStudent.Text
Score(1, intNumber) = txtGrade.Text
hsbStudent.Maximum = intNumber
hsbStudent.Value = intNumber
intNumber = intNumber + 1
txtGrade.Clear()
txtStudent.Clear()
txtStudent.Focus()
End Sub
Private Sub hsbStudent_Scroll(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles hsbStudent.Scroll
txtStudent.Text = Score(0, hsbStudent.Value)
txtGrade.Text = Score(1, hsbStudent.Value)
End Sub
Private Sub cmdFirst_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdFirst.Click
txtStudent.Text = Score(0, hsbStudent.Minimum)
txtGrade.Text = Score(1, hsbStudent.Minimum)
End Sub
Private Sub cmdLast_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdLast.Click
txtStudent.Text = Score(0, hsbStudent.Maximum)
txtGrade.Text = Score(1, hsbStudent.Maximum)
End Sub
**Private Sub CmdEdit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CmdEdit.Click
If Score.ContainsKey(txtStudent.Text) Then
Score.Item(txtStudent.Text) = txtGrade.Text
Else
Score.Add(txtStudent.Text, txtGrade.Text)
End If
End Sub
End Class**
Now I would like to edit the grade text box which should also change the grade in the array. Any idea on how could this be done.
UPDATE:
OK, I see the code has a little more now and the problem is more clear as well as the need for a different approach. I rewrote your code. See if this works for you:
Public Class frmGrades
Public Class StudentGrade
Public Name As String
Public Grade As String
End Class
Private Score As List(Of StudentGrade) = New List(Of StudentGrade)
Private Sub cmdApply_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdApply.Click
AddStudent()
End Sub
Private Sub hsbStudent_Scroll(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles hsbStudent.Scroll
Update(hsbStudent.Value - 1) 'lists are zero-based
End Sub
Private Sub cmdFirst_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdFirst.Click
Update(0)
End Sub
Private Sub cmdLast_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdLast.Click
Update(hsbStudent.Maximum - 1)
End Sub
Private Sub AddStudent()
Dim nm As New StudentGrade
nm.Name = txtStudent.Text
nm.Grade = txtGrade.Text
Score.Add(nm)
hsbStudent.Minimum = 1
hsbStudent.Maximum = Score.Count
hsbStudent.Value = Score.Count
txtGrade.Clear()
txtStudent.Clear()
txtStudent.Focus()
End Sub
Private Sub Update(i As Integer)
txtStudent.Text = Score(i).Name
txtGrade.Text = Score(i).Grade
End Sub
Private Sub CmdEdit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CmdEdit.Click
Dim index As Integer = -1, cnt As Integer = 0
For Each nm As StudentGrade In Score
If nm.Name.ToLower = txtStudent.Text.ToLower Then
index = cnt
Exit For
End If
cnt += 1
Next
If index = -1 Then
AddStudent()
Else
Score(index).Name = txtStudent.Text
Score(index).Grade = txtGrade.Text
hsbStudent.Value = index + 1
End If
End Sub
End Class
With this code you can expand the class StudentGrade to contain whatever you need to store. The list, contrary to dictionary, allow you to use index values as well.

Resources