Nested List of Custom Object. VB.NET - vb.net-2010

I'm new to VB.net and requires your help.
I've two vb.net Structures, Quotation and FareAsPerVehicleType, Quotation is dependent on FareAsPerVehicleType. I am trying to add VehicleType in Quotation by using the following:
Dim Quot As New Quotation
Dim vT As FareAsPerVehicleType
vT.TypeOfVehicle = "S"
vT.Fare = _raw_Price * vF.Saloon_Factor
Quot.VehicleType.Add(vT)
Public Structure FareAsPerVehicleType
Dim TypeOfVehicle As String
Dim Fare As Decimal
End Structure
Public Structure Quotation
Dim VehicleType As List(Of FareAsPerVehicleType)
Dim Mileage As Decimal
Dim TimeToTravel As Decimal
Dim Pickup As String
Dim Dropoff As String
End Structure
In doing so I am getting the following error.
<"System.NullReferenceException was unhandled">
<" Message=Object reference not set to an instance of an object.">
<" Source=WindowsApplication1">
Please help
Regards

You need to instantiate the collection before you can use it. As is, when you are declaring a new Quotation object, the VehicleType list is set to nothing. Change the declaration line to
Dim VehicleType As New List(Of FareAsPerVehicleType)
Or even better, change to declaration to remove the Dim and replace with Public to show the accessibility of the field.
Public VehicleType As New List(Of FareAsPerVehicleType)
To really make the code shine, you could replace the field with an auto property:
Public Property VehicleType() As New List(Of FareAsPerVehicleType)
Any of these will work to get rid of your error.

Related

vb.net - How to concatenate a variable(trimmed) to another variable to complete its variable name

Needed code is something like this:
Dim myArray(0) As String
Dim ay As String = "ay"
myArr & ay(0) = "asd"
I've tried but did not worked
Dim classlist1(0) As String
Dim classlist2(0) As String
Dim classlist3(0) As String
Dim classlist4(0) As String
Dim count As Integer = 0
For _year As Integer = 1 To 4
("classlist" & _year)(count) = "hi"
count += 1
Next
Any time you see something like this:
Dim classlist1(0) As String
Dim classlist2(0) As String
Dim classlist3(0) As String
' etc.
It's an indication that you're using the wrong data structure. Instead of trying to dynamically build variable names (which isn't really possible in a static language, at least not without some really ugly reflection code with a high potential for runtime errors), just use a collection.
For example, if you want a collection of strings:
Dim classList As New List(Of String)()
And if you want a collection of collections of strings:
Dim classLists As New List(Of List(Of String))()
Then you can reference the nested lists within the parent list. So to add your first "year" of classes:
classLists.Add(new List(Of String))
And add a class to that year:
classLists(0).Add("some value")
As you can see, it starts to get a little difficult to keep track of the data structures. This is where creating custom types and structures becomes very useful. For example, rather than representing a "year" as a list of strings, create an actual Year class. That class can internally hold a list of strings, and other logic/data.
Try Dictionary<TKey, TValue> Class From MSDN.
Dim classLists As New Dictionary(Of String, String)()
'Add items with keys
For _year As Integer = 1 To 4
classLists.Add(String.Format("classlist{0}",_year), "hi")
Next
And you can get value by key later
Dim key As String = "classlist2"
Dim value As String = classLists(key)

List (Of T) as DataGridView.DataSource makes sorting fail

I have read some threads about this "error" but I can't figure out how to solve my problem.
I have a class that looks something like this:
Public Class Person
Public Property Name As String
Public Property PhoneNumber As string
Public Property Age As Integer
Public sub New(ByVal Values As String())
Me.Name = Values(0)
Me.PhoneNumber = Values(1)
Me.Age = Convert.ToInt32(Values(2))
End Sub
End Class
I get my data from a semicolon separated file, and i create a list of Person objects by looping this file and split on semicolon. Like this
Dim PersonsList As New List(Of Person)
For Each line in textfile..........
PersonsList.Add(New Person(line.Split(";")))
Next
When the list is complete, I tell my DataGridView that DataSource is PersonsList.
This works like a charm, but I'm not able to sort the columns.
I found this post amongst many (where the class values are not properties, which mine are) and tried that converting function which did'nt really work in my case. The right amount of rows were created, but all of the columns were blank.
What am I missing?
If you use a datatable as the data source, column sorting is automatically enabled and you can sort the data by any column:
Dim dt As New DataTable
dt.Columns.AddRange(
{
New DataColumn("Name"),
New DataColumn("Phone"),
New DataColumn("Age")
})
For Each s As String In IO.File.ReadAllLines("textfile1.txt")
Dim temprow As DataRow = dt.NewRow
temprow.ItemArray = s.Split(";"c)
dt.Rows.Add(temprow)
Next
DataGridView1.DataSource = dt

Defining the type of a List in vb.net at runtime

I'm creating a class at run time using typebuilder and after I create this class I want to define its type for a list like
dim fooList as new List(of DynamicClassName)
Since this doesn't exist at compile time of course it throws an error. When I generate this type I return the type so I can't do something like
dim newType = createNewType(foobar)
dim fooList as new List(of getType(newType))
How do I assign the type of a List at runtime?
You can create a List(Of T), but AFAIK you won't be able to cast it to a typed object. I've used the String type in the following example.
Dim list As Object = Activator.CreateInstance(GetType(List(Of )).MakeGenericType(New Type() {GetType(String)}))
Debug.WriteLine((TypeOf list Is List(Of String)).ToString())
Output
True
So in your case it would look like this:
Dim newType = createNewType(foobar)
'Creates a List(Of foobar):
Dim list As IList = Ctype(Activator.CreateInstance(GetType(List(Of )).MakeGenericType(New Type() {newType})), IList)
'Creates a BindingList(Of foobar):
Dim bindingList As IBindingList = Ctype(Activator.CreateInstance(GetType(BindingList(Of )).MakeGenericType(New Type() {newType})), IBindingList)
This does not answer your question, but may solve your problem.
Another option would be to use an ArrayList (for which you don't have to assign a type). You can see the details here: http://msdn.microsoft.com/en-us/library/system.collections.arraylist(v=vs.110).aspx.
Here is a basic example:
Dim anyArrayList as new ArrayList()
anyArrayList.add("Hello")
anyArrayList.add("Testing")

VBA Dictionary - Adding an item overwrites all items

I have a Problem with a Dictionary. If I add an Object to the Dictionary, it overwrites the whole containing Items with the added item.
After adding all elements, the Dictionary contains the right number of items, but the items are all the last added item.
For Each shp In pg.Shapes
Dim tmp As New cls_dtyp_link
//Filling tmp with Variables - not Displayed - tmp.link_obj is the Key
If link_dic.Exists(tmp.link_obj) Then
Debug.Print "not added:" & tmp.link_obj
Else
link_dic.Add tmp.link_obj, tmp
End If
Next
The cls_dtyp_link Class:
Public link_ne As String
Public link_obj As String
Public link_ref As Visio.Shape
Public obj_left As String
Public obj_right As String
Public ref_left As Visio.Shape
Public ref_right As Visio.Shape
Public basekey_left As String
Public basekey_right As String
Public root_site_ne_left As String
Public root_site_ne_right As String
Public root_obj_left As String
Public root_obj_right As String
Public ref_root_left As Visio.Shape
Public ref_root_right As Visio.Shape
Public hops As Integer
Public geht_zu_konzentrator As Boolean
Thank you for your help!
The problem comes from the Dim tmp As New cls_dtyp_link statement: what is does is adding a reference to the existing cls_dtyp_link object, it does not instantiate a new one as you would expect. If you want to create a new object, kill the existing one explicitly at the end of your loop: Set cls_dtyp_link = Nothing. Then a new instance will be created every time you re-enter the loop.
Generally, declaring and instantiating in one go is considered bad practice in VBA, because of issues like the one you encountered. I would suggest Dim-ing the object outside the loop, and Set-ting it inside the loop.
Also, have a look here:
VBA: Difference in two ways of declaring a new object? (Trying to understand why my solution works)
I hope that helps!

How does one dynamically declare variables during program execution?

I am using VS 2012.
I can't figure out how to dynamically declare variables while my code is running. I am trying to write a program that pulls data for EMS dispatches off a website. The website updates every several second, and each call that is posted has a unique ID number. I want to use the unique ID number from each dispatch, and declare a new incident variable using that unique id number and add it to a collection of active dispatches. The only part I cant figure out, is how do I declare a variable for each dispatch as it is posted, and name it with its unique ID number?
something like:
Structure Incident
Dim id As Integer
Dim numer As String
Dim date1 As String
Dim time As String
Dim box As String
Dim type As String
Dim street As String
Dim crosstreet As String
Dim location As String
Dim announced As Boolean
Dim complete As Boolean
End Structure
UniqueIDstringfromwebsite = "1234"
Dim (code to get variable declared with unique ID as variable name) as incident
This is my first post, and I cant quite get the codesample to work quite right in the post.
This is my first answer - so you are in good company!
Do you not need to implement a class instead of a structure - that way you can implement a constructor. I don't think you want to create a variable with the ID as it's name, but you should add the ID to the dispatches collection (this is could be a list(of Incident):
e.g.
Public Class Incident
'define private variables
Private _id as integer
Private _number as string
Private _date1 as String
Private _time as String
'etc...
'define public properties
Public Property Number as string
Get
Return _number
End Get
Set (value as string)
_number = value
End Set
End Property
'Repeat for each Public Property
'Implement Constuctor that takes ID
Public Sub New(id as integer)
_id = id
'code here to get incident properties based on id
End Sub
End Class
Hope this helps!
You can use a Dictionary to identify your var:
Dim myVar As New Dictionary(Of Integer, Incident)
UniqueIDstringfromwebsite = 1234
myVar.Add(UniqueIDstringfromwebsite, New Incident)
I don't think you can change the name of a variable with a value dinamically, and sincerily, and don't get when it can be useful.
And, in this way, better turn your structure into a class.