VB.net convert , to decimal (order of placement) - vb.net

Hi I have a textbox which dose some math calculations perfect if you work with decimals not so if you work with commas.. the first option i explored was to just accept numbers and decimals in a masked textbox... but why? some of us have learned to use commas since we first started school... so my idea is to have a textbox which searches for commas and turns them into decimals for the user.
I have the following code but as example if I type in 2,5 my conversion becomes 25. so yes i have converted the comma to decimal but have lost its placing. The question thus being how can I do my conversion properly with the right decimal placement?
If TextBox13.Text.Contains(",") Then
TextBox13.Text = Replace(TextBox13.Text, ",", ".")
dim test as double textbox1.text
msgbox(test)
End If

Why not make comma an illegal entry. Don't you block entering letters anyway.
Private Sub textBox1_KeyPress(sender As Object, e As KeyPressEventArgs)
e.Handled = SingleDecimal(sender, e.KeyChar)
End Sub
Public Function SingleDecimal(sender As System.Object, eChar As Char) As Boolean
Dim chkstr As String = "0123456789."
If chkstr.IndexOf(eChar) > -1 OrElse eChar = Constants.vbBack Then
If eChar = "." Then
If DirectCast(sender, TextBox).Text.IndexOf(eChar) > -1 Then
Return True
Else
Return False
End If
End If
Return False
Else
Return True
End If
End Function
Other solution maybe is replacing comma with dot in string and then passing it back to textbox.
If TextBox13.Text.Contains(",") Then
dim tempStr as string = TextBox13.Text
TextBox13.Text = Replace(tempStr, ",", ".")
dim test as double textbox1.text
msgbox(test)
End If
And anyway shouldn't this be written this way:
TextBox13.Text = tempStr.Replace(",", ".")

Have you tried to cast the string to decimal or double?
Dim test as Decimal = CDec(textbox1.Text)
Or Dim test as Double= CDbl(textbox1.Text)

Related

Encode and Decode VBA Program

in my programming class I have to create a program which allows the user in order to enter a sentence, with the buttons "Encode" and "Decode" as options. So, for "Encode", you have to translate the sentence into Asc numbers (already did this). However, I'm currently stuck on the "Decode" section, for you have to use a For loop and an array to separate the Asc numbers by spaces, then translate them into characters one by one. Here's what I have so far:
Public Class Form1
Dim Message As String
Dim NewMessage As String
Dim Part As String
Dim Part2 As Integer
Dim Letter As String
Dim Length As String
Dim ints() As Integer
Dim intlength As Integer
Private Sub btn_Enter_Click(sender As Object, e As EventArgs) Handles btn_Enter.Click
Message = txt_Message.Text
Length = Message.Length() - 1
If rbn_Encode.Checked = True Then
For Num As Integer = 0 To Length
Letter = Message(Num)
Me.lbl_Code.Text = lbl_Code.Text & Asc(Letter) & " "
Next
End If
If rbn_Decode.Checked = True Then
For Num As Integer = 0 To intlength Step 1
If Message(Num) <> " " Then
Part = Part & Message(Num)
Else
NewMessage = NewMessage & ChrW(Part) & " "
End If
Next
Me.lbl_Code.Text = NewMessage
End If
End Sub
Private Sub ExitToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExitToolStripMenuItem.Click
Application.Exit()
End Sub
End Class
I've been stuck on this for about 2 week, and I'm still clueless. Thank you for your help and have a wonderful day.
This might seem to veer off the topic of the question, but it all meanders towards a better answer.
OK there are a few issues with your code. Firstly, make sure that "Option Strict" is on - have a look here. This will force you to convert types properly and reduce the potential for problems. Bearing the above in mind,
Dim Length As String
should be
Dim Length As Integer
on to the next bit
Each procedure should have a single responsibility. Your btn_Enter.Click event handler includes code for encoding text and decoding numbers. These should be separated out into their own procedures. In a relatively short bit of code like yours, it's not too much of a problem, but even here, it makes things a little fuzzier. Have a look at the code below. There are more issues, but we'll look at them in a moment. The code below is a bit clearer and more maintainable.
Private Sub btn_Enter_Click(sender As Object, e As EventArgs) Handles btn_Enter.Click
Message = txt_Message.Text
Length = Message.Length() - 1
If rbn_Encode.Checked = True Then
EncodeTextToAscii()
End If
If rbn_Decode.Checked = True Then
DecodeToText()
End If
End Sub
Private Sub DecodeToText()
For Num As Integer = 0 To intlength Step 1
If Message(Num) <> " " Then
Part = Part & Message(Num)
Else
NewMessage = NewMessage & ChrW(Part) & " "
End If
Next
Me.lbl_Code.Text = NewMessage
End Sub
Private Sub EncodeTextToAscii()
For Num As Integer = 0 To Length
Letter = Message(Num)
Me.lbl_Code.Text = lbl_Code.Text & Asc(Letter) & " "
Next
End Sub
Next.
In your code to encode the string as ASCII, you store the resulting data directly in the label lbl_Code's text property. The user interface should never be used as the primary store for data. It's bad practice and potentially allows the user to change data accidentally - in textboxes for example. In the case of a label, it's not to important, but it's far better to get into the good habits.
To store your encoded ASCII numbers, you can use the array ints, but as your code stands, the declaration of ints is just that. There is no space in the array to store data. So, in the Encode procedure, you need to resize ints to the same as the number of characters in the string.
So now we have ..
Private Sub EncodeTextToAscii()
ReDim ints(Length)
For Num As Integer = 0 To Length
Letter = Message(Num)
ints(Num) = Asc(Letter)
Next
End Sub
Finally onto the meat of your question. The Decode procedure can now be written as this ..
Private Sub DecodeToText()
NewMessage = ""
For Each asciiNumber As Integer In ints
NewMessage = NewMessage & ChrW(asciiNumber) & " "
Next
Me.lbl_Code.Text = NewMessage
End Sub
Instead of mucking around getting the length of a loop and getting the ascii number in each element of an array, you can simplyfy it using a For Each statement. You dont need to know the length of the array. It just loops over the whole length. Much easier.
As an excercise, try applying the For Each idea to the Encode procedure. :-)

Automatic decimal places in textbox

It looks very strange, but I can't find an online solution for my problem! At least in VB.NET.
Here's the deal:
I have a TextBox in a form (limited to numbers by a KeyPress event) and want to keep two decimal places as long as the user inputs his data.
For example, if the TextBox is blank, then, when the user presses, let's say, "2", the TextBox shows "0,02". Then, if the user presses "7", the TextBox shows "0,27". Then again, by pressing "6", it shows "2,76" and so on...
I managed to do this for one decimal place with the code:
Select Case Me.TextBox.Text
Case ""
Case ","
Me.TextBox.Text = ""
Case Else
Me.TextBox.Text = Strings.Left(Replace(Me.TextBox.Text, ",", ""), Strings.Len(Replace(Me.TextBox.Text, ",", "")) - 1) & "," & Strings.Right(Replace(Me.TextBox.Text, ",", ""), 1)
Me.TextBox.SelectionStart = Len(Me.TextBox.Text)
End Select
Please note that: 1. This code's running on a TextChanged event; 2. I'm from Portugal and here we use a comma (",") instead of a dot (".") for the decimal separator.
Could you help me to adjust my piece of code to work properly with two decimal places?
Any help will be very appreciated. And, as always, thank you all in advance.
Here's a custom class I've made which does what you require:
Public Class FactorDecimal
Private _value As String = "0"
Public DecimalPlaces As Integer
Public Sub AppendNumber(ByVal Character As Char)
If Char.IsNumber(Character) = False Then Throw New ArgumentException("Input must be a valid numerical character!", "Character")
_value = (_value & Character).TrimStart("0"c)
End Sub
Public Sub RemoveRange(ByVal Index As Integer, ByVal Length As Integer)
If _value.Length >= Me.DecimalPlaces + 1 AndAlso _
Index + Length > _value.Length - Me.DecimalPlaces Then Length -= 1 'Exclude decimal point.
If Index + Length >= _value.Length Then Length = _value.Length - Index 'Out of range checking.
_value = _value.Remove(Index, Length)
If _value.Length = 0 Then _value = "0"
End Sub
Public Overrides Function ToString() As String
Dim Result As Decimal
If Decimal.TryParse(_value, Result) = True Then
'Divide Result by (10 ^ DecimalPlaces) in order to get the amount of decimal places we want.
'For example: 2 decimal places => Result / (10 ^ 2) = Result / 100 = x,xx.
Return (Result / (10 ^ Me.DecimalPlaces)).ToString("0." & New String("0"c, Me.DecimalPlaces))
End If
Return "<parse error>"
End Function
Public Sub New(ByVal DecimalPlaces As Integer)
If DecimalPlaces <= 0 Then DecimalPlaces = 1
Me.DecimalPlaces = DecimalPlaces
End Sub
End Class
It works by letting you append numbers to form a long string of numerical characters (for example 3174 + 8 = 31748), then when you call ToString() it does the following:
It parses the long number string into a decimal (ex. "31748" => 31748.0)
It divides the decimal by 10 raised to the power of the amount of decimals you want (for example: 2 decimals => 31748.0 / 102 = 317.48).
Finally it calls ToString() on the decimal with the format 0.x - where x is a repeating amount of zeros depending on how many decimals you want (ex. 2 decimals => 0.00).
NOTE: This solution adapts to the current system's culture settings and will therefore automatically use the decimal point defined in that culture. For example in an American (en-US) system it will use the dot: 317.48, whereas in a Swedish (sv-SE) or Portuguese (pt-PT) system it will use the comma: 317,48.
You can use it like this:
Dim FactorDecimal1 As New FactorDecimal(2)
Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
If Char.IsNumber(e.KeyChar) = False Then
e.Handled = True 'Input was not a number.
Return
End If
FactorDecimal1.AppendNumber(e.KeyChar)
TextBox1.Text = FactorDecimal1.ToString()
End Sub
Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown
Dim TargetTextBox As TextBox = DirectCast(sender, TextBox)
e.SuppressKeyPress = True
Select Case e.KeyData 'In order to not block some standard keyboard shortcuts (ignoring paste since the pasted text won't get verified).
Case Keys.Control Or Keys.C
TargetTextBox.Copy()
Case Keys.Control Or Keys.X
TargetTextBox.Cut()
Case Keys.Control Or Keys.A
TargetTextBox.SelectAll()
Case Keys.Back, Keys.Delete 'Backspace or DEL.
FactorDecimal1.RemoveRange(TextBox1.SelectionStart, If(TextBox1.SelectionLength = 0, 1, TextBox1.SelectionLength))
TextBox1.Text = FactorDecimal1.ToString()
Case Else
e.SuppressKeyPress = False 'Allow all other key presses to be passed on to the KeyPress event.
End Select
End Sub
Online test: http://ideone.com/fMcKJr
Hope this helps!
Thank you #Visual Vincent. Your method works fine. However I managed to find a simpler way of doing what I asked by the following code:
Private Sub TextBox_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox.KeyPress
If Not Char.IsDigit(e.KeyChar) And Not Char.IsControl(e.KeyChar) Then
e.Handled = True
End If
End Sub
Private Sub TextBox_TextChanged(sender As Object, e As EventArgs) Handles TextBox.TextChanged
Select Case Val(Replace(Me.TextBox.Text, ",", "."))
Case 0 : Me.TextBox.Text = ""
Case Else
Me.TextBox.Text = Format(Val(Replace(Me.TextBox.Text, ",", "")) / 100, "0.00")
Me.TextBox.SelectionStart = Len(Me.TextBox.Text)
End Select
End Sub
This piece of code look suspicious simple to me. For now it works fine and does the trick exactly how I wanted. Maybe there's something missing to me, or maybe I wasn't clear enough on the description of my goal.
If you find any flaw on my method, please feel free to point it! I'll appreciate it very much.

tOGGLE cASE For Textbox?

How can I add tOGGLE cASE to textboxes, for example, I click a button and it changes the text in a textbox to tOGGLE cASE (hello -> hELLO), basically it takes first letter and lower cases it and the rest upper cases it.
Here is a method using .NET Culture functions to first convert to Title Case and then invert the case to your "tOGGLE cASE"
Private Sub btn_ConvertTotOGGLEcASE_Click(sender As Object, e As EventArgs) Handles btn_ConvertTotOGGLEcASE.Click
'Get the current value of the textbox
Dim MyText As String = MyTextBox.Text
'Convert it to Title Case using built in .NET tools
Dim MyTextInfo As System.Globalization.TextInfo = New System.Globalization.CultureInfo("en-US", False).TextInfo
MyText = MyTextInfo.ToTitleCase(MyText)
'Then invert the case of all the characters
Dim InvertedText As Char() = MyText.Select(Function(c) If(Char.IsLetter(c), If(Char.IsUpper(c), Char.ToLower(c), Char.ToUpper(c)), c)).ToArray()
'Finally convert it back to a string
MyTextBox.Text = New String(InvertedText)
End Sub
You can split you string in an array, iterate in the array with lcase(mid(string,1,1) & ucase(mid(string,2, len(string)-1)), and recompose your array in a string
Public function ToogleText(myStr as string) as string
dim str() as string
str = split(myStr," ")
dim toogleStr as string
toogleStr = ""
for each substr as string in str
toogleStr = toogleStr & lcase(mid(substr,1,1)) & ucase(mid(substr, 2,len(substr)-1)) & " "
next substr
if len(toogleStr) > 0 then
ToogleText = mid(toogleStr,1,len(toogleStr)-1)
else
ToogleText =""
end if
end function

Using Functions in Visual Basic

The program I'm working on has two different functions, one that calculates the number of syllables in a text file, and another that calculates the readability of the text file based on the formula
206.835-85.6*(Number of Syllables/Number of Words)-1.015*(Number of Words/Number of Sentences)
Here are the problems I'm having:
I'm supposed to display the contents of the text file in a multi-line text box.
I'm supposed to display the answer I get from the function indexCalculation in a label below the text box.
I'm having trouble calling the function to actually have the program calculate the answer to be displayed in the label.
Here is the code I have so far.
Option Strict On
Imports System.IO
Public Class Form1
Private Sub ExitToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExitToolStripMenuItem.Click
Me.Close()
End Sub
Private Sub OpenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OpenToolStripMenuItem.Click
Dim open As New OpenFileDialog
open.Filter = "text files |project7.txt|All file |*.*"
open.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
If open.ShowDialog() = Windows.Forms.DialogResult.OK Then
Dim selectedFileName As String = System.IO.Path.GetFileName(open.FileName)
If selectedFileName.ToLower = "project7.txt" Then
Dim text As String = File.ReadAllText("Project7.txt")
Dim words = text.Split(" "c)
Dim wordCount As Integer = words.Length
Dim separators As Char() = {"."c, "!"c, "?"c, ":"c}
Dim sentences = text.Split(separators, StringSplitOptions.RemoveEmptyEntries)
Dim sentenceCount As Integer = sentences.Length
Dim vowelCount As Integer = 0
For Each word As String In words
vowelCount += CountSyllables(word)
Next
vowelCount = CountSyllables(text)
Label1.Show(indexCalculation(wordCount, sentenceCount, vowelCount))
Else
MessageBox.Show("You cannot use that file!")
End If
End If
End Sub
Function CountSyllables(word As String) As Integer
word = word.ToLower()
Dim dipthongs = {"oo", "ou", "ie", "oi", "ea", "ee", _
"eu", "ai", "ua", "ue", "au", "io"}
For Each dipthong In dipthongs
word = word.Replace(dipthong, dipthong(0))
Next
Dim vowels = "aeiou"
Dim vowelCount = 0
For Each c In word
If vowels.IndexOf(c) >= 0 Then vowelCount += 1
Next
If vowelCount = 0 Then
vowelCount = 1
End If
Return vowelCount
End Function
Function indexCalculation(ByRef wordCount As Integer, ByRef sentenceCount As Integer, ByRef vowelCount As Integer) As Integer
Dim answer As Integer = CInt(206.835 - 85.6 * (vowelCount / wordCount) - 1.015 * (wordCount / sentenceCount))
Return answer
End Function
End Class
Any suggestions would be greatly appreciated.
Here are my suggestions:
update your indexCalculation function to take in Integers, not strings. that way you don't have to convert them to numbers.
remove all of your extra variables you are not using. this will clean things up a bit.
remove your streamreader. it appears you are reading the text via File.ReadAllText
Label1.Show(answer) should be changed to Label1.Show(indexCalculation(wordCount,sentenceCount,vowelCount)) -- unless Label1 is something other than a regular label, use Label1.Text = indexCalculation(wordCount,sentenceCount,vowelCount))
Then for the vowelCount, you need to do the following:
Dim vowelCount as Integer = 0
For Each word as String in words
vowelCount += CountSyllables(word)
Next
Also, add the logic to the CountSyllables function to make it 1 if 0. If you don't want to include the last character in your vowel counting, then use a for loop instead of a for each loop and stop 1 character short.

Keeping Leading Zeros in a Textbox

I need to keep leading zerod in a textbox that will be used to input data into a database. It is for SKU Numbers. I need to be able to type in leading zeros (ex. 001234567890) and then input them into the database.
However I can't figure out how to keep the leading zeros in a double. I do not need it in a string format but in a double. Is there a way to do this while keeping it a number and not a string?
EX.
txtProductBarcode.Text = Format(txtProductBarcode.Text, "############")
'This does not work
Using 0 in place of # will cause leading zeros to be output.
For example:
Dim s as string = string.Format("{0:000###}", 12345d)
Console.WriteLine(s)
will output
012345
See Pad a Number with Leading Zeros on MSDN.
BTW, not sure why you are worried about keeping the leading zeros whilst "as a double". The double is just a double, and formatting for display shouldn't matter. 0123 is the same as 123, otherwise you should be using a string datatype and not a double.
Try this is one.
You can convert the integer num to double.
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
Dim num As Integer
Dim temp As String = ""
Try
If Regex.IsMatch(TextBox1.Text, "^[0-9 ]+$") Then
num = Integer.Parse(TextBox1.Text)
If num <> 0 then
TextBox1.Text = num.ToString("D6")
temp = num
else
TextBox1.ReadOnly = False
End If
If num.Length = 6 Then
TextBox1.ReadOnly = True
TextBox1.BackColor = Color.White
ElseIf num = 0 Then
TextBox1.ReadOnly = False
End If
TextBox1.SelectionStart = TextBox1.Text.Length
End If
Catch ex As Exception
Msgbox(ex.Message)
End Try
End Sub