Set string values inside for without knowing names - vb.net

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

Related

literate for each loop my string in VB.Net

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.

Display variable content dynamically

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.

Save clicks to file

I got asked a couple of days ago how to save number of clicks you have done to each button in a program to a small file, to keep track of what is most used. Since it was ages ago i dabbled with visual basic i said i would raise the question here, so here goes.
There are 5 buttons labels Button1-Button5. When a button is clicked it should look for the correct value in a file.txt and add +1 to the value. The file is structured like this.
Button1 = 0
Button2 = 0
Button3 = 0
Button4 = 0
Button5 = 0
So when button1 is clicked it should open file.txt, look for the line containing Button1 and add +1 to the value and close the file.
I have tried looking for some kind of tutorial on this but have not found it so i'm asking the collective of brains here on Stackoverflow for some guidance.
Thanks in advance.
delete file first
new ver ..
Imports System.IO.File
Imports System.IO.Path
Imports System.IO
Imports System.Text
Public Class Form1
Dim line() As String
Dim strbild As StringBuilder
Dim arr() As String
Dim i As Integer
Dim pathAndFile As String
Dim addLine As System.IO.StreamWriter
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim fileName As String = "myfile.txt"
Dim appPath As String = My.Application.Info.DirectoryPath
pathAndFile = Path.Combine(appPath, fileName)
If System.IO.File.Exists(pathAndFile) Then
'line = File.ReadAllLines(pathAndFile)
Else
Dim addLineToFile = System.IO.File.CreateText(pathAndFile) 'Create an empty txt file
Dim countButtons As Integer = 5 'add lines with your desired number of buttons
For i = 1 To countButtons
addLineToFile.Write("Button" & i & " = 0" & vbNewLine)
Next
addLineToFile.Dispose() ' and close file
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
writeToFile(1)
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
writeToFile(2)
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
writeToFile(3)
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
writeToFile(4)
End Sub
Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
writeToFile(5)
End Sub
Public Sub writeToFile(buttonId As Integer)
Dim tmpButton As String = "Button" & buttonId
strbild = New StringBuilder
line = File.ReadAllLines(pathAndFile)
Dim f As Integer = 0
For Each lineToedit As String In line
If InStr(1, lineToedit, tmpButton) > 0 Then
Dim lineSplited = lineToedit.Split
Dim cnt As Integer = lineSplited.Count
Dim newVal = addCount(CInt(lineSplited.Last()))
lineSplited(cnt - 1) = newVal
lineToedit = String.Join(" ", lineSplited)
line(f) = lineToedit
End If
f = f + 1
Next
strbild = New StringBuilder
'putting together all the reversed word
For j = 0 To line.GetUpperBound(0)
strbild.Append(line(j))
strbild.Append(vbNewLine)
Next
' writing to original file
File.WriteAllText(pathAndFile, strbild.ToString())
Me.Refresh()
End Sub
' Reverse Function
Public Function ReverseString(ByRef strToReverse As String) As String
Dim result As String = ""
For i As Integer = 0 To strToReverse.Length - 1
result += strToReverse(strToReverse.Length - 1 - i)
Next
Return result
End Function
Public Function addCount(ByVal arr As Integer) As Integer
Return arr + 1
End Function
End Class
Output in myfile.txt
Button1 = 9
Button2 = 2
Button3 = 4
Button4 = 0
Button5 = 20
Create a vb winform Application
Drag on your form 5 buttons (Button1, Button2, ... etc)
copy that :
Imports System.IO.File
Imports System.IO.Path
Imports System.IO
Imports System.Text
Public Class Form1
Dim line() As String
Dim strbild As StringBuilder
Dim arr() As String
Dim i As Integer
Dim pathAndFile As String
Dim addLine As System.IO.StreamWriter
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim fileName As String = "myfile.txt"
Dim appPath As String = My.Application.Info.DirectoryPath
pathAndFile = Path.Combine(appPath, fileName)
If System.IO.File.Exists(pathAndFile) Then
line = File.ReadAllLines(pathAndFile)
Else
Dim addLineToFile = System.IO.File.CreateText(pathAndFile) 'Create an empty txt file
Dim countButtons As Integer = 5 'add lines with your desired number of buttons
For i = 1 To countButtons
addLineToFile.Write("Button" & i & " = 0" & vbNewLine)
Next
addLineToFile.Dispose() ' and close file
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
writeToFile(1)
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
writeToFile(2)
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
writeToFile(3)
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
writeToFile(4)
End Sub
Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
writeToFile(5)
End Sub
Public Sub writeToFile(buttonId As Integer)
Dim tmpButton As String = "Button" & buttonId
strbild = New StringBuilder
line = File.ReadAllLines(pathAndFile)
i = 0
For Each lineToedit As String In line
If lineToedit.Contains(tmpButton) Then
Dim lineSplited = lineToedit.Split
Dim newVal = addCount(CInt(lineSplited.Last()))
'lineToedit.Replace(lineSplited.Last, newVal)
lineToedit = lineToedit.Replace(lineToedit.Last, newVal)
line(i) = lineToedit
End If
i = i + 1
Next
strbild = New StringBuilder
'putting together all the reversed word
For j = 0 To line.GetUpperBound(0)
strbild.Append(line(j))
strbild.Append(vbNewLine)
Next
' writing to original file
File.WriteAllText(pathAndFile, strbild.ToString())
End Sub
' Reverse Function
Public Function ReverseString(ByRef strToReverse As String) As String
Dim result As String = ""
For i As Integer = 0 To strToReverse.Length - 1
result += strToReverse(strToReverse.Length - 1 - i)
Next
Return result
End Function
Public Function addCount(ByVal arr As Integer) As Integer
Return arr + 1
End Function
End Class
Have fun ! :)CristiC777
try this on vs2013
change If confition
line = File.ReadAllLines(pathAndFile)
i = 0
For Each lineToedit As String In line
If InStr(1, lineToedit, tmpButton) > 0 Then
'If lineToedit.Contains(tmpButton) = True Then
Dim lineSplited = lineToedit.Split
Dim newVal = addCount(CInt(lineSplited.Last()))
lineToedit = lineToedit.Replace(lineToedit.Last, newVal)
line(i) = lineToedit
End If
i = i + 1
Next

vb.net How to reference a local variable

Hi I have the below code:
Dim ColMap As Integer = Val(Microsoft.VisualBasic.Left(dr("MappedTo").ToString(), 3))
Dim ValorLeido As String
ValorLeido = temp(dr("NoColumn").ToString())
Select Case ColMap
Case 101
_101 = ValorLeido
Case 102
_102 = ValorLeido
Case 103
_103 = ValorLeido
End Select
Is there a way that I can use something like me("_" & ColMap) = ValorLeido ??
Here's a simplified example showing CallByName(). Note the the target variables are Public:
Public Class Form1
Public _101 As String
Public _102 As String = "{Default Value}"
Public _103 As String
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Debug.Print("Before: _102 = " & _102)
Dim ColMap As Integer = 102
Dim ValorLeido As String = "Hello World!"
Dim varName As String = "_" & ColMap
CallByName(Me, varName, CallType.Let, ValorLeido)
Debug.Print("After: _102 = " & _102)
End Sub
End Class
And here's the same thing via Reflection, which allows the target variables to be Private:
Imports System.Reflection
Public Class Form1
Private _101 As String
Private _102 As String = "{Default Value}"
Private _103 As String
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Debug.Print("Before: _102 = " & _102)
Dim ColMap As Integer = 102
Dim ValorLeido As String = "Hello World!"
Dim varName As String = "_" & ColMap
Dim fi As FieldInfo = Me.GetType.GetField(varName, Reflection.BindingFlags.Public Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)
fi.SetValue(Me, ValorLeido)
Debug.Print("After: _102 = " & _102)
End Sub
End Class
Try using a storage medium meant to hold a series of ID's to a series of values such as a Dictionary
Dim ColMap As Integer = Val(Microsoft.VisualBasic.Left(dr("MappedTo").ToString(), 3))
Dim ValorLeido As String = temp(dr("NoColumn").ToString())
Dim Lookup as New Generic.Dictionary(of Integer,String)
Lookup(ColMap) = ValorLeido
' 1 way of Reading values out of a dictionary safely
Dim Value as string
Value=""
if lookup.trygetvalue("101",value) then
msgbox("Value for 101 is """ & value & """")
else
msgbox("Value for 101 is not found)
end if
You could also access via a single indexed property if this structure already exists
public property Value(Index as integer) as string
get
select case index
case 101
return _101
case 102
return _102
case 103
return _103
case else
Throw new exception("Index not present " & index)
end get
set (value as string)
' populate with reverse process ...
end set
end property

Reading from and manipulating a .csv file

I have multiple .csv files for each month which go like:
01/04/2012,00:00,7.521527,80.90972,4.541667,5.774305,7,281.368
02/04/2012,00:00,8.809029,84.59028,6.451389,5.797918,7,274.0764
03/04/2012,00:00,4.882638,77.86806,1.152778,15.13611,33,127.6389
04/04/2012,00:00,5.600694,50.35417,-3.826389,15.27222,33,40.05556
The format is : Date in the form dd/mm/yy,Current time,Current temperature,Current humidity,Current dewpoint,Current wind speed,Current wind gust,Current wind bearing
The program needs to calculate the average for
temperature
humidity
wind speed
wind direction
and display them on a text box.
any ideas?
Here is what I have done so far...
Option Strict On
Option Explicit On
Imports System.IO
Imports System
Public Class Form1
Private Sub cmb1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmb1.SelectedIndexChanged
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnexit.Click
Me.Close()
End Sub
Private Sub btn1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btndata.Click
'This is for August
If cmb1.SelectedIndex = 1 Then
TextBox1.Clear()
Using reader As New StreamReader("c://temp/DailyAug12log.csv")
Dim line As String = reader.ReadLine()
Dim avgTemp As Integer
Dim fields() As String = line.Split(",".ToCharArray())
Dim fileDate = CDate(fields(0))
Dim fileTime = fields(1)
Dim fileTemp = fields(2)
Dim fileHum = fields(3)
Dim fileWindSpeed = fields(4)
Dim fileWindGust = fields(5)
Dim fileWindBearing = fields(6)
While line IsNot Nothing
counter = counter + 1
line = reader.ReadLine()
End While
avgTemp = CInt(fields(2))
avgTemp = CInt(CDbl(avgTemp / counter))
TextBox1.Text = TextBox1.Text & "Month = August" & vbCrLf & "Temperature Average: " & avgTemp & vbCrLf
End Using
End If
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim files() As String
files = Directory.GetFiles("C:\Temp", "*.csv", SearchOption.AllDirectories)
For Each FileName As String In files
cmb1.Items.Add(FileName.Substring(FileName.LastIndexOf("\") + 1, FileName.Length - FileName.LastIndexOf("\") - 1))
Next
End Sub
End Class
Private Class Weather
Public SampleTimeStamp AS Date
Public Temperature AS Double
Public Humidity As Double
Public WindSpeed AS Double
Public WindBearing AS Double
End Class
Sub Main
Dim samples = ReadFile("c://temp/DailyAug12log.csv")
Dim avgTemperature = samples.Average(Function(s) s.Temperature)
...
End Sub
Private Function ReadFile(ByVal fileName as String) AS List(Of Weather)
Dim samples As New List(Of Weather)
Using tfp As new TextFieldParser(filename)
tfp.Delimiters = new String() { "," }
tfp.TextFieldType = FieldType.Delimited
While Not tfp.EndOfData
Dim fields = tfp.ReadFields()
Dim sample As New Weather()
sample.SampleTimeStamp = Date.ParseExact(fields(0) & fields(1), "dd\/MM\/yyyyHH\:mm", CultureInfo.InvariantCulture)
sample.Temperature = Double.Parse(fields(2), CultureInfo.InvariantCulture)
sample.Humidity = Double.Parse(fields(3), CultureInfo.InvariantCulture)
sample.WindSpeed = Double.Parse(fields(4), CultureInfo.InvariantCulture)
sample.WindBearing = Double.Parse(fields(5), CultureInfo.InvariantCulture)
samples.Add(sample)
End While
Return samples
End Using
End Function
I would not use a this aprroach - if the order of the columns changes, your program will show wrong results.
I would use a good csv reader like http://kbcsv.codeplex.com/ and read the Data to a datatable. then you can calculate your resulting columns quite easily and reliablly, because you can adress each column like MyDatatable.Cooumns["Headername"].