![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| 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. |
| |||||||
![]() |
| |
| | #1 (permalink) |
| | 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 Specs![]() |
| | #2 (permalink) |
| | 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 > 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 Specs![]() |
| | #3 (permalink) |
| | 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 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 Specs![]() |
| | #4 (permalink) |
| | 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 Specs![]() |
| | #5 (permalink) |
| | 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) Quote: Quote: >> Next Quote: > If you really just wanted a list, I'd modify it as ... 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 Specs![]() |
| | #6 (permalink) |
| | 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. > 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. > 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 Specs![]() |
| | #7 (permalink) |
| | 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. 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. 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? 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 Specs![]() |
| | #8 (permalink) |
| | 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. > 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 Specs![]() |
![]() |
| 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 | |||