Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.

Go Back   Vista Forums > Misc Newsgroups > VB Script

Vista - Problem in returning an object from a function

Reply
 
Old 05-21-2009   #1 (permalink)
VbScript function returning an object


 
 

Problem in returning an object from a function


Hi,
I want a vbscript function to return an object. When i tried the following
piece of code, i got therun time error as "Invalid Assignment". I am not sure
where am wrong. Kindly help me out.




Dim colFiles as Object
colFiles= ListFiles("C:\")

for each objFile in colFiles
Msgbox(objFile.Name)
Next


Function ListFiles(Byval path as string) as Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = path

Set objFolder = objFSO.GetFolder(objStartFolder)

Set colFiles = objFolder.Files

set ListFiles =colFiles
End Function


My System SpecsSystem Spec
Old 05-21-2009   #2 (permalink)
Richard Mueller [MVP]


 
 

Re: Problem in returning an object from a function


"VbScript function returning an object" <VbScript function returning an
object@xxxxxx> wrote in message
news:FF1D0265-B996-4EE0-9D6A-650105B478B3@xxxxxx
Quote:

>
> Hi,
> I want a vbscript function to return an object. When i tried the following
> piece of code, i got therun time error as "Invalid Assignment". I am not
> sure
> where am wrong. Kindly help me out.
>
>
>
>
> Dim colFiles as Object
> colFiles= ListFiles("C:\")
>
> for each objFile in colFiles
> Msgbox(objFile.Name)
> Next
>
>
> Function ListFiles(Byval path as string) as Object
> Set objFSO = CreateObject("Scripting.FileSystemObject")
> objStartFolder = path
>
> Set objFolder = objFSO.GetFolder(objStartFolder)
>
> Set colFiles = objFolder.Files
>
> set ListFiles =colFiles
> End Function
>
First, your snippet is vb6. You cannot type variables in VBScript. You need
to remove "as string" and "as object". Then the script will work if you use
the Set keyword when you assign the object to the reference colFiles. For
example:
===========
Dim colFiles
Set colFiles= ListFiles("C:\")

for each objFile in colFiles
MsgBox objFile.Name
Next

Function ListFiles(Byval path)
Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = path
Set objFolder = objFSO.GetFolder(objStartFolder)
Set colFiles = objFolder.Files
set ListFiles =colFiles
End Function
=========
The function can be simplified a bit as follows:
=======
Function ListFiles(Byval path)
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(path)
Set ListFiles = objFolder.Files
End Function

--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
--


My System SpecsSystem Spec
Old 05-21-2009   #3 (permalink)
mayayana


 
 

Re: Problem in returning an object from a function

How did you manage to get that far? VBScript doesn't have
"strong datatyping". Your script should have failed first with
the declarations of "as Object" and "as string".

If you want to return an object you have to use Set. Your
script works that way:

'-----------------------------------------------

Dim colFiles
Set colFiles = ListFiles("C:\")

For Each objFile in colFiles
MsgBox(objFile.Name)
Next

Function ListFiles(byval path)
Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = path
Set objFolder = objFSO.GetFolder(objStartFolder)
Set colFiles = objFolder.Files
Set ListFiles =colFiles
End Function

'-------------------------------------------

It's a bit sloppy, though, to be passing around objects
and depending on the WSH to clean them all up. If you
want a list of folder files it might be better to put the
path strings into an array and pass that:

Dim FolFiles, s, i
FolFiles = ListFiles("C:\")

For i = 0 to UBound(FolFiles)
s = s & FolFiles(i) & vbCrLf
Next

MsgBox s

Function ListFiles(byval path)
Dim A1(), Cnt, i2, colFiles, objFSO, objFolder
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(path)
Set colFiles = objFolder.Files
Cnt = colFiles.count
i2 = 0
ReDim A1(Cnt - 1)
For Each objFile in colFiles
A1(i2) = objFile.Name
i2 = i2 + 1
Next
Set colFiles = Nothing
Set objFolder = Nothing
Set objFSO = Nothing
ListFiles = A1
End Function

Quote:

>
> Hi,
> I want a vbscript function to return an object. When i tried the following
> piece of code, i got therun time error as "Invalid Assignment". I am not
sure
Quote:

> where am wrong. Kindly help me out.
>
>
>
>
> Dim colFiles as Object
> colFiles= ListFiles("C:\")
>
> for each objFile in colFiles
> Msgbox(objFile.Name)
> Next
>
>
> Function ListFiles(Byval path as string) as Object
> Set objFSO = CreateObject("Scripting.FileSystemObject")
> objStartFolder = path
>
> Set objFolder = objFSO.GetFolder(objStartFolder)
>
> Set colFiles = objFolder.Files
>
> set ListFiles =colFiles
> End Function
>

My System SpecsSystem Spec
Old 05-21-2009   #4 (permalink)
ekkehard.horner


 
 

Re: Problem in returning an object from a function

mayayana schrieb:
[...]
Quote:

> It's a bit sloppy, though, to be passing around objects
> and depending on the WSH to clean them all up. If you
> want a list of folder files it might be better to put the
> path strings into an array and pass that:
>
> Dim FolFiles, s, i
> FolFiles = ListFiles("C:\")
>
> For i = 0 to UBound(FolFiles)
> s = s & FolFiles(i) & vbCrLf
> Next
>
> MsgBox s
>
> Function ListFiles(byval path)
> Dim A1(), Cnt, i2, colFiles, objFSO, objFolder
> Set objFSO = CreateObject("Scripting.FileSystemObject")
> Set objFolder = objFSO.GetFolder(path)
> Set colFiles = objFolder.Files
> Cnt = colFiles.count
> i2 = 0
> ReDim A1(Cnt - 1)
> For Each objFile in colFiles
> A1(i2) = objFile.Name
> i2 = i2 + 1
> Next
> Set colFiles = Nothing
> Set objFolder = Nothing
> Set objFSO = Nothing
> ListFiles = A1
> End Function
[...]

(1) It's not sloppy to be passing around objects and depending
on the WSH to clean them all up, but good programming practice.
Memory management is what the runtime system is good for. Except
for a few special cases, setting a variable to Nothing is a waste
of time.

(2) Taking a (rich) collection you got for free from the FSO and copy it
to an array (with reduced info) is wasteful and distracts from the
problem to be solved.

(3) Who - if not the WSH - will take care of A1, ListFiles, and FolFiles?
(*Three* instances of the list of names, as = copies)

Demo:

Dim oFS : Set oFS = CreateObject( "Scripting.FileSystemObject" )
Dim sSDir : sSDir = ".\tmp"
Dim oFiles : Set oFiles = oFS.GetFolder( sSDir ).Files
Dim oFile
For Each oFile In oFiles
WScript.Echo oFile.Name, oFile.Size
Next
Dim aFiles : aFiles = getFilesToArray( oFS, sSDir )
For Each oFile In aFiles
WScript.Echo oFile, "Sorry, no size available"
Next

WScript.Quit 0

Function getFilesToArray( oFS, sSDir )
Dim oFiles : Set oFiles = oFS.GetFolder( sSDir ).Files
ReDim aFiles( oFiles.Count - 1 )
Dim nIdx : nIdx = 0
Dim oFile
For Each oFile In oFiles
aFiles( nIdx ) = oFile.Name
nIdx = nIdx + 1
Next
getFilesToArray = aFiles
aFiles( 0 ) = "No risk to write to aFiles( 0 )"
WScript.Echo "**********************", aFiles( 0 )
Dim sName
For Each sName In getFilesToArray
WScript.Echo "still here:", sName
Next
End Function

Output:

Bind 848
Create 2843
g-xxx 7114
o-xxx 9237
xusca.edp 7114
********************** No risk to write to aFiles( 0 )
still here: Bind
still here: Create
still here: g-xxx
still here: o-xxx
still here: xusca.edp
Bind Sorry, no size available
Create Sorry, no size available
g-xxx Sorry, no size available
o-xxx Sorry, no size available
xusca.edp Sorry, no size available
My System SpecsSystem Spec
Old 05-21-2009   #5 (permalink)
ekkehard.horner


 
 

Re: Problem in returning an object from a function

T Lavedas schrieb:
Quote:

> On May 21, 6:14 am, VbScript function returning an object <VbScript
> function returning an obj...@xxxxxx> wrote:
Quote:

>> Hi,
>> I want a vbscript function to return an object.
[...]
Quote:
Quote:

>> for each objFile in colFiles
>> Msgbox(objFile.Name)
should be: Msgbox objFile.Name
Quote:
Quote:

>> Next
[...]
Quote:

> If you really just wanted a list, I'd modify it as ...
the OT obviously wants an array of objects.
Quote:

>
> Function arrListFiles(Byval path) ' as file list array
> Dim f, s
> with CreateObject("Scripting.FileSystemObject")
> for each f in .GetFolder(path).Files
> s = s & f.Name & vbCRLF
> next
> end with
> arrListFiles = Split(Replace(s, vbCRLF & vbCRLF, vbCRLF), vbCRLF)
> End Function
[...]

Using string concatenation to handle a list of elements is
inefficient and often - as in this case - looses information
by converting=destroying types. Here the excuse "I don't
want to use the costly "ReDim Preserve" isn't applicable,
as the number of files/elements is known.

The line

arrListFiles = Split(Replace(s, vbCRLF & vbCRLF, vbCRLF), vbCRLF)

may look clever, but just results in an array with an empty
element at the end. If you really need concatenation to a
temporary result, put the 'separator' in front as in

Function arrListFiles2(path) ' as file list array
Dim f, s
for each f in CreateObject("Scripting.FileSystemObject").GetFolder(path).Files
s = s & vbTab & f.Name
next
arrListFiles2 = Split( Mid( s, 2 ), vbTab )
End Function

BTW: What is the use of the "ByVal" in nearly all the sample
function posted?



My System SpecsSystem Spec
Old 05-21-2009   #6 (permalink)
mayayana


 
 

Re: Problem in returning an object from a function

> (1) It's not sloppy to be passing around objects and depending
Quote:

> on the WSH to clean them all up, but good programming practice.
> Memory management is what the runtime system is good for. Except
> for a few special cases, setting a variable to Nothing is a waste
> of time.
>
That's an old debate and I can see the logic
of your view. There are good points on both sides.
Personally I would especially avoid passing an
object whose parent object is going out of scope.
It might work OK under the WSH. I don't really
know. But it's sloppy and potentially risky either
way. And someday you might need to be coding
in something that doesn't coddle you as much
as the WSH does.

It's kind of like signalling a turn when driving. It's
not necessary if there are no other cars around,
but if one just gets into the habit of always signalling
then one doesn't have to look around and make a
decision at each turn; and there's no harm in "wasted"
signalling.
Quote:

> (2) Taking a (rich) collection you got for free from the FSO and copy it
> to an array (with reduced info) is wasteful and distracts from the
> problem to be solved.
>
You didn't get it for free. So why hold it if you don't
need it? (The OP gave no indication that anything
more than file names was needed.) WSH may hide the
details, but there's still cost. Not much cost in this case,
for sure, but again, why not be attentive and avoid bad
habits?



My System SpecsSystem Spec
Old 05-22-2009   #7 (permalink)
ekkehard.horner


 
 

Re: Problem in returning an object from a function

mayayana schrieb:
Quote:
Quote:

>> (1) It's not sloppy to be passing around objects and depending
>> on the WSH to clean them all up, but good programming practice.
>> Memory management is what the runtime system is good for. Except
>> for a few special cases, setting a variable to Nothing is a waste
>> of time.
>>
>
> That's an old debate and I can see the logic
> of your view. There are good points on both sides.
> Personally I would especially avoid passing an
> object whose parent object is going out of scope.
> It might work OK under the WSH. I don't really
> know. But it's sloppy and potentially risky either
> way. And someday you might need to be coding
> in something that doesn't coddle you as much
> as the WSH does.
The memory management is part of the VBScript language runtime.
Objects will be destroyed when they go out of scope with a reference
count = 0 regardless of whether the script is hosted by cscript, wscript,
ie, mshta, or a scripthost.

VBScript's memory management depends on reference counting. An
object won't be destroyed if it is still needed. So returning a
(child) object from a function - as in Richard's

Function ListFiles(Byval path)
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(path)
Set ListFiles = objFolder.Files
End Function

or in Tom's

Function colFiles(Byval path) ' as file collection
with CreateObject("Scripting.FileSystemObject")
set colFiles = .GetFolder(path).Files
end with
End Function

is absolutely correct. Calling this sloppy or risky - without any
evidence for a faulty implementation of VBScript's memory management
- is just fearmongering. To imply that a programmer using the
features of his language as specified is coddled, is ridiculous.
Quote:

> It's kind of like signalling a turn when driving. It's
> not necessary if there are no other cars around,
> but if one just gets into the habit of always signalling
> then one doesn't have to look around and make a
> decision at each turn; and there's no harm in "wasted"
> signalling.
No, it's like advising to always disconnect the battery before you
switch off your car, because you don't trust the switch. In the
best case it hides a problem with the car that should be remedied.

There is no evidence that the VBScript runtime does not do its duty.
If there were, you should

(a) switch to a language with better memory management

(b) ask Microsoft to fix the implementation error

(c) use the "Set x = Nothing" only in those cases where it is
necessary as a workaround (and use a comment to explain why)
Quote:
Quote:

>> (2) Taking a (rich) collection you got for free from the FSO and copy it
>> to an array (with reduced info) is wasteful and distracts from the
>> problem to be solved.
>>
>
> You didn't get it for free. So why hold it if you don't
> need it? (The OP gave no indication that anything
> more than file names was needed.) WSH may hide the
> details, but there's still cost. Not much cost in this case,
> for sure, but again, why not be attentive and avoid bad
> habits?
The OP clearly indicated that she/he wants to loop over a
collection and to MsgBox oFile.Name. That can't be done without
creating a files collection, which needs to be around until after
the OP's top level loop. The problem of waste and its disposal
was created solely by your idea to copy that collection into an
array (of the file names only).

Now I will repeat: Your claim that

...
Next
Set colFiles = Nothing
Set objFolder = Nothing
Set objFSO = Nothing
ListFiles = A1
End Function

is more attentive ('better') than

...
Next
ListFiles = A1
End Function <=== all objects with a reference count = 0 (including A1)
are destroyed

is unfounded.
My System SpecsSystem Spec
Old 05-22-2009   #8 (permalink)
mayayana


 
 

Re: Problem in returning an object from a function

> Calling this sloppy or risky - without any
Quote:

> evidence for a faulty implementation of
> VBScript's memory management
> is just fearmongering...
Quote:

>
Quote:

> > It's kind of like signalling a turn when driving. It's
> > not necessary if there are no other cars around,
> > but if one just gets into the habit of always signalling
> > then one doesn't have to look around and make a
> > decision at each turn; and there's no harm in "wasted"
> > signalling.
>
> No, it's like advising to always disconnect the battery before you
> switch off your car, because you don't trust the switch. In the
> best case it hides a problem with the car that should be remedied.
>
I really don't understand the vehement
emotionalism this topic evokes. Fearmongering?!
Only if paying attention to resources scares you.

I've got two links here. People can read them
and decide for themselves. (This isn't the first
time such links have been posted here, but there
may be people who haven't seen them.)

On the issue of Set x = Nothing before leaving
a sub or function, for an object created within the
function, I think all of the experts are
in agreement with you that it's not necessary.

As for other
cases, the link from Eric Lippert describes lots of
issues. Even Eric Lippert himself, who's as vehement
as you are about this issue, tempers his position:

"However, just to clarify, my beef is specifically with people who clear
object variables IMMEDIATELY before they go out of a local scope. It is a
really good idea to clear variables that hold expensive resources as soon as
you're done with them if you're going to go do other stuff before they fall
out of scope."

In the case of the sample code we were talking
about, FSO, Folder, and a Files collection object
are all created within the function. The Files collection
is then passed. So while the objects should all be
ready to be cleared after exiting the function, I doubt
they can be because of the reference to the Files
collection. That situation could get worse if multiple
variables are used to return several Files collections.

So there are two issues there. If you don't want
to set objects to nothing within a function then you
have all the experts to back you up. But passing
the Files collection gets into an issue of paying
attention to resources and writing orderly code. The
original code as written implies ignorance of that.

If you don't like the idea of returning the array of
file names then you could use a global FSO, or a class.
But however you look at, wouldn't you agree that a
function should encapsulate its functionality? And
wouldn't you agree that it's a good idea to try to keep
track of resources and understand what resources you're
using? I don't see how you can defend overlapping objects
from within a function into the global scope of the script.
After all, if it's OK to pass Files then why not Folder?
Or even FSO itself? ... See what I mean? The whole
purpose of the function is not understood in code like
that.

Which gets back to one of the reasons I gave to
use Set x = Nothing -- because even if it's not really
needed in some cases, and even if WSH is good at
picking up after us, it's still a good idea to cultivate
the habit of being aware of what the code is doing,
as much as possible, and of what resources are being
used. (One need only look at Windows Vista/7 and .Net
to see how quickly things can go south when one ignores
resource usage.


Anyway, here are the links. People can make
their own decisions based on the discussion of
several Microsoft experts:

http://www.ddj.com/windows/184405720

http://blogs.msdn.com/ericlippert/ar...28/122259.aspx


My System SpecsSystem Spec
Reply

Thread Tools


Similar Threads
Thread Forum
function not returning anything PowerShell
Function returning a value VB Script
select-object not returning properties that are objects PowerShell
Returning Variables from a Function... PowerShell
HOW TO: Return an Object from a Function/Filter PowerShell


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46