Set the value of a public variable whose name is stored in a string

arvindn

Registered User.
Local time
Today, 21:26
Joined
Oct 1, 2003
Messages
99
Let's say i have variables :-

mformname = "Form1"
mvariable = "var1"

Var1 is a public variable in Form1.
i.e. the module of form1 contains the declaration


Public var1 as integer


How do i set the value of var1 provided i have only two string mformname, mvariable ?

To elaborate , Just as a property can be set by

forms(mformname).properties(mpropertyname)=mvalue

Is there some analogous way (or trick) for variables ?
 
arvindn,

Adding a public variable to a form with module level scope is tantamount to adding a property to a form. Within the form itself, you can easily set its value like this...

Code:
Me.Var1 = 99
or this ...
Code:
Var1 = 287

When the form is currently open, to assign a value to this variable from outside the form module, you might do so as follows:

Code:
TheFormName.PublicVar = 99

And if the form is closed...

Code:
'Open the form object
  Dim MyForm as Form
  Set MyForm = New TheFormName
'Assign a value to our variable.
  MyForm.PublicVar = 99

But to better control things, you would not create a module-level public variable. You would, instead, create a module-level private -- or "member" -- variable.

Code:
'The "m" prefix stands for member, meaning the variable
'is private, visible to the programmer only from within the 
'form module.
  Private mVariable as Integer
  Option Explicit
--------------------------------------------------------

To let a coder (who is often yourself) assign a value to the member variable from outside of the form module, you would add a property procedure to the form module. Among other things, you can use this procedure to protect the private variable from invalid assignments.

Code:
Property Let PropVariable(newValue as integer)

'Only let values from 1 to 100 be assigned to my member variable.
  If newValue >= 1 and <= 100 then
    mVariable = newValue
  Else
    'Silently fail...
  End if

End Property

(Note: Please consider all of this as pseudo code, something to use as a conceptual model rather than something to cut and paste into a project.)

Key piece of knowledge: a property is a public variable acting as a bodyguard for a private variable. A property procedure is the meeting place -- the interface -- for programmer and property.

Regards,
Tim
 
Last edited:
I posted a non-pseudo example of a form property here.
 
I have been unable to express my question properly it seems. :(


Dim mformname, mvarname as string
mformname=inputbox(Please enter name of form)
mvarname=inputbox(Please enter name of variable)


Now i want to set value of variable mvarname for form mformname.

For eg. if mvarname="var1" and mformname="form1" then i want to be able to set the value of public variable var1 of form form1.

So i cannot use forms(mformname).var1 as i do not know what will be the value of mvarname in advance.
 
Arvindn.

Again this seems like a hypothetical question.

In the real world if something can’t be done, or if we can’t find a solution, then the workaround comes into play.

It is “getting the job done” that is important…not if we can do it in a specific way.
That is why I think that some of your questions emanate from some teacher or hypothetical challenge.

Workaround…
Forget the Class Public variable idea.
Change var1 to a Text Box, even hidden, on the Form.
Write back to that Text Box, string, number, date…whatever.
Access that Text Box from wherever you like.

Code:
Public Sub Test()
    Dim mformname As String
    Dim mvariable As String

    mformname = "Form1"
    mvariable = "var1"

    Forms(mformname)(mvariable) = 1234

End Sub
Why oh why does it need to be a Public Integer?
What is the importance of that?
Why do you have to do it that way?
 
ChrisO.

Since u have taken this stance many times to my questions (As far as i remember).

One of the most important things for a modern human being is to accept that others may be thinking differently from u, (and u may be unaware of the full context and which may not be possible to describe) and it is possible that even though the situation be inexplicable to u, the other person needn't compulsorily be a maniac or a fool.

U yourself are very innovative and i genuinely respect that. Unfortunately i had this workaround (and some others) in mind but it does not satisfy my requirement.

I also thought of


eval("setvariablevalue(forms('" & mformname & "')." & mvarname & ",newvalue)")

Public functin setvariablevalue (mvar as integer, newvalue as integer)
mvar=newvalue
end function


But this doesn't work and i confess i don't know enough VBA to know why it doesn't.

I'll wait for a while and if anyone else cannot come up with a solution then i'll try to describe the full context.
But one of the answers is that integer was taken only for an example, it can be any data type.
 
arvindn said:
One of the most important things for a modern human being is to accept that others may be thinking differently from u, (and u may be unaware of the full context and which may not be possible to describe) and it is possible that even though the situation be inexplicable to u, the other person needn't compulsorily be a maniac or a fool.

I believe Chris's question was more rhetorical than an insult to your intelligence. By asking why you were doing something it makes you stop and think about what you are doing and what you are trying to achieve. I ask people similar questions when I can see a more logical solution.
 
Part of the problem here, arvindn, is knowing exactly what you seek to do.

Your problem is that a public variable doesn't always exist. I.e. if it exists as a public variable in a general module, it STILL doesn't exist until and unless something happens to force the general module to instantiate it. In C++ or VBA, this must be done by specific instantiation code. AND if it exists in a class module (as in your case), it is GUARANTEED to not exist unless that form happens to be open at the time. When a form is closed, its module and variables don't exist any more. Not to mention that declaring a variable public from a class module is a questionable tactic to start with. From a general module... maybe. From a class module... very bad form, no pun intended.

But now, let's talk about what ELSE you are asking. You want to store a variable in a module. Typically, the syntax for this would be something (kind of) like module-name-as-qualifier.variable-name - also called a "qualified reference" - but this ONLY works for references to the variable from VBA code that already knows that there is a qualified path to the variable that MUST be open at the time. The issue is "binding time" - a complex concept on a good day. You cannot bind this reference unless the module is open so that its symbol offsets are available. Why is that? ...

Your problem is that the syntax for this is not dynamic (AFAIK). The variables in a module are not treated as though they are part of a formal collection (or at least, they weren't the last time I looked), so there is no syntax for Modules("module-name").variables("variable-name") - or Forms("form-name").Module.Variables("Variable-name") for the equivalent class module.

This is very different for the case of, say, a text box on a form, which IS a part of a formal collection. You CAN say Forms("Foobar").Controls("SNAFU") and it will (more or less) work - because the elements of those collections can be enumerated. Your original question asked about properties. As it happens, there is a collection called Properties for each object, so you are quite right that you could specify a property name and set it. The above could be extended to Forms("Foobar").Controls("SNAFU").Properties("Backcolor") quite easily. Except, of course, that Access stores collections in a way that makes them "sparse." That is, if the property isn't used and isn't referenced, it also isn't STORED. I.e. an IMAGE property would be blank on objects that weren't image controls, even though technically the IMAGE property is a general object property.

This dynamic control reference ability is just not there for the variables. No corresponding variable-collection enumeration syntax exists ('cause they ain't in collections), so you have no way to dynamically select variables. And THAT is the key. If you cannot enumerate it as a collection, you can't get there in a simple step from ANYWHERE, be it VBA, queries, or any other method you name.

Therefore, what you seek is not supported by Access using any simple-minded methods. And the answers ChrisO gave you were spot-on as far as I could see. When he is asking why you need to do it this way, it is because he knows (as I do) that you are asking for the impossible. And the correct way to get the impossible is to compromise on the nearest POSSIBLE method that has the same effect - but doesn't break the rules.

The ONLY way I could ever see to do this using Access is to define a public subroutine that "knows the name" of every public OWN variable defined in your data-storage module or segment. You would give it the name of the variable and the value. It would have a CASE/SELECT or IF-THEN ladder to see which variable you named. If you didn't name a variable it knew about, you would be S.O.L. for that call. AND - this isn't going to work too well for a class module anyway, which is your specific case.
 
Thanks Doc Man.

I understand what u say quite well. Please do me one more favor. I wrote about a trick that i tried to use to overcome this (ref. my prev. post).

If i use eval and then pass the variable by reference to a function, its value should be modified, but it isn't? Can anyone think of a modification/enhancement that makes it work ?
 
G’day Arvindn.

May I say up front that I am not in the slightest way offended by your reply, nor should you be by mine.

So here we go…

I will try to help anyone where I can and do it for free, just like everyone else on this site.

But if it is a hypothetical assignment, perhaps from some ‘Nutty Professor’, then that ‘Professor’ needs to get into the ‘Real World’.
On the other hand, it may have been asked of you in order to see if you could find a ‘workaround’.

My aim is to try and answer questions when I can…but not do assignments for students.

Get the point??? We/I have absolutely no idea for the reason for the question.

Question therefore for you…
Given we/I don’t know the circumstances, should we/I waste our time answering possibly hypothetical questions and do assignments for you? What would that gain you?

So please answer this simple question…
Just what is the purpose and origin of the question?

Regards,
Chris.
 
ChrisO.

This is exactly what i meant in my previous reply.


One of the most important things for a modern human being is to accept that others may be thinking differently from u, (and u may be unaware of the full context and which may not be possible to describe) and it is possible that even though the situation be inexplicable to u, the other person needn't compulsorily be a maniac or a fool.


If u feel that these are just hypothetical questions, then please do me one favour; Don't bother to reply. I can do without ur reasoning which has not helped me in any way as evident by this thread.

As i mentioned earlier the entire context is not possible to describe here and i would have loved to have done so would it have been possible.

Anyway, returning to work, W.r.t. my last post, can anyone suggest an enhancement or the flaw with the eval technique i am using to work around this ?
 
Anyway, returning to work, W.r.t. my last post, can anyone suggest an enhancement or the flaw with the eval technique i am using to work around this ?

Code:
eval("setvariablevalue(forms('" & mformname & "')." & mvarname & ",newvalue)")

Public functin setvariablevalue (mvar as integer, newvalue as integer)
mvar=newvalue
end function

This still tries to apply a collection concept to a non-collected item. Nor is mvar necessarily sure to be extant unless the form itself is open. Hence it will not work either. Sorry I had to point to the flaw rather than a clever work-around. You cannot avoid this problem. Variables are not always available cross-module, even if public - and certainly not for class modules. Without reverse-engineering your Access program (which your license expressly forbids, by the way), you simply cannot get there from here.

In passing, ChrisO is not out of bounds in asking what he asked. Remember I said that sometimes the only way to do the impossible is to get to the closest possible point and do THAT instead? ChrisO was trying to identify the closest possible point. You were kind of hard on him, really, and I'm sure he means well. You've got to realize we aren't mind readers here. When you want to do something, we cannot always tell the difference between a mental masturbation, a carelessly-worded school assignment, and a career-threatening do-or-die assignment. If you read this board enough, you would realize we get a smattering of all of those.

As you say, back to work:

About the ONLY other way I can think of to do this sort of thing is to execute some dynamically-created SQL UPDATE query that names the desired variable as a field in a table and provides the desired value of the variable as another field (the one being updated). Then you can use DLookup in other places to get the current value that was last loaded by this putative UPDATE query.

Unlike your module-based variable approach, the records in a table CAN be enumerated and shared from other code. Unfortunately, this is about a thousand times slower than memory-to-memory ops, 'cause it usually involves a disk operation or two or six. So if you have lots of these to do and speed is an issue, my solution ain't so good, either.

It also suffers from the problem that if this DB is shared, you have to qualify the query with the username for each user so two users cannot step on each other. Initializing the temp tables would be a real pain. You also need to do lots of cleanup on exiting from your DB so that your temp table doesn't get all blown up with leftovers over a period of some days of use.
 
Thank u Doc Man.

I guess i will have to think of some other way to achieve my goal.
 
Arvindn…please don’t read this because I’m not replying (to you).

In my view, yes my view, because if it weren’t my view I would be plagiarizing someone else...

You are correct in that you and I have been down this dark alley before. (That much is certain.)

I have made the same comments before, criticized before (if you like), but at least I have been consistent.
And so have you… been consistent.

But in the past, when you have been asked to give a reason for your questions, you seem to fail. You invariably, bail out of the conversation, with some comment about the ‘personal qualities’ of the person asking you for details. Some comment like: -

“One of the most important things for a modern human being is to accept that others may be thinking differently…”

That, at the extreme, is utter crap. It is nothing less than a foil, to ‘for whatever reason’ evade the question.

I doubt if you are old enough to know what ‘modern’ means. I doubt if you are intelligent enough to know what is ‘one of the most important’ things. And I do doubt if you know what ‘thinking differently’ actually means.

If you wish to be ‘mystical’ and try the impossible in some way then try this…

Drop your pants, contemplate your navel, sit on a bucket of water and try to inhale it.
(Clue…The workaround may be through the orifice of your choice without outside influence!)

Let’s cut the crap…

This is a public forum.
Your question is yours.
We do it for free.
The answers given are not compulsory.
Stop thinking about yourself and your own little problems.
The answers given are everyone’s.
Don’t try to inhibit answers from anyone… they are here for everyone.
If you don’t want answers then don’t ask questions.

Glad you didn’t read my non-reply…
 
Now, trying to be constructive here, I'm going to offer a possible solution that is faster than a recordset - but still slower than you might have wished.

Pat Hartman, in another thread, suggests using an open but hidden form as a point of common contact for a problem someone else had in moving data from form to form when one of the forms isn't necessarily there at all times. This same idea might work for you. As I have tried to explain, the issue is "collection membership." You can't update something cross-form too easily when there is no collection that holds it. Stated another way, you can only change that which is exposed, and Access doesn't expose variables underlying a class module.

BUT....

Imagine, if you will, an unbound form with text boxes for all of the things you need to hold. You have to design it ahead of time to have enough variables and they cannot be arbitrarily/dynamically named - BUT as controls, they are in a collection that isn't bound to a recordset. ('cause as I said, it is an unbound form.) Now use the Form.Hidden property to make it invisible.

You cannot store a variable in its class module - but you CAN store a value in one of the text boxes of a hidden form. The issue will be one of having enough control/variables to meet your needs. If they are forever dynamic, you STILL can't get there without doing something a bit MORE bizarre - by creating and deleting text-box controls on the hidden form. Or perhaps is there a rename option? But in any case, I'm sure you see where this is going.

I reiterate, there is no direct way in Access to get to where you said you wanted to go. IMHO, Access is an excellent tool - but it doesn't always support every possible design decision you could make. And you have to live with its limitations.

I have to say this: If you had opened up even a little bit with the nature of your problem, we might have been able to figure a workaround for you that made sense in your context. But without at least SOME glimpse of the context, there is NO HOPE of getting that workaround beyond some abstract ideas that might be in a totally wrong direction. I can understand that even my solutions might be wrong for you, and I'm a 29-year programming veteran who has seen his share of nasty problems - and their solutions.

Remember: At this site, you are getting advice for the cost of your internet connection. It costs nothing to be a member. It costs no more to connect to this site than to any others. Less than some. FREE advice is given by folks who truly try to help. We do it out of, I guess, some variant of the old Greek work agape - the love of people in general, or perhaps you would see it as a generally friendly or charitable attitude.

ChrisO's last reply (the one that immediately precedes this one) expresses anger that you blew him off. For you to have shown him less than minimal gratitude for what you were GIVEN earlier is unbecoming a gentleperson. ChrisO is JUSTIFIED in having his nose out of joint. You are the one who slapped first.
 
ChrisO, ur reply ably suits ur vulgar character and mind. The language and content both illustrate what sort of an uncivilized person u are and to the deficiencies of ur upbringing.

U have and u had absolutely nothing to offer at the points we met and yet u kept blabbering on. Read the threads in which we have met here and elsewhere for proof (and inspite of what u claim all of those except this one have the full context).

Yes my questions may seem impossible to a person like u who probably thinks anything he can't think of is impossible and that is what i wrote twice.

Doc Man, i appreciate the help given by u. Thank You.
 
You know Arvindn, I don’t really give a shit about ‘your’ predicament…

What perturbs me most of all is that you still do not have an answer, nor does anyone else.

That answer will only come with a description of the problem.

You write very well in English, and that is no minor matter.

But…let us have another look at the bolded line in my last post…

Let’s cut the crap…

I have worked for many years (>20) with people from India, both male and female.
Invariably they all have had a sense of humor.
They have seen, both in that which I say and what which I write, as both humorous and logical.
And me in them. It has been an exchange of ideas, that is all, and that is everything.

You want to differ? Fine. But do not try to lower my esteem of other Indian Nationals based on your performance.
Apart from me, they would eat you alive.

So let’s get back to the posted logic and try to forget the personal diversion.

I know for a fact that the word ‘crap’ is well understood in India.
I also know that the word ‘cut’ is well understood in India, within the context of the sentence.
It centers on the contraction ‘Let’s’.
Let’s means ‘let us’.
‘Us’ is plural.
Within the context of my original reply, it means ‘you and I’.
Therefore ‘Let’s cut the crap’ equates to…
Let you and I cut the crap.
I believe you wrote crap…
I turned it around to demonstrate that I too can write crap…

But what will you and I, and everyone else, have at the end of the day…crap?
What did the ‘hard yards’ produce…crap?
Why should anyone waist their time producing ‘crap’?.

I will say again, if I was not clear…
I do not get offended all that easily.
What offends me is outright stupidity.

Question…
Do you still want to find an answer, or are you still pissing into the wind?
 
This is better than Pay Per View. :cool:
 
You both seem pretty childish to me, i mean come on.. this is an access help board, not a gathering forum for 11yr old kids desperatly awaiting the next DragonBall Z game or pokemon episode.

Let's keep the flaming in those boards, not here.

Although I don't have an answer for you arvindn i will say that what you are trying to do is tricky at most. In defence of ChrisO i found that some of what he has suggested helped me, and some i already have done before and works well. Now yes, this may not work in the context of your project, but without describing even a tiny bit of the context then how do you expect us to help you? Perhaps we may be able to find a workaround to your liking that fits your needs.

Im not here to rant, im just here to let you both know that you both are in the wrong at least to some degree, so like ChirsO said, cut the crap and try not to act like an 11yr. old who's balls haven't even dropped (aka grown up) this goes for you too ChrisO .
 
Last edited:

Users who are viewing this thread

Back
Top Bottom