Visual Basic Split() returning null - vb.net

Code for reading and splitting from file:
Public Sub LoadAccount()
currentfilereader = New StreamReader(filename)
Dim Seperator As Char = " "c
For count As Integer = 0 To NumUsers - 1
textstring = currentfilereader.ReadLine
Dim words() As String = currentfilereader.ReadLine.Split(Seperator)
Username = words(0)
Password = words(1)
If words(2) = "1" Then
AccessGranted = True
Else
AccessGranted = False
End If
Users(count, 0) = Username
Users(count, 1) = Password
Users(count, 2) = AccessGranted
Next
currentfilereader.Close()
End Sub
Code for logging in:
Public Sub Login()
Dim InvalidUsername, InvalidPassword As Boolean
InvalidUsername = True
InvalidPassword = True
LoginName = Form1.tbun.Text
LoginPassword = Form1.tbpw.Text
For count As Integer = 0 To NumUsers - 1
If LoginName = Users(count, 0) Then
InvalidUsername = False
If LoginPassword = Users(count, 1) Then
InvalidPassword = False
CurrentUsername = LoginName
CurrentPassword = LoginPassword
CurrentAccessGranted = Users(count, 2)
loggedin = True
Else
MsgBox("Invalid Password")
End If
Else
MsgBox("Invalid Username")
End If
Next
End Sub
Code for calculating number of users:
Public Sub NumberOfUsers()
currentfilereader = New StreamReader(filename)
NumUsers = File.ReadAllLines("Accounts.txt").Length
MsgBox("There are " & NumUsers & " users")
End Sub
I have added a MsgBox to show the number of users to make sure all is working fine which returns the value of 2, since I currently have 2 lines in the text file, "a a 1" and "b b 1".
However when this line runs, Dim words() As String = currentfilereader.ReadLine.Split(Seperator), it returns null.
The purpose of subtracting 1 from the NumUsers in the count is since the count starts at zero along with the array. Meaning that if I didn't it would check 3 times if there is only 2 users in the file. But I just can't seem to figure out what is wrong and why it is returning null.

You call ReadLine twice for each user:
textstring = currentfilereader.ReadLine
Dim words() As String = currentfilereader.ReadLine.Split(Seperator)
This means that for the first user you read both lines, and for the second user you read nothing, leading to the empty split array.
Replace
Dim words() As String = currentfilereader.ReadLine.Split(Seperator)
With
Dim words() As String = textstring.Split(Seperator)

Related

DataTable.Delete() Removing rows before Accept Changes

I'm having an issue where I mark several rows for deletion within a loop, but when it gets to a certain point in the loop, the rows actually start to be removed.
As you can see what I'm basically doing is checking if the row needs to be deleted and if so, add it to a new table and delete it.
The problem is this works for the first 60 ish rows, then all of a sudden the rows appear to actually be removed and it eventually throws a row with that index doesn't exist error (at 65).
The original table is a list of contacts with firstname, lastname, email and company, with 70 records.
I tried to cut the list in half, but then the issue started happening at around row 23.
dtSelectCompany = dt_data.Clone
Dim s_company As String
Dim b_add As Boolean
Dim dtCompanies As Data.DataTable
For i = 0 To dt_data.Rows.Count - 1
b_add = False
s_company = dt_data.Rows(i).Item(columnsDictionary("company")).ToString
If s_company = "" Then : b_add = True
Else
dtCompanies = crm_functions.getCompaniesByName(s_company.Replace(" ", "%"))
If dtCompanies.Rows.Count > 1 Then : b_add = True
ElseIf dtCompanies.Rows.Count = 1 Then
dt_data.Rows(i).Item(columnsDictionary("company")) = dtCompanies.Rows(0).Item("id")
Else : b_add = True
End If
End If
If b_add Then
Dim temp_row As Data.DataRow = dtSelectCompany.NewRow
temp_row.ItemArray = dt_data.Rows(i).ItemArray.Clone()
temp_row.Item("fullName") = temp_row.Item(columnsDictionary("firstname")) & " " & temp_row.Item(columnsDictionary("lastname"))
dtSelectCompany.Rows.Add(temp_row)
dt_data.Rows(i).Delete()
End If
Next
Instead of a counter, use a datarow, for example:
dtSelectCompany = dt_data.Clone
Dim s_company As String
Dim b_add As Boolean
Dim dtCompanies As Data.DataTable
Dim MyDataRow as DataRow
For Each MyDataRow IN dt_data.Rows
b_add = False
s_company = MyDataRow("company").ToString
If s_company = "" Then : b_add = True
Else
' not sure what crm_functions is, so left this alone
dtCompanies = crm_functions.getCompaniesByName(s_company.Replace(" ", "%"))
If dtCompanies.Rows.Count > 1 Then : b_add = True
ElseIf dtCompanies.Rows.Count = 1 Then
MyDataRow("company")) = dtCompanies.Rows(0).Item("id")
Else : b_add = True
End If
End If
If b_add Then
Dim temp_row As Data.DataRow = dtSelectCompany.NewRow
temp_row = MyDataRow
temp_row.Item("fullName") = temp_row.Item(columnsDictionary("firstname")) & " " & temp_row.Item(columnsDictionary("lastname"))
dtSelectCompany.Rows.Add(temp_row)
MyDataRow.Delete()
End If
Next
Wrote this off the top of my head, so .....

How do you replace the last occurance of a , with the word "and"?

How do you replace the last occurance of a , with the word and? Can you please give me an idea?
i have 3 checkboxes, 1 rich textbox
to display the output, 1 button
(Aparri) or (Camalanuigan) or (Lallo)
Cagayan(Aparri, Camalanuigan) or Cagayan(Aparri,Camalanuigan,Lallo)
I would like the output to be like this: #Cagayan(Aparri and Camalanuigan) or #Cagayan(Aparri,Camalanuigan And Lallo)
this is my code:
Dim rws As String
If Aparri.Checked = True Then
close_parenthesis.Checked = True
If rws = "" Then
rws = "(" + Aparri.Text
End If
End If
If Aparri.Checked = False Then
rws = ""
End If
If Camalanuigan.Checked = True Then
close_parenthesis.Checked = True
If rws = "" Then
rws = "(" + Camalanuigan.Text
Else
rws = rws & ", " & Camalanuigan.Text
End If
End If
If Lallo.Checked = True Then
close_parenthesis.Checked = True
If rws = "" Then
rws = "(" + Lallo.Text
Else
rws = rws & ", " & Lallo.Text
End If
End If
If close_parenthesis.Checked = True Then
If rws = "" Then
Else
rws = rws + close_parenthesis.Text
End If
End If
Display.Text = rws.ToString
Output: (Aparri,Camalanuigan,Lallo)
i want the out like this (Aparri,Camalanuigan and Lallo)
Here, I haven't even seen your code but I get what you want to do by looking at the picture. It can be done in shorter version but I have explained what's going on in each and every line so it's lengthy.
I have written this code:
'let's say the string is "Aparri, Camalanuigan, Lallo" . that's what your code does, right?
dim Strng as string = "Aparri, Camalanuigan, Lallo"
'now find the position of last appearing ","
Dim comaposition As Integer
comaposition = Strng.LastIndexOf(",") 'it is zero based
'if not found, it will return -1 and u can exit, no need to do the work
if commaposition = "-1" then
exit sub
end if
'remove the comma
Dim String_After_Removing_Comma As String
String_After_Removing_Comma = Strng.Remove(comaposition, 1)
'add "and" in the same position where comma was found
Dim final_string As String
final_string = String_After_Removing_Comma.Insert(comaposition, " and")
'show it on the textbox
DisplayTxt.Text = final_string
You can do this thing after finding your final string (rws in your code).
Hope this helps
You can use the following function to replace last occurrence.
Public Function ReplaceLastOccurrence(ByVal source As String, ByVal searchText As String, ByVal replace As String) As String
Dim position = source.LastIndexOf(searchText)
If (position = -1) Then Return source
Dim result = source.Remove(position, searchText.Length).Insert(position, replace)
Return result
End Function
and you use display text as
Display.Text = ReplaceLastOccurence(rws, ",", "and")
in your last line of code
You always can do it by yourself with single loop and knowledge about last index
' Create array of selected strings
Dim selectedTexts =
New List(Of CheckBox) From { Aparri, Camalanuigan, Lallo }.
Where(Function(checkbox) checkbox.Checked).
Select(Function(checkbox) checkbox.Text).
ToArray()
' Separate selected strings by delimeters
Dim lastIndex = selectedTexts.GetUpperBound(0)
Dim builder = New StringBuilder()
For i As Integer = 0 To lastIndex
If i > 0 Then
Dim delimeter = If(lastIndex > 0 AndAlso lastIndex = i, " and ", ", ")
builder.Append(delimeter)
End If
builder.Append(test(i))
Next
' Wrap with parenthesis if result not empty
If builder.Length > 0 Then
builder.Insert(0, "(")
Dim close = If(close_parenthesis.Checked, close_parenthesis.Text, "")
builder.Append(close)
End If
' Print result
Display.Text = builder.ToString()

Pictures wont become visible

So today in my Computer Programming Class, we created a project called CaseStudy. I saw a way to make the program have more replay value. I decided to morph the code and interface to be like a Hangman game. I've got the limbs to appear, but only after clicking Ok on the messageBox.
I'm wondering if anyone has a way to make these limbs appear in real time.
Here is the important code:
Dim SECRET_WORD As String = newSecretWord
Const FLAG As Char = "!"
Const GUESS_PROMPT As String = "Enter a letter or " & FLAG & " to guess word:"
Dim numGuesses As Integer = 0
Dim letterGuess As Char
Dim wordGuess As String
Dim tempWord As String
Dim endGame As Boolean
Dim wordGuessedSoFar As String = ""
Dim lenght As Integer = SECRET_WORD.Length
wordGuessedSoFar = wordGuessedSoFar.PadLeft(lenght, "_")
Me.lblSecretWord.Text = wordGuessedSoFar
Dim tempLetterGuess = InputBox(GUESS_PROMPT, Me.Text)
If tempLetterGuess = Nothing Then
endGame = True
Else
letterGuess = tempLetterGuess
End If
Do While letterGuess <> FLAG And wordGuessedSoFar <> SECRET_WORD And Not endGame
numGuesses += 1
For letterPos As Integer = 0 To SECRET_WORD.Length - 1
If SECRET_WORD.Chars(letterPos) = Char.ToUpper(letterGuess) Then
tempWord = wordGuessedSoFar.Remove(letterPos, 1)
wordGuessedSoFar = tempWord.Insert(letterPos, Char.ToUpper(letterGuess))
Me.lblSecretWord.Text = wordGuessedSoFar
End If
Next letterPos
If wordGuessedSoFar <> SECRET_WORD Then
tempLetterGuess = InputBox(GUESS_PROMPT, Me.Text)
If tempLetterGuess = Nothing Then
endGame = True
Else
letterGuess = tempLetterGuess
End If
End If
Loop
If wordGuessedSoFar = SECRET_WORD Then
MessageBox.Show("You guessed it in " & numGuesses & " guesses!")
ElseIf letterGuess = FLAG Then
wordGuess = InputBox("Enter a word: ", Me.Text)
If wordGuess.ToUpper = SECRET_WORD Then
MessageBox.Show("You guessed it in " & numGuesses & " guesses!")
Me.lblSecretWord.Text = SECRET_WORD
Else
MessageBox.Show("Sorry, you lose.")
End If
Else
MessageBox.Show("Game over.")
lblSecretWord.Text = Nothing
End If
Dim place As Integer = SECRET_WORD.Length - 1
If tempLetterGuess <> SECRET_WORD.Chars(place) Then
numWrong += 1
End If
If numWrong = 1 Then
picHead.Visible = True
End If
If numWrong = 2 Then
picBody.Visible = True
End If
End Sub
End Class
I can take any other pictures if you'd like.
If I'm understanding you right, you want to show your "pictures" before the user sees the message. If so, you need to move the following code to an area just before your MessageBox and just after the InputBox:
Dim place As Integer = SECRET_WORD.Length - 1
If tempLetterGuess <> SECRET_WORD.Chars(place) Then
numWrong += 1
End If
If numWrong = 1 Then
picHead.Visible = True
End If
If numWrong = 2 Then
picBody.Visible = True
End If

Read Line-By-Line without using StreamReader

I have been doing A-Level Computing for a couple of months now and I have decided to make a phonebook relevant to the methods used in class. For my exam I am not allowed to use StreamReader etc... However, I can use methods such as FileOpen(1, "FILE NAME", OpenMode.Binary).
I want to store usernames and passwords in a text file (I know its not a good method but it links to my lessons). My .txt file is formatted like:
Username, Password.
Username2, Password2.
What would i be able to do to make it store each Username and Password in a list?
Here's what I've got... (don't know why it doesn't work)
Private Sub CheckAccount()
Dim Username_File As New ArrayList
Dim Username_Temp As String = ""
Dim Password_File As New ArrayList
Dim Password_Temp As String = ""
FileOpen(1, "Users.txt", OpenMode.Binary)
Do While Not EOF(1)
Dim PosCount_Start As Integer = 0
Dim PosCount_End As Integer = 0
Dim TempChar As Char = ""
Do
FileGet(1, TempChar)
If TempChar = "," Then Exit Do
Username_Temp = Username_Temp + TempChar
PosCount_End = PosCount_End + 1
Loop
Username_Temp = Username_Temp.Substring(PosCount_Start, (PosCount_End - PosCount_Start))
Username_File.Add(Username_Temp)
PosCount_End = 0
Do
FileGet(1, TempChar)
If TempChar = "." Then Exit Do
Password_Temp = Password_Temp + TempChar
PosCount_End = PosCount_End + 1
Loop
Password_Temp = Password_Temp.Substring(0, PosCount_End)
Password_Temp = Password_Temp.Trim
Password_File.Add(Password_Temp)
PosCount_End = 0
Loop
FileClose(1)
For i = 0 To Username_File.Count - 1
Dim Temp As String
Temp = Username_File(i)
If Temp.ToLower = Username.ToLower Then
If Password = Password_File(i) Then
LoggedIn = True
End If
End If
Next
End Sub

Visual Basic, Opening forms

I am trying to make a program that requires the user to sign in and if the right username and password is entered then open a form for that user. The way I have it done just now is the username is stored in a variable and I was wondering how I can use the text from the variable in the form name for example:
UserName = User1 then
FrmUser1.show
UserName = JohnSmith then
FrmJohnSmith.show
Here is an excerpt from the code I have so far:
Dim Path As String = "Account_File.text "
Dim Read_File() As String = File.ReadAllLines(Path)
Dim NoOfLines As Integer = Read_File.Length
Dim UserName(NoOfLines) As String
Dim Password(NoOfLines) As String
Dim LastNonEmpty As Integer = -1
Dim InputUserName As String = ""
Dim InputPassword As String = ""
If TxtUserName.Text = "" Then
MsgBox("Please enter a username.")
GoTo InvalidDetails
Else
InputUserName = TxtUserName.Text
End If
If TxtPassword.Text = "" Then
MsgBox("Please enter a Password.")
GoTo InvalidDetails
Else
InputPassword = TxtPassword.Text
End If
For i = 0 To NoOfLines
Dim SplitString() As String = Split(Read_File(i))
For j As Integer = 0 To SplitString.Length - 1
If SplitString(j) <> "" Then
LastNonEmpty += 1
SplitString(LastNonEmpty) = SplitString(j)
End If
Next
ReDim Preserve SplitString(LastNonEmpty)
LastNonEmpty = -1
UserName(i) = SplitString(0)
Password(i) = SplitString(1)
Next
For i = 0 To NoOfLines
If UserName(i) = InputUserName And Password(i) = InputPassword Then
frm.show()
Else
MsgBox("Either the username or password is incorrect.")
End If
Next
Some sample code:
Dim formname = "Form" + TxtUserName.Text
Dim typename = Me.GetType().Namespace + "." + formname
Dim type = Me.GetType().Assembly.GetType(typename)
If type IsNot Nothing Then
Dim form = CType(Activator.CreateInstance(type), Form)
form.Show()
End If
Which assumes that all forms live in the same assembly and have the same namespace. Do keep in mind that your customer isn't very likely to be thrilled to have to call you every single time he gets a new employee. Or for that matter is going to like you asking for username + password without providing the kind of security guarantees that a Windows logon already provides. Don't do this.