Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Dim Dynamic Variable Names?

1,661 views
Skip to first unread message

Dan

unread,
Nov 11, 2002, 11:36:20 AM11/11/02
to
I want to take each item from a query sting with unknown
content and put each item into a local variable. For
example, if an ASP gets passed ?name=dan, then I want to
create a variable 'name' and set it equal to 'dan'.

The problem is that I can't figure out how to do dynamic
variable names. Is something like this even possible in
vbScript?

For Each x In Request.QueryString
'Dim x
'x = Request.QueryString(x)
Next

Joe Earnest

unread,
Nov 11, 2002, 11:58:50 AM11/11/02
to
Hi Dan,

Take a look at the execute command. It executes
a string, and you can define a variable name in the
string.

E.g.,

x= "variablename"

Execute x & "= ""something"""

Execute has some quirks, and it's available
in different flavors, so it pays to read the
documentation. Also, it was a new command
with VBS5, so be careful if you script may run
on older setups.

Regards,
Joe Earnest


"Dan" <d...@emedia-solutions.biz> wrote in message
news:d49601c289a0$770341b0$2ae2...@phx.gbl...

Joe Earnest

unread,
Nov 11, 2002, 12:32:16 PM11/11/02
to
I should have added -- in my experience,
Execute circumvents any Option Explicit
statement, so Dim'ing is unnecessary
(though you could execute a Dim command
first if you wanted to). The new variable is
created at the script level. This becomes
an issue if using Execute to set variables,
and particularly new object variables, in a
procedure and expecting them to be
automatically destroyed when exiting the
procedure.

Don't think that info is in the standard
documentation.

Regards,
Joe Earnet

"Joe Earnest" <joeea...@qwest.net> wrote in message
news:#aCjULaiCHA.3736@tkmsftngp08...

Paul Randall

unread,
Nov 12, 2002, 2:09:20 AM11/12/02
to
Hi, Joe
I read your response right after having re-read Dino Exposito's words about the execute and executeglobal functions in his Windows
Script Host book. It seemed as though either you or Dino must be wrong. So I modifed and combined two scripts from the book to
test the two functions. See the code below. I think that the execute function works pretty much as advertised in SCRIPT56.CHM.
But the executeglobal function definitely does circumvent Option Explicit! I think that 'option explicit' may be one of the few
VBScript statements that the execute and executeglobal functions can't handle - maybe they just ignore each other.

I think you are at least partially wrong about the destruction of object variables. I will try to cook up a script tomorrow to show
you what I mean. I'd appreciate seeing your example of execute() and executeglobal() scripts that do not properly destroy objects.

I think Dino created an oxymoron when he named a function 'main' and then called it from the main (global?) stream of the code. His
comment just before invoking the main function is especially confusing.

<CODE>
' ExecGlob.vbs
' Demonstrates the Execute() and ExecuteGlobal() functions
'------------------------------------------------------------

Option Explicit
dim strMsg
' Call the main function (this is the GLOBAL scope)
Main
strMsg = strMsg & "In the main stream of code, after calling function Main:" & vbcrlf
strMsg = strMsg & vbcrlf & "Here, referencing a causes an error too" & vbcrlf
strMsg = strMsg & "because it has not been Dimed here." & vbcrlf

on error resume next
strMsg = strMsg & "a has no value here: " & a & vbcrlf
if err.number then strMsg = strMsg & err.Description & vbcrlf
on error goto 0
strMsg = strMsg & "b is 2 everywhere: " & b
msgbox strMsg

' First function that gets called
Function Main
Dim strCode1, strCode2
strCode1 = "Dim a: a = 1"
strCode2 = " b = 2"

' Declares the variable 'a' and initializes it to 1
Execute strCode1
ExecuteGlobal strCode2
strMsg = "In function main, 'execute' set a to 1 and " & vbcrlf & _
"'execute global' set b to 2." & vbcrlf
' The value HERE is 1
strMsg = strMsg & "a is 1 here: " & a & vbcrlf
strMsg = strMsg & "b is 2 here: " & b & vbcrlf & vbcrlf

' Call another function
AnotherFunc
End Function


Function AnotherFunc
strMsg = strMsg & "Function main called AnotherFunc" & vbcrlf & _
"In this function, the value of A will not be reported" & vbcrlf & _
" and will cause an error because it has not been Dimed" & _
" here." & vbcrlf
' The value of 'a' is 1 HERE as well
on error resume next
strMsg = strMsg & "a has no value here: " & a & vbcrlf
if err.number then strMsg = strMsg & err.Description & vbcrlf
on error goto 0
strMsg = strMsg & "b is 2 here too: " & b & vbcrlf & vbcrlf
End Function

</CODE>
-Paul Randall

"Joe Earnest" <joeea...@qwest.net> wrote in message news:umEoAeaiCHA.1368@tkmsftngp09...

Joe Earnest

unread,
Nov 12, 2002, 12:44:02 PM11/12/02
to
Hi Paul,

Thanks for your response. If I'm off on this, I really
need to know, so I'm keenly interested. (Besides
not wanting to give bad advice.)

I use Execute extensively in standard library error
trapping (where I pass script lines to a function and
execute them in an error-trapped environment) and
in object-variable control procedures, as well as
building recursive temporary procedures within
procedures. My scripts all seem to be operating
properly on both WinXP and Win98 with vbs5.6
installed, but my library subroutines are built to take
various contingencies into account, and may be
masking a problem that I'm not aware of.

I had found little difference between the operation
of Execute and ExecuteGlobal. I have routinely
created undimmed object variables in a subroutine
with Execute, then exited the subroutine and used
them in another subroutine.

My best understanding of Execute has been the
following:

Execute must use a limited interpreter environment,
in the sense that it must lack some of the secondary
pointers. This shows up in its limited response to
error handling and inability to effect an internal
"on error ...".

It will check the local variable list and use a local
variable, if defined. (I use this to pass ByRef
variables in my procedures and to use in-routine
defined local variables in Execute statements.)
My prior experience, however, was that if the
statement referred to a variable that did not exist,
Execute creates it, regardless of any Option Explicit
statement, and creates it as a global (script-level)
variable. (This limits it for trapping variable name
errors, but gives it tremendous capability for
handling object variables within procedures.) I
had assumed that Execute lacked sufficient pointers
to know where it was or to know that Option
Explicit was invoked.

From your insightful example, however, it appears
that if one uses the "Dim" statement in the Execute
command (and, I assume, *not* the ExecuteGlobal
command) in a procedure, then one can take advantage
of the pointers accessed by the "Dim" statement and
create the variable as local. This makes Execute even
more useful.

Try the following air code:

---

Option Explicit
zTest1
WScript.Echo "Shell object = " _
& TypeName(oShell)
On Error Resume next
WScript.Echo "FileSystem object= " _
& VarType(oFileSys)
If Err Then WScript.Echo _
"FileSystem object error."
On Error GoTo 0
zTest2
WScript.Quit

Function zTest1 ()
Execute "Set oShell= " _
& "CreateObject(""WScript.Shell"")"
Execute "Dim oFileSys"
Execute "Set oFileSys= " _
& "CreateObject(""" _
& "Scripting.FileSystemObject"")"
zTest1= 0
End Function

Function zTest2 ()
WScript.Echo "Shell object = " _
& TypeName(oShell)
On Error Resume next
WScript.Echo "FileSystem object= " _
& VarType(oFileSys)
If Err Then WScript.Echo _
"FileSystem object error."
On Error GoTo 0
End Function

---

Regards,
Joe Earnest


"Paul Randall" <paul...@cableone.net> wrote in message
news:OookNphiCHA.2636@tkmsftngp08...


> Hi, Joe
> I read your response right after having re-read Dino Exposito's words
about the execute and executeglobal functions in his Windows
> Script Host book. It seemed as though either you or Dino must be wrong.
So I modifed and combined two scripts from the book to
> test the two functions. See the code below. I think that the execute
function works pretty much as advertised in SCRIPT56.CHM.
> But the executeglobal function definitely does circumvent Option Explicit!
I think that 'option explicit' may be one of the few
> VBScript statements that the execute and executeglobal functions can't
handle - maybe they just ignore each other.
>
> I think you are at least partially wrong about the destruction of object
variables. I will try to cook up a script tomorrow to show
> you what I mean. I'd appreciate seeing your example of execute() and
executeglobal() scripts that do not properly destroy objects.
>
> I think Dino created an oxymoron when he named a function 'main' and then
called it from the main (global?) stream of the code. His
> comment just before invoking the main function is especially confusing.
>

> [code removed]
>
> -Paul Randall

Paul Randall

unread,
Nov 12, 2002, 8:41:15 PM11/12/02
to
Hi, Joe
There is too much food for thought here. I will try to get a reply in here tomorrow.
"Joe Earnest" <joeea...@qwest.net> wrote in message news:eVafOJniCHA.2748@tkmsftngp11...

Michael Harris (MVP)

unread,
Nov 12, 2002, 8:49:31 PM11/12/02
to
> I had found little difference between the operation
> of Execute and ExecuteGlobal. I have routinely
> created undimmed object variables in a subroutine
> with Execute, then exited the subroutine and used
> them in another subroutine.
>

I checked with Eric Lippert (who wrote the Execute and ExecuteGlobal
implementation code)...

What you observe is actually a bug and unintended behavior. Execute within
a procedure is *not* supposed to create a variable with global scope. He
also noted that this is probably something that will never get fixed ;-)...

--
Michael Harris
Microsoft.MVP.Scripting
Seattle WA US


Joe Earnest

unread,
Nov 12, 2002, 11:13:33 PM11/12/02
to
Hi Michael,

Thanks very much for the info and the sanity check.
This one time that I may be happy that the bug won't
get fixed. The ability to circumvent Option Explicit
and create global variables in a selective and
knowledgable manner really makes Execute a far
more powerful tool than it was "intended" to be.
With an object-checking/setting procedure, I can let
my library procedures create the object connections
as needed, when they're not already established,
without having to Dim everything at the outset, close
them when and as needed, and still insure that I never
have more than one instance of any primary object
open at any one time.

Regards,
Joe Earnest

"Michael Harris (MVP)" <mik...@mvps.org> wrote in message
news:#YWlwariCHA.4228@tkmsftngp08...


---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.410 / Virus Database: 231 - Release Date: 10-31-02


Paul Randall

unread,
Nov 13, 2002, 1:28:10 AM11/13/02
to
Hi, Joe
I've been trying to come up with a way to instrument code to display information about it without obscuring the code. Not and easy
task. I don't really like what I've got, but I don't know how to improve it. This is your code which creates the two objects -- I
wanted to start with a simple example. Run it once but don't close the message box. Then change whether 'option explicit' is
executed and run it again. Then compare the two message boxes.

I've got a lot to learn about VBScript's scope and context issues. And after reading Michael's comment, I guess the Scripting 5.6
docs is a good source for the designer's intent, but a bad source for how these issues are actually implimented.

<CODE>
Option Explicit
Dim strMsg, strWhere

InitializeMsg

zTest1

strWhere = "In Main after returning from ztest1"
TellAboutIt oShell, "Shell object oShell", strWhere
On Error Resume next
TellAboutIt oFileSys, "File System object oFileSys", strWhere
If Err Then
TellAboutItsError Err, "oFileSys, File System object", strWhere
End if
On Error GoTo 0

zTest2

msgbox strMsg

WScript.Quit

Function zTest1 ()
Dim strShell, strFileSys

strShell = "Set oShell = CreateObject(""WScript.Shell"")"
strFileSys = "Dim oFileSys" & vbcrlf & _


"Set oFileSys= " _
& "CreateObject(""" _
& "Scripting.FileSystemObject"")"

execute strShell
execute strFileSys

strMsg = strMsg & _
"In Function zTest1, 'Execute'd the following statements" & _
vbcrlf & strShell & vbcrlf & strFileSys & vbcrlf & vbcrlf

zTest1= 0
End Function

Function zTest2 ()

strWhere = "In Function ztest2"
TellAboutIt oShell, "Shell object oShell", strWhere
On Error Resume next
TellAboutIt oFileSys, "File System object oFileSys", strWhere
If Err Then
TellAboutItsError Err, "oFileSys, File System object", strWhere
End if
On Error GoTo 0

End Function

Function TellAboutIt(Who, strWhat, strWhere)
strMsg = strMsg & strWhere & vbcrlf & vbtab & _
strWhat & " TypeName = " & TypeName(Who) & _
" VarType = " & VarType(Who) & vbcrlf
End Function

Function TellAboutItsError(objError, strWhat, strWhere)
With objError
strMsg = strMsg & strWhere & vbcrlf & vbtab & _
"Error occurred while accessing " & strWhat & vbcrlf & vbtab & vbtab & _
"Description = " & .Description & vbcrlf & vbtab & vbtab & _
"Number = "
If .Number < 0 then
strMsg = strMsg & Hex(.Number) & vbcrlf & vbtab & vbtab
else
strMsg = strMsg & .Number & vbcrlf & vbtab & vbtab
end if
strMsg = strMsg & "Source = " & .Source & vbcrlf
End With
End Function

Function InitializeMsg
strMsg = _
"Structure of this program:" & vbcrlf & _
"Main Program" & vbcrlf & _
"(" & GetExplicit & ")" & vbcrlf & _
" -Call zTest1 which creates a shell " & _
"and a file system object" & vbcrlf & _
" -Display info on the two objects" & vbcrlf & _
" -Call zTest2, which also displays info on " & _
"objects created in zTest1" & vbcrlf & _
" -Display this message" & vbcrlf & _
"Quit" & vbcrlf & vbcrlf & _
"Info on objects: " & vbcrlf & vbcrlf
end function

Function GetExplicit()
Dim strTemp
strTemp = "Option Explicit "
on error resume next
gobldygook = gobldygook
if err.Number = 500 then
strTemp = strTemp & "WAS "
else
strTemp = strTemp & "was NOT "
end if
GetExplicit = strTemp & "declared."
end function
</CODE>

-Paul Randall

"Joe Earnest" <joeea...@qwest.net> wrote in message news:eVafOJniCHA.2748@tkmsftngp11...

Joe Earnest

unread,
Nov 13, 2002, 2:36:59 AM11/13/02
to
Hi Paul,

Great script. Yours are some of the most thoroughly
revealing scripts I see on the group. I never run
without Option Explicit, so I would never have caught
this. I tried some other variations to insure that there
is a valid local oFileSys association and that the local
Dim causes the Empty variable effect. I'm at a loss as
to why (or how) Execute would (or could) create a
global definition, but set the association only locally.
The only reasons I can see for this anomolous behavior
are (1) as I speculated previously, Execute isn't playing
with a full set of pointers and gets confused, or (2) it's
just a bug and who knows. I'm trusting that its behavior
with Option Explicit set is sufficiently consistent to rely
upon.

Also, I sure don't mean to knock the standard
documentation. It's really quite good, and I rely on it
a lot. But I'm not shocked when it's wrong. (I'm
personally aware of only three points where the
documentation is actually erroneous -- which is really
good when you consider that it must be a committee
effort.) I like to experiment, so I trust my experimentation
when in doubt, and spend a few minutes hammering
out a few quick tests. I think of it as a trail guide.
Really useful when planning or starting a new trail,
and a nice reference for what you forgot, but I always
rely on general compass and topo skills when in doubt.

Regards,
Joe Earnest

"Paul Randall" <paul...@cableone.net> wrote in message

news:eLUrz2tiCHA.1736@tkmsftngp11...

---


Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).

Version: 6.0.410 / Virus Database: 231 - Release Date: 11-01-02


0 new messages