1

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).

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
  • Why would anyone post C code when you have tagged the question VB.NET and posted VB.NET code? As for the question, try explaining what you're actually trying to achieve rather than how you're trying to achieve it. As you are obviously aware, what you posted doesn't work so saying that you're trying to do it doesn't help anyone. You obviously need different code so we need to know what that code is actually supposed to achieve. – jmcilhinney Jun 10 '20 at 06:47
  • 1
    @jmcilhinney Apparently the OP meant C#, because yes, we routinely use links to C# questions as duplicates of VB questions - because they are, and we routinely get complaints that it's a different language, even though often all the OP needs to do is to delete the semicolons. – GSerg Jun 10 '20 at 06:58
  • Does this answer your question? [Referencing value by variable name](https://stackoverflow.com/questions/30195741/referencing-value-by-variable-name) – GSerg Jun 10 '20 at 06:58
  • well obviously because every time I do post a vb.net question, someone answers in C. sometimes the software gets stuck somewhere and I have many variables and I need to know the content of it dynamically. For example right now there was a do loop and a string variable I created didn't do what it needed to exit the string and I needed to know the variable of it. So I want to be able to click on a button, enter the variables name I mean what I declared the name of the variable and it shows the content of any variable I input. Does that make sense? –  Jun 10 '20 at 06:58
  • 1
    I can say with confidence that no one has answered you with C code. C# is more plausible, as it is a .NET language that uses C-based syntax, where VB.NET is a .NET language that uses BASIC-based syntax. It's unlikely that you received any actual answers in C# either though. It's certainly plausible that people have provided links to C# examples that demonstrate a relevant principle but you should not discourage that. Instead, get used to it. There is far more C# examples out there than VB but the principles are the same and C# code is not very difficult to read if you understand VB.NET. – jmcilhinney Jun 10 '20 at 07:38
  • As for your description, no it doesn't make sense. I understand it but the idea doesn't make sense. If you're talking about during development then that's what the debugger is for so you should learn how to use that. If you're talking about after deployment then you can use Reflection to get field values by name but building that functionality into a Production application would be bizarre. It's also not so easy for local variables and pretty much impossible for local variables outside the current method, which would be your `Click` event handler. – jmcilhinney Jun 10 '20 at 07:45
  • my software is being run on another computer without visual studio installed so I can't run debugger to see the content of a specific variable. All I will have is the application running and I just want to know the content of any variable during the application running. It's actually a REALLY great idea. But if you're saying it's not possible I understand. I appreciate your help –  Jun 10 '20 at 08:37
  • I'd recommend to add copious logging to the app so that you can get a handle on what's happening. That doesn't require doing something string-based; you can just log `my_variable` directly. If you can't do this, you're SOL, you have to either have access to a debugger or ability to modify the program to chase down things like this. Logging-based debugging is not interactive, unfortunately, but sometimes it's the only thing we can do. – Craig Jun 10 '20 at 14:02
  • One other thing... there are other debuggers than Visual Studio. – Craig Jun 10 '20 at 14:05
  • It's just that I have sooo many variables so for me to create a menu where software asks me what variable I want to see the content of requires each an "IF" lines where it shows the variable content. Other debuggers? So if my EXE file is running in windows, and I defined a variable there (dim temp as string), I can run a debugger and it can tell me the content of variables my exe app currently has? sorry I actually never used ANY type of debugger before I never understood how visual studio's own debugger worked :/ All I know is I have over 50 public variables all have an important part a –  Jun 10 '20 at 17:24
  • @Andrea How big is your app? 50+ vars seems like a lot of vars. I've written pretty large apps and still had nowhere near 50 vars. I wonder if you can't tighten things up with your vars a bit so there are less. Maybe reusing vars where appropriate. Don't forget, each individual var also increases the amount of mem your app uses. In most cases it's negligible, but, with 50+ it may not be so negligible. – J. Scott Elblein Jun 10 '20 at 18:31
  • Whether you can examine a local variable in a debugger depends on how the program was built; it's a lot more likely to be successful in a debug build than a release build (a common optimization is for local variables to never be stored in memory). The Visual Studio debugger is excellent and usually easy to work with. The alternatives are much less user-friendly. I've done some release build debugging with WinDbg; it can be done, but it's very much not for the faint of heart. – Craig Jun 10 '20 at 18:40
  • @J.ScottElblein 50 variables is trivial (and about the number I would expect, in total, in a small app of limited scope). You could have 5000 and still not make much of a dent in how much memory you use, depending on the contents. The important thing isn't how many variables you have, it's how well you use them (descriptive names, appropriate lifetimes, etc.). – Craig Jun 10 '20 at 18:42
  • @Andrea Even though you have 50 variables, if you're trying to track down a problem, presumably the problem isn't in all 50. You can do a lot with logger (and msgbox) based debugging to narrow down the scope of a problem to something more manageable. You should have a mental model of what the program is supposed to be doing; debugging is fundamentally about spotting where the actual behavior diverges from your mental model. – Craig Jun 10 '20 at 18:44

2 Answers2

2

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:

enter image description here

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
Idle_Mind
  • 38,363
  • 3
  • 29
  • 40
  • 1
    Maybe you have a special hotkey you hit and a hidden textbox and button appears so you can "debug" your program?! – Idle_Mind Jun 10 '20 at 19:27
  • one question though, the "CallByName" line. I have a module where I have defined a PUBLIC string. the name of that module is "putthings". I tried this code below but didn't work. Any suggestions? Dim value As String = CallByName(putthings, variable, CallType.Get) –  Jun 10 '20 at 23:42
  • 1
    Modules in VB.Net are a special beast and can't be accessed with CallByName(). For that, you'd need Reflection, and you'd have to hard-code the name of the module (or have an additional input to get the name of the module). – Idle_Mind Jun 11 '20 at 00:30
1

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.

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
  • 1
    Thank you so much for your effort. My application has over 50 public variables and they are changed soooo often it would take me hours to add extra code to update the content from each variable to the directory unfortunately :/ –  Jun 10 '20 at 18:17
  • @Andrea Welcome to the world of coding. ;) That's how it goes. The initial setup of adding 50 keys to the dictionary will take some time, but once it's done it's done. After that it's just a matter of copy/pasting the `dictionary(var) = var` wherever relevant. Time consuming? Yes. But it does what you asked. – J. Scott Elblein Jun 10 '20 at 18:22