Reading to a file line by line multiple choice quiz vb.net - vb.net

I'm trying to create a multi choice quiz that will read questions and answers from a text file and if the RadioButton selected by the user contains text the same as the answer then the mark will increment by 2. I have tried every single loops and techniques but it either reads the last line only (for loop) or doesn't read the text file at all (do until / do while / while). I need help.
This is what I have done so far
Imports System.IO
Public Class Form5
Dim easy As Boolean
Dim medium As Boolean
Dim difficult As Boolean
Dim easytest As New System.IO.StreamReader("he.txt")
Dim lineseasy() As String = IO.File.ReadAllLines("he.txt")
Dim mediumtest As New System.IO.StreamReader("hm.txt")
Dim linesmedium() As String = IO.File.ReadAllLines("hm.txt")
Dim difficulttest As New System.IO.StreamReader("hd.txt")
Dim fulldata As String
Dim mark As Integer = 0
Private Sub Form5_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Label2.Text = Form3.ComboBox1.Text
Label3.Text = Form3.ComboBox2.Text
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
easytest.Read()
Dim counter As Integer = 0
Dim answer As String
While (easytest.Peek() <> -1)
Dim items() As String = lineseasy(1).Split(",")
Label4.Text = items(0)
RadioButton1.Text = items(1)
RadioButton2.Text = items(2)
answer = Str(3)
End While
End Sub
End Class

Why do you want a textfile where if u use Access database or sql database, it will be very simple .
For example, you create a db in either sql or access, create a table in it, create 3 columns, 1st column for question id,2nd column for question and the last one for the answer.Now add your question id(any random alpha-numeric/any string value),questions and answers in specific cells one by one. Now in you vb.net app,add a label(make it invisible) that will contain the question id, add reference to System.Data.SqlClient(for sql database) or System.Data.OleDb(for access). Now use the following code to check if the answer is correct or not ..
'add this code to all 4 radio buttons
Private Sub RadioBtn1_CheckedChanged
'create your connection string
connectionstring.open
Dim cmd as new SqlCommand("Select * from [table name from database-remove brackets if required] where [question id]=#quid and [answer]=#ans",connectionstring) 'use OleDbCommand of access db
cmd.parametres.add("#quid",sqldbtype.varchar).value=label1.text 'use oledbtype for access db
cmd.parametres.add("#ans",sqldbtype.varcha).value=radiobutton1.text 'when adding this code to radio button2, chage radiobutton1.text with radiobutton2.text , when using it in radio button 3 do the same
Dim adapter As New SqlDataAdapter(cmd) ' use oledbdataadapter for access
Dim table As New DataTable
adapter.Fill(table)
If table.Rows.Count() <= 0 Then
msgbox("WRONG ANSWER")
Else
marktext.text = mark.text+2 ' to increase point by 2
'what ever you want to do when the answer is correct
end if
Now, i hope u know how to load the question/question id(i mean the data) from the database...if you don't that please leave a reply and i'll add them

Related

VB.NET DataSet table data empty

I'm trying to use the dataset for a report, but the data is gone when I try to use it. Here is my code for the most part:
Variables:
Dim ResultsDataView As DataView
Dim ResultsDataSet As New DataSet
Dim ResultsTable As New DataTable
Dim SQLQuery As String
Search:
This is where a datagrid is populated in the main view. The data shows up perfectly.
Private Sub Search(Optional ByVal Bind As Boolean = True, Optional ByVal SearchType As String = "", Optional ByVal SearchButton As String = "")
Dim SQLQuery As String
Dim ResultsDataSet
Dim LabelText As String
Dim MultiBudgetCenter As Integer = 0
SQLQuery = "A long and detailed SQL query that grabs N rows with 7 columns"
ResultsDataSet = RunQuery(SQLQuery)
ResultsTable = ResultsDataSet.Tables(0)
For Each row As DataRow In ResultsTable.Rows
For Each item In row.ItemArray
sb.Append(item.ToString + ","c)
Response.Write(item.ToString + "\n")
Response.Write(vbNewLine)
Next
sb.Append(vbCr & vbLf)
Next
'Response.End()
If Bind Then
BindData(ResultsDataSet)
End If
End Sub
Binding Data:
I think this is a cause in the issue.
Private Sub BindData(ByVal InputDataSet As DataSet)
ResultsDataView = InputDataSet.Tables("Results").DefaultView
ResultsDataView.Sort = ViewState("SortExpression").ToString()
ResultsGridView.DataSource = ResultsDataView
ResultsGridView.DataBind()
End Sub
Reporting action:
This is where I am trying to use the table data. But it is showing as nothing.
Protected Sub ReportButton_Click(sender As Object, e As EventArgs) Handles ReportButton.Click
For Each row As DataRow In ResultsTable.Rows
For Each item In row.ItemArray
Response.Write(item.ToString)
Next
Next
End Sub
The reason I'm trying to loop through this data is to both display the data in a gridview on the main view as well as export the data to CSV. If there is a different way to export a SQL query to CSV, I'm open to any suggestions.
There has to be something I can do to get the data from the SQL query to persist through the ReportButton_Click method. I've tried copying the datatable, I've tried global variables, I've tried different methods of looping through the dataset. What am I missing?!
Thank you all in advance.
EDIT
Here is the Page_Load:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Page.IsPostBack Then
'set focus to postback control
Dim x As String = GetPostBackControlName(Page)
If Len(x) > 0 Then
x = x.Replace("$", "_")
SetFocus(x)
End If
End If
If Not IsPostBack Then
ResultsGridView.AllowPaging = False
'Enable Gridview sorting
ResultsGridView.AllowSorting = True
'Initialize the sorting expression
ViewState("SortExpression") = "ID DESC"
'Populate the Gridview
Search()
End If
End Sub
In your search function add this line after the ResultsTable setting
ResultsTable = ResultsDataSet.Tables(0)
Session("LastSearch") = ResultsTable
Then in your report click event handler recover your data from the Session variable
Protected Sub ReportButton_Click(sender As Object, e As EventArgs) Handles ReportButton.Click
ResultsTable = DirectCast(Session("LastSearch"), DataTable)
For Each row As DataRow In ResultsTable.Rows
For Each item In row.ItemArray
Response.Write(item.ToString)
Next
Next
End Sub
You need to read about ASP.NET Life Cycle and understand that every time ASP.NET calls your methods it creates a new instance of your Page class. Of course this means that global page variables in ASP.NET are not very useful.
Also consider to read about that Session object and not misuse it.
What is the difference between SessionState and ViewState?

VB.NET Program is always reading last created textfile

Trying to create a login form,
My coding is currently:
Imports System
Imports System.IO
Public Class frmLogin
Dim username As String
Dim password As String
Dim fileReader As String
Dim folderpath As String
Dim files As Integer
Dim filepath As String
Public Structure info
Dim U As String
Dim P As String
End Structure
Dim details As info
Private Sub btnlogin_Click(sender As Object, e As EventArgs) Handles btnlogin.Click
If txtusername.Text = details.U And txtpassword.Text = details.P Then
MessageBox.Show("Correct!")
frmmenu.Show()
Me.Hide()
Else
MessageBox.Show("wrong")
txtusername.Clear()
txtpassword.Clear()
End If
End Sub
Private Sub btncreate_Click(sender As Object, e As EventArgs) Handles btncreate.Click
frmcreate.Show()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
files = files + 1
filepath = "C:\Users\TheGlove\Desktop\Alex's Program\loginfile" & files & ".txt"
Dim di As DirectoryInfo = New DirectoryInfo("C:\Users\TheGlove\Desktop\Alex's Program")
folderpath = "C:\Users\TheGlove\Desktop\Alex's Program"
files = System.IO.Directory.GetFiles(folderpath, "*.txt").Count
For Each fi In di.GetFiles()
MsgBox(fi.Name)
Dim FILE = System.IO.File.ReadAllLines("C:\Users\TheGlove\Desktop\Alex's Program\loginfile" & files & ".txt")
Dim myArray As String() = FILE
details.U = myArray(0)
details.P = myArray(1)
Next
End Sub
End Class
Button 1 will be merged with btnlogin when i get it working and for now is currently just a seperate button to read each textfile.
When each button is pressed (Button 1 -> btnlogin), only the last created textfile is correct.
By the looks of things, your code does read all the text files, but keeps overwriting details.u and details.p with the value retrieved from each file. So, when the loop gets to the last file, those values are what ends up in the details object.
I'm assuming that you want to read all the usernames and passwords into a list and check the details in the TextBoxes against that list, so .. Your code should probably be something like the code below (see the code comments for an explanation of some of the differences.
Before we get to the code, can give you a couple of pointers.
Firstly, always try to use names that are meaningful. Defining your structure as Info is not as meaningful as it could be. For example, you would be better calling it UserInfo and rather than use P and U, you would be better using Password and UserName. It may not matter so much right now, but when you start writing larger more complex programs, and have to come back to them in 6 months time to update them, info.P or details.P aren't as informative as the suggested names.
Secondly, as #ajd mentioned. Don't use magic strings. Create one definition at the beginning of your code which can be used throughout. Again it makes maintenance much easier if you only have to change a string once instead of multiple times, and reduces the chance of mistakes.
Finally, several of the variables you have defined aren't used in your code at all. Again, at this level, it isn't a major issue, but with large programs, you could end up with a bigger memory footprint than you want.
Dim username As String
Dim password As String
Dim fileReader As String
Dim folderpath As String = "C:\Users\TheGlove\Desktop\Alex's Program"
Dim files As Integer
Dim filepath As String
Public Structure UserInfo
Dim Name As String
Dim Password As String
End Structure
'Change details to a list of info instead of a single instance
Dim userList As New List(Of UserInfo)
Private Sub Btnlogin_Click(sender As Object, e As EventArgs) Handles btnlogin.Click
'Iterate through the list of details, checking each instance against the textboxes
For Each tempUserInfo As UserInfo In userList
If txtusername.Text = tempUserInfo.Name And txtpassword.Text = tempUserInfo.Password Then
MessageBox.Show("Correct!")
frmmenu.Show()
Me.Hide()
'This is here, because after your form has opened an closed, the loop
'that checks usernames and passwords will continue. The line below exits the loop safely
Exit For
Else
MessageBox.Show("wrong")
txtusername.Clear()
txtpassword.Clear()
End If
Next
End Sub
Private Sub Btncreate_Click(sender As Object, e As EventArgs) Handles btncreate.Click
frmcreate.Show()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'clear the list of user details otherwise, if the files are loaded a second time,
'you'll get the same details added again
userList.Clear()
'This line replaces several lines in your code that searches the folder for files
'marching the search pattern
Dim fileList() As FileInfo = New DirectoryInfo(folderpath).GetFiles("loginfile*.txt")
For Each fi As FileInfo In fileList
MsgBox(fi.Name)
Dim userDetails() As String = System.IO.File.ReadAllLines(fi.FullName)
Dim tempInfo As New UserInfo With {.Name = userDetails(0), .Password = userDetails(1)}
'An expanded version of the above line is
'Dim tempInfo As New info
'tempInfo.U = userDetails(0)
'tempInfo.P = userDetails(1)
userList.Add(tempInfo)
Next
files = fileList.Count
End Sub

Carry objreader file being read over from form to form

Okay so I'm making a multiple-choice quiz game for an assignment and I have a form for the list of categories and the actual questions. Because I'm quite new at coding and don't really have a whole lot of time to totally restructure my code in a way that I probably wouldn't understand, instead of adding all the buttons to one buttons "Handles" I just made a sub for each click event.
This is an example of one of these subs:
Public Sub btnMusic_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnMusic.Click
Questions.Show()
Me.Close()
Dim objReader As New System.IO.StreamReader("Music.txt")
End Sub
My text is read by the following structure:
Structure QuizQ
Dim Q As String
Dim A As String
Dim B As String
Dim C As String
Dim D As String
Dim Correct As String
End Structure
I then try to read the lines according to the structure with:
Dim I As Integer
For I = 0 To 5
MyQ(I).Q = objReader.ReadLine
MyQ(I).A = objReader.ReadLine
MyQ(I).B = objReader.ReadLine
MyQ(I).C = objReader.ReadLine
MyQ(I).D = objReader.ReadLine
MyQ(I).Correct = objReader.ReadLine
Next I
and then set the text for all of the buttons to the possible answers like so:
lblQuestion.Text = MyQ(qNum).Q
btnA.Text = MyQ(qNum).A
btnB.Text = MyQ(qNum).B
btnC.Text = MyQ(qNum).C
BtnD.Text = MyQ(qNum).D
But at this point the text isn't displayed on the buttons or where the question should be. I really have no idea what I could do from this point so any help really would be appreciated.
Thank you in advance!

Using a combo box to store items in an array from a text file and then using that array and its components in another form

I'm currently designing an application within visual basic using vb.net. The first form asks for login information and then prompts the next form to select a customer. The customer information is stored in a text file that gets put in an array. I next have a form for the user to display and edit that information. How can I use the array I already created in the previous form in my display and edit form?
Private Sub frmCustomerList_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim sr As StreamReader = File.OpenText("customer.txt")
Dim strLine As String
Dim customerInfo() As String
Do While sr.Peek <> -1
strLine = sr.ReadLine
customerInfo = strLine.Split("|")
cboCustomers.Items.Add(customerInfo(0))
customerList(count) = strLine
count = count + 1
Loop
End Sub
Private Sub cboCustomers_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboCustomers.SelectedIndexChanged
Dim customerInfo() As String
Dim index As Integer = cboCustomers.SelectedIndex
Dim selectedCustomer As String = customerList(index)
customerInfo = selectedCustomer.Split("|")
End Sub
Make the next form require it in the constructor:
Public Class EditCustomer
Public Sub New(customerInfo As String())
InitializeComponent() 'This call is required, do not remove
'Yay! Now you have your info
End Sub
End Class
You'd call it by doing something like...
Dim editForm = New EditCustomerFrom(customerInfo)
editForm.Show()
Alternatively, you could have a property on the form you set.
Dim editForm = New EditCustomerFrom()
editForm.Customer = customerInfo
editForm.Show()
Then inside the Load event of that form, you'd write the logic that would display it looking at that property.
Aside: You should look at maybe defining an object to hold customer info and do some JSON or XML serialization for reading/writing to the file, IMO. This architecture is kind of not good as is....

Cannot get the text of multiple selected items in a VB.NET ListBox because it's of type "datarowview"

I've got listbox1 in VB 2010, which is bound to a data source and displays values from a dataset. I bound it using the Designer - i.e. not via the code. I just selected the datasource in the properties of listbox1.
Now I want to retrieve the selected values. When I leave the listbox as single select, then ListBox1.SelectedValue.ToString does the job - it gives me the text of the selected item.
But I need it to allow multiple selections.
This is my code:
Dim items As ListBox.SelectedObjectCollection
items = ListBox1.SelectedItems
For Each i As String In items
MsgBox(i)
Next
And this is the error I get:
Conversion from type 'DataRowView' to type 'String' is not valid.
I've tried a few different ways to get the values of the selected items but there doesn't seem to be any straightforward way to do it. Is it impossible? Is it necessary to declare a new dataset and fill the listbox programmatically or something?
For Each drv As DataRowView In ListBox1.SelectedItems
MessageBox.Show(drv.Item(0).ToString)
Next
Off the top of my head I think you can do:
Dim items As ListBox.SelectedObjectCollection
items = ListBox1.SelectedItems
For Each i As ListViewItem In items
MsgBox(i.Value.ToString())
Next
Check out my question and answer. It allows you to break out the individual entries from a Database into list boxes.
Add 2 List Boxes and a text box to a form then copy this code, You will have to substitute your own Server and database etc entries.
Imports System
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Collections
Imports System.Data.SqlClient
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' get the data
Dim SQLConnectionString As String = "Data Source=HL605\RIVWARE;Database=RIVWARE;Integrated Security=true;"
Dim mySQLConnection As New SqlConnection(SQLConnectionString)
' Populate the list box using an array as DataSource.
mySQLConnection.Open()
Dim SQLDataTable As New System.Data.DataTable
'Create new DataAdapter
Dim mySQLDataAdapter = New SqlDataAdapter("SELECT * FROM [Rivware].[dbo].[RivetTypes]", mySQLConnection)
mySQLDataAdapter.Fill(SQLDataTable)
ListBox1.DataSource = SQLDataTable
ListBox1.DisplayMember = "RivetType"
' remove validation data from list
Dim Count As Integer
Dim X As Integer
'get the column of data to search for
For Count = 0 To ListBox1.DataSource.Columns.Count - 1
X = InStr(ListBox1.DataSource.Columns.Item(Count).ToString, "Name")
If X <> 0 Then Exit For
Next
' now search for any invalid rows, in that column. those containing "---"
Dim TheTable As DataTable = CType(ListBox1.DataSource, DataTable)
Dim theRow As DataRow() = TheTable.Select()
Dim RowNumber As Integer
For RowNumber = 0 To UBound(theRow) - 1
If theRow(RowNumber).Item(Count).ToString <> "---" Then
' data is OK so transer it to the other listbox
ListBox2.Items.Add(theRow(RowNumber).Item(Count - 1).ToString)
End If
Next
ListBox2.ClearSelected()
End Sub 'NewNew
Private Sub ListBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox2.SelectedIndexChanged
TextBox1.Text = ListBox2.SelectedItem.ToString()
End Sub
End Class 'ListBoxSample3