l have a data source that contains two columns
block_name total_lands
A-0 5
A-1 15
A-2 18
A-3 18
And I have two combo boxes one for the block name and the other for the no of lands
the first one is loaded with the block names
Private Sub LoadItems()
SQL.ExecQuery("SELECT block_name FROM blocks;")
For Each i As DataRow In SQL.DBDTable.Rows
ComboBox1.Items.Add(i("block_name"))
Next
End Sub
I want the second one to be loaded with numbers from 1 to whatever is in the data source row total_lands
For example if the user chose the block name as A-1 I want the second combo box to have the items from 1 to 15 add in it
My code trying to do so
Private Sub LoadNoOfLands()
SQL.AddParam("#blockname", ComboBox1.Text)
SQL.ExecQuery("SELECT totla_lands FROM blocks WHERE total_lands LIKE #blockname;")
For Each no As DataRow In SQL.DBDTable.Rows
Dim lands As Integer = no("block_lands")
'For Each i As Integer In lands
'
'
'Next
Next
End Sub
Load required data at once and use Enumerator.Range to generate collection of numbers for second combobox
Public Class Block
Public ReadOnly Property Name As String
Public ReadOnly Property TotalLands As Integer
Public ReadOnly Property Lands As Integer()
Public Sub New(name As String, totalLands As Intger)
Name = name
TotalLands = totalLands
Lands = Enumerable.Range(1, totalLands).ToArray()
End Sub
End Class
Private Function LoadBlocks() As Block()
Dim query = "SELECT block_name, total_lands FROM table"
Dim rows = SQL.ExecuteQuery(query)
Return rows.AsEnumerable().
Select(Function(row) New Block(row.Field(Of String)("block_name"), row.Field(Of Integer)("total_lands"))).
ToArray()
End Function
Private Sub SetupComboBox()
cmbBlocks.DisplayMemeber = "Name"
cmbBlocks.DataSource = LoadBlocks()
End Sub
Private Sub cmbBlocks_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles cmbBlocks.SelectionChangeCommitted
Dim combobox As ComboBox = DirectCast(sender, ComboBox)
Dim block As Block = DirectCast(combobox.SelectedValue, Block)
cmbLands.DataSource = block.Lands
End
I have come up with a simple answer
Private Sub LoadNoOfLands()
cmbLands.Items.Clear()
SQL.AddParam("#blockname", cmbBlocks.Text)
SQL.ExecQuery("SELECT total_lands FROM blocks WHERE block_name LIKE #blockname;")
If SQL.HasException(True) Then Exit Sub
For Each i As DataRow In SQL.DBDTable.Rows
Dim lands = i("total_lands")
Dim r = 1
For r = 1 To lands
cmbLands.Items.Add(r).ToString()
Next
Next
End Sub
This function just adds number to combobox form 1 to the total_lands value
I created a class for the data.
Public Class Block
Public Property Name As String
Public Property TotalLands As Integer
Public Sub New(BlockName As String, Lands As Integer)
Name = BlockName
TotalLands = Lands
End Sub
Public Overrides Function ToString() As String
Return Name
End Function
End Class
The combo box will call .ToString on the items to determine what to display.
We get the data from the database and add it to the List(Of Block)
Public Function FillBlocksList() As List(Of Block)
Dim lst As New List(Of Block)
Using cn As New SqlConnection("Your connection string"),
cmd As New SqlCommand("Select block_name, total_lands From BlockTable;", cn)
cn.Open()
Using reader = cmd.ExecuteReader
Do While reader.Read
Dim b As New Block(reader.GetString(0), reader.GetInt32(1))
lst.Add(b)
Loop
End Using
End Using
Return lst
End Function
To fill the first combo we get the list then loop through it adding the Block objects to the combo. You would probably call this from Form.Load.
Public Sub FillBlocksCombo()
Dim lst = FillBlocksList()
For Each item In lst
ComboBox1.Items.Add(item)
Next
End Sub
To fill the second combo cast the select item back its underlying type, Block and use the TotalLands property to add the numbers.
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim NumberOfLands = DirectCast(ComboBox1.SelectedItem, Block).TotalLands
For i = 1 To NumberOfLands
ComboBox2.Items.Add(i.ToString)
Next
End Sub
Related
I'm trying to write the array persons to a file and read it and have no clue on how to go about it. Here's my code:
Public Class Form1
Structure Person
Public name As String
Public height As Integer
Public weight As Double
End Structure
Dim persons(49) As Person
Dim arraySize As Integer = 0
Private Sub submitBtn_Click(sender As Object, e As EventArgs) Handles submitBtn.Click
If arraySize < 50 Then
Dim Name As String
Dim Height As Integer
Dim Weight As Double
Name = nameTxt.Text
Height = CInt(heightTxt.Text)
Weight = CDbl(weightTxt.Text)
nameTxt.Text = Nothing
heightTxt.Text = Nothing
weightTxt.Text = Nothing
arraySize += 1
persons(arraySize).name = Name
persons(arraySize).height = Height
persons(arraySize).weight = Weight
Else
MsgBox("The list of people is full now. You may no longer enter new people.")
End If
End Sub
Private Sub saveBtn_Click(sender As Object, e As EventArgs) Handles saveBtn.Click
End Sub
Private Sub readBtn_Click(sender As Object, e As EventArgs) Handles readBtn.Click
End Sub
End Class
Any help on how to code this would be appreciated. Thank you!
I tried coding it to save the array persons (which is linked to the structure Person) to a file, but the app freezes, and i am not sure how to get around it.
try to use list :
Public Class Form1
<Serializable()> Structure Person
Public name As String
Public height As Integer
Public weight As Double
End Structure
dim persons As List(Of Person)
Private Sub submitBtn_Click(sender As Object, e As EventArgs) Handles submitBtn.Click
If persons.length < 50 Then
Dim Name As String
Dim Height As Integer
Dim Weight As Double
Name = nameTxt.Text
Height = CInt(heightTxt.Text)
Weight = CDbl(weightTxt.Text)
nameTxt.Text = Nothing
heightTxt.Text = Nothing
weightTxt.Text = Nothing
person.name = Name
person.height = Height
person.weight = Weight
persons.add(person)
Else
MsgBox("The list of people is full now. You may no longer enter new people.")
End If
End Sub
Private Sub saveBtn_Click(sender As Object, e As EventArgs) Handles saveBtn.Click
Using fs As New IO.FileStream("d:\backup\persons.dat", IO.FileMode.Create)
Dim formatter As New BinaryFormatter
formatter.Serialize(fs, persons)
End Using
End Sub
Private Sub readBtn_Click(sender As Object, e As EventArgs) Handles readBtn.Click
Using fs As New IO.FileStream("d:\backup\persons.dat", IO.FileMode.Open)
Dim formatter As New BinaryFormatter
persons = DirectCast(formatter.Deserialize(fs), List(Of person))
End Using
End Sub
dont forget to add <Serializable()> in front of struc definition.
I have to make a application that organizes a list of runners and their teams. In the following text file, I have to remove the top half of the text file (the top half being the listed teams) and display only the bottom half (the runners)in a listbox item.
The Text file:
# School [School Code|School Name|Coach F-Name|Coach L-Name|AD F-Name|AD L Name]
WSHS|Worcester South High School|Glenn|Clauss|Bret|Zane
WDHS|Worcester Dorehty High School|Ellsworth|Quackenbush|Bert|Coco
WBCHS|Worcester Burncoat High School|Gail|Cain|Kevin|Kane
QRHS|Quabbin Regional High School|Bob|Desilets|Seth|Desilets
GHS|Gardner High School|Jack|Smith|George|Fanning
NBHS|North Brookfield High School|Hughe|Fitch|Richard|Carey
WHS|Winchendon High School|Bill|Nice|Sam|Adams
AUBHS|Auburn High School|Katie|Right|Alice|Wonderland
OXHS|Oxford High School|Mary|Cousin|Frank|Daughter
# Roster [Bib #|School Code|Runner's F-Name|Runner's L-Name]
101|WSHS|Sanora|Hibshman
102|WSHS|Bridgette|Moffitt
103|WSHS|Karine|Chunn
104|WSHS|Shanita|Wind
105|WSHS|Fernanda|Parsell
106|WSHS|Albertha|Baringer
107|WSHS|Carlee|Sowards
108|WDHS|Maisha|Kleis
109|WDHS|Lezlie|Berson
110|WDHS|Deane|Rocheleau
111|WDHS|Hang|Hodapp
112|WDHS|Zola|Dorrough
113|WDHS|Shalon|Mcmonigle
I have some code that reads each row from the text file as an array and uses boolean variables to determine where to end the text file. This worked with displaying only the teams, which I've managed to do. But I now need to do the opposite and display only the players, and I'm a bit stumped.
My Code:
Private Sub btnLoadTeams_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoadTeam.Click
' This routine loads the lstTeam box from an ASCII .txt file
' # School [School Code | Name | Coach F-Name| Coach L-Name | AD F-Name | AD L-Name]
Dim strRow As String
Dim bolFoundCode As Boolean = False
Dim bolEndCode As Boolean = False
Dim bolFoundDup As Boolean = False
Dim intPosition As Integer
Dim intPosition2 As Integer
Dim strTeamCodeIn As String
Dim textIn As New StreamReader( _
New FileStream(txtFilePath.Text, FileMode.OpenOrCreate, FileAccess.Read))
' Clear Team listbox
lstTeam.Items.Clear()
btnDeleteRunner.Enabled = True
Do While textIn.Peek <> -1 And Not bolEndCode
Me.Refresh()
strRow = textIn.ReadLine.Trim
If Not bolFoundCode Then
If "# SCHOOL " = UCase(Mid(strRow, 1, 9)) Then
bolFoundCode = True
End If
Else
If Mid(strRow, 1, 2) <> "# " Then
For Each item As String In lstTeam.Items
intPosition = InStr(1, strRow, "|")
strTeamCodeIn = Mid(strRow, 1, intPosition - 1)
intPosition2 = InStr(1, item, strTeamCodeIn)
If intPosition2 > 0 Then
bolFoundDup = True
MsgBox("Found Duplicate School Code: " & strTeamCodeIn)
End If
Else
bolEndCode = True
Next
If Not bolFoundDup Then
lstTeam.Items.Add(strRow)
Else
lstTeam.Items.Add("DUPLICATE School Code: " & strRow)
lstTeam.Items.Add("Please correct input file and reload teams")
bolEndCode = True
End If
End If
End If
Loop
End Sub
Ive put bolEndCode = True in between the part that reads the mid section of the text file, but all Ive managed to display is the following in the listbox:
# Roster [Bib #|School Code|Runner's F-Name|Runner's L-Name]
Any help or hints on how I would display just the runners to my "lstPlayers" listbox would be greatly appreciated. I'm a beginner programmer and We've only just started learning about reading and writing arrays in my .NET class.
First I made 2 classes, one Runner and one School. These have the properties available in the text file. As part of the class I added a function that overrides .ToString. This is for he list boxes that call .ToString for display.
Next I made a function that reads all the data in the file. This is very simple with the File.ReadLines method.
Then I created 2 variables List(Of T) T stands for Type. Ours Types are Runner and School. I used List(Of T) instead of arrays because I don't have to worry about what the size of the list is. No ReDim Preserve, just keep adding items. The FillList method adds the data to the lists. First I had to find where the schools ended and the runners started. I used the Array.FindIndex method which is a bit different because the second parameter is a predicate. Check it out a bit. Now we know the indexes of the lines we want to use for each list and use a For...Next loop. In each loop an instance of the class is created and the properties set. Finally the new object is added to the the list.
Finally we fill the list boxes with a simple .AddRange and the lists.ToArray. Note that we are adding the entire object, properties and all. The neat thing is we can access the properties from the listbox items. Check out the SelectedIndexChanged event. You can do the same thing with the Runner list box.
Sorry, I couldn't just work with your code. I have all but forgotten the old vb6 methods. InStr, Mid etc. It is better when you can to use .net methods. It makes your code more portable when the boss says "Rewrite the whole application in C#"
Public Class Runner
Public Property BibNum As Integer
Public Property SchoolCode As String
Public Property FirstName As String
Public Property LastName As String
Public Overrides Function ToString() As String
'The listbox will call .ToString when we add a Runner object to determin what to display
Return $"{FirstName} {LastName}" 'or $"{LastName}, {FirstName}"
End Function
End Class
Public Class School
Public Property Code As String
Public Property Name As String
Public Property CoachFName As String
Public Property CoachLName As String
Public Property ADFName As String
Public Property ADLName As String
'The listbox will call .ToString when we add a School object to determin what to display
Public Overrides Function ToString() As String
Return Name
End Function
End Class
Private Runners As New List(Of Runner)
Private Schools As New List(Of School)
Private Function ReadData(path As String) As String()
Dim lines = File.ReadLines(path).ToArray
Return lines
End Function
Private Sub FillLists(data As String())
Dim location = Array.FindIndex(data, AddressOf FindRosterLine)
'The first line is the title so we don't start at zero
For index = 1 To location - 1
Dim SplitData = data(index).Split("|"c)
Dim Schl As New School
Schl.Code = SplitData(0)
Schl.Name = SplitData(1)
Schl.CoachFName = SplitData(2)
Schl.CoachLName = SplitData(3)
Schl.ADFName = SplitData(4)
Schl.ADLName = SplitData(5)
Schools.Add(Schl)
Next
For index = location + 1 To data.GetUpperBound(0)
Dim SplitData = data(index).Split("|"c)
Dim Run As New Runner
Run.BibNum = CInt(SplitData(0))
Run.SchoolCode = SplitData(1)
Run.FirstName = SplitData(2)
Run.LastName = SplitData(3)
Runners.Add(Run)
Next
End Sub
Private Function FindRosterLine(s As String) As Boolean
If s.Trim.StartsWith("# Roster") Then
Return True
Else
Return False
End If
End Function
Private Sub FillListBoxes()
Dim arrRunners As Runner() = Runners.ToArray
Dim arrSchools As School() = Schools.ToArray
ListBox1.Items.AddRange(arrSchools)
ListBox2.Items.AddRange(arrRunners)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim arrRunner = ReadData("Runners.txt")
FillLists(arrRunner)
FillListBoxes()
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
Dim Schl = DirectCast(ListBox1.SelectedItem, School)
TextBox1.Text = Schl.CoachLName
TextBox2.Text = Schl.Code
End Sub
I am stuck and have tried re-writing my code multiple times and cannot figure out a solution. The application has a text file containing items and prices in a sequential access file. The app should display the price corresponding with the item when it is selected from the list box. Each line in the text file contains the item's number followed by a comma and then the price.
I need to define a structure named item. The structure has 2 member variables, a string to store the item number and a decimal storing the price. I also need to declare a class level array with 5 item structure variables. The load even should read the items and prices and store this info in the class-level array. Then it should add the item numbers to the list box.
This is what I have so far but nothing is working.
Option Explicit On
Option Strict On
Option Infer Off
Public Class frmMain
'declare structure with 2 member variables
Structure Item
Public strItemNum As String
Public decPrice As Decimal
End Structure
'declare array for 5 item structure variables
Private items(4) As Item
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Me.Close()
End Sub
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles Me.Load
'declare variables
Dim inFile As IO.StreamReader
Dim strLineofText As String
Dim intSub As Integer
'check if the file exists
If IO.File.Exists("ItemInfo.txt") Then
'open the file
inFile = IO.File.OpenText("ItemInfo.txt")
'read the file
Do Until inFile.Peek = -1 OrElse
intSub = items.Length
strLineofText = inFile.ReadLine.Trim
'add item to list box
lstNumbers.Items.Add(items(intSub).strItemNum)
Loop
'close the file
inFile.Close()
Else
MessageBox.Show("Can't find the ItemInfo.txtfile",
"Kensington Industries",
MessageBoxButtons.OK,
MessageBoxIcon.Information)
End If
End Sub
Private Sub lstNumbers_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstNumbers.SelectedIndexChanged
lblPrice.Text = items(lstNumbers.SelectedIndex).decPrice.ToString("C2")
End Sub
End Class
I think that you need to change the name of Structure. Item can be used in another references.
Try to change the name to itemstr (for example)
Do Until inFile.Peek = -1 OrElse
intSub = items.Length
strLineofText = inFile.ReadLine.Trim
'add item to list box
Dim arr As String() = str.Split(","C)
Dim valitem As New itemstr()
valitem.text = arr(0)
valitem.value = Convert.ToDecimal(arr(1))
lstNumbers.Items.Add(valitem)
Loop
Thanks everyone. I ended up starting over again and trying something different that works finally!
Option Explicit On
Option Strict On
Option Infer Off
Public Class frmMain
'declare structure
Structure Item
Public strItemNum As String
Public decPrice As Decimal
End Structure
'declare class level array
Public itemList(4) As Item
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Me.Close()
End Sub
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles Me.Load
'declare variables
Dim inFile As IO.StreamReader
Dim strLineOfText As String
Dim decPrice As Decimal
Dim strInfo(4, 1) As String
'check to see if the file exists
If IO.File.Exists("ItemInfo.txt") Then
'open the file
inFile = IO.File.OpenText("ItemInfo.txt")
For intRow As Integer = 0 To strInfo.GetUpperBound(0)
'read the line
strLineOfText = inFile.ReadLine
'assign substring from comma to first coloumn
strInfo(intRow, 0) = strLineOfText.Substring(0, strLineOfText.IndexOf(","))
Dim intSep As Integer = strLineOfText.IndexOf(",") + 1
'assign substring after comma to 2nd column
strInfo(intRow, 1) = strLineOfText.Substring(intSep)
'assign first column value to strItemNum variable
itemList(intRow).strItemNum = (strInfo(intRow, 0))
Decimal.TryParse(strInfo(intRow, 1), decPrice)
'assign 2nd columnn value to decPrice variable
itemList(intRow).decPrice = decPrice
'add item to listbox
lstNumbers.Items.Add(itemList(intRow).strItemNum)
Next intRow
'clost the file
inFile.Close()
Else
'error message if file cannot be found
MessageBox.Show("Can't find the ItemInfo.txtfile",
"Kensington Industries",
MessageBoxButtons.OK,
MessageBoxIcon.Information)
End If
End Sub
Private Sub lstNumbers_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles lstNumbers.SelectedIndexChanged
'display the price
lblPrice.Text = itemList(lstNumbers.SelectedIndex).decPrice.ToString("C2")
End Sub
End Class
I have a CSV file that is formatted as (name,number) on each line.
I'm creating an app that loads all names, index(0), into a listbox at form-load and when a name is selected the number, index(1), is displayed in a .textbox.
I start by filling an array and displaying index(0) in the box. No Prob. But when the selected text changes I have problems. If you cant tell I'm new to VB. If I could assign a var to the selected text I could use a while loop but I'm not sure how to assign that. Is there a better way to go about this? Below is my source. Any help would be great.
Public Class Form1
Public Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each line As String In IO.File.ReadAllLines("MembershipPhone.txt")
Dim myData = line.Split(","c)
Dim mName = myData(0)
Dim mPhone = myData(1)
ListBox1.Items.Add(mName)
Next
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
For Each line As String In IO.File.ReadAllLines("MembershipPhone.txt")
Dim query = line.Split(","c)
Dim mName = query(0)
Dim mPhone = query(1)
TextBox2.Text = mPhone
Next
End Sub
I have to code a WPF application for college which reads from a csv file. I get a null reference exception when I want to output the parts of the CSV lines into arrays. You can find the line where the error happens in commentary. Here is the code.
Imports System.Windows.Forms
Imports System.IO
Imports System.Globalization
Class MainWindow
Private foldername As String
Private arrGemeenten As String()
Private arrOppervlakte As Double()
Private arrInwoners As Integer()
Private arrDeelgemeenten As Integer()
Private Sub cboProvincie_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles cboProvincie.SelectionChanged
CSVInlezen()
End Sub
Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
FileBrowserAanmaken()
comboBoxVullen()
End Sub
Private Sub comboBoxVullen()
For Each file As String In IO.Directory.GetFiles(foldername)
If file.EndsWith(".csv") Then
Dim filenaam As String = System.IO.Path.GetFileNameWithoutExtension(file)
cboProvincie.Items.Add(filenaam)
End If
Next
End Sub
Private Sub FileBrowserAanmaken()
'folderbrowserdialog aanmaken
Dim fbd As New FolderBrowserDialog
fbd.SelectedPath = AppDomain.CurrentDomain.BaseDirectory
' Show the FolderBrowserDialog.
Dim result As DialogResult = fbd.ShowDialog()
If (result = Forms.DialogResult.OK) Then
foldername = fbd.SelectedPath
End If
End Sub
Private Sub CSVInlezen()
Dim filepath As String = foldername & "\" & cboProvincie.SelectedValue & ".csv"
If File.Exists(filepath) Then
fileInlezenHulpMethode(filepath)
End If
End Sub
Private Sub fileInlezenHulpMethode(ByVal path As String)
'declarations
Dim sr As New StreamReader(path)
Dim iTeller As Integer = 0
Dim arrLijn As String()
Dim culture As New System.Globalization.CultureInfo("nl-BE")
'eerste lijn meteen uitlezen, dit zijn kolomkoppen en hebben we niet nodig
'read out first line, these are titles and we don't need them
sr.ReadLine()
Do While sr.Peek <> -1
Dim lijn As String = sr.ReadLine()
arrLijn = lijn.Split(";")
arrGemeenten(iTeller) = Convert.ToString(arrLijn(0)) 'HERE I GET THE ERROR!
arrOppervlakte(iTeller) = Double.Parse(arrLijn(2), NumberStyles.AllowDecimalPoint, culture.NumberFormat)
arrInwoners(iTeller) = Integer.Parse(arrLijn(3), NumberStyles.Integer Or NumberStyles.AllowThousands, culture.NumberFormat)
arrDeelgemeenten(iTeller) = Convert.ToString(arrLijn(4))
Loop
End Sub
End Class
You haven't created the array, you have only created a reference for it. To create the array you need to specify a size, for example:
Private arrGemeenten As String(100)
However, to specify the size, you need to know the size when you create the array. (Well, actually you put all data in the first item, so just the size 1 would keep it from crashing, but I don't thing that's what you intended.) You probably want to use lists instead:
Private gemeenten As New List(Of String)()
Then you use the Add method to add items to the list:
gemeenten.Add(Convert.ToString(arrLijn(0)))
Also, consider putting the data in a single list of a custom object, instead of having several lists of loosely coupled data.