VB .Remove from String - vb.net

I have to prepare a school project of a Currency Converter in Visual Studio using Basic language.
I get the value of extange from XE website and it returns a string like "1.23454 GBP' So I need to remove most characters and numbers from it to have it as a Decimal, not String anymore so I can times it later in calculation.
I've tried to use .Remove anywhere and place it in textBox or Label but it didn't work.
Public Class receipt
Private Sub receipt_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim testString As String = "sadasdasd"
customername.Text = "Name: " + My.Settings.Username
Label6.Text = "Entered Money: " + My.Settings.inputamount + " " + My.Settings.currency
Label7.Text = "Converted To: " + My.Settings.outputamount
Label8.Text = "Charge: 0 (0%)"
TextBox1.Text = testString.Remove(4, 9)
End Sub
End Class
Screenshot of program running
Can someone help me to get this work?

Given your current input of "sadasdasd" and your expected return value then the call to string.Remove should be
TextBox1.Text = testString.Remove(3)
If you look at the MSDN documentation page of string.Remove you could see that the index is zero based so you want to remove anything starting from the fourth character that is at index 3 (keeps 0,1,2, removes from 3)
Also It seems that you think that the Remove second parameter is the end index where the Remove action should stop. But this is wrong, the second parameter is the number of characters to remove so 9 is not correct and probably gives you an ArgumentOutofRange Exception

Related

How to remove and re-add a comma in a string?

I have a textbox on my form that when a button is clicked, it is populated with numbers that are separated by a comma. I have a delete button that will remove the numbers with the comma one at a time. My question is how would I go about re-adding the comma every time i hit the add button, again? I thought i could add the comma in the beginning in an if statement, but its adding two commas, every time I hit the add button, if I delete, then try to re- add.
here is what i have :
if textbox1.text = "" then
textbox1.text = textbox1.text & testNumber(combobox.selecteditem) & ","
else
textbox1.text = "," & textbox1.text & testnumber(combox.selecteditem)
end if
The contents of the textbox should only be a view of a more appropriate underlying data structure. For example, you might have a List(Of Integer) or Queue(Of Integer) as a member of your form. When you add or remove an item you first update the collection, then you set the text. For example:
Add:
MyList.Add(nextNumber)
textbox1.text = String.Join(","c, MyList)
Remove:
MyList.RemoveAt(MyList.Count - 1);
textbox1.text = String.Join(","c, MyList)
Do this even if they want the ability to update the textbox directly. It's just in this case you must also be able to validate and parse the contents of the textbox to recreate the list.
First of all, storing numbers in a comma delimited string is pretty strange requirement. I'd suggest to store numbers in a proper data type, such as: List(Of Integer).
Assuming that testnumber function returns integer...
'define at the top of Form's module:
Private myNumbers As List(Of Integer) = New List(Of Integer)()
'copy-paste below method to the form's module
Private Function GetCommaSeparatedNumbers() As String
Return String.Join(",", myNumbers)
End Function
'finally:
'to add number
myNumbers.Add(testnumber(combox.selecteditem))
'to remove number
myNumbers.Remove(testnumber(combox.selecteditem))
'to display numbers
Me.textbox1.Text = GetCommaSeparatedNumbers()
If you would like to check out if number already exists on the list, use:
If myNumbers.Contains(testnumber(combox.selecteditem)) Then
'display warning
Else
'add number
End If
Good luck!
Your code is initial testing textbox1.Text = "" and then, if that is true, it is then doing textbox1.Text = textbox1.Text & testNumber(combobox.SelectedItem) & ",", but since textbox1.Text is "" this is the equivalent of:
textbox1.Text = "" & testNumber(combobox.SelectedItem) & ","
That really means you are adding a comma when you only have one number.
This is what you should be doing:
if textbox1.Text = "" then
textbox1.Text = testNumber(combobox.SelectedItem)
else
textbox1.Text = textbox1.Text & "," & testnumber(combox.SelectedItem)
end if
To add a number, I'd do it with this line:
TextBox1.AppendText(If(TextBox1.TextLength = 0, "", ",") & testNumber(ComboBox.SelectedItem))
Are numbers being deleted from the beginning or end?...or is a "selected" number from anywhere in the list being deleted?

AppendLine and replacing

I want to get my output from
223-F456
to
223-F456
223-F456#
223-F4560
223-#456
I've done simple code for this but only adding #,0 to the ends of lines works:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sb As New StringBuilder
For Each line In TextBox1.Lines
sb.AppendLine(line)
sb.AppendLine(line & "#")
sb.AppendLine(line & "0")
sb.Replace(line.LastIndexOf("-") + 1, "#") -> this doesn't work
Next
TextBox2.Text = sb.ToString
output:
223-F456
223-F456#
223-F4560
The letter is not always "F": I want to replace first letter after "-" not replace "F", also might some serials have "F" letter that not what I want.
Simple products serial in shop but replacing the string after "-" doesn't work and doesn't show, any help would be appreciated.
You can use String.Remove and String.Insert like this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sb As New StringBuilder()
For Each line In TextBox1.Lines
sb.AppendLine(line)
sb.AppendLine(line & "#")
sb.AppendLine(line & "0")
Dim replaceAt = line.LastIndexOf("-") + 1
sb.AppendLine(line.Remove(replaceAt, 1).Insert(replaceAt, "#"))
Next
TextBox2.Text = sb.ToString()
End Sub
Or if you preferred then you could use the String.Substring function:
sb.AppendLine(line.Substring(0, replaceAt) & "#" & line.Substring(replaceAt + 1))
It would also be possible to use a regular expression to do the replace, I expect someone else could come up with a better regex, but this works:
Dim re As New Regex("(.*-)([^-])(.*)")
For Each line In TextBox1.Lines
' ...
sb.AppendLine(re.Replace(line, "$1#$3"))
The problem is that
line.LastIndexOf("-") + 1
will return a number (indicating the place in line where it found the last - character, plus one).
But the replace function expects you to tell it what string you want to replace. You want to replace F, not a number. (Your current code would resolve to sb.Replace(4, "#"), which clearly won't find any 4s to replace.)
And if you do sb.Replace it'll replace it for all the versions of the string you've previously added to the stringbuilder. Therefore, it would make more sense to replace it in line, and then append that modified version of line to the stringbuilder.
sb.AppendLine(line.Replace("F", "#"))
Live demo: https://dotnetfiddle.net/5BZAUg
Edit:
If you need to replace any character following the -, not specifically an F, you can do it by finding the character index in line, and then removing the character at that index and replacing it with another one, e.g.
Dim index = line.LastIndexOf("-") + 1
sb.AppendLine(line.Remove(index, 1).Insert(index, "#"))
Demo: https://dotnetfiddle.net/RTbiUG

How to display my data from a text-file determined by a combo box?

I am trying to retrieve a surfer from a list on a textfile, the user selects the surfer from the combo box which then displays that surfers data in a bunch of labels. My code requires each surfer to have an ID for it to be able to know which record to retrieve from the database. However when I try to put my ID from my loop together with each surfers name, I receive an error saying "Conversion from string to type 'Long' is not valid." I have tried different methods of getting around this, none of which have worked. Here is my code:
Private Sub Lookup_Load(sender As Object, e As EventArgs) Handles MyBase.Load
madelabel = False
For i = 1 To maxrecJudge
FileGet(2, ajudge, i)
recnoJudge = i
judgename = recnoJudge And " " And ajudge.name
cmbJudge.Items.Add(judgename)
Next i
For i = 1 To maxrecSurfer
FileGet(1, asurfer, i)
recnoSurfer = i
surfername = recnoSurfer And " " And asurfer.name
cmbSurfer.Items.Add(surfername)
Next i
End Sub
Private Sub cmbSurfer_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbSurfer.SelectedIndexChanged
recnoSurfer = CInt(Val(New Text.StringBuilder((From ch In cmbSurfer.Text.ToCharArray Where IsNumeric(ch)).ToArray).ToString))
FileGet(1, asurfer, recnoSurfer)
If madelabel = False Then
lblName = New Label
lblName.Top = 160
lblName.Left = 253
lblName.Autosize = True
lblName.Text = asurfer.name
Me.Controls.Add(lblName)
End Sub
For simplicity I have only included one label creation above, but there are several labels spawned each with data of the surfer.
Am I on the right track with this? In the second sub my code extracts the integer (ID) from the combo box which then is used as a record number to find the rest of the data. The error relates to these lines:
surfername = recnoSurfer And " " And asurfer.name
cmbSurfer.Items.Add(surfername)
It won't let me concatenate the ID and the surfers name. Any help?
If you are doing a lot of concatenation, use a StringBuilder. It is far quicker. Every time you concatenation strings, a new string is created. Over a large amount of iterations, StringBuilder is the better choice.

How can i check for a character after certain text within a listbox?

How can i check for a character after other text within a listbox?
e.g
Listbox contents:
Key1: V
Key2: F
Key3: S
Key4: H
How do I find what comes after Key1-4:?
Key1-4 will always be the same however what comes after that will be user defined.
I figured out how to save checkboxes as theres only 2 values to choose from, although user defined textboxes is what im struggling with. (I have searched for solutions but none seemed to work for me)
Usage:
Form1_Load
If ListBox1.Items.Contains("Key1: " & UsersKey) Then
TextBox1.Text = UsersKey
End If
Which textbox1.text would then contain V / whatever the user defined.
I did try something that kind of worked:
Form1_Load
Dim UsersKey as string = "V"
If ListBox1.Items.Contains("Key1: " & UsersKey) Then
TextBox1.Text = UsersKey
End If
but i'm not sure how to add additional letters / numbers to "V", then output that specific number/letter to the textbox. (I have special characters blocked)
Reasoning I need this is because I have created a custom save settings which saves on exit and loads with form1 as the built in save settings doesn't have much customization.
e.g Can't choose save path, when filename is changed a new user.config is generated along with old settings lost.
Look at regular expressions for this.
Using the keys from your sample:
Dim keys As String = "VFSH"
Dim exp As New RegEx("Key[1-4]: ([" & keys& "])")
For Each item As String in ListBox1.Items
Dim result = exp.Match(item)
If result.Success Then
TextBox1.Text = result.Groups(1).Value
End If
Next
It's not clear to me how your ListBoxes work. If you might find, for example, "Key 2:" inside ListBox1 that you need to ignore, you will want to change the [1-4] part of the expression to be more specific.
Additionally, if you're just trying to exclude unicode or punctuation, you could also go with ranges:
Dim keys As String = "A-Za-z0-9"
If you are supporting a broader set of characters, there are some you must be careful with: ], \, ^, and - can all have special meanings inside of a regular expression character class.
You have multiple keys, I assume you have multiple textboxes to display the results?
Then something like this would work. Loop thru the total number of keys, inside that you loop thru the alphabet. When you find a match, output to the correct textbox:
Dim UsersKey As String
For i As Integer = 1 To 4
For Each c In "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray()
UsersKey = c
If ListBox1.Items.Contains("Key" & i & ": " & UsersKey) Then
Select Case i
Case 1
TextBox1.Text = UsersKey
Case 2
TextBox2.Text = UsersKey
Case 3
TextBox3.Text = UsersKey
Case 4
TextBox4.Text = UsersKey
End Select
Exit For 'match found so exit inner loop
End If
Next
Next
Also, you say your settings are lost when the filename is changed. I assume when the version changes? The Settings has an upgrade method to read from a previous version. If you add an UpgradeSettings boolean option and set it to True and then do this at the start of your app, it will load the settings from a previous version:
If My.Settings.UpgradeSettings = True Then
My.Settings.Upgrade()
My.Settings.Reload()
My.Settings.UpgradeSettings = False
My.Settings.Save()
End If
Updated Answer:
Instead of using a listtbox, read the settings file line by line and output the results to the correct textbox based on the key...something like this:
Dim settingsFile As String = "C:\settings.txt"
If IO.File.Exists(settingsFile) Then
For Each line As String In IO.File.ReadLines(settingsFile)
Dim params() As String = Split(line, ":")
If params.Length = 2 Then
params(0) = params(0).Trim
params(1) = params(1).Trim
Select Case params(0)
Case "Key1"
Textbox1.Text = params(1)
Case "Key2"
Textbox2.Text = params(1)
End Select
End If
Next line
End If
You can associate text box with a key via its Name or Tag property. Lets say you use Name. In this case TextBox2 is associated with key2. TextBox[N] <-> Key[N]
Using this principle the code will look like this [considering that your list item is string]
Sub Test()
If ListBox1.SelectedIndex = -1 Then Return
Dim data[] As String = DirectCast(ListBox1.SelectedItem, string).Split(new char(){":"})
Dim key As String = data(0).Substring(3)
Dim val As String = data(1).Trim()
' you can use one of the known techniques to get control on which your texbox sits.
' I omit this step and assume "Surface1" being a control on which your text boxes sit
DirectCast(
(From ctrl In Surface1.Controls
Where ctrl.Name = "TextBox" & key
Select ctrl).First()), TextBox).Text = val
End Sub
As you can see, using principle I just explained, you have little parsing and what is important, there is no growing Select case if, lets say, you get 20 text boxes. You can add as many text boxes and as many corresponding list items as you wish, the code need not change.

Read file name for 5 to 10 digit account number, is this possible?

I am attempting to write a program in VB.net which will output some values in to a text file. Please be patient with me as I am very new to VB.net.
What I have so far is below:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim str As String
For Each File As String In System.IO.Directory.GetFiles(TextBox1.Text)
str = str & File & "|" & System.IO.Path.GetFileNameWithoutExtension(File).Split("-")(0).Trim & "|" & System.IO.Path.GetFileNameWithoutExtension(File).Split("-")(0).Trim & "||" & DateTimePicker1.Text & "|" & Environment.NewLine
Next
System.IO.File.WriteAllText("C:\output\output.txt", str)
End Sub
Results of output file (output.txt) when button3 is clicked are below:
C:\DirectoryTest\Clients\2356851-Kathy Winkler - Family Investments.pdf|2356851|2356851||04/10/2013|
C:\DirectoryTest\Clients\58736 -Katrina Armon - Sandlewood Homes Co.pdf|58736|58736||04/10/2013|
C:\DirectoryTest\Clients\Karen Cooper - 001548 - Famtime.pdf|Karen Cooper|Karen Cooper||04/10/2013|
My code so far does exactly what I want it to do, the only thing is that I want to make the code smarter but don’t know how. Smarter as in is there a way I can make the below code only pick up the 5 to 10 digit account number seen in the filename, and if no account number exists in the file name to bring up a message box?
System.IO.Path.GetFileNameWithoutExtension(File).Split("-")(0).Trim & "|" & System.IO.Path.GetFileNameWithoutExtension(File).Split("-")(0).Trim
As you can see from the last line of the output…
C:\DirectoryTest\Clients\Karen Cooper - 001548 - Famtime.pdf|Karen Cooper|Karen Cooper||04/10/2013|
…the customers name “Karen Cooper” is being displayed in both areas where the account number should be displayed. This is why I need to make this code smarter somehow have it search the file name for a 5 to 10 digit account number to display it after the file name as see in the other 2 examples.
Please let me know if this is possible. And do let me know if you have any questions.
Here is you some simple logic .... ofcouse you can just do something like finding the filename first but here you go
Dim returnval As String = ""
Dim s As String = "C:\DirectoryTest\Clients\Karen Cooper - 001548 - Famtime.pdf|Karen Cooper|Karen Cooper||04/10/2013|"
For Each p As String In s
If IsNumeric(p) Then
returnval += p
Else
'MsgBox("no")
End If
Next
msgbox(returnval) will hold all your numbers 5-10 , depends on how specific you want to get from here
to break apart the filenames
'This will extract and return the filename from the specified path and filename.
'
Dim filePath As String = "c:\MyDirectory\MYFile.txt"
Dim slashPosition As Integer = filePath.LastIndexOf("\")
Dim filenameOnly As String = filePAth.Substring(slashPosition + 1)
MsgBox(filenameOnly)
*FOUND AT LINK http://www.vbforfree.com/274/extract-and-retrieve-the-filename-from-a-path/*
then manipulate your string from there as much as you want
You should give this a try. I haven't had a chance to test it but it should work
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim str As String
For Each File As String In System.IO.Directory.GetFiles(TextBox1.Text)
Dim strs as String() = System.IO.Path.GetFileNameWithoutExtension(File).Split("-")
Dim AccountNum as int = 0
For each section in strs()
' Loop through each section separated by - and try to cast it to an int
' you may want to use cLong instead
Try
AccountNum = cInt(section.trim())
exit for
Catch
End Try
Next
' DO LOGIC HERE TO BUILD OUTPUT with the account num now known
Next
System.IO.File.WriteAllText("C:\output\output.txt", str)
End Sub
How about yor file name ?
C:\DirectoryTest\Clients\Karen Cooper - 001548 - Famtime.pdf
Fairly, It should be
C:\DirectoryTest\Clients\001548 - Karen Cooper - Famtime.pdf
I would recommend using RegEx to extract the account number. A side benefit of using RegEx is that you can store the RegEx pattern outside of your code, such as in a configuration file, so if you ever need to modify the pattern, you could do so easily without recompiling your application.
Function GetAccountNumber(fileName As String) As String
Dim pattern As String = ".*?(?<acct>\d{5,10}).*?"
Dim regEx As New Regex(pattern)
Dim match As Match = regEx.Match(fileName)
Dim accountNumber As String = Nothing
If match.Success Then
Dim group As Group = match.Groups("acct")
If group.Success Then
accountNumber = group.Value
End If
End If
Return accountNumber
End Function
In the above example, I am using the following RegEx pattern to find the five to ten digit number in the string:
.*?(?<acct>\d{5,10}).*?
The .*? at the beginning and end of the pattern means any character, any number of times. The question mark means it's non-greedy. In other words, it only matches as many characters as necessary. By making it non-greedy, it will not steal-away any of the digits from the account number.
The parentheses surround the part of the string we are looking for (the account number). The ?<acct> at the beginning of the parenthetical group a name by which we can refer to it. In this case, I named the group acct. The \d means any digit character. The {5,10} means repeated between five and ten times.