Using the New List command with a Passed Parameter - vb.net

I'm trying to Pass a Field Parameter from my form textbox to a Function to create a New List object from the Data Table parameter I'm passing.
In the following code, the first tmpReadTable shows with no syntax error, but when I try to use the Parm with the Datatable name I'm not sure what I'm missing syntax wise. I'm new to this, thanks in advance!
Updated code below:
Thank you for all the helpful replies...sorry I'm not more experienced, I'm coming from a Visual Foxpro background.
To summarize:
I want to pass in my IMPORT table parameters from my form.
The cImportTable is an empty SQL Table to use to import and validate each CSV file row.
I found this example in Murach's VB book but he leaves out how the LIST is being created from a PRODUCTS table in an earlier exercise. So I thought I could just substitute my passed cImportTable to do the same...that's where I'm stuck and maybe you all know of a better way.
Private Function ReadImportFile(ByVal cImportFile As String, ByVal cGroupID As String, ByVal cControlTable As String, ByVal cImportTable As String)
MessageBox.Show(cImportFile + " " + cGroupID + " " + cControlTable)
If Not File.Exists(cImportFile) Then
MessageBox.Show("File: " + cImportFile + " does not exist - cancelling process.")
Return False
End If
Dim curFileStream As New StreamReader(New FileStream(cImportFile, FileMode.Open, FileAccess.Read))
Dim curImportTable = "NewDataSet." + cImportTable
'Here I'm trying to create a LIST or DATASET using my Empty SQL Import Table and read in each row of the CSV file in the DO WHILE loop
'...I'm coming from Visual Foxpro background so am not sure what I'm missing or what is the standard procedure to do this simple task.
'This line gives me a syntax issue - and I'm not even sure what it's suppose to do, I'm taking it from Murach's VB book example,
'but he leaves out this vital piece of how to create this LIST from a Datatable - or if it's even the right method to use.
Dim tmpReadTable = New List(Of curImportTable)
Do While curFileStream.Peek <> -1
Dim row As String = curFileStream.ReadLine
Dim columns() As String = row.Split(",")
Dim ImportRecord As New curImportTable
ImportRecord.GroupId = columns(0)
ImportRecord.MemberId = columns(1)
Loop
'More Processing after Importing CSV file.....
curFileStream.Close()
'If lNoErrors
Return True
End Function

You are using a variable instead of TYPE on the code line #3 here
' This seems to be ok, no syntax error
Dim tmpReadTable = New List(Of NewDataSet.FO_ImportDataTable)
' The variable below implicitely will be of STRING type
Dim curImportTable = "NewDataSet." + cImportTable.ToString
' This line is not going to work
Dim tmpReadTable = New List(Of curImportTable)
' BUT THIS WILL
Dim x = New List(Of String)
Another issue is that Dim tmpReadTable happened twice in your code! can't re-declare variable. On top you declared it as NewDataSet.FO_ImportDataTable
Besides, I recommend declare all variables like Dim curImportTable as String, this way you can recognize types easier. Option Infer is good when you use anonymous types, LINQ, etc

Related

Convert an unknown structure to an untyped Object in VB.NET

I'd like to convert an unknown basic structure to an Object (no type here).
I'm building a library that will be used by many users to extract data from my system but don't want to do a new function for everyone of them. They have to know what will be the result.
In vb, it is possible to create an Object with some properties and use it as it is a regular Class like so:
Dim myObj as New With { .name = "Matt", .age = "28" }
MsgBox( myObj.name & " is now " & myObj.age & " years old.")
So far, so good.
Next step : my user will give me some instructions that I need to extract data from various DBs, and I've no idea of what the result will be.
What I know after the execution is a list of String containing the columns of the result set and, of course a (set of) rows.
And here is the problem of course
My function (for a single row) so far:
Public Function GetData(ByVal instructions as String) as Object ' User is supposed to know what will be inside, instructions is as XML describing DB, table, query, ...
' Do what is needed to retrieve data
' Here I have a variable cols As List(Of String) ' e.g. ("BP", "NAME", "VAT")
Dim o As New With ???
Return o
End Function
What I've tried: build a fake JSon on the fly, and try to Deserialize to Object.
But even if it seems to work, I (and the user) can't access the property as in my top piece of code like:
MsgBox(o.BP)
I know that I could do
Public Function GetData(Of T As {New})(ByVal instructions as String) As T
Dim o As T
' Use some Reflexion to TryInvokeMember of T
Return o
End Function
But I wanted to remove the hassle to create a class to use my code.
Plus, My librairy will be use in a webservice and the class of the user is then unknown.
One approach could be - to use Dictionary(Of String, Object)
Public Function GetData(instructions as String) As Dictionary(Of String, Object)
Dim data = ' Load data
Dim columns As String() = { "BP", "NAME", "VAT" }
Return columns.ToDictionary(
Function(column) column,
Function(column) data.GetByColumnName(column)
)
End Function
` Usage
Dim result = GetDate("instructions: ['BP', 'NAME']")
' Because user knows it is Integer
Dim bpValue = DirectCast(result.Item("BP"), Integer)
Thanks to #GSerg, #Fabio and a few other searches about ExpandoObject, I did it !
Imports System.Dynamic
Dim o As Object = New ExpandoObject()
For Each col In cols
DirectCast(o, IDictionary(Of String, Object)).Add(col, row.GetString(col))
Next

VB Import variable then use part 1 in dropdown and display part 2 to match selection in part 1

I'm using Visual studio to build a small utility.
I'm importing variables from a text file (this makes my program expandable in the future).
I'm running into a road block trying to split the variables into usable parts.
The text file is set up as such:
Game1:flshflhdlsfsdsfs
Game2:ugdjgndrgbdvdnjd
Game3:gnnereknengievke
And the code I've gathered from searching around trying to understand how I could do this is (It's gone through multiple rewrites but I feel this is probably the closest I've gotten):
Dim value As String = File.ReadAllText("Games.txt")
Dim cut_at As String = ":"
Dim x As Integer = InStr(value, cut_at)
Dim string_before As String = value.Substring(0, x - 2)
Dim string_after As String = value.Substring(x + cut_at.Length - 1)
Games_drp.Items.AddRange(string_before)
When I run a test like this, I get an error that String_before cannot be converted to an object. I tried switching "Dim string_before As String = value.Substring(0, x - 2)" to Dim string_before As Object = value.Substring(0, x - 2), but the dropdown that's supposed to be populated by at least one of the entries before the : has absolutely nothing in it.
Being pretty new at VB and feeling like I've exhausted pretty much every way I could think of searching in google and trying to piece together various bits of information, I figure I'd try asking my own direct question:
How would I go about reading all the lines from a text file, then splitting before the : to fill a combobox, and using a label to display the string after the : matching which ever entry is selected in the dropdown.
Thanks in advance for any help.
EDIT with full code:
Imports System.IO
Public Class Saves_frm
Private Sub Saves_frm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim value As String = File.ReadAllText("Games.txt")
Dim cut_at As String = ":"
Dim x As Integer = InStr(value, cut_at)
Dim string_before As String = value.Substring(0, x - 2)
Dim string_after As String = value.Substring(x + cut_at.Length - 1)
Games_drp.Items.AddRange(string_before)
End Sub
End Class
When run as is, I get an error that 'string_before' can't be converted from a string to an object, but when I make the following change from:
Dim string_before As String = value.Substring(0, x - 2)
to:
Dim string_before As Object = value.Substring(0, x - 2)
The error goes away, but the dropdown remains blank.
It's easier to use File.ReadAllLines, as it returns an array with all the file's lines. Then, you can loop through the lines, splitting each line and adding the result to the ListBox. This should be an example, but feel free to correct any mistakes I made, as I wrote it on my phone and it's been a long time since I used VB.
Dim lines() As String = File.ReadAllLines("file.txt")
For Each line As String In lines
Dim split() As String = line.Split(":"c)
gDic.Add(split(0), split(1))
Next
EDIT: Then, you most certainly want a dictionary that contains the name and the data, check the updated code.
Then, add the names by looping through gDic.Keys. When a name is selected, access its value with gDic("key").

NullReferenceException was unhandled in small loop

Hello I recieve a "nullreferenceexception was unhandled" error when I try to run this code:
For i As Integer = 1 To aantaltags
csvopc(i) = csvtagssplit(17 * i)
csvsql(i) = csvtagssplit(17 * i + 15)
Next
Background:
I read a csv file that I clean up and split into csvtagssplit()
csvopc and csvsql are both declared as string() at the top of the program.
anything dumb I did and I'm not noticing?
replicate it if you want to:
code:
http://pastebin.com/JDPa6FSB
csv:
http://pastebin.com/2e66i9EB
Your problem is in the intial part of your code where you declare the two variables cvsopc and cvssql,
As from your comment you write
Dim csvopc As String()
Dim csvsql As String()
But this only declares the two variables without any dimension.
So when you try to reach csvopc(i) you are effectively referencing a index that doesn't exist
Why use arrays when you don't know the exact size of your elements?.
You can easily switch to a List(Of String) where you can dinamically add elements
Dim csvopc As List(Of String) = new List(Of String)
Dim csvsql As List(Of String) = new List(Of String)
and then in your loop
For i As Integer = 0 To aantaltags - 1
csvopc.Add(csvtagssplit(17 * i))
csvsql.Add(csvtagssplit(17 * i + 15))
Next
A List(Of String) could also be referenced by Index as in
Dim aValue = csvopc(0)
You should step through your code with a debugger in order to inspect the data as the code runs. You could put a breakpoint at a place where everything should be initialized but before the exception happens and then see what the values are.
Which iteration of the loop fails, and what line specifically fails? Put a breakpoint on that line and see what all the values are immediately before the line executes. If this debugging doesn't reveal the error to you, update your post with the data you find during debugging and maybe we can get somewhere.

how to input data into an array from a text file that are vbTab separated?

I am having trouble turning a set of data from a .txt file into arrays, basically, what i have in the text file is:
Eddy vbtab 20
Andy vbtab 30
James vbtab 20
etc..
I want to set up the names as a Names array, and numbers as number array.
Now what I have done is
strFilename = "CustomerPrices.txt"
If File.Exists(strFilename) Then
Dim srReader As New StreamReader(strFilename)
intRecords = srReader.ReadLine()
intRows = intRecords
For i = 0 To intRows - 1
intLastBlank = strInput.IndexOf(vbTab)
strName(intPrices) = strInput.Substring(0, intLastBlank)
dblPrices(intPrices) = Double.Parse(strInput.Substring(intLastBlank + 1))
But when I debug I get a problem "Object Reference not set to an instance of an object"
Can anyone give me some advise?
Thanks
Separate arrays are probably a bad idea here. They group your data by fields, when it's almost always better to group your data by records. What you want instead is a single collection filled with classes of a particular type. Go for something like this:
Public Class CustomerPrice
Public Property Name As String
Public Property Price As Decimal
End Class
Public Function ReadCustomerPrices(ByVal fileName As String) As List(Of CustomerPrice)
Dim result As New List(Of CustomerPrice)()
Using srReader As New StreamReader(fileName)
Dim line As String
While (line = srReader.ReadLine()) <> Nothing
Dim data() As String = line.Split(vbTab)
result.Add(new CustomerPrice() From {Name = data(0), Price = Decimal.Parse(data(1))})
End While
End Using
Return result
End Function
Some other things worth noting in this code:
The Using block will guarantee the file is closed, even if an exception is thrown
It's almost never appropriate to check File.Exists(). It's wasteful code, because you still have to be able to handle the file io exceptions.
When working with money, you pretty much always want to use the Decimal type rather than Double
This code requires Visual Studio 2010 / .Net 4, and was typed directly into the reply window and so likely contains a bug, or even base syntax error.

VB.NET - Load a List of Values from a Text File

I Have a text file that is like the following:
[group1]
value1
value2
value3
[group2]
value1
value2
[group3]
value3
value 4
etc
What I want to be able to do, is load the values into an array (or list?) based on a passed in group value. eg. If i pass in "group2", then it would return a list of "value1" and "value2".
Also these values don't change that often (maybe every 6 months or so), so is there a better way to store them instead of a plain old text file so that it makes it faster to load etc?
Thanks for your help.
Leddo
This is a home work question?
Use the StreamReader class to read the file (you will need to probably use .EndOfStream and ReadLine()) and use the String class for the string manipulation (probably .StartsWith(), .Substring() and .Split().
As for the better way to store them "IT DEPENDS". How many groups will you have, how many values will there be, how often is the data accessed, etc. It's possible that the original wording of the question will give us a better clue about what they were after hear.
Addition:
So, assuming this program/service is up and running all day, and that the file isn't very large, then you probably want to read the file just once into a Dictionary(of String, List(of String)). The ContainsKey method of this will determine if a group exists.
Function GetValueSet(ByVal filename As String) As Dictionary(Of String, List(Of String))
Dim valueSet = New Dictionary(Of String, List(Of String))()
Dim lines = System.IO.File.ReadAllLines(filename)
Dim header As String
Dim values As List(Of String) = Nothing
For Each line As String In lines
If line.StartsWith("[") Then
If Not values Is Nothing Then
valueSet.add(header, values)
End If
header = GetHeader(line)
values = New List(Of String)()
ElseIf Not values Is Nothing Then
Dim value As String = line.Trim()
If value <> "" Then
values.Add(value)
End If
End If
Next
If Not values Is Nothing Then
valueSet.add(header, values)
End If
Return valueSet
End Function
Function GetHeader(ByVal line As String)
Dim index As Integer = line.IndexOf("]")
Return line.Substring(1, index - 1)
End Function
Addition:
Now if your running a multi-threaded solution (that includes all ASP.Net solutions) then you either want to make sure you do this at the application start up (for ASP.Net that's in Global.asax, I think it's ApplicationStart or OnStart or something), or you will need locking. WinForms and Services are by default not multi-threaded.
Also, if the file changes you need to restart the app/service/web-site or you will need to add a file watcher to reload the data (and then multi-threading will need locking because this is not longer confined to application startup).
ok, here is what I edned up coding:
Public Function FillFromFile(ByVal vFileName As String, ByVal vGroupName As String) As List(Of String)
' open the file
' read the entire file into memory
' find the starting group name
Dim blnFoundHeading As Boolean = False
Dim lstValues As New List(Of String)
Dim lines() As String = IO.File.ReadAllLines(vFileName)
For Each line As String In lines
If line.ToLower.Contains("[" & vGroupName.ToLower & "]") Then
' found the heading, now start loading the lines into the list until the next heading
blnFoundHeading = True
ElseIf line.Contains("[") Then
If blnFoundHeading Then
' we are at the end so exit the loop
Exit For
Else
' its another group so keep going
End If
Else
If blnFoundHeading And line.Trim.Length > 0 Then
lstValues.Add(line.Trim)
End If
End If
Next
Return lstValues
End Function
Regarding a possible better way to store the data: you might find XML useful. It is ridiculously easy to read XML data into a DataTable object.
Example:
Dim dtTest As New System.Data.DataTable
dtTest.ReadXml("YourFilePathNameGoesHere.xml")