Re: passing variable name rather than the variable
Yes, as I said, you have to know what you are doing with CopyMem.
Well, come to think of it, there is another neat solution which simply uses a good old well known VB object, without a new class or fancy tricks. Look at this:
Code:
Private Fruit As New Collection
Private LastFruit As String
Private Sub Form_Load()
Fruit.Add 10, "apple"
Fruit.Add 10, "banana"
Fruit.Add 10, "orange"
End Sub
Private Sub ChangeFruit(FruitName, Increment)
Fruit(FruitName) = Fruit(FruitName) + Increment
End Sub
'and you can do
LastFruit = "apple"
ChangeFruit LastFruit, 10
Items in a collection act exactly like named variable, if you use the key as an index to retrieve the value, the key being a name which is nothing more than a string.
Re: passing variable name rather than the variable
That's an interesting approach WoF. I doubt I would have thought of it, since I don't use collections. Though for the example I posted, I did consider a function which iterates through the UDT to find the correct element to update, which would be similar in some ways.
Re: passing variable name rather than the variable
Yes, right. I thought something like that, too.
But then I thought, my, what do we have the nice Collection for? It does the searching much faster.
This has nothing to do with the OPs request, but:
I like to use collections well. They are a real versatile tool, when you consider that you can collect not only numbers or strings, but also any kind of objects or controls, which you want to retrieve by a key or index.
I often use them to group controls, which have to be operated commonly and are not somehow in the same container or have nothing in common. You just add the groups of them to collections at form-load, and in the code you can do a for each pass over all controls in one collection, enabling, disabling or making them visible or whatnot.
Re: passing variable name rather than the variable
Thanks Wof--your ideas are always top-shelf.
As an additional twist, do you think it is possible to have an incoming string select a particular variable? Probably not, from what I've seen.
for example: IncomingString= "intDollars=100" would be processed and set intdollars to 100,
"bolOpenTheDoor= True" ,would do just what you see. Of course you can go through some lengthy case statement, listing every variable you might ever want to possibly change in your program.
case strVname= "intdollars"
intdollars=intdollars+strVvalue
case strVname= "bolOpenTheDoor"
BolOpenTheDoor=... etc
etc
But is it possible to have a generic processing, so you need not list all the variable in a lengthy case statment ahead of time. Something like the CallByName function to call routines.
Re: passing variable name rather than the variable
You nearly answered your own question, by referring to the CallByName statement. At least that's the first thing which comes to mind. What you might do, is create a class with Public Properties to access your variables. Then a string could determine which property would get called, hence which variable gets set. I suppose you would also need to parse the string based on the position of the "=", to pass what's after it as a separate argument.
However, if your intent is to allow the user to type in a string, and the program uses it as the ProcName parameter of CallByName, you'd need to account for non-compliant strings, including the variable types of the values being passed.
Re: passing variable name rather than the variable
The Collection solution I mentioned earlier should work as well.
Code:
Dim Fruit As New Collection
Private Sub Command1_Click()
Dim a$
a$ = InputBox("Your command>", "apple and banana")
ChangeFruit a$
End Sub
Private Sub Form_Load()
Fruit.Add 10, "apple"
Fruit.Add 10, "banana"
End Sub
Private Sub ChangeFruit(LiteralCommand As String)
Dim arg$()
arg = Split(LiteralCommand, "=")
Fruit.Remove arg(0)
Fruit.Add Val(arg(1)), arg(0)
Debug.Print arg(0), Fruit(arg(0))
End Sub
The only question remaining is:
Why can I not do Fruit(arg(0)) = Val(arg(1)) ???
It seems it can't be done. To change the value of a collected item you have to remove it and add it with the new value, like shown.
But no matter, this seems the most generic solution possible.
You can even "declare" new collected items if you do apropriate checks or on error resume.
If an item is not yet in the collection, it will simply be created.
orange=20 will create a new fruit named orange with an amount of 20.
Some more safety checks should be elaborated, analysing the user input, like stripping blanks, putting everything to lowercase and so on.
Re: passing variable name rather than the variable
Adding a little conclusion:
Instead of using the Collection I'd go and use the Dictionary.
It is more verstile than the Collection. It has a method to find out if a key already exists, provides a list of all keys AND allows to change a stored item's value in-line, that is without deleting and recreating it.
You have to add a reference to the Windows Scripting Runtime, though, to make use of this object.
And watch out. The syntax of adding an item is reverse to the collection:
Directory.Add KeyString, Value