How to Recognize Variable Globally in VB.NET? I have the code below, my problem is that VB.NET does not recognize the variables "Z_lenght" and "Z_width" outside the IF Statement (i.e. after ENDIF).
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If TextBox1.Text > TextBox2.Text Then
Dim Z_lenght = TextBox1.Text
Dim Z_width = TextBox2.Text
Else
Dim Z_lenght = TextBox2.Text
Dim Z_width = TextBox1.Text
End If
Dim Z_area = Z_lenght * Z_width
RichTextBox1.AppendText("Length = " & Z_lenght)
RichTextBox1.AppendText("Width = " & Z_width)
RichTextBox1.AppendText("Area = " & Z_area)
End Sub
End Class
I appreciate any help/comment.
Public Class Form1
Dim Z_length As Double = 0
Dim Z_width As Double = 0
Dim Z_area As Double = 0
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If TextBox1.Text > TextBox2.Text Then
' I don't know what you're trying to achieve here,
' but I recommend try using Double.TryParse()
Double.TryParse(TextBox1.Text, Z_length)
Double.TryParse(TextBox2.Text, Z_width)
Else
Double.TryParse(TextBox2.Text, Z_length)
Double.TryParse(TextBox1.Text, Z_width)
End If
Z_area = Z_length * Z_width
RichTextBox1.AppendText("Length = " & Z_length)
RichTextBox1.AppendText("Width = " & Z_width)
RichTextBox1.AppendText("Area = " & Z_area)
End Sub
End Class
This will make Z_Length, Z_width and Z_area usable in class Form1
declare your variables outside of the if else scope.
http://msdn.microsoft.com/en-us/library/1t0wsc67.aspx
If you declare a variable within a block, you can use it only within
that block. In the following example, the scope of the integer
variable cube is the block between If and End If, and you can no
longer refer to cube when execution passes out of the block.
Given your comments, it seems you should review variable scopes. You can use your variables outside your if-else inside your if-else.
Related
Dim txtLinqSum1Ad, txtLinqSum2Ad, txtLinqSum3Ad, txtLinqSum4Ad as String
instead of writing this thing
TextBox1.AppendText(txtLinqSum1Ad & vbNewLine)
TextBox1.AppendText(txtLinqSum2Ad & vbNewLine)
TextBox1.AppendText(txtLinqSum3Ad & vbNewLine)
TextBox1.AppendText(txtLinqSum4Ad & vbNewLine)
I would like to do something like that
For i as integer = 0 to 3
TextBox1.AppendText(txtLinqSum & i & Ad & vbNewLine)
Next
Do you think that could be possible? it would be useful when I have a lot of strings?
Yes, it's possible with CallByName(), or via Reflection (much longer syntax).
For CallByName() to work, though, your variables have to be PUBLIC at Form/Class level:
Public Class Form1
Public txtLinqSum1Ad, txtLinqSum2Ad, txtLinqSum3Ad, txtLinqSum4Ad As String
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
txtLinqSum1Ad = "A"
txtLinqSum2Ad = "B"
txtLinqSum3Ad = "C"
txtLinqSum4Ad = "D"
End Sub
Private Sub butBereken_Click(sender As Object, e As EventArgs) Handles butBereken.Click
For i As Integer = 1 To 4
Dim s As String = CallByName(Me, "txtLinqSum" & i & "Ad", CallType.Get)
TextBox1.AppendText(s & vbNewLine)
Next
End Sub
End Class
But just because you can, doesn't mean you should. An array or other type of collection (List/Dictionary) would probably be a better choice.
I was able to debug my coding then, when I click my "Calculate" button, the error message
System.ArgumentException: 'Argument 'NPer' is not a valid value.'
pops up (first pic). The second pic is my app. The reset button and the exit button work, but when I click the "Calculate" button it doesn't work.
Public Class Form1
Const dblMonths_Year As Double = 12
Const dblNew_Rate As Double = 0.05
Const dblUsed_Rate As Double = 0.08
Dim dblAnnualRate As Double = dblNew_Rate
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim dblVehicleCost As Double
Dim dblDownPayment As Double
Dim dblMonths As Double
Dim dblLoan As Double
Dim dblMonthlyPayment As Double
Dim dblInterest As Double
Dim dblPrincipal As Double
Dim intCount As Integer
Dim strOut As String
Dim blnInputOK As Boolean = True
If blnInputOK = True Then
dblLoan = dblVehicleCost - dblDownPayment
dblMonthlyPayment = Pmt(dblAnnualRate / dblMonths_Year, dblMonths, -dblLoan)
lstOutput.Items.Clear()
For intCount = 1 To dblMonths
dblInterest = IPmt(dblAnnualRate / dblMonths_Year, intCount, dblMonths, -dblLoan)
dblPrincipal = PPmt(dblAnnualRate / dblMonths_Year, intCount, dblMonths, -dblLoan)
strOut = "Month" & intCount.ToString("d2")
strOut &= ": payment =" & dblMonthlyPayment.ToString("n2")
strOut &= ", interest =" & dblInterest.ToString("n2")
strOut &= ", principal =" & dblPrincipal.ToString("n2")
lstOutput.Items.Add(strOut)
Next
End If
End Sub
Private Sub btnReset_Click(sender As Object, e As EventArgs) Handles btnReset.Click
radNew.Checked = True
dblAnnualRate = dblNew_Rate
lblAnualRate.Text = dblNew_Rate.ToString("p")
txtCost.Clear()
txtDownPayment.Clear()
txtMonths.Clear()
lstOutput.Items.Clear()
txtCost.Focus()
End Sub
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Close()
End Sub
Private Sub radNew_CheckedChanged(sender As Object, e As EventArgs) Handles radNew.CheckedChanged
If radNew.Checked = True Then
dblAnnualRate = dblNew_Rate
lblAnualRate.Text = dblNew_Rate.ToString("p")
lstOutput.Items.Clear()
End If
End Sub
Private Sub radUsed_CheckedChanged(sender As Object, e As EventArgs) Handles radUsed.CheckedChanged
If radUsed.Checked = True Then
dblAnnualRate = dblUsed_Rate
lblAnualRate.Text = dblUsed_Rate.ToString("p")
lstOutput.Items.Clear()
End If
End Sub
End Class
You need to set the variables from the input fields, preferably making sure that the user has input sensible values, for example:
Public Class Form1
Const MONTHS_PER_YEAR = 12
Const NEW_RATE = 0.05
Const USED_RATE = 0.08
Dim annualInterestRate As Double = NEW_RATE
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim vehicleCost = 0.0D
Dim downPayment = 0.0D
Dim monthsToPay = 0
Dim inputOk = Decimal.TryParse(tbCost.Text, vehicleCost) AndAlso
Decimal.TryParse(tbDownPayment.Text, downPayment) AndAlso
Integer.TryParse(tbMonthsToPay.Text, monthsToPay)
If inputOk Then
lstOutput.Items.Clear()
Dim loanAmount = vehicleCost - downPayment
Dim monthlyPayment = Pmt(annualInterestRate / MONTHS_PER_YEAR, monthsToPay, -loanAmount)
For monthNumber = 1 To monthsToPay
Dim interestPayment = IPmt(annualInterestRate / MONTHS_PER_YEAR, monthNumber, monthsToPay, -loanAmount)
Dim principalPayment = PPmt(annualInterestRate / MONTHS_PER_YEAR, monthNumber, monthsToPay, -loanAmount)
Dim strOut = $"Month {monthNumber:D2}"
strOut &= $": payment = {monthlyPayment:C2}"
strOut &= $", interest = {interestPayment:C2}"
strOut &= $", principal = {principalPayment:C2}"
lstOutput.Items.Add(strOut)
Next
End If
End Sub
' other code here
End Class
It is convention to use UPPER_SNAKE_CASE for constants. Variables should (usually) be declared at the point of use.
In VB.NET, set Option Strict On and Option Infer On for an easier programming experience.
The D is a forced literal type for a Decimal value. The Decimal type should be used for money, even though the Pmt, IPmt, and PPmt functions don't (I suspect the Decimal type wasn't available when those functions were written).
I used interpolated strings to show you how they could be used in your program: they can be useful for making code more readable.
I'm trying to do this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim my_variable as String = "hello"
Dim blabla as string = "my_variable"
msgbox(blabla) ' I want this to display: "hello"
End Sub
Any way you guys can help me in VB.NET (not C# please).
What you want cannot be done for a LOCAL variable like my_variable.
If that variable is at CLASS level, though, it can be done with REFLECTION.
If the variable is at class level and is PUBLIC, you can cheat and use CallByName:
Public Class Form1
Public counter As Integer = 911
Public my_variable As String = "Hello World!"
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim variable As String = TextBox1.Text
Try
Dim value As String = CallByName(Me, variable, CallType.Get)
MessageBox.Show(variable & " = " & value)
Catch ex As Exception
MessageBox.Show("Variable not found: " & variable)
End Try
End Sub
End Class
Type the name of the variable in TextBox1 and its value will be displayed in the message box....easy peasy.
If you don't want the variables to be public, then it can be accomplished via Reflection, but it doesn't look quite as simple and pretty. Look it up if you want to go that route.
--- EDIT ---
Here's a version that can find public members of a module:
Code:
Imports System.Reflection
Public Class Form2
Public counter As Integer = 911
Public my_variable As String = "Hello World!"
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
lblResults.Text = ""
Dim variable As String = TextBox1.Text
Try
Dim value As String = CallByName(Me, variable, CallType.Get)
lblResults.Text = variable & " = " & value
Catch ex As Exception
End Try
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
lblResults.Text = ""
Dim moduleName As String = txtModule.Text
Dim moduleField As String = txtModuleMember.Text
Dim myType As Type = Nothing
Dim myModule As [Module] = Nothing
For Each x In Assembly.GetExecutingAssembly().GetModules
For Each y In x.GetTypes
If y.Name.ToUpper = moduleName.ToUpper Then
myType = y
Exit For
End If
Next
If Not IsNothing(myType) Then
Exit For
End If
Next
If Not IsNothing(myType) Then
Dim flags As BindingFlags = BindingFlags.IgnoreCase Or BindingFlags.NonPublic Or BindingFlags.Public Or BindingFlags.Static Or BindingFlags.Instance
Dim fi As FieldInfo = myType.GetField(moduleField, flags)
If Not IsNothing(fi) Then
Dim value As String = fi.GetValue(Nothing)
lblResults.Text = moduleField & " = " & value
End If
End If
End Sub
End Class
Public Module PutThings
Public SomeValue As String = "...success!..."
End Module
My suggestion (just 1 idea, thinking out loud) would be to create a separate, global list of all of your variables, and every single time one of the variables you want to know the contents of changes, update the global list.
For example:
' Global declaration
Dim dictionary As New Dictionary(Of String, String)
Sub Form_Load()
' Add keys to all vars you want to lookup later
With dictionary
.Add("varCarrot", String.Empty)
.Add("varPerl", String.Empty)
End With
End Sub
Sub SomeSub()
strCarrot = "hello"
intPerl = 12
' Any time the vars change that you want to track, update the respective dictionary key
dictionary(varCarrot) = strCarrot
dictionary(varPerl) = intPerl.ToString
Do Until intPerl = 100
intPerl += 1
strCarrot = "hello " & intPerl
dictionary(varCarrot) = strCarrot
dictionary(varPerl) = intPerl.ToString
Loop
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
dim strLookup as String = text1.text ' the variable you want to lookup entered in the text1 textbox; i.e. "varCarrot"
' See if the requested key exists
If dictionary.ContainsKey(strLookup) Then messagebox.show(dictionary.Item(strLookup))
End Sub
When you're ready to no longer have that functionality in your app, such as when all done debugging it, and ready to finally release it, comment out all the dictionary stuff.
I have the simplest of if statements to work out if a person has passed an exam or not when I run the code the result always comes up as fail.
Public Class Form1
Dim EnglishMark As Single
Dim ScienceMark As Single
Dim MathsMark As Single
Dim AverageMark As Single
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
EnglishMark = Val(txtEnglish.Text)
ScienceMark = Val(txtScience.Text)
MathsMark = Val(txtMaths.Text)
AverageMark = (EnglishMark + ScienceMark + MathsMark) / 3 / 100
If (AverageMark >= 50) Then
lblDisplay.Text = "You Passed Well Done" & Format(AverageMark, "Percent")
Else
lblDisplay.Text = "You Failed Try Again" & Format(AverageMark, "Percent")
End If
End Sub
End Class
Thanks
I am trying to find the correct way to set the string values inside the For without knowing the actual numbers. here's what i am trying to do as it was possible in vb6 but not sure using vb.net
Public Class Form1
Dim iTest1 As String
Dim iTest2 As String
Dim iTest3 As String
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For i = 1 To 3
"iTest" & i = "aaa" & i
Next
Debug.Print("iTest1:" & iTest1)
Debug.Print("iTest2:" & iTest2)
Debug.Print("iTest3:" & iTest3)
End Sub
End Class
Try using Arrays instead.
Dim iTest(3) As String
For i = 1 To 3
iTest(i) = "aaa" & i
Next
Or this
Dim variables As New Dictionary(Of String, String)()
For i = 1 To 3
variables("iTest" + i.ToString) = "aaa" & i
Next
Console.WriteLine("iTest1:" + variables("iTest1"))
Console.WriteLine("iTest2:" + variables("iTest2"))
Console.WriteLine("iTest3:" + variables("iTest3"))
It's technically possible, but not really a recommended approach...
If you make the variables Public, then you can use the legacy CallByName() function brought over from VB6:
Public Class Form1
Public iTest1 As String
Public iTest2 As String
Public iTest3 As String
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For i As Integer = 1 To 3
CallByName(Me, "iTest" & i, CallType.Let, "aaa" & i)
Next
Debug.Print("iTest1:" & iTest1)
Debug.Print("iTest2:" & iTest2)
Debug.Print("iTest3:" & iTest3)
End Sub
End Class
Without CallByName(), this can be accomplished via Reflection. Note that this works with Private or Public variables:
Public Class Form1
Private iTest1 As String
Private iTest2 As String
Private iTest3 As String
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim T As Type = Me.GetType
For i As Integer = 1 To 3
Dim F As Reflection.FieldInfo = T.GetField("iTest" & i, Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic)
If Not IsNothing(F) Then
F.SetValue(Me, "aaa" & i)
End If
Next
Debug.Print("iTest1:" & iTest1)
Debug.Print("iTest2:" & iTest2)
Debug.Print("iTest3:" & iTest3)
End Sub
End Class