Can you populate a Dataset with User Input? - vb.net

I need to store user input (entered from the console) to a Dataset in Visual Basic. Is this possible? I can't seem to find any information online about doing so. If anyone can point me in the right direction, that would be awesome!
EDIT: The columns in my table are FirstName, LastName, State, etc. in a table named Person.
The start of the application for the console: "Enter FirstName: ", then "EnterLastName: " then etc.
The values for the user inputs are stored in there specific variables eg. firstName, lastName, so I want to know how I can put those variables in a dataset.
Thank you.

Here is a short and basic example. Most likely it will not directly work for what you need as you will probably want to use a typed dataset among other things. Since your question does not specify a question regarding the code you may have already tried, this all I am going to provide.
Option Strict On
Module Module1
Sub Main()
Dim ds As DataSet = CreateNewDataSet()
Dim entries As New List(Of String())
For i = 1 To 3
Console.WriteLine($"Enter first column value for row {i.ToString}:")
Dim input1 As String = Console.ReadLine()
Console.WriteLine($"Enter second column value for row {i.ToString}:")
Dim input2 As String = Console.ReadLine()
entries.Add({input1, input2})
Next
entries.ForEach(Sub(x) ds.Tables(0).Rows.Add(x))
End Sub
Private Function CreateNewDataSet() As DataSet
Dim ds As New DataSet()
Dim dt As New DataTable()
Dim col1 As New DataColumn("Column1")
Dim col2 As New DataColumn("Column2")
dt.Columns.AddRange({col1, col2})
ds.Tables.Add(dt)
Return ds
End Function
End Module

If you don't know column names, you can use reflection to get names of properties of input objects. You can also use attributes to filter properties. Use DataTable.LoadDataRow method to load an array as row.
here is an example to how to do it dynamically:
Dim input As New List(Of Object)
For i = 0 To 5
Console.WriteLine("enter your first name and last name:")
input.Add(New With {.First = Console.ReadLine, .Last = Console.ReadLine})
Next
Dim myData As New DataSet
Dim table = myData.Tables.Add()
table.Columns.AddRange(input.First.GetType.GetProperties.Select(Function(p) New DataColumn(p.Name)).ToArray)
input.ForEach(Function(o) table.LoadDataRow(o.GetType.GetProperties.Select(Function(p) p.GetValue(o, Nothing)).ToArray, False))
For Each row In table.Rows
Console.WriteLine("first:{0} ,Last:{1}", row(0), row(1))
Next

Related

2-D array from txt in VB.NET

I am needing to create a code that is versatile enough where I can add more columns in the future with minimum reconstruction of my code. My current code does not allow me to travel through my file with my 2-D array. If I was to change MsgBox("map = "+ map(0,1) I can retrieve the value easily. Currently all I get in the code listed is 'System.IndexOutOfRangeException' and that Index was outside the bounds of the array. My current text file is 15 rows (down) and 2 columns (across) which puts it at a 14x1. they are also comma separated values.
Dim map(14,1) as string
Dim reader As IO.StreamReader
reader = IO.File.OpenText("C:\LocationOfTextFile")
Dim Linie As String, x,y As Integer
For x = 0 To 14
Linie = reader.ReadLine.Trim
For y = 0 To 1
map(x,y) = Split(Linie, ",")(y)
Next 'y
Next 'x
reader.Close()
MsgBox("map = " + map(y,x))``
Here's a generic way to look at reading the file:
Dim data As New List(Of List(Of String))
For Each line As String In IO.File.ReadAllLines("C:\LocationOfTextFile")
data.Add(New List(Of String)(line.Split(",")))
Next
Dim row As Integer = 1
Dim col As Integer = 10
Dim value As String = data(row)(col)
This is the method suggested by Microsoft. It is generic and will work on any properly formatted comma delimited file. It will also catch and display any errors found in the file.
Using MyReader As New Microsoft.VisualBasic.
FileIO.TextFieldParser(
"C:\LocationOfTextFile")
MyReader.TextFieldType = FileIO.FieldType.Delimited
MyReader.SetDelimiters(",")
Dim currentRow As String()
While Not MyReader.EndOfData
Try
currentRow = MyReader.ReadFields()
Dim currentField As String
For Each currentField In currentRow
MsgBox(currentField)
Next
Catch ex As Microsoft.VisualBasic.
FileIO.MalformedLineException
MsgBox("Line " & ex.Message &
"is not valid and will be skipped.")
End Try
End While
End Using
Essentially what you are asking is how can I take the contents of comma-separated values and convert this to a 2D array.
The easiest way, which is not necessarily the best way, is to return an IEnuemrable(Of IEnumerable(Of String)). The number of items will grow both vertically based on the number of lines and the number of items will grow horizontally based on the values split on a respective line by a comma.
Something along these lines:
Private Function GetMap(path As String) As IEnumerable(Of IEnumerable(Of String)
Dim map = New List(Of IEnumerable(Of String))()
Dim lines = IO.File.ReadAllLines(path)
For Each line In lines
Dim row = New List(Of String)()
Dim values = line.Split(","c)
row.AddRange(values)
map.Add(row)
Next
Return map
End Function
Now when you want to grab a specific cell using the (row, column) syntax, you could use:
Private _map As IEnumerable(Of IEnumerable(Of String))
Private Sub LoadMap()
_map = GetMap("C:/path-to-map")
End Sub
Private Function GetCell(row As Integer, column As Integer) As String
If (_map Is Nothing) Then
LoadMap()
End If
Return _map.ElementAt(row).ElementAt(column)
End Function
Here is an example: https://dotnetfiddle.net/ZmY5Ki
Keep in mind that there are some issues with this, for example:
What if you have commas in your cells?
What if you try to access a cell that doesn't exist?
These are considerations you need to make when implementing this in more detail.
You can consider the DataTable class for this. It uses much more memory than an array, but gives you a lot of versatility in adding columns, filtering, etc. You can also access columns by name rather than index.
You can bind to a DataGridView for visualizing the data.
It is something like an in-memory database.
This is much like #Idle_Mind's suggestion, but saves an array copy operation and at least one allocation per row by using an array, rather than a list, for the individual rows:
Dim data = File.ReadLines("C:\LocationOfTextFile").
Select(Function(ln) ln.Split(","c)).
ToList()
' Show last row and column:
Dim lastRow As Integer = data.Count - 1
Dim lastCol As Integer = data(row).Length - 1
MsgBox($"map = {data(lastRow)(lastCol)}")
Here, assuming Option Infer, the data variable will be a List(Of String())
As a step up from this, you could also define a class with fields corresponding to the expected CSV columns, and map the array elements to the class properties as another call to .Select() before calling .ToList().
But what I really recommend is getting a dedicated CSV parser from NuGet. While a given CSV source is usually consistent, more broadly the format is known for having a number of edge cases that can easily confound the Split() function. Therefore you tend to get better performance and consistency from a dedicated parser, and NuGet has several good options.

how to increase datatable's name number in vb.net

I know, how to increase integer, string by for statement
but I want know how to change the name by 'for ~next' statement.
For example,
Dim row_sort1 As DataTable = rows1.CopyToDataTable
Dim row_sort2 As DataTable = rows2.CopyToDataTable
Dim row_sort3 As DataTable = rows3.CopyToDataTable
Dim row_sort4 As DataTable = rows4.CopyToDataTable
Dim row_sort5 As DataTable = rows5.CopyToDataTable
Dim row_sort6 As DataTable = rows6.CopyToDataTable
Dim row_sort7 As DataTable = rows7.CopyToDataTable
I had coding like this,, bad cording So I want change by 'for ~next' statement.
I want increase the datatable name's number (1~7)
how can reflect in this coding. I want fix my coding more simple and useful.
I need your help
thank you
I assume you have a Collection of Rows which is your master where you want to copy from.
I have a similiar approach like OSKM. Better use a list collection than an array.
To access tables afterwards in the collection you can use Linq.
' Given master rowcollection
Dim masterRow As EnumerableRowCollection(Of DataRow)
' Empty table collection
Dim tableList As New List(Of DataTable)
For t As Integer = 0 To 6
' copy Master to a new table
Dim newTable As DataTable = masterRow.CopyToDataTable()
' give the new table a name
newTable.TableName = "Table" & t.ToString
' Add new table to collection
tableList.Add(newTable)
Next
' Access a certain table (i.e. Table5) using Linq
Dim table5 As DataTable = tableList.FirstOrDefault(Function(x) x.TableName = "Table5")
If i understand your question correct the following might help.
'Note your datatables will be named Datatable0 to Datatable6
Dim DTs(6) As DataTable
For i = 0 To 6
DTs(i) = New DataTable
DTs(i).TableName = "Datatable" & i
Next
There is probably better ways but this will work!

How can I populate this dictionary from a textfile?

I am making a quiz for my computer science class and the basic concept is that you have 15 keywords and 15 definitions. All need to be randomly displayed and the correct answer has to appear. The user has to match the correct definition to the keyword twice and then that keyword and definition are not displayed again. When all have been answered twice the quiz is over.
I have stored both my keywords and my definitions in the same file so they don't get out of sync. The text file looks like so:
Keyword1,Definition1
Keyword2,Definition2
Keyword3,Definition3
Keyword4,Definition4
etc (15 lines in total)
Currently I have my dictionary manually created like so:
Const NUMBER_OF_ANSWERS As Integer = 3
Public Class Form1
Dim kv As New Dictionary(Of String, String)
kv.Add("Keyword1", "Definition1")
kv.Add("Keyword2", "Definition2")
kv.Add("Keyword3", "Definition3")
kv.Add("Keyword4", "Definition4")
kv.Add("Keyword5", "Definition5")
kv.Add("Keyword6", "Definition6")
kv.Add("Keyword7", "Definition7")
kv.Add("Keyword8", "Definition8")
kv.Add("Keyword9", "Definition9")
kv.Add("Keyword10", "Definition10")
kv.Add("Keyword11", "Definition11")
kv.Add("Keyword12", "Definition12")
kv.Add("Keyword13", "Definition13")
kv.Add("Keyword14", "Definition14")
kv.Add("Keyword15", "Definition15")
Dim r As New Random
Dim kvRandom As List(Of KeyValuePair(Of String, String)) =
kv.OrderBy(Function() r.Next).ToList
'questions will appear in random order
For Each line As KeyValuePair(Of String, String) In kvRandom
Dim keyword As String = line.Key
Dim correctDefinition As String = line.Value
Dim keywords As New List(Of String)
keywords.Add(keyword)
keywords.AddRange(kv.Keys.Except({keyword}).
OrderBy(Function() r.Next).Take(NUMBER_OF_ANSWERS - 1))
Dim definitionsRandom As List(Of String) =
keywords.Select(Function(x) kv(x)).OrderBy(Function() r.Next).ToList
'TODO: need to write some code here
'display keyword and three possible definitions to the user
'(out of which one is correct)
'answers will also appear in random order
'Check answer against value stored in "correctDefinition"
LabelKeyword.Text = keyword
RadioButtonDef1.Text = definitionsRandom(0)
RadioButtonDef2.Text = definitionsRandom(1)
RadioButtonDef3.Text = definitionsRandom(2)
Next
End Sub
I know that to populate a dictionary from a textfile I do the following:
For Each line As String In IO.File.ReadAllLines("keywords_and_definitions.txt")
Dim parts() As String = line.Split(",")
kv.Add(parts(0), parts(1))
Next
However I am not sure how to change this code to successfully implement this. Thanks to previous help here I was told to do this (by #Neolisk):
set your progress variable to 0 of 14 (number of questions minus 1, indexes are zero based in VB.NET). At first question, display question #0, when user presses Next, increment progress variable. Don't forget to count valid/invalid answers. You may want to store full answer history for a user. If you need mode detail on this one, I think it's worth asking a separate question - provide the functionality you need there.
Again I am not sure how to go about doing this. The above code works wonders it's just I'm not sure how to change the code to populate the dictionary from the text file rather than how I have done it above as it is a requirement that we include our keywords and definitions from a text file.
Maybe I'm not understanding your question, but just mixing the two together should do the trick, no??
Const NUMBER_OF_ANSWERS As Integer = 3
Public Class Form1
Dim kv As New Dictionary(Of String, String)
For Each line As String In IO.File.ReadAllLines("keywords_and_definitions.txt")
Dim parts() As String = line.Split(",")
kv.Add(parts(0), parts(1))
Next
Dim r As New Random
...
Or am I not understanding your question?
Also, I'll give you the hint, since this is homework, that the Dim parts() As String could be moved outside of your loop.
Hopw this is what you were asking and it helps set you in the right direction

iteration through TableAdapter of a strongly typed DataSet

We would like to use a For-Next loop to iterate through a TableAdapter row by row and extract the value of a column in each row from a strongly typed DataSet.
The TableAdapter was created in the Visual Studio DataSet designer. The following names have been used for the database objects.
DataSet Name: DataSetSchedules
DataTable Name: DataTableSchedules
TableAdapter Name: DataTableDataAdapterSchedules
This is the coding I have started:
Dim strClassName As String = ""
Dim objAadapter As New DataSetSchedulesTableAdapters.DataTableTableAdapterSchedules
Dim objDataTable As DataSetSchedulesTableAdapters.DataTableTableAdapterSchedules
<I need a way to fill the table with data from> = objAadapter.GetDataByAll(TextBoxSearch)
For Each row As System.Data.DataRow In objDataTable
strClassName = row.ClassName
Next
Please help by supplying the missing coding we will need because I tried using:
Dim objDataTable As DataTableSchedules = objAadapter.GetDataByAll(TextBoxSearch)
and this error was shown:
Error 1 Type 'DataTableSchedules' is not defined.
I realize that I can set up a command object and DataReader but prefer to use objects that are already existing instead. This one has had us stuck for several days now.
If you type DataSetSchedulesTableAdapters.DataTableTableAdapterSchedules is the data retrieving part, you will also have a class called DataSetSchedules that will have the class structure that will hold the data you retrieve and the strongly typed datatables and datarows.
Dim strClassName As String = ""
Dim objAadapter As New Knowledge_Academy.DataSetSchedulesTableAdapters.DataTableTableAdapterSchedules
Dim objDataTable As Knowledge_Academy.DataSetSchedules.DataSetSchedulesDataTable
Dim objDataRow As Knowledge_Academy.DataSetSchedules.DataSetSchedulesRow
objDataTable = objAadapter.GetDataByAll(TextBoxSearch)
For Each objDataRow In objDataTable.Rows
strClassName = objDataRow.ClassName
Next
I am kind of guessing on some of this, but it should be very close.

Display all contents of a "table" created in LINQ in VB.NET

Working from a previous question I asked (which was answered very well).. Ive come across another snag... In the following code
Public Sub Main()
Dim EntireFile As String
Dim oRead As System.IO.StreamReader
oRead = File.OpenText("testschedule.txt")
EntireFile = oRead.ReadToEnd
Dim table As New List(Of List(Of String))
' Process the file
For Each line As String In EntireFile.Split(Environment.NewLine)
Dim row As New List(Of String)
For Each value In line.Split(",")
row.Add(value)
Next
table.Add(row)
Next
' Display all contents of 5th column in the "table" using LINQ
Dim v = From c In table Where c(5) = ""
For Each x As List(Of String) In v
Console.WriteLine(x(0)) ' printing the 1st column only
Next
Console.WriteLine("Value of (2, 3): " + table(1)(2))
End Sub
`
The area where it says Dim v = From c In table Where c(5) = "" the blank quotations will only accept a specific number that its looking for in that column.
For Example:
Dim v = From c In table Where c(5) = "7" Will only show me any 7's in that column. Normally there will be many different values and I want it to print everything in that column, I just cant figure out the command to have it display everything in the selected column
Once again Many MANY Thanks!
If you want to show all rows (to be precise: items in the IEnumerable), just remove the Where condition
Dim v = From c In table
Just a note: table is not a very good name for your list, it leads the thought to SQL. This is just Linq2Objects and you don't query tables you query plain objects with a syntax very similar to Linq2SQL that in turn is heavily inspired by SQL.